drew the rest of the fucking owl
This commit is contained in:
parent
1bd59415ba
commit
4889e49839
2
games/devtest/mods/fonts/mod.conf
Normal file
2
games/devtest/mods/fonts/mod.conf
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
name = fonts
|
||||||
|
description = Provides font media files
|
@ -52,10 +52,10 @@ FontEngine::~FontEngine()
|
|||||||
{
|
{
|
||||||
g_settings->deregisterAllChangedCallbacks(this);
|
g_settings->deregisterAllChangedCallbacks(this);
|
||||||
|
|
||||||
cleanCache();
|
clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontEngine::cleanCache()
|
void FontEngine::clearCache()
|
||||||
{
|
{
|
||||||
RecursiveMutexAutoLock l(m_font_mutex);
|
RecursiveMutexAutoLock l(m_font_mutex);
|
||||||
|
|
||||||
@ -155,8 +155,8 @@ void FontEngine::readSettings()
|
|||||||
m_default_bold = g_settings->getBool("font_bold");
|
m_default_bold = g_settings->getBool("font_bold");
|
||||||
m_default_italic = g_settings->getBool("font_italic");
|
m_default_italic = g_settings->getBool("font_italic");
|
||||||
|
|
||||||
cleanCache();
|
clearCache();
|
||||||
updateFontCache();
|
updateCache();
|
||||||
updateSkin();
|
updateSkin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,13 +168,34 @@ void FontEngine::updateSkin()
|
|||||||
m_env->getSkin()->setFont(font);
|
m_env->getSkin()->setFont(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontEngine::updateFontCache()
|
void FontEngine::updateCache()
|
||||||
{
|
{
|
||||||
/* the only font to be initialized is default one,
|
/* the only font to be initialized is default one,
|
||||||
* all others are re-initialized on demand */
|
* all others are re-initialized on demand */
|
||||||
getFont(FONT_SIZE_UNSPECIFIED, FM_Unspecified);
|
getFont(FONT_SIZE_UNSPECIFIED, FM_Unspecified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FontEngine::setMediaFont(const std::string &name, const std::string &data)
|
||||||
|
{
|
||||||
|
std::string copy = data;
|
||||||
|
irr_ptr<gui::SGUITTFace> face(gui::SGUITTFace::createFace(std::move(copy)));
|
||||||
|
m_media_faces.emplace(name, face);
|
||||||
|
// HACK dedup this
|
||||||
|
clearCache();
|
||||||
|
updateCache();
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontEngine::clearMediaFonts()
|
||||||
|
{
|
||||||
|
RecursiveMutexAutoLock l(m_font_mutex);
|
||||||
|
m_media_faces.clear();
|
||||||
|
// HACK dedup this
|
||||||
|
clearCache();
|
||||||
|
updateCache();
|
||||||
|
updateSkin();
|
||||||
|
}
|
||||||
|
|
||||||
gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
|
gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
|
||||||
{
|
{
|
||||||
assert(spec.mode != FM_Unspecified);
|
assert(spec.mode != FM_Unspecified);
|
||||||
@ -220,11 +241,46 @@ gui::IGUIFont *FontEngine::initFont(const FontSpec &spec)
|
|||||||
Settings::getLayer(SL_DEFAULTS)->get(path_setting)
|
Settings::getLayer(SL_DEFAULTS)->get(path_setting)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const std::string &font_path : fallback_settings) {
|
std::string media_name = spec.mode == FM_Mono
|
||||||
gui::CGUITTFont *font = gui::CGUITTFont::createTTFont(m_env,
|
? "mono" + setting_suffix
|
||||||
font_path.c_str(), size, true, true, font_shadow,
|
: (setting_suffix.empty() ? "" : setting_suffix.substr(1));
|
||||||
|
if (media_name == "") media_name = "regular";
|
||||||
|
|
||||||
|
auto it = m_media_faces.find(media_name);
|
||||||
|
if (it != m_media_faces.end()) {
|
||||||
|
auto *face = it->second.get();
|
||||||
|
face->grab();
|
||||||
|
auto *font = gui::CGUITTFont::createTTFont(m_env,
|
||||||
|
face, size, true, true, font_shadow,
|
||||||
font_shadow_alpha);
|
font_shadow_alpha);
|
||||||
|
|
||||||
|
if (!font) {
|
||||||
|
errorstream << "FontEngine: Cannot load media font '" << media_name <<
|
||||||
|
"'. Falling back to client settings." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK this tidbit is duplicated
|
||||||
|
if (spec.mode != _FM_Fallback) {
|
||||||
|
FontSpec spec2(spec);
|
||||||
|
spec2.mode = _FM_Fallback;
|
||||||
|
font->setFallback(getFont(spec2, true));
|
||||||
|
}
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const std::string &font_path : fallback_settings) {
|
||||||
|
infostream << "Creating new font: " << font_path.c_str()
|
||||||
|
<< " " << size << "pt" << std::endl;
|
||||||
|
|
||||||
|
// Grab the face.
|
||||||
|
auto *face = irr::gui::SGUITTFace::loadFace(font_path);
|
||||||
|
gui::CGUITTFont *font = nullptr;
|
||||||
|
if (face) {
|
||||||
|
font = gui::CGUITTFont::createTTFont(m_env,
|
||||||
|
face, size, true, true, font_shadow,
|
||||||
|
font_shadow_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
if (!font) {
|
if (!font) {
|
||||||
errorstream << "FontEngine: Cannot load '" << font_path <<
|
errorstream << "FontEngine: Cannot load '" << font_path <<
|
||||||
"'. Trying to fall back to another path." << std::endl;
|
"'. Trying to fall back to another path." << std::endl;
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include "irr_ptr.h"
|
||||||
|
#include "irrlicht_changes/CGUITTFont.h"
|
||||||
#include "util/basic_macros.h"
|
#include "util/basic_macros.h"
|
||||||
#include "irrlichttypes.h"
|
#include "irrlichttypes.h"
|
||||||
#include "irrString.h" // utf8_to_wide
|
#include "irrString.h" // utf8_to_wide
|
||||||
@ -66,7 +69,7 @@ public:
|
|||||||
/** get text height for a specific font */
|
/** get text height for a specific font */
|
||||||
unsigned int getTextHeight(const FontSpec &spec);
|
unsigned int getTextHeight(const FontSpec &spec);
|
||||||
|
|
||||||
/** get text width if a text for a specific font */
|
/** get text width of a text for a specific font */
|
||||||
unsigned int getTextHeight(
|
unsigned int getTextHeight(
|
||||||
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
||||||
FontMode mode=FM_Unspecified)
|
FontMode mode=FM_Unspecified)
|
||||||
@ -77,7 +80,7 @@ public:
|
|||||||
|
|
||||||
unsigned int getTextWidth(const std::wstring &text, const FontSpec &spec);
|
unsigned int getTextWidth(const std::wstring &text, const FontSpec &spec);
|
||||||
|
|
||||||
/** get text width if a text for a specific font */
|
/** get text width of a text for a specific font */
|
||||||
unsigned int getTextWidth(const std::wstring& text,
|
unsigned int getTextWidth(const std::wstring& text,
|
||||||
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
unsigned int font_size=FONT_SIZE_UNSPECIFIED,
|
||||||
FontMode mode=FM_Unspecified)
|
FontMode mode=FM_Unspecified)
|
||||||
@ -118,11 +121,15 @@ public:
|
|||||||
/** update internal parameters from settings */
|
/** update internal parameters from settings */
|
||||||
void readSettings();
|
void readSettings();
|
||||||
|
|
||||||
|
void setMediaFont(const std::string &name, const std::string &data);
|
||||||
|
|
||||||
|
void clearMediaFonts();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
irr::gui::IGUIFont *getFont(FontSpec spec, bool may_fail);
|
irr::gui::IGUIFont *getFont(FontSpec spec, bool may_fail);
|
||||||
|
|
||||||
/** update content of font cache in case of a setting change made it invalid */
|
/** update content of font cache in case of a setting change made it invalid */
|
||||||
void updateFontCache();
|
void updateCache();
|
||||||
|
|
||||||
/** initialize a new TTF font */
|
/** initialize a new TTF font */
|
||||||
gui::IGUIFont *initFont(const FontSpec &spec);
|
gui::IGUIFont *initFont(const FontSpec &spec);
|
||||||
@ -131,7 +138,7 @@ private:
|
|||||||
void updateSkin();
|
void updateSkin();
|
||||||
|
|
||||||
/** clean cache */
|
/** clean cache */
|
||||||
void cleanCache();
|
void clearCache();
|
||||||
|
|
||||||
/** pointer to irrlicht gui environment */
|
/** pointer to irrlicht gui environment */
|
||||||
gui::IGUIEnvironment* m_env = nullptr;
|
gui::IGUIEnvironment* m_env = nullptr;
|
||||||
@ -142,6 +149,9 @@ private:
|
|||||||
/** internal storage for caching fonts of different size */
|
/** internal storage for caching fonts of different size */
|
||||||
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];
|
std::map<unsigned int, irr::gui::IGUIFont*> m_font_cache[FM_MaxMode << 2];
|
||||||
|
|
||||||
|
/** media-provided faces, indexed by filename (without extension) */
|
||||||
|
std::unordered_map<std::string, irr_ptr<gui::SGUITTFace>> m_media_faces;
|
||||||
|
|
||||||
/** default font size to use */
|
/** default font size to use */
|
||||||
unsigned int m_default_size[FM_MaxMode];
|
unsigned int m_default_size[FM_MaxMode];
|
||||||
|
|
||||||
|
@ -51,6 +51,7 @@ namespace gui
|
|||||||
|
|
||||||
std::map<io::path, SGUITTFace*> SGUITTFace::faces;
|
std::map<io::path, SGUITTFace*> SGUITTFace::faces;
|
||||||
std::optional<FT_Library> SGUITTFace::freetype_library;
|
std::optional<FT_Library> SGUITTFace::freetype_library;
|
||||||
|
std::size_t SGUITTFace::n_faces;
|
||||||
|
|
||||||
std::optional<FT_Library> SGUITTFace::getFreeTypeLibrary()
|
std::optional<FT_Library> SGUITTFace::getFreeTypeLibrary()
|
||||||
{
|
{
|
||||||
@ -64,11 +65,19 @@ std::optional<FT_Library> SGUITTFace::getFreeTypeLibrary()
|
|||||||
SGUITTFace::SGUITTFace(std::string &&buffer) : face_buffer(std::move(buffer))
|
SGUITTFace::SGUITTFace(std::string &&buffer) : face_buffer(std::move(buffer))
|
||||||
{
|
{
|
||||||
memset((void*)&face, 0, sizeof(FT_Face));
|
memset((void*)&face, 0, sizeof(FT_Face));
|
||||||
|
n_faces++;
|
||||||
}
|
}
|
||||||
|
|
||||||
SGUITTFace::~SGUITTFace()
|
SGUITTFace::~SGUITTFace()
|
||||||
{
|
{
|
||||||
FT_Done_Face(face);
|
FT_Done_Face(face);
|
||||||
|
n_faces--;
|
||||||
|
// If there are no more faces referenced by FreeType, clean up.
|
||||||
|
if (n_faces == 0) {
|
||||||
|
assert(freetype_library);
|
||||||
|
FT_Done_FreeType(*freetype_library);
|
||||||
|
freetype_library = std::nullopt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SGUITTFace* SGUITTFace::createFace(std::string &&buffer)
|
SGUITTFace* SGUITTFace::createFace(std::string &&buffer)
|
||||||
@ -105,22 +114,17 @@ SGUITTFace* SGUITTFace::loadFace(const io::path &filename)
|
|||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGUITTFace::dropFilename(const io::path &filename)
|
void SGUITTFace::dropFilename()
|
||||||
{
|
{
|
||||||
auto it = faces.find(filename);
|
if (!filename.has_value()) return;
|
||||||
|
|
||||||
|
auto it = faces.find(*filename);
|
||||||
if (it == faces.end()) return;
|
if (it == faces.end()) return;
|
||||||
|
|
||||||
SGUITTFace* f = it->second;
|
SGUITTFace* f = it->second;
|
||||||
// Drop our face. If this was the last face, the destructor will clean up.
|
// Drop our face. If this was the last face, the destructor will clean up.
|
||||||
if (f->drop())
|
if (f->drop())
|
||||||
faces.erase(filename);
|
faces.erase(*filename);
|
||||||
|
|
||||||
// If there are no more faces referenced by FreeType, clean up.
|
|
||||||
if (faces.empty()) {
|
|
||||||
assert(freetype_library);
|
|
||||||
FT_Done_FreeType(*freetype_library);
|
|
||||||
freetype_library = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVideoDriver* driver) const
|
video::IImage* SGUITTGlyph::createGlyphImage(const FT_Bitmap& bits, video::IVideoDriver* driver) const
|
||||||
@ -260,11 +264,11 @@ void SGUITTGlyph::unload()
|
|||||||
// TODO constructor which takes bogus filename and data
|
// TODO constructor which takes bogus filename and data
|
||||||
|
|
||||||
CGUITTFont* CGUITTFont::createTTFont(IGUIEnvironment *env,
|
CGUITTFont* CGUITTFont::createTTFont(IGUIEnvironment *env,
|
||||||
const io::path& filename, u32 size, bool antialias,
|
SGUITTFace *face, u32 size, bool antialias,
|
||||||
bool transparency, u32 shadow, u32 shadow_alpha)
|
bool transparency, u32 shadow, u32 shadow_alpha)
|
||||||
{
|
{
|
||||||
CGUITTFont* font = new CGUITTFont(env);
|
CGUITTFont* font = new CGUITTFont(env);
|
||||||
bool ret = font->load(filename, size, antialias, transparency);
|
bool ret = font->load(face, size, antialias, transparency);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
font->drop();
|
font->drop();
|
||||||
@ -297,30 +301,20 @@ shadow_offset(0), shadow_alpha(0), fallback(0)
|
|||||||
setInvisibleCharacters(L" ");
|
setInvisibleCharacters(L" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antialias, const bool transparency)
|
bool CGUITTFont::load(SGUITTFace *face, const u32 size, const bool antialias, const bool transparency)
|
||||||
{
|
{
|
||||||
// Some sanity checks.
|
// Some sanity checks.
|
||||||
if (!Driver) return false;
|
if (!Driver) return false;
|
||||||
if (size == 0) return false;
|
if (size == 0) return false;
|
||||||
if (filename.empty()) return false;
|
if (!face) return false;
|
||||||
|
|
||||||
this->size = size;
|
this->size = size;
|
||||||
this->filename = filename;
|
|
||||||
|
|
||||||
// Update the font loading flags when the font is first loaded.
|
// Update the font loading flags when the font is first loaded.
|
||||||
this->use_monochrome = !antialias;
|
this->use_monochrome = !antialias;
|
||||||
this->use_transparency = transparency;
|
this->use_transparency = transparency;
|
||||||
update_load_flags();
|
update_load_flags();
|
||||||
|
|
||||||
infostream << "CGUITTFont: Creating new font: " << filename.c_str() << " "
|
|
||||||
<< size << "pt " << (antialias ? "+antialias " : "-antialias ")
|
|
||||||
<< (transparency ? "+transparency" : "-transparency") << std::endl;
|
|
||||||
|
|
||||||
// Grab the face.
|
|
||||||
auto *face = SGUITTFace::loadFace(filename);
|
|
||||||
if (!face)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Store our face.
|
// Store our face.
|
||||||
tt_face = face->face;
|
tt_face = face->face;
|
||||||
|
|
||||||
@ -350,9 +344,6 @@ CGUITTFont::~CGUITTFont()
|
|||||||
reset_images();
|
reset_images();
|
||||||
Glyphs.clear();
|
Glyphs.clear();
|
||||||
|
|
||||||
// We aren't using this face anymore.
|
|
||||||
SGUITTFace::dropFilename(filename);
|
|
||||||
|
|
||||||
// Drop our driver now.
|
// Drop our driver now.
|
||||||
if (Driver)
|
if (Driver)
|
||||||
Driver->drop();
|
Driver->drop();
|
||||||
|
@ -62,6 +62,7 @@ namespace gui
|
|||||||
|
|
||||||
static std::map<io::path, SGUITTFace*> faces;
|
static std::map<io::path, SGUITTFace*> faces;
|
||||||
static std::optional<FT_Library> freetype_library;
|
static std::optional<FT_Library> freetype_library;
|
||||||
|
static std::size_t n_faces;
|
||||||
|
|
||||||
static std::optional<FT_Library> getFreeTypeLibrary();
|
static std::optional<FT_Library> getFreeTypeLibrary();
|
||||||
|
|
||||||
@ -71,6 +72,8 @@ namespace gui
|
|||||||
|
|
||||||
~SGUITTFace();
|
~SGUITTFace();
|
||||||
|
|
||||||
|
std::optional<std::string> filename;
|
||||||
|
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
/// Must not be deallocated until we are done with the face!
|
/// Must not be deallocated until we are done with the face!
|
||||||
std::string face_buffer;
|
std::string face_buffer;
|
||||||
@ -79,7 +82,7 @@ namespace gui
|
|||||||
|
|
||||||
static SGUITTFace* loadFace(const io::path &filename);
|
static SGUITTFace* loadFace(const io::path &filename);
|
||||||
|
|
||||||
static void dropFilename(const io::path &filename);
|
void dropFilename();
|
||||||
};
|
};
|
||||||
class CGUITTFont;
|
class CGUITTFont;
|
||||||
|
|
||||||
@ -247,13 +250,12 @@ namespace gui
|
|||||||
public:
|
public:
|
||||||
//! Creates a new TrueType font and returns a pointer to it. The pointer must be drop()'ed when finished.
|
//! Creates a new TrueType font and returns a pointer to it. The pointer must be drop()'ed when finished.
|
||||||
//! \param env The IGUIEnvironment the font loads out of.
|
//! \param env The IGUIEnvironment the font loads out of.
|
||||||
//! \param filename The filename of the font.
|
|
||||||
//! \param size The size of the font glyphs in pixels. Since this is the size of the individual glyphs, the true height of the font may change depending on the characters used.
|
//! \param size The size of the font glyphs in pixels. Since this is the size of the individual glyphs, the true height of the font may change depending on the characters used.
|
||||||
//! \param antialias set the use_monochrome (opposite to antialias) flag
|
//! \param antialias set the use_monochrome (opposite to antialias) flag
|
||||||
//! \param transparency set the use_transparency flag
|
//! \param transparency set the use_transparency flag
|
||||||
//! \return Returns a pointer to a CGUITTFont. Will return 0 if the font failed to load.
|
//! \return Returns a pointer to a CGUITTFont. Will return 0 if the font failed to load.
|
||||||
static CGUITTFont* createTTFont(IGUIEnvironment *env,
|
static CGUITTFont* createTTFont(IGUIEnvironment *env,
|
||||||
const io::path& filename, u32 size, bool antialias = true,
|
SGUITTFace *face, u32 size, bool antialias = true,
|
||||||
bool transparency = true, u32 shadow = 0, u32 shadow_alpha = 255);
|
bool transparency = true, u32 shadow = 0, u32 shadow_alpha = 255);
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
@ -372,7 +374,7 @@ namespace gui
|
|||||||
std::u32string convertWCharToU32String(const wchar_t* const) const;
|
std::u32string convertWCharToU32String(const wchar_t* const) const;
|
||||||
|
|
||||||
CGUITTFont(IGUIEnvironment *env);
|
CGUITTFont(IGUIEnvironment *env);
|
||||||
bool load(const io::path& filename, const u32 size, const bool antialias, const bool transparency);
|
bool load(SGUITTFace *face, const u32 size, const bool antialias, const bool transparency);
|
||||||
void reset_images();
|
void reset_images();
|
||||||
void update_glyph_pages() const;
|
void update_glyph_pages() const;
|
||||||
void update_load_flags()
|
void update_load_flags()
|
||||||
@ -390,7 +392,7 @@ namespace gui
|
|||||||
core::vector2di getKerning(const char32_t thisLetter, const char32_t previousLetter) const;
|
core::vector2di getKerning(const char32_t thisLetter, const char32_t previousLetter) const;
|
||||||
|
|
||||||
video::IVideoDriver* Driver;
|
video::IVideoDriver* Driver;
|
||||||
io::path filename;
|
std::optional<io::path> filename;
|
||||||
FT_Face tt_face;
|
FT_Face tt_face;
|
||||||
FT_Size_Metrics font_metrics;
|
FT_Size_Metrics font_metrics;
|
||||||
FT_Int32 load_flags;
|
FT_Int32 load_flags;
|
||||||
|
Loading…
Reference in New Issue
Block a user