we do a minuscule amount of refactoring
This commit is contained in:
parent
ea61fcd2bf
commit
12d861d295
@ -31,7 +31,11 @@
|
||||
john@suckerfreegames.com
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <freetype/freetype.h>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include "irr_ptr.h"
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
#include "debug.h"
|
||||
@ -45,29 +49,79 @@ namespace irr
|
||||
namespace gui
|
||||
{
|
||||
|
||||
// Manages the FT_Face cache.
|
||||
struct SGUITTFace : public irr::IReferenceCounted
|
||||
std::map<io::path, SGUITTFace*> SGUITTFace::faces;
|
||||
std::optional<FT_Library> SGUITTFace::freetype_library;
|
||||
|
||||
std::optional<FT_Library> SGUITTFace::getFreeTypeLibrary()
|
||||
{
|
||||
SGUITTFace()
|
||||
{
|
||||
memset((void*)&face, 0, sizeof(FT_Face));
|
||||
if (freetype_library) return *freetype_library;
|
||||
FT_Library ft;
|
||||
if (FT_Init_FreeType(&ft))
|
||||
return std::nullopt; // TODO can't we just bail out entirely if this fails?
|
||||
return freetype_library = ft;
|
||||
}
|
||||
|
||||
SGUITTFace::SGUITTFace(std::string &&buffer) : face_buffer(std::move(buffer))
|
||||
{
|
||||
memset((void*)&face, 0, sizeof(FT_Face));
|
||||
}
|
||||
|
||||
SGUITTFace::~SGUITTFace()
|
||||
{
|
||||
FT_Done_Face(face);
|
||||
}
|
||||
|
||||
SGUITTFace* SGUITTFace::createFace(std::string &&buffer)
|
||||
{
|
||||
irr_ptr<SGUITTFace> face(new SGUITTFace(std::move(buffer)));
|
||||
auto ft = getFreeTypeLibrary();
|
||||
if (!ft) return nullptr;
|
||||
return (FT_New_Memory_Face(*ft,
|
||||
reinterpret_cast<const FT_Byte*>(face->face_buffer.data()),
|
||||
face->face_buffer.size(), 0, &face->face))
|
||||
? nullptr : face.release();
|
||||
}
|
||||
|
||||
SGUITTFace* SGUITTFace::loadFace(const io::path &filename)
|
||||
{
|
||||
auto it = faces.find(filename);
|
||||
if (it != faces.end()) {
|
||||
it->second->grab();
|
||||
return it->second;
|
||||
}
|
||||
|
||||
~SGUITTFace()
|
||||
{
|
||||
FT_Done_Face(face);
|
||||
std::string buffer;
|
||||
if (!fs::ReadFile(filename.c_str(), buffer, true)) {
|
||||
errorstream << "CGUITTFont: Reading file " << filename.c_str() << " failed." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FT_Face face;
|
||||
std::string face_buffer;
|
||||
};
|
||||
auto *face = SGUITTFace::createFace(std::move(buffer));
|
||||
if (!face) {
|
||||
errorstream << "CGUITTFont: FT_New_Memory_Face failed." << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
faces.emplace(filename, face);
|
||||
return face;
|
||||
}
|
||||
|
||||
// Static variables.
|
||||
FT_Library CGUITTFont::c_library;
|
||||
std::map<io::path, SGUITTFace*> CGUITTFont::c_faces;
|
||||
bool CGUITTFont::c_libraryLoaded = false;
|
||||
void SGUITTFace::dropFilename(const io::path &filename)
|
||||
{
|
||||
auto it = faces.find(filename);
|
||||
if (it == faces.end()) return;
|
||||
|
||||
//
|
||||
SGUITTFace* f = it->second;
|
||||
// Drop our face. If this was the last face, the destructor will clean up.
|
||||
if (f->drop())
|
||||
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
|
||||
{
|
||||
@ -203,15 +257,12 @@ void SGUITTGlyph::unload()
|
||||
|
||||
//////////////////////
|
||||
|
||||
CGUITTFont* CGUITTFont::createTTFont(IGUIEnvironment *env, const io::path& filename, const u32 size, const bool antialias, const bool transparency, const u32 shadow, const u32 shadow_alpha)
|
||||
{
|
||||
if (!c_libraryLoaded)
|
||||
{
|
||||
if (FT_Init_FreeType(&c_library))
|
||||
return 0;
|
||||
c_libraryLoaded = true;
|
||||
}
|
||||
// TODO constructor which takes bogus filename and data
|
||||
|
||||
CGUITTFont* CGUITTFont::createTTFont(IGUIEnvironment *env,
|
||||
const io::path& filename, u32 size, bool antialias,
|
||||
bool transparency, u32 shadow, u32 shadow_alpha)
|
||||
{
|
||||
CGUITTFont* font = new CGUITTFont(env);
|
||||
bool ret = font->load(filename, size, antialias, transparency);
|
||||
if (!ret)
|
||||
@ -266,32 +317,9 @@ bool CGUITTFont::load(const io::path& filename, const u32 size, const bool antia
|
||||
<< (transparency ? "+transparency" : "-transparency") << std::endl;
|
||||
|
||||
// Grab the face.
|
||||
SGUITTFace* face = nullptr;
|
||||
auto node = c_faces.find(filename);
|
||||
if (node == c_faces.end()) {
|
||||
face = new SGUITTFace();
|
||||
|
||||
if (!fs::ReadFile(filename.c_str(), face->face_buffer, true)) {
|
||||
delete face;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the face.
|
||||
if (FT_New_Memory_Face(c_library,
|
||||
reinterpret_cast<const FT_Byte*>(face->face_buffer.data()),
|
||||
face->face_buffer.size(), 0, &face->face))
|
||||
{
|
||||
errorstream << "CGUITTFont: FT_New_Memory_Face failed." << std::endl;
|
||||
delete face;
|
||||
return false;
|
||||
}
|
||||
|
||||
c_faces.emplace(filename, face);
|
||||
} else {
|
||||
// Using another instance of this face.
|
||||
face = node->second;
|
||||
face->grab();
|
||||
}
|
||||
auto *face = SGUITTFace::loadFace(filename);
|
||||
if (!face)
|
||||
return false;
|
||||
|
||||
// Store our face.
|
||||
tt_face = face->face;
|
||||
@ -323,22 +351,7 @@ CGUITTFont::~CGUITTFont()
|
||||
Glyphs.clear();
|
||||
|
||||
// We aren't using this face anymore.
|
||||
auto n = c_faces.find(filename);
|
||||
if (n != c_faces.end())
|
||||
{
|
||||
SGUITTFace* f = n->second;
|
||||
|
||||
// Drop our face. If this was the last face, the destructor will clean up.
|
||||
if (f->drop())
|
||||
c_faces.erase(filename);
|
||||
|
||||
// If there are no more faces referenced by FreeType, clean up.
|
||||
if (c_faces.empty())
|
||||
{
|
||||
FT_Done_FreeType(c_library);
|
||||
c_libraryLoaded = false;
|
||||
}
|
||||
}
|
||||
SGUITTFace::dropFilename(filename);
|
||||
|
||||
// Drop our driver now.
|
||||
if (Driver)
|
||||
|
@ -33,6 +33,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
@ -44,11 +45,42 @@
|
||||
#include "util/enriched_string.h"
|
||||
#include "util/basic_macros.h"
|
||||
|
||||
// TODO these should be in the C++ when the struct is properly split into C++ & header
|
||||
#include <optional>
|
||||
#include "irr_ptr.h"
|
||||
#include "log.h"
|
||||
#include "filesys.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
struct SGUITTFace;
|
||||
// Manages the FT_Face cache.
|
||||
struct SGUITTFace : public irr::IReferenceCounted
|
||||
{
|
||||
private:
|
||||
|
||||
static std::map<io::path, SGUITTFace*> faces;
|
||||
static std::optional<FT_Library> freetype_library;
|
||||
|
||||
static std::optional<FT_Library> getFreeTypeLibrary();
|
||||
|
||||
public:
|
||||
|
||||
SGUITTFace(std::string &&buffer);
|
||||
|
||||
~SGUITTFace();
|
||||
|
||||
FT_Face face;
|
||||
/// Must not be deallocated until we are done with the face!
|
||||
std::string face_buffer;
|
||||
|
||||
static SGUITTFace* createFace(std::string &&buffer);
|
||||
|
||||
static SGUITTFace* loadFace(const io::path &filename);
|
||||
|
||||
static void dropFilename(const io::path &filename);
|
||||
};
|
||||
class CGUITTFont;
|
||||
|
||||
//! Structure representing a single TrueType glyph.
|
||||
@ -220,7 +252,9 @@ namespace gui
|
||||
//! \param antialias set the use_monochrome (opposite to antialias) flag
|
||||
//! \param transparency set the use_transparency flag
|
||||
//! \return Returns a pointer to a CGUITTFont. Will return 0 if the font failed to load.
|
||||
static CGUITTFont* createTTFont(IGUIEnvironment *env, const io::path& filename, const u32 size, const bool antialias = true, const bool transparency = true, const u32 shadow = 0, const u32 shadow_alpha = 255);
|
||||
static CGUITTFont* createTTFont(IGUIEnvironment *env,
|
||||
const io::path& filename, u32 size, bool antialias = true,
|
||||
bool transparency = true, u32 shadow = 0, u32 shadow_alpha = 255);
|
||||
|
||||
//! Destructor
|
||||
virtual ~CGUITTFont();
|
||||
@ -329,11 +363,6 @@ namespace gui
|
||||
core::dimension2du max_page_texture_size;
|
||||
|
||||
private:
|
||||
// Manages the FreeType library.
|
||||
static FT_Library c_library;
|
||||
static std::map<io::path, SGUITTFace*> c_faces;
|
||||
static bool c_libraryLoaded;
|
||||
|
||||
// Helper functions for the same-named public member functions above
|
||||
// (Since std::u32string is nicer to work with than wchar_t *)
|
||||
core::dimension2d<u32> getDimension(const std::u32string& text) const;
|
||||
|
Loading…
Reference in New Issue
Block a user