Merge branch 'master' of https://github.com/supertuxkart/stk-code
This commit is contained in:
commit
e31a7ca4a8
@ -18,9 +18,10 @@
|
||||
|
||||
#include "font/bold_face.hpp"
|
||||
|
||||
#include "font/face_ttf.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Constructor of BoldFace.
|
||||
* \param ttf \ref FaceTTF for BoldFace to use.
|
||||
*/
|
||||
BoldFace::BoldFace(FaceTTF* ttf) : FontWithFace("BoldFace", ttf)
|
||||
{
|
||||
} // BoldFace
|
||||
@ -53,3 +54,12 @@ void BoldFace::reset()
|
||||
insertCharacters(preload_chars.c_str());
|
||||
updateCharactersList();
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Embolden the glyph to make bold font using FT_Outline_Embolden.
|
||||
* \return A FT_Error value.
|
||||
*/
|
||||
int BoldFace::shapeOutline(FT_Outline* outline) const
|
||||
{
|
||||
return FT_Outline_Embolden(outline, getDPI() * 2);
|
||||
} // shapeOutline
|
||||
|
@ -23,24 +23,28 @@
|
||||
|
||||
class FaceTTF;
|
||||
|
||||
/** A font which uses regular TTFs to render title or important message in STK
|
||||
* with a bold outline, it shares the same \ref FaceTTF with \ref RegularFace.
|
||||
* \ingroup font
|
||||
*/
|
||||
class BoldFace : public FontWithFace
|
||||
{
|
||||
private:
|
||||
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 1024; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual float getScalingFactorOne() const OVERRIDE { return 0.2f; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual unsigned int getScalingFactorTwo() const OVERRIDE { return 120; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool isBold() const { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual int shapeOutline(FT_Outline* outline) const OVERRIDE;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
BoldFace(FaceTTF* ttf);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~BoldFace() {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset() OVERRIDE;
|
||||
|
@ -18,9 +18,10 @@
|
||||
|
||||
#include "font/digit_face.hpp"
|
||||
|
||||
#include "font/face_ttf.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Constructor of DigitFace.
|
||||
* \param ttf \ref FaceTTF for DigitFace to use.
|
||||
*/
|
||||
DigitFace::DigitFace(FaceTTF* ttf) : FontWithFace("DigitFace", ttf)
|
||||
{
|
||||
} // DigitFace
|
||||
|
@ -23,6 +23,9 @@
|
||||
|
||||
class FaceTTF;
|
||||
|
||||
/** A font which uses a more cartonish style TTF to render big numbers in STK.
|
||||
* \ingroup font
|
||||
*/
|
||||
class DigitFace : public FontWithFace
|
||||
{
|
||||
private:
|
||||
@ -39,8 +42,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
DigitFace(FaceTTF* ttf);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~DigitFace() {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset() OVERRIDE;
|
||||
|
@ -18,22 +18,29 @@
|
||||
|
||||
#include "font/face_ttf.hpp"
|
||||
|
||||
#include "font/font_manager.hpp"
|
||||
#include "io/file_manager.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)
|
||||
{
|
||||
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(),
|
||||
(file_manager->getAssetChecked(FileManager::TTF,
|
||||
font.c_str(), true)).c_str(), 0, &face), "loading fonts");
|
||||
loc.c_str(), 0, &face), loc + " is loaded");
|
||||
m_faces.push_back(face);
|
||||
}
|
||||
} // FaceTTF
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Destructor. Clears all TTFs.
|
||||
*/
|
||||
FaceTTF::~FaceTTF()
|
||||
{
|
||||
for (unsigned int i = 0; i < m_faces.size(); i++)
|
||||
@ -42,6 +49,9 @@ FaceTTF::~FaceTTF()
|
||||
}
|
||||
} // ~FaceTTF
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Return a TTF in \ref m_faces.
|
||||
* \param i index of TTF file in \ref m_faces.
|
||||
*/
|
||||
FT_Face FaceTTF::getFace(unsigned int i) const
|
||||
{
|
||||
assert(i < m_faces.size());
|
||||
|
@ -19,15 +19,30 @@
|
||||
#ifndef HEADER_FACE_TTF_HPP
|
||||
#define HEADER_FACE_TTF_HPP
|
||||
|
||||
#include "font/font_manager.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
/** This class will load a list of TTF files from \ref STKConfig, 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
|
||||
{
|
||||
private:
|
||||
/** Contains all TTF files loaded. */
|
||||
std::vector<FT_Face> m_faces;
|
||||
|
||||
public:
|
||||
LEAK_CHECK();
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
FaceTTF(const std::vector<std::string>& ttf_list);
|
||||
// ------------------------------------------------------------------------
|
||||
@ -35,6 +50,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
FT_Face getFace(unsigned int i) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the total TTF files loaded. */
|
||||
unsigned int getTotalFaces() const { return m_faces.size(); }
|
||||
|
||||
}; // FaceTTF
|
||||
|
@ -28,15 +28,22 @@
|
||||
|
||||
FontManager *font_manager = NULL;
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Constructor. It will initialize the \ref m_ft_library.
|
||||
*/
|
||||
FontManager::FontManager()
|
||||
{
|
||||
checkFTError(FT_Init_FreeType(&m_ft_library), "loading freetype library");
|
||||
} // FontManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Destructor. Clears all fonts and related stuff.
|
||||
*/
|
||||
FontManager::~FontManager()
|
||||
{
|
||||
m_fonts.clearAndDeleteAll();
|
||||
for (unsigned int i = 0; i < m_fonts.size(); i++)
|
||||
delete m_fonts[i];
|
||||
m_fonts.clear();
|
||||
|
||||
delete m_normal_ttf;
|
||||
m_normal_ttf = NULL;
|
||||
delete m_digit_ttf;
|
||||
@ -47,6 +54,8 @@ FontManager::~FontManager()
|
||||
} // ~FontManager
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Initialize all \ref FaceTTF and \ref FontWithFace members.
|
||||
*/
|
||||
void FontManager::loadFonts()
|
||||
{
|
||||
// First load the TTF files required by each font
|
||||
@ -72,15 +81,10 @@ void FontManager::loadFonts()
|
||||
} // loadFonts
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void FontManager::checkFTError(FT_Error err, const std::string& desc) const
|
||||
{
|
||||
if (err > 0)
|
||||
{
|
||||
Log::error("FontManager", "Something wrong when %s!", desc.c_str());
|
||||
}
|
||||
} // checkFTError
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Unit testing that will try to load all translations in STK, and discover if
|
||||
* there is any characters required by it are not supported in \ref
|
||||
* m_normal_ttf.
|
||||
*/
|
||||
void FontManager::unitTesting()
|
||||
{
|
||||
std::vector<std::string> list = *(translations->getLanguageList());
|
||||
|
@ -19,14 +19,18 @@
|
||||
#ifndef HEADER_FONT_MANAGER_HPP
|
||||
#define HEADER_FONT_MANAGER_HPP
|
||||
|
||||
/** \defgroup font Font
|
||||
* This module stores font files and tools used to draw characters in STK.
|
||||
*/
|
||||
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/ptr_vector.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
@ -34,17 +38,26 @@
|
||||
class FaceTTF;
|
||||
class FontWithFace;
|
||||
|
||||
/** This class stores all font files required in STK.
|
||||
* \ingroup font
|
||||
*/
|
||||
class FontManager : public NoCopy
|
||||
{
|
||||
private:
|
||||
PtrVector<FontWithFace> m_fonts;
|
||||
/** Stores all \ref FontWithFace used in STK. */
|
||||
std::vector<FontWithFace*> m_fonts;
|
||||
|
||||
/** A FreeType library, it holds the FT_Face internally inside freetype. */
|
||||
FT_Library m_ft_library;
|
||||
|
||||
/** 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;
|
||||
|
||||
public:
|
||||
@ -54,11 +67,12 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
~FontManager();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return a specfic type of \ref FontWithFace found in \ref m_fonts. */
|
||||
template <typename T> T* getFont()
|
||||
{
|
||||
T* out = NULL;
|
||||
const unsigned int n = m_font_type_map[std::type_index(typeid(T))];
|
||||
out = dynamic_cast<T*>(m_fonts.get(n));
|
||||
out = dynamic_cast<T*>(m_fonts[n]);
|
||||
if (out != NULL)
|
||||
{
|
||||
return out;
|
||||
@ -68,16 +82,23 @@ public:
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Check for any error discovered in a freetype function that will return
|
||||
* a FT_Error value.
|
||||
* a FT_Error value, and log into the terminal.
|
||||
* \param err The Freetype function.
|
||||
* \param desc The description of what is the function doing.
|
||||
*/
|
||||
void checkFTError(FT_Error err, const std::string& desc) const;
|
||||
* \param desc The description of what is the function doing. */
|
||||
void checkFTError(FT_Error err, const std::string& desc) const
|
||||
{
|
||||
if (err > 0)
|
||||
{
|
||||
Log::error("FontManager", "Something wrong when %s! The error "
|
||||
"code was %d.", desc.c_str(), err);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void loadFonts();
|
||||
// ------------------------------------------------------------------------
|
||||
void unitTesting();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the \ref m_ft_library. */
|
||||
FT_Library getFTLibrary() const { return m_ft_library; }
|
||||
|
||||
}; // FontManager
|
||||
|
@ -25,21 +25,34 @@
|
||||
|
||||
using namespace irr;
|
||||
|
||||
/** This class stores settings when rendering fonts, used when instantiating
|
||||
* \ref irr::gui::ScalableFont.
|
||||
* \ingroup font
|
||||
*/
|
||||
class FontSettings
|
||||
{
|
||||
private:
|
||||
/** True if black border will be drawn when rendering. */
|
||||
bool m_black_border;
|
||||
|
||||
/** If true, characters will have right alignment when rendering, for RTL
|
||||
* language. */
|
||||
bool m_rtl;
|
||||
|
||||
/** Scaling when rendering. */
|
||||
float m_scale;
|
||||
|
||||
/** True if shadow will be drawn when rendering. */
|
||||
bool m_shadow;
|
||||
|
||||
/** Save the color of shadow when rendering. */
|
||||
video::SColor m_shadow_color;
|
||||
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
/** Constructor. It will initialize all members with default values if no
|
||||
* parameter is given. */
|
||||
FontSettings(bool black_border = false, bool rtl = false,
|
||||
float scale = 1.0f, bool shadow = false,
|
||||
const video::SColor& color = video::SColor(0, 0, 0, 0))
|
||||
@ -51,26 +64,39 @@ public:
|
||||
m_shadow_color = color;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
~FontSettings() {}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set the scaling.
|
||||
* \param scale Scaling to be set. */
|
||||
void setScale(float scale) { m_scale = scale; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the scaling. */
|
||||
float getScale() const { return m_scale; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set the color of shadow.
|
||||
* \param col The color of shadow to be set. */
|
||||
void setShadowColor(const video::SColor &col) { m_shadow_color = col; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the color of shadow. */
|
||||
const video::SColor& getShadowColor() const { return m_shadow_color; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return if shadow is enabled. */
|
||||
bool useShadow() const { return m_shadow; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set whether shadow is enabled.
|
||||
* \param shadow If it's enabled. */
|
||||
void setShadow(bool shadow) { m_shadow = shadow; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set whether black border is enabled.
|
||||
* \param border If it's enabled. */
|
||||
void setBlackBorder(bool border) { m_black_border = border; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return if black border is enabled. */
|
||||
bool useBlackBorder() const { return m_black_border; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set right text alignment for RTL language.
|
||||
* \param rtl If it's enabled. */
|
||||
void setRTL(bool rtl) { m_rtl = rtl; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return if right text alignment for RTL language is enabled. */
|
||||
bool isRTL() const { return m_rtl; }
|
||||
|
||||
}; // FontSettings
|
||||
|
@ -18,17 +18,20 @@
|
||||
|
||||
#include "font/font_with_face.hpp"
|
||||
|
||||
#include "font/bold_face.hpp"
|
||||
#include "font/face_ttf.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/font_settings.hpp"
|
||||
#include "graphics/2dutils.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/skin.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Constructor. It will initialize the \ref m_spritebank and TTF files to use.
|
||||
* \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)
|
||||
{
|
||||
m_spritebank = irr_driver->getGUI()->addEmptySpriteBank(name.c_str());
|
||||
@ -43,6 +46,8 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
|
||||
|
||||
} // FontWithFace
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Destructor. Clears the glyph page and sprite bank.
|
||||
*/
|
||||
FontWithFace::~FontWithFace()
|
||||
{
|
||||
m_page->drop();
|
||||
@ -56,6 +61,8 @@ FontWithFace::~FontWithFace()
|
||||
} // ~FontWithFace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Initialize the font structure, but don't load glyph here.
|
||||
*/
|
||||
void FontWithFace::init()
|
||||
{
|
||||
setDPI();
|
||||
@ -83,7 +90,11 @@ void FontWithFace::init()
|
||||
|
||||
reset();
|
||||
} // init
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Clear all the loaded characters, sub-class can do pre-loading of characters
|
||||
* after this.
|
||||
*/
|
||||
void FontWithFace::reset()
|
||||
{
|
||||
m_new_char_holder.clear();
|
||||
@ -94,6 +105,12 @@ void FontWithFace::reset()
|
||||
} // reset
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Convert a character to a glyph index in one of the font in \ref m_face_ttf,
|
||||
* it will find the first TTF that supports this character, if the final
|
||||
* glyph_index is 0, this means such character is not supported by all TTFs in
|
||||
* \ref m_face_ttf.
|
||||
* \param c The character to be loaded.
|
||||
*/
|
||||
void FontWithFace::loadGlyphInfo(wchar_t c)
|
||||
{
|
||||
unsigned int font_number = 0;
|
||||
@ -108,11 +125,12 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
|
||||
} // loadGlyphInfo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Create a new glyph page by filling it with transparent content.
|
||||
*/
|
||||
void FontWithFace::createNewGlyphPage()
|
||||
{
|
||||
// Clean the current glyph page by filling it with transparent content
|
||||
m_page->fill(video::SColor(0, 255, 255, 255));
|
||||
m_temp_height = 0;
|
||||
m_current_height = 0;
|
||||
m_used_width = 0;
|
||||
m_used_height = 0;
|
||||
|
||||
@ -140,6 +158,10 @@ void FontWithFace::createNewGlyphPage()
|
||||
} // 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)
|
||||
{
|
||||
assert(gi.glyph_index > 0);
|
||||
@ -147,7 +169,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
FT_Face cur_face = m_face_ttf->getFace(gi.font_number);
|
||||
FT_GlyphSlot slot = cur_face->glyph;
|
||||
|
||||
// Faces may be shared across regular and bold,
|
||||
// Same face may be shared across the different FontWithFace,
|
||||
// so reset dpi each time
|
||||
font_manager->checkFTError(FT_Set_Pixel_Sizes(cur_face, 0, getDPI()),
|
||||
"setting DPI");
|
||||
@ -155,15 +177,11 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
font_manager->checkFTError(FT_Load_Glyph(cur_face, gi.glyph_index,
|
||||
FT_LOAD_DEFAULT), "loading a glyph");
|
||||
|
||||
if (dynamic_cast<BoldFace*>(this) != NULL)
|
||||
{
|
||||
// Embolden the outline of the glyph
|
||||
font_manager->checkFTError(FT_Outline_Embolden(&(slot->outline),
|
||||
getDPI() * 2), "embolden a glyph");
|
||||
}
|
||||
font_manager->checkFTError(shapeOutline(&(slot->outline)),
|
||||
"shaping outline");
|
||||
|
||||
font_manager->checkFTError(FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL),
|
||||
"render a glyph to bitmap");
|
||||
"rendering a glyph to bitmap");
|
||||
|
||||
// Convert to an anti-aliased bitmap
|
||||
FT_Bitmap bits = slot->bitmap;
|
||||
@ -176,7 +194,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
true, 0);
|
||||
|
||||
if ((m_used_width + texture_size.Width > getGlyphPageSize() &&
|
||||
m_used_height + m_temp_height + texture_size.Height >
|
||||
m_used_height + m_current_height + texture_size.Height >
|
||||
getGlyphPageSize()) ||
|
||||
m_used_height + texture_size.Height > getGlyphPageSize())
|
||||
{
|
||||
@ -244,8 +262,8 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
if (m_used_width + texture_size.Width > getGlyphPageSize())
|
||||
{
|
||||
m_used_width = 0;
|
||||
m_used_height += m_temp_height;
|
||||
m_temp_height = 0;
|
||||
m_used_height += m_current_height;
|
||||
m_current_height = 0;
|
||||
}
|
||||
|
||||
// Copy to the full glyph page
|
||||
@ -283,11 +301,13 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
|
||||
// Store used area
|
||||
m_used_width += texture_size.Width;
|
||||
if (m_temp_height < texture_size.Height)
|
||||
m_temp_height = texture_size.Height;
|
||||
if (m_current_height < texture_size.Height)
|
||||
m_current_height = texture_size.Height;
|
||||
} // insertGlyph
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Update the supported characters for this font if required.
|
||||
*/
|
||||
void FontWithFace::updateCharactersList()
|
||||
{
|
||||
if (m_fallback_font != NULL)
|
||||
@ -321,6 +341,10 @@ void FontWithFace::updateCharactersList()
|
||||
} // updateCharactersList
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Write the current glyph page in png inside current running directory.
|
||||
* Mainly for debug use.
|
||||
* \param name The file name.
|
||||
*/
|
||||
void FontWithFace::dumpGlyphPage(const std::string& name)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
|
||||
@ -341,20 +365,23 @@ void FontWithFace::dumpGlyphPage(const std::string& name)
|
||||
} // dumpGlyphPage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Write the current glyph page in png inside current running directory.
|
||||
* Useful in gdb without parameter.
|
||||
*/
|
||||
void FontWithFace::dumpGlyphPage()
|
||||
{
|
||||
dumpGlyphPage("face");
|
||||
} // dumpGlyphPage
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Set the face dpi which 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.
|
||||
* Bold text will range from 0.2, in 640x* resolutions (won't scale below
|
||||
* that) to 0.4, in 1024x* resolutions, and linearly up.
|
||||
*/
|
||||
void FontWithFace::setDPI()
|
||||
{
|
||||
// Set face dpi:
|
||||
// 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
|
||||
// Bold 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;
|
||||
@ -371,6 +398,10 @@ void FontWithFace::setDPI()
|
||||
} // setDPI
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Return the \ref FontArea about a character.
|
||||
* \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
|
||||
@ -397,6 +428,12 @@ const FontWithFace::FontArea&
|
||||
} // getAreaFromCharacter
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Get the dimension of text with support to different \ref FontSettings,
|
||||
* it will also do checking for missing characters in font and lazy load them.
|
||||
* \param text The text to be calculated.
|
||||
* \param font_settings \ref FontSettings to use.
|
||||
* \return The dimension of text
|
||||
*/
|
||||
core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
|
||||
FontSettings* font_settings)
|
||||
{
|
||||
@ -441,6 +478,12 @@ core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
|
||||
} // getDimension
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Calculate the index of the character in the text on a specific position.
|
||||
* \param text The text to be calculated.
|
||||
* \param pixel_x The specific position.
|
||||
* \param font_settings \ref FontSettings to use.
|
||||
* \return The index of the character, -1 means no character in such position.
|
||||
*/
|
||||
int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
|
||||
FontSettings* font_settings) const
|
||||
{
|
||||
@ -466,6 +509,17 @@ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
|
||||
} // getCharacterFromPos
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Render text and clip it to the specified rectangle if wanted, it will also
|
||||
* do checking for missing characters in font and lazy load them.
|
||||
* \param text The text to be rendering.
|
||||
* \param position The position to be rendering.
|
||||
* \param color The color used when rendering.
|
||||
* \param hcenter If rendered horizontally center.
|
||||
* \param vcenter If rendered vertically center.
|
||||
* \param clip If clipping is needed.
|
||||
* \param font_settings \ref FontSettings to use.
|
||||
* \param char_collector \ref FontCharCollector to render billboard text.
|
||||
*/
|
||||
void FontWithFace::render(const core::stringw& text,
|
||||
const core::rect<s32>& position,
|
||||
const video::SColor& color, bool hcenter,
|
||||
@ -473,7 +527,6 @@ void FontWithFace::render(const core::stringw& text,
|
||||
FontSettings* font_settings,
|
||||
FontCharCollector* char_collector)
|
||||
{
|
||||
const bool is_bold_face = (dynamic_cast<BoldFace*>(this) != NULL);
|
||||
const bool black_border = font_settings ?
|
||||
font_settings->useBlackBorder() : false;
|
||||
const bool rtl = font_settings ? font_settings->isRTL() : false;
|
||||
@ -621,7 +674,7 @@ void FontWithFace::render(const core::stringw& text,
|
||||
|
||||
const int sprite_amount = sprites.size();
|
||||
|
||||
if ((black_border || is_bold_face) && char_collector == NULL)
|
||||
if ((black_border || isBold()) && char_collector == NULL)
|
||||
{
|
||||
// Draw black border first, to make it behind the real character
|
||||
// which make script language display better
|
||||
@ -693,7 +746,7 @@ void FontWithFace::render(const core::stringw& text,
|
||||
m_fallback_font->m_spritebank->getTexture(tex_id) :
|
||||
m_spritebank->getTexture(tex_id));
|
||||
|
||||
if (fallback[n] || is_bold_face)
|
||||
if (fallback[n] || isBold())
|
||||
{
|
||||
video::SColor top = GUIEngine::getSkin()->getColor("font::top");
|
||||
video::SColor bottom = GUIEngine::getSkin()
|
||||
|
@ -19,47 +19,84 @@
|
||||
#ifndef HEADER_FONT_WITH_FACE_HPP
|
||||
#define HEADER_FONT_WITH_FACE_HPP
|
||||
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/font_settings.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include "utils/leak_check.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
#include <irrlicht.h>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
const int BEARING = 64;
|
||||
|
||||
class FaceTTF;
|
||||
class FontSettings;
|
||||
|
||||
/** An abstract class which contains functions which convert vector fonts into
|
||||
* bitmap and render them in STK. To make STK draw characters with different
|
||||
* render option (like scaling, shadow) using a same FontWithFace, you need
|
||||
* to wrap this with \ref irr::gui::ScalableFont and configure the
|
||||
* \ref FontSettings for it.
|
||||
* \ingroup font
|
||||
*/
|
||||
class FontWithFace : public NoCopy
|
||||
{
|
||||
public:
|
||||
/** A class for \ref STKTextBillboard to get font info to render billboard
|
||||
* text. */
|
||||
class FontCharCollector
|
||||
{
|
||||
public:
|
||||
/** Collect the character info for billboard text.
|
||||
* \param texture The texture of the character.
|
||||
* \param destRect The destination rectangle
|
||||
* \param sourceRect The source rectangle in the glyph page
|
||||
* \param colors The color to render it. */
|
||||
virtual void collectChar(video::ITexture* texture,
|
||||
const core::rect<float>& destRect,
|
||||
const core::rect<s32>& sourceRect,
|
||||
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:
|
||||
int m_font_max_height;
|
||||
/** Used in vertical dimension calculation. */
|
||||
int m_font_max_height;
|
||||
|
||||
int m_glyph_max_height;
|
||||
/** Used in top side bearing calculation. */
|
||||
int m_glyph_max_height;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Check characters to see if they are loaded in font, if not load them.
|
||||
* For font that doesn't need lazy loading, nothing will be done.
|
||||
* \param in_ptr Characters to check.
|
||||
* \param first_load If true, it will ignore \ref supportLazyLoadChar,
|
||||
* which is called in \ref reset. */
|
||||
void insertCharacters(const wchar_t* in_ptr, bool first_load = false)
|
||||
{
|
||||
if (!supportLazyLoadChar() && !first_load) return;
|
||||
@ -88,44 +125,69 @@ protected:
|
||||
// ------------------------------------------------------------------------
|
||||
void updateCharactersList();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set the fallback font for this font, so if some character is missing in
|
||||
* this font, it will use that fallback font to try rendering it.
|
||||
* \param face A \ref FontWithFace font. */
|
||||
void setFallbackFont(FontWithFace* face) { m_fallback_font = face; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Set the scaling of fallback font.
|
||||
* \param scale The scaling to set. */
|
||||
void setFallbackFontScale(float scale) { m_fallback_font_scale = scale; }
|
||||
|
||||
private:
|
||||
/** Mapping of glyph index to a TTF in \ref FaceTTF. */
|
||||
struct GlyphInfo
|
||||
{
|
||||
GlyphInfo(unsigned int font_num = 0, unsigned int glyph_idx = 0) :
|
||||
font_number(font_num), glyph_index(glyph_idx) {}
|
||||
/** Index to a TTF in \ref FaceTTF. */
|
||||
unsigned int font_number;
|
||||
/** Glyph index in the TTF, 0 means no such glyph. */
|
||||
unsigned int glyph_index;
|
||||
GlyphInfo(unsigned int first = 0, unsigned int second = 0)
|
||||
{
|
||||
font_number = first;
|
||||
glyph_index = second;
|
||||
}
|
||||
};
|
||||
|
||||
/** \ref FaceTTF to load glyph from. */
|
||||
FaceTTF* m_face_ttf;
|
||||
|
||||
/** Fallback font to use if some character isn't supported by this font. */
|
||||
FontWithFace* m_fallback_font;
|
||||
|
||||
/** Scaling for fallback font. */
|
||||
float m_fallback_font_scale;
|
||||
|
||||
/** A temporary holder stored new char to be inserted. */
|
||||
/** A temporary holder to store new characters to be inserted. */
|
||||
std::set<wchar_t> m_new_char_holder;
|
||||
|
||||
/** Sprite bank to store each glyph. */
|
||||
gui::IGUISpriteBank* m_spritebank;
|
||||
|
||||
/** A full glyph page for this font. */
|
||||
video::IImage* m_page;
|
||||
|
||||
unsigned int m_temp_height;
|
||||
/** The current max height at current drawing line in glyph page. */
|
||||
unsigned int m_current_height;
|
||||
|
||||
/** The used width in glyph page. */
|
||||
unsigned int m_used_width;
|
||||
|
||||
/** The used height in glyph page. */
|
||||
unsigned int m_used_height;
|
||||
|
||||
/** 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)
|
||||
@ -134,6 +196,9 @@ private:
|
||||
return area.advance_x * scale;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Test if a character has already been tried to be loaded.
|
||||
* \param c Character to test.
|
||||
* \return True if tested. */
|
||||
bool loadedChar(wchar_t c) const
|
||||
{
|
||||
std::map<wchar_t, GlyphInfo>::const_iterator n =
|
||||
@ -143,6 +208,10 @@ private:
|
||||
return false;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the \ref GlyphInfo from \ref m_character_glyph_info_map about a
|
||||
* character.
|
||||
* \param c Character to get.
|
||||
* \return \ref GlyphInfo of this character. */
|
||||
const GlyphInfo& getGlyphInfo(wchar_t c) const
|
||||
{
|
||||
std::map<wchar_t, GlyphInfo>::const_iterator n =
|
||||
@ -152,6 +221,10 @@ private:
|
||||
return n->second;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Tells whether a character is supported by all TTFs in \ref m_face_ttf
|
||||
* which is determined by \ref GlyphInfo of this character.
|
||||
* \param c Character to test.
|
||||
* \return True if it's supported. */
|
||||
bool supportChar(wchar_t c)
|
||||
{
|
||||
std::map<wchar_t, GlyphInfo>::const_iterator n =
|
||||
@ -167,22 +240,36 @@ private:
|
||||
// ------------------------------------------------------------------------
|
||||
void createNewGlyphPage();
|
||||
// ------------------------------------------------------------------------
|
||||
/** 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 setDPI();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool supportLazyLoadChar() const = 0;
|
||||
/** Override it if sub-class should not do lazy loading characters. */
|
||||
virtual bool supportLazyLoadChar() const { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Defined by sub-class about the texture size of glyph page, it should be
|
||||
* a power of two. */
|
||||
virtual unsigned int getGlyphPageSize() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Defined by sub-class about the scaling factor 1. */
|
||||
virtual float getScalingFactorOne() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Defined by sub-class about the scaling factor 2. */
|
||||
virtual unsigned int getScalingFactorTwo() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Override it if sub-class has bold outline. */
|
||||
virtual bool isBold() const { return false; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Override it if any outline shaping is needed to be done before
|
||||
* rendering the glyph into bitmap.
|
||||
* \return A FT_Error value if needed. */
|
||||
virtual int shapeOutline(FT_Outline* outline) const { return 0; }
|
||||
|
||||
public:
|
||||
LEAK_CHECK();
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
FontWithFace(const std::string& name, FaceTTF* ttf);
|
||||
// ------------------------------------------------------------------------
|
||||
@ -204,22 +291,17 @@ public:
|
||||
FontSettings* font_settings,
|
||||
FontCharCollector* char_collector = NULL);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Write the current glyph page in png inside current running directory.
|
||||
* Mainly for debug use.
|
||||
* \param name The file name.
|
||||
*/
|
||||
void dumpGlyphPage(const std::string& name);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Write the current glyph page in png inside current running directory.
|
||||
* Useful in gdb without parameter.
|
||||
*/
|
||||
void dumpGlyphPage();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the sprite bank. */
|
||||
gui::IGUISpriteBank* getSpriteBank() const { return m_spritebank; }
|
||||
// ------------------------------------------------------------------------
|
||||
const FontArea& getAreaFromCharacter(const wchar_t c,
|
||||
bool* fallback_font) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the dpi of this face. */
|
||||
unsigned int getDPI() const { return m_face_dpi; }
|
||||
|
||||
}; // FontWithFace
|
||||
|
@ -16,11 +16,12 @@
|
||||
// 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/regular_face.hpp"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Constructor of RegularFace.
|
||||
* \param ttf \ref FaceTTF for RegularFace to use.
|
||||
*/
|
||||
RegularFace::RegularFace(FaceTTF* ttf) : FontWithFace("RegularFace", ttf)
|
||||
{
|
||||
} // RegularFace
|
||||
|
@ -23,11 +23,12 @@
|
||||
|
||||
class FaceTTF;
|
||||
|
||||
/** A font which uses regular TTFs to render most text in STK.
|
||||
* \ingroup font
|
||||
*/
|
||||
class RegularFace : public FontWithFace
|
||||
{
|
||||
private:
|
||||
virtual bool supportLazyLoadChar() const OVERRIDE { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual unsigned int getGlyphPageSize() const OVERRIDE { return 512; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual float getScalingFactorOne() const OVERRIDE { return 0.7f; }
|
||||
@ -39,8 +40,6 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
RegularFace(FaceTTF* ttf);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~RegularFace() {}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void reset() OVERRIDE;
|
||||
|
@ -659,6 +659,8 @@ namespace GUIEngine
|
||||
#include "config/user_config.hpp"
|
||||
#include "font/bold_face.hpp"
|
||||
#include "font/digit_face.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/font_settings.hpp"
|
||||
#include "font/regular_face.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
|
||||
#include "font/font_settings.hpp"
|
||||
#include "font/font_with_face.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
// 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/font_manager.hpp"
|
||||
#include "font/regular_face.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "font/bold_face.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "graphics/camera.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/explosion.hpp"
|
||||
|
@ -101,6 +101,8 @@
|
||||
This module handles the user configuration, the supertuxkart configuration
|
||||
file (which contains options usually not edited by the player) and the input
|
||||
configuration file.
|
||||
\li \ref font :
|
||||
This module stores font files and tools used to draw characters in STK.
|
||||
\li \ref graphics :
|
||||
This module contains the core graphics engine, that is mostly a thin layer
|
||||
on top of irrlicht providing some additional features we need for STK
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "animations/three_d_animation.hpp"
|
||||
#include "font/digit_face.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "graphics/central_settings.hpp"
|
||||
#include "graphics/stk_text_billboard.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "font/bold_face.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/regular_face.hpp"
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
#include "guiengine/screen.hpp"
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "font/bold_face.hpp"
|
||||
#include "font/digit_face.hpp"
|
||||
#include "font/font_manager.hpp"
|
||||
#include "font/regular_face.hpp"
|
||||
#include "graphics/camera_debug.hpp"
|
||||
#include "graphics/camera_fps.hpp"
|
||||
|
Loading…
Reference in New Issue
Block a user