aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/crepe/api/AssetManager.h62
-rw-r--r--src/crepe/api/Config.h11
-rw-r--r--src/crepe/api/Text.cpp0
-rw-r--r--src/crepe/api/Text.h35
-rw-r--r--src/crepe/facade/CMakeLists.txt2
-rw-r--r--src/crepe/facade/SDLFontContext.cpp54
-rw-r--r--src/crepe/facade/SDLFontContext.h18
-rw-r--r--src/crepe/facade/font.cpp21
-rw-r--r--src/crepe/facade/font.h31
-rw-r--r--src/example/CMakeLists.txt1
-rw-r--r--src/example/loadfont.cpp13
12 files changed, 250 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 97b21f0..2b8873f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,6 +13,7 @@ find_package(SoLoud REQUIRED)
find_package(GTest REQUIRED)
find_package(whereami REQUIRED)
find_library(BERKELEY_DB db)
+find_package(Fontconfig REQUIRED)
add_library(crepe SHARED)
add_executable(test_main EXCLUDE_FROM_ALL)
@@ -27,6 +28,7 @@ target_link_libraries(crepe
PUBLIC SDL2_image
PUBLIC ${BERKELEY_DB}
PUBLIC whereami
+ PUBLIC ${Fontconfig_LIBRARIES}
)
add_subdirectory(crepe)
diff --git a/src/crepe/api/AssetManager.h b/src/crepe/api/AssetManager.h
new file mode 100644
index 0000000..3b1cc4b
--- /dev/null
+++ b/src/crepe/api/AssetManager.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <any>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+namespace crepe {
+
+/**
+ * \brief The AssetManager is responsible for storing and managing assets over multiple scenes.
+ *
+ * The AssetManager ensures that assets are loaded once and can be accessed across different
+ * scenes. It caches assets to avoid reloading them every time a scene is loaded. Assets are
+ * retained in memory until the AssetManager is destroyed, at which point the cached assets are
+ * cleared.
+ */
+class AssetManager {
+
+private:
+ //! A cache that holds all the assets, accessible by their file path, over multiple scenes.
+ std::unordered_map<std::string, std::any> asset_cache;
+
+private:
+ AssetManager();
+ virtual ~AssetManager();
+
+public:
+ AssetManager(const AssetManager &) = delete;
+ AssetManager(AssetManager &&) = delete;
+ AssetManager & operator=(const AssetManager &) = delete;
+ AssetManager & operator=(AssetManager &&) = delete;
+
+ /**
+ * \brief Retrieves the singleton instance of the AssetManager.
+ *
+ * \return A reference to the single instance of the AssetManager.
+ */
+ static AssetManager & get_instance();
+
+public:
+ /**
+ * \brief Caches an asset by loading it from the given file path.
+ *
+ * \param file_path The path to the asset file to load.
+ * \param reload If true, the asset will be reloaded from the file, even if it is already
+ * cached.
+ * \tparam T The type of asset to cache (e.g., texture, sound, etc.).
+ *
+ * \return A shared pointer to the cached asset.
+ *
+ * This template function caches the asset at the given file path. If the asset is already
+ * cached and `reload` is false, the existing cached version will be returned. Otherwise, the
+ * asset will be reloaded and added to the cache.
+ */
+ template <typename T>
+ std::shared_ptr<T> cache(const std::string & file_path, bool reload = false);
+};
+
+} // namespace crepe
+
+#include "AssetManager.hpp"
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index 6472270..def4c49 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -76,6 +76,17 @@ struct Config final {
*/
std::string root_pattern = ".crepe-root";
} asset;
+ //! Default font options
+ struct {
+ /**
+ * \brief Default font size
+ *
+ * using the SDL_ttf library the font size needs to be set when loading the font.
+ * This config option is the font size at which all fonts will be loaded initially.
+ *
+ */
+ int font_size = 16;
+ } font;
//! Audio system settings
struct {
diff --git a/src/crepe/api/Text.cpp b/src/crepe/api/Text.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/crepe/api/Text.cpp
diff --git a/src/crepe/api/Text.h b/src/crepe/api/Text.h
new file mode 100644
index 0000000..9dd275b
--- /dev/null
+++ b/src/crepe/api/Text.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <string>
+
+#include "../Component.h"
+
+#include "Asset.h"
+#include "Color.h"
+#include "UIObject.h"
+
+namespace crepe{
+class Text : public UIObject{
+public:
+ Text(game_object_id_t id,const vec2 & dimensions, const vec2 & offset, const Asset & font, int font_size);
+
+ //! Label text.
+ std::string text;
+ //! Label text color
+ Color text_color = Color::BLACK;
+ /**
+ * \brief fontsize for text rendering
+ *
+ * \note this is not the actual font size that is loaded in.
+ *
+ * Since SDL_TTF requires the font size when loading in the font it is not possible to switch the font size.
+ * The default font size that is loaded is set in the Config.
+ * Instead this value is used to upscale the font texture which can cause blurring or distorted text when upscaling or downscaling too much.
+ */
+ int font_size = 16;
+
+ const Asset source;
+private:
+};
+
+} // namespace crepe
diff --git a/src/crepe/facade/CMakeLists.txt b/src/crepe/facade/CMakeLists.txt
index 0598e16..f4d71ff 100644
--- a/src/crepe/facade/CMakeLists.txt
+++ b/src/crepe/facade/CMakeLists.txt
@@ -4,6 +4,7 @@ target_sources(crepe PUBLIC
SoundContext.cpp
SDLContext.cpp
DB.cpp
+ SDLFontContext.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -12,5 +13,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
SoundContext.h
SDLContext.h
DB.h
+ SDLFontContext.h
)
diff --git a/src/crepe/facade/SDLFontContext.cpp b/src/crepe/facade/SDLFontContext.cpp
new file mode 100644
index 0000000..a4be143
--- /dev/null
+++ b/src/crepe/facade/SDLFontContext.cpp
@@ -0,0 +1,54 @@
+#include <stdexcept>
+
+#include "SDLFontContext.h"
+
+
+using namespace crepe;
+using namespace std;
+
+SDLFontContext::SDLFontContext(){
+
+}
+
+SDLFontContext::~SDLFontContext(){
+
+}
+unique_ptr<Asset> SDLFontContext::get_font_asset(const std::string & font_family) {
+ if (!FcInit()) {
+ throw std::runtime_error("Failed to initialize Fontconfig.");
+ }
+ // Create a pattern to search for the font family
+ FcPattern* pattern = FcNameParse(reinterpret_cast<const FcChar8*>(font_family.c_str()));
+ if (!pattern) {
+ throw std::runtime_error("Failed to create font pattern.");
+ }
+
+ // Default configuration
+ FcConfig* config = FcConfigGetCurrent();
+ if (!config) {
+ FcPatternDestroy(pattern);
+ throw std::runtime_error("Failed to get current Fontconfig configuration.");
+ }
+
+ // Match the font pattern
+ FcResult result;
+ FcPattern* matched_pattern = FcFontMatch(config, pattern, &result);
+ FcPatternDestroy(pattern);
+
+ if (!matched_pattern) {
+ throw std::runtime_error("No matching font found.");
+ }
+
+ // Extract the file path
+ FcChar8* file_path = nullptr;
+ if (FcPatternGetString(matched_pattern, FC_FILE, 0, &file_path) != FcResultMatch || !file_path) {
+ FcPatternDestroy(matched_pattern);
+ throw std::runtime_error("Failed to get font file path.");
+ }
+
+ // Convert the file path to a std::string
+ std::string font_file_path(reinterpret_cast<const char*>(file_path));
+ FcPatternDestroy(matched_pattern);
+ FcFini();
+ return std::move(make_unique<Asset>(font_file_path));
+}
diff --git a/src/crepe/facade/SDLFontContext.h b/src/crepe/facade/SDLFontContext.h
new file mode 100644
index 0000000..cd91383
--- /dev/null
+++ b/src/crepe/facade/SDLFontContext.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <memory>
+#include <SDL2/SDL_ttf.h>
+#include <fontconfig/fontconfig.h>
+
+#include "../api/Asset.h"
+
+namespace crepe {
+ class SDLFontContext{
+ public:
+ SDLFontContext();
+ ~SDLFontContext();
+ std::unique_ptr<Asset> get_font_asset(const std::string & font_family);
+ private:
+ };
+
+}
diff --git a/src/crepe/facade/font.cpp b/src/crepe/facade/font.cpp
new file mode 100644
index 0000000..259a6cd
--- /dev/null
+++ b/src/crepe/facade/font.cpp
@@ -0,0 +1,21 @@
+#include "font.h"
+#include "../api/Config.h"
+using namespace std;
+using namespace crepe;
+
+void Font::load(unique_ptr<Asset> res){
+ const char* font_path = res->get_path();
+ int font_size = Config::get_instance().font.font_size;
+ this->font = std::unique_ptr<TTF_Font, decltype(&TTF_CloseFont)>(
+ TTF_OpenFont(font_path, font_size), &TTF_CloseFont);
+
+ if (!font) {
+ throw std::runtime_error("Failed to load font: " + std::string(TTF_GetError()));
+ }
+}
+Font::Font(const char* src){
+ this->load(make_unique<Asset>(src));
+}
+Font::Font(std::unique_ptr<Asset> res){
+ this->load(std::move(res));
+}
diff --git a/src/crepe/facade/font.h b/src/crepe/facade/font.h
new file mode 100644
index 0000000..a8d8040
--- /dev/null
+++ b/src/crepe/facade/font.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <memory>
+#include <SDL2/SDL_ttf.h>
+
+#include "../api/Asset.h"
+
+namespace crepe {
+
+/**
+ * \brief Font resource facade
+ *
+ * This class is a wrapper around an SDL_ttf font instance, encapsulating font loading and usage.
+ */
+class Font : public Resource{
+public:
+ /**
+ * \param res A unique pointer to an Asset holding the font resource.
+ */
+ Font(const Asset & src, Mediator & mediator);
+
+ /**
+ * \brief Destructor to clean up font resources.
+ */
+ ~Font() = default;
+private:
+ //! The SDL_ttf font object with custom deleter.
+ std::unique_ptr<TTF_Font, decltype(&TTF_CloseFont)> font;
+};
+
+} // namespace crepe
diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt
index 187ed46..0e2d5e2 100644
--- a/src/example/CMakeLists.txt
+++ b/src/example/CMakeLists.txt
@@ -19,4 +19,5 @@ endfunction()
add_example(rendering_particle)
add_example(game)
add_example(button)
+add_example(loadfont)
add_example(AITest)
diff --git a/src/example/loadfont.cpp b/src/example/loadfont.cpp
new file mode 100644
index 0000000..8931ce3
--- /dev/null
+++ b/src/example/loadfont.cpp
@@ -0,0 +1,13 @@
+#include <iostream>
+#include <memory>
+
+#include <crepe/facade/SDLFontContext.h>
+
+using namespace crepe;
+
+int main(){
+ SDLFontContext font_facade;
+ std::unique_ptr<Asset> asset = font_facade.get_font_asset("OpenSymbol");
+ std::cout << "path: " << asset->get_path() << std::endl;
+ return 0;
+}