From 2964aa4a95301126fa6e5136109078c6ae99102c Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 16 Jun 2023 10:46:41 -0700 Subject: [PATCH] Removed old TrueType --- src/dawn/asset/AssetManager.hpp | 1 - src/dawn/asset/assets/CMakeLists.txt | 1 - src/dawn/asset/assets/NewTrueTypeAsset.cpp | 190 ------------ src/dawn/asset/assets/NewTrueTypeAsset.hpp | 72 ----- src/dawn/asset/assets/TrueTypeAsset.cpp | 274 ++++++++++++------ src/dawn/asset/assets/TrueTypeAsset.hpp | 110 ++++--- src/dawn/display/font/truetype/CMakeLists.txt | 2 +- ...aceTexture.cpp => TrueTypeFaceTexture.cpp} | 16 +- ...aceTexture.hpp => TrueTypeFaceTexture.hpp} | 26 +- src/dawn/scene/components/ui/text/UILabel.cpp | 6 +- src/dawn/scene/components/ui/text/UILabel.hpp | 10 +- .../components/ui/text/UIRichTextLabel.cpp | 6 +- src/dawnliminal/CMakeLists.txt | 2 +- src/dawnliminal/scenes/HelloWorldScene.hpp | 2 +- ...wTrueTypeShared.hpp => TrueTypeShared.hpp} | 8 +- src/dawntools/CMakeLists.txt | 3 +- src/dawntools/newtruetypetool/CMakeLists.txt | 70 ----- .../newtruetypetool/NewTrueTypeTool.cpp | 164 ----------- .../newtruetypetool/NewTrueTypeTool.hpp | 30 -- src/dawntools/truetypetool/CMakeLists.txt | 18 +- src/dawntools/truetypetool/TrueTypeTool.cpp | 176 ++++++++--- src/dawntools/truetypetool/TrueTypeTool.hpp | 16 +- 22 files changed, 455 insertions(+), 748 deletions(-) delete mode 100644 src/dawn/asset/assets/NewTrueTypeAsset.cpp delete mode 100644 src/dawn/asset/assets/NewTrueTypeAsset.hpp rename src/dawn/display/font/truetype/{NewTrueTypeFaceTexture.cpp => TrueTypeFaceTexture.cpp} (83%) rename src/dawn/display/font/truetype/{NewTrueTypeFaceTexture.hpp => TrueTypeFaceTexture.hpp} (65%) rename src/dawnshared/display/font/truetype/{NewTrueTypeShared.hpp => TrueTypeShared.hpp} (50%) delete mode 100644 src/dawntools/newtruetypetool/CMakeLists.txt delete mode 100644 src/dawntools/newtruetypetool/NewTrueTypeTool.cpp delete mode 100644 src/dawntools/newtruetypetool/NewTrueTypeTool.hpp diff --git a/src/dawn/asset/AssetManager.hpp b/src/dawn/asset/AssetManager.hpp index c88e13d3..d4eccc36 100644 --- a/src/dawn/asset/AssetManager.hpp +++ b/src/dawn/asset/AssetManager.hpp @@ -12,7 +12,6 @@ #include "assets/TextureAsset.hpp" #include "assets/TilesetAsset.hpp" #include "assets/TrueTypeAsset.hpp" -#include "assets/NewTrueTypeAsset.hpp" namespace Dawn { class AssetManager { diff --git a/src/dawn/asset/assets/CMakeLists.txt b/src/dawn/asset/assets/CMakeLists.txt index 29e8e3b5..6a1e322e 100644 --- a/src/dawn/asset/assets/CMakeLists.txt +++ b/src/dawn/asset/assets/CMakeLists.txt @@ -11,5 +11,4 @@ target_sources(${DAWN_TARGET_NAME} TextureAsset.cpp TilesetAsset.cpp TrueTypeAsset.cpp - NewTrueTypeAsset.cpp ) \ No newline at end of file diff --git a/src/dawn/asset/assets/NewTrueTypeAsset.cpp b/src/dawn/asset/assets/NewTrueTypeAsset.cpp deleted file mode 100644 index f0e1a191..00000000 --- a/src/dawn/asset/assets/NewTrueTypeAsset.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "NewTrueTypeAsset.hpp" -#include "asset/AssetManager.hpp" - -using namespace Dawn; - -NewTrueTypeAsset::NewTrueTypeAsset(AssetManager *assMan, std::string name) : - Asset(assMan, name), - loader(name + ".newtruetype") -{ - -} - -void NewTrueTypeAsset::updateSync() { - -} - -void NewTrueTypeAsset::updateAsync() { - if(this->state != NEW_TRUE_TYPE_ASSET_STATE_INITIAL) return; - - this->state = NEW_TRUE_TYPE_ASSET_STATE_OPEN; - this->loader.open(); - - this->state = NEW_TRUE_TYPE_ASSET_STATE_VALIDATE_HEADER; - - uint8_t buffer[64]; - this->loader.rewind(); - size_t read = this->loader.read(buffer, sizeof(char) * 6); - assertTrue(read == (6 * sizeof(char))); - buffer[6] = '\0'; - - // Confirm "DE_TTF" - assertTrue(std::string((char *)buffer) == "DE_TTF"); - - // Vertical bar - this->loader.read(buffer, 1); - assertTrue(buffer[0] == '|'); - - // Read version - this->state = NEW_TRUE_TYPE_ASSET_STATE_VALIDATE_VERSION; - read = this->loader.read(buffer, sizeof(char) * 5); - assertTrue(buffer[0] == '3'); - assertTrue(buffer[1] == '.'); - assertTrue(buffer[2] == '0'); - assertTrue(buffer[3] == '0'); - assertTrue(buffer[4] == '|'); - - // Read the count of font styles / variants. - size_t styleListBegin = this->loader.getPosition(); - this->state = NEW_TRUE_TYPE_ASSET_STATE_READ_VARIANT_COUNT; - read = this->loader.read(buffer, 64); - assertTrue(read > 0); - - // Get position of vertical bar. - size_t i = 0; - while(buffer[i] != '|' && i < 64) i++; - assertTrue(buffer[i] == '|'); - styleListBegin += i + 1; - buffer[i] = '\0'; - - int32_t count = atoi((char *)buffer); - assertTrue(count > 0); - - // Now begin parsing each font style. - this->state = NEW_TRUE_TYPE_ASSET_STATE_READ_VARIANT; - assetStyles.clear(); - while(assetStyles.size() != count) { - struct NewTrueTypeAssetStyle style; - - // Buffer - this->loader.rewind(); - this->loader.setPosition(styleListBegin); - read = this->loader.read(buffer, 32); - assertTrue(read == 32); - - // Read style - i = 0; - while(buffer[i] != ':' && i < 64) i++; - buffer[i] = '\0'; - style.style = atoi((char *)buffer); - styleListBegin += i + 1; - - // Buffer - this->loader.rewind(); - this->loader.setPosition(styleListBegin); - read = this->loader.read(buffer, 32); - assertTrue(read == 32); - - // Read length - i = 0; - while(buffer[i] != '|' && i < 64) i++; - buffer[i] = '\0'; - styleListBegin += i + 1; - style.dataSize = atol((char *)buffer); - - // Push - assetStyles.push_back(style); - } - - // Now we are at the first byte of the first style. - this->state = NEW_TRUE_TYPE_ASSET_STATE_ADJUSTING_OFFSETS; - auto itStyle = assetStyles.begin(); - while(itStyle != assetStyles.end()) { - (*itStyle).dataOffset = styleListBegin; - styleListBegin += (*itStyle).dataSize; - styleListBegin += 1; // Vertical bar - ++itStyle; - } - - // Init FreeType - this->state = NEW_TRUE_TYPE_ASSET_STATE_INIT_FREETYPE; - int32_t ret = FT_Init_FreeType(&fontLibrary); - assertTrue(ret == 0); - - // Done parsing! - this->state = NEW_TRUE_TYPE_ASSET_STATE_READY; - this->loaded = true; -} - -usagelockid_t NewTrueTypeAsset::lock(struct NewTrueTypeFaceTextureStyle style) { - assertTrue(this->state == NEW_TRUE_TYPE_ASSET_STATE_READY); - - // Try and find an existing texture that matches this style - auto it = this->textureByStyle.find(style); - NewTrueTypeFaceTexture *texture = nullptr; - - if(it == this->textureByStyle.end()) { - // Does not exist, Find asset style - auto itAssetStyle = this->assetStyles.begin(); - while(itAssetStyle != this->assetStyles.end()) { - if((*itAssetStyle).style == style.style) { - // Found - break; - } - ++itAssetStyle; - } - assertTrue(itAssetStyle != this->assetStyles.end()); - - // Create and read buffer. - uint8_t *dataBuffer = (uint8_t*)memoryAllocate(sizeof(uint8_t) * itAssetStyle->dataSize); - this->loader.rewind(); - this->loader.setPosition(itAssetStyle->dataOffset); - auto read = this->loader.read(dataBuffer, itAssetStyle->dataSize); - assertTrue(read == itAssetStyle->dataSize); - - // Create the face - FT_Face face; - auto ret = FT_New_Memory_Face(this->fontLibrary, (FT_Byte*)dataBuffer, itAssetStyle->dataSize, 0, &face); - assertTrue(ret == 0); - texture = new NewTrueTypeFaceTexture(face, style); - memoryFree(dataBuffer); - - this->textures.push_back(texture); - this->textureByStyle[style] = texture; - } else { - // Exists - texture = it->second; - } - - auto lock = texture->locks.createLock(); - this->textureByLock[lock] = texture; - return lock; -} - -NewTrueTypeFaceTexture * NewTrueTypeAsset::getTexture(usagelockid_t id) { - auto it = this->textureByLock.find(id); - assertTrue(it != this->textureByLock.end()); - return it->second; -} - -void NewTrueTypeAsset::unlock(usagelockid_t id) { - auto it = this->textureByLock.find(id); - assertTrue(it != this->textureByLock.end()); - it->second->locks.removeLock(id); - this->textureByLock.erase(it); -} - -NewTrueTypeAsset::~NewTrueTypeAsset() { - auto it = this->textures.begin(); - while(it != this->textures.end()) { - delete (*it); - it++; - } - - FT_Done_FreeType(this->fontLibrary); -} \ No newline at end of file diff --git a/src/dawn/asset/assets/NewTrueTypeAsset.hpp b/src/dawn/asset/assets/NewTrueTypeAsset.hpp deleted file mode 100644 index e7b3201f..00000000 --- a/src/dawn/asset/assets/NewTrueTypeAsset.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "../Asset.hpp" -#include "../AssetLoader.hpp" -#include "util/flag.hpp" -#include "display/font/truetype/NewTrueTypeFaceTexture.hpp" - -namespace Dawn { - enum NewTrueTypeAssetState { - NEW_TRUE_TYPE_ASSET_STATE_INITIAL, - NEW_TRUE_TYPE_ASSET_STATE_OPEN, - NEW_TRUE_TYPE_ASSET_STATE_VALIDATE_HEADER, - NEW_TRUE_TYPE_ASSET_STATE_VALIDATE_VERSION, - NEW_TRUE_TYPE_ASSET_STATE_READ_VARIANT_COUNT, - NEW_TRUE_TYPE_ASSET_STATE_READ_VARIANT, - NEW_TRUE_TYPE_ASSET_STATE_ADJUSTING_OFFSETS, - NEW_TRUE_TYPE_ASSET_STATE_INIT_FREETYPE, - NEW_TRUE_TYPE_ASSET_STATE_READY - }; - - struct NewTrueTypeAssetStyle { - flag_t style; - size_t dataSize; - size_t dataOffset; - }; - - class NewTrueTypeAsset : public Asset { - protected: - AssetLoader loader; - FT_Library fontLibrary; - enum NewTrueTypeAssetState state = NEW_TRUE_TYPE_ASSET_STATE_INITIAL; - std::vector assetStyles; - std::vector textures; - std::map textureByLock; - std::map textureByStyle; - - public: - NewTrueTypeAsset(AssetManager *assMan, std::string name); - void updateSync() override; - void updateAsync() override; - - /** - * Create a lock for a specific style. Locks will ensure that the font is - * held loaded until it is no longer required. - * - * @param style Style to lock. - * @return A unique lock ID for this style. - */ - usagelockid_t lock(struct NewTrueTypeFaceTextureStyle style); - - /** - * Get a texture by a previous lock ID. - * - * @param lock Lock to get the texture of. - * @return Matching texture by this ID. - */ - NewTrueTypeFaceTexture * getTexture(usagelockid_t lock); - - /** - * Releases a previously held font lock. - * - * @param lock Lock to release/unlock. - */ - void unlock(usagelockid_t lock); - - ~NewTrueTypeAsset(); - }; -} \ No newline at end of file diff --git a/src/dawn/asset/assets/TrueTypeAsset.cpp b/src/dawn/asset/assets/TrueTypeAsset.cpp index ae6c047b..d71343f2 100644 --- a/src/dawn/asset/assets/TrueTypeAsset.cpp +++ b/src/dawn/asset/assets/TrueTypeAsset.cpp @@ -1,86 +1,190 @@ -// Copyright (c) 2022 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "TrueTypeAsset.hpp" - -using namespace Dawn; - -TrueTypeAsset::TrueTypeAsset(AssetManager *assMan, std::string name) : - Asset(assMan, name), - loader(name + ".truetype") -{ -} - -void TrueTypeAsset::updateSync() { - if(this->state != 0x04) return; - this->font.texture.setSize(this->width, this->height, TEXTURE_FORMAT_R); - this->font.texture.buffer(this->pixels); - auto i = this->pixels; - memoryCopy( - this->characterData, - this->font.characterData, - sizeof(truetypechar_t) * TRUETYPE_NUM_CHARS - ); - - memoryFree(this->buffer); - this->buffer = nullptr; - - this->state = 0x05; - this->loaded = true; -} - -void TrueTypeAsset::updateAsync() { - int32_t fontSize; - size_t i, j; - char intBuffer[32]; - char c; - - if(this->state != 0x00) return; - - this->state = 0x01; - this->loader.loadRaw(&this->buffer); - this->state = 0x02; - - // Parse header data. - i = j = 0; - width = -1, height = -1, fontSize = -1; - while(true) { - c = this->buffer[i++]; - if(c == '|') { - intBuffer[j] = '\0'; - if(width == -1) { - this->width = atoi(intBuffer); - assertTrue(this->width > 0); - j = 0; - continue; - } else if(height == -1) { - this->height = atoi(intBuffer); - assertTrue(this->height > 0); - j = 0; - continue; - } else { - fontSize = atoi(intBuffer); - assertTrue(fontSize > 0); - break; - } - } - intBuffer[j++] = c; - } - - this->state = 0x03; - this->font.fontSize = fontSize; - this->pixels = (uint8_t*)(this->buffer + i); - this->characterData = (truetypechar_t*)( - (uint8_t*)this->pixels + (this->width * this->height * sizeof(uint8_t)) - ); - this->state = 0x04; -} - -TrueTypeAsset::~TrueTypeAsset() { - if(this->buffer != nullptr) { - memoryFree(this->buffer); - this->buffer = nullptr; - } +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "TrueTypeAsset.hpp" +#include "asset/AssetManager.hpp" + +using namespace Dawn; + +TrueTypeAsset::TrueTypeAsset(AssetManager *assMan, std::string name) : + Asset(assMan, name), + loader(name + ".truetype") +{ + +} + +void TrueTypeAsset::updateSync() { + +} + +void TrueTypeAsset::updateAsync() { + if(this->state != TRUE_TYPE_ASSET_STATE_INITIAL) return; + + this->state = TRUE_TYPE_ASSET_STATE_OPEN; + this->loader.open(); + + this->state = TRUE_TYPE_ASSET_STATE_VALIDATE_HEADER; + + uint8_t buffer[64]; + this->loader.rewind(); + size_t read = this->loader.read(buffer, sizeof(char) * 6); + assertTrue(read == (6 * sizeof(char))); + buffer[6] = '\0'; + + // Confirm "DE_TTF" + assertTrue(std::string((char *)buffer) == "DE_TTF"); + + // Vertical bar + this->loader.read(buffer, 1); + assertTrue(buffer[0] == '|'); + + // Read version + this->state = TRUE_TYPE_ASSET_STATE_VALIDATE_VERSION; + read = this->loader.read(buffer, sizeof(char) * 5); + assertTrue(buffer[0] == '3'); + assertTrue(buffer[1] == '.'); + assertTrue(buffer[2] == '0'); + assertTrue(buffer[3] == '0'); + assertTrue(buffer[4] == '|'); + + // Read the count of font styles / variants. + size_t styleListBegin = this->loader.getPosition(); + this->state = TRUE_TYPE_ASSET_STATE_READ_VARIANT_COUNT; + read = this->loader.read(buffer, 64); + assertTrue(read > 0); + + // Get position of vertical bar. + size_t i = 0; + while(buffer[i] != '|' && i < 64) i++; + assertTrue(buffer[i] == '|'); + styleListBegin += i + 1; + buffer[i] = '\0'; + + int32_t count = atoi((char *)buffer); + assertTrue(count > 0); + + // Now begin parsing each font style. + this->state = TRUE_TYPE_ASSET_STATE_READ_VARIANT; + assetStyles.clear(); + while(assetStyles.size() != count) { + struct TrueTypeAssetStyle style; + + // Buffer + this->loader.rewind(); + this->loader.setPosition(styleListBegin); + read = this->loader.read(buffer, 32); + assertTrue(read == 32); + + // Read style + i = 0; + while(buffer[i] != ':' && i < 64) i++; + buffer[i] = '\0'; + style.style = atoi((char *)buffer); + styleListBegin += i + 1; + + // Buffer + this->loader.rewind(); + this->loader.setPosition(styleListBegin); + read = this->loader.read(buffer, 32); + assertTrue(read == 32); + + // Read length + i = 0; + while(buffer[i] != '|' && i < 64) i++; + buffer[i] = '\0'; + styleListBegin += i + 1; + style.dataSize = atol((char *)buffer); + + // Push + assetStyles.push_back(style); + } + + // Now we are at the first byte of the first style. + this->state = TRUE_TYPE_ASSET_STATE_ADJUSTING_OFFSETS; + auto itStyle = assetStyles.begin(); + while(itStyle != assetStyles.end()) { + (*itStyle).dataOffset = styleListBegin; + styleListBegin += (*itStyle).dataSize; + styleListBegin += 1; // Vertical bar + ++itStyle; + } + + // Init FreeType + this->state = TRUE_TYPE_ASSET_STATE_INIT_FREETYPE; + int32_t ret = FT_Init_FreeType(&fontLibrary); + assertTrue(ret == 0); + + // Done parsing! + this->state = TRUE_TYPE_ASSET_STATE_READY; + this->loaded = true; +} + +usagelockid_t TrueTypeAsset::lock(struct TrueTypeFaceTextureStyle style) { + assertTrue(this->state == TRUE_TYPE_ASSET_STATE_READY); + + // Try and find an existing texture that matches this style + auto it = this->textureByStyle.find(style); + TrueTypeFaceTexture *texture = nullptr; + + if(it == this->textureByStyle.end()) { + // Does not exist, Find asset style + auto itAssetStyle = this->assetStyles.begin(); + while(itAssetStyle != this->assetStyles.end()) { + if((*itAssetStyle).style == style.style) { + // Found + break; + } + ++itAssetStyle; + } + assertTrue(itAssetStyle != this->assetStyles.end()); + + // Create and read buffer. + uint8_t *dataBuffer = (uint8_t*)memoryAllocate(sizeof(uint8_t) * itAssetStyle->dataSize); + this->loader.rewind(); + this->loader.setPosition(itAssetStyle->dataOffset); + auto read = this->loader.read(dataBuffer, itAssetStyle->dataSize); + assertTrue(read == itAssetStyle->dataSize); + + // Create the face + FT_Face face; + auto ret = FT_New_Memory_Face(this->fontLibrary, (FT_Byte*)dataBuffer, itAssetStyle->dataSize, 0, &face); + assertTrue(ret == 0); + texture = new TrueTypeFaceTexture(face, style); + memoryFree(dataBuffer); + + this->textures.push_back(texture); + this->textureByStyle[style] = texture; + } else { + // Exists + texture = it->second; + } + + auto lock = texture->locks.createLock(); + this->textureByLock[lock] = texture; + return lock; +} + +TrueTypeFaceTexture * TrueTypeAsset::getTexture(usagelockid_t id) { + auto it = this->textureByLock.find(id); + assertTrue(it != this->textureByLock.end()); + return it->second; +} + +void TrueTypeAsset::unlock(usagelockid_t id) { + auto it = this->textureByLock.find(id); + assertTrue(it != this->textureByLock.end()); + it->second->locks.removeLock(id); + this->textureByLock.erase(it); +} + +TrueTypeAsset::~TrueTypeAsset() { + auto it = this->textures.begin(); + while(it != this->textures.end()) { + delete (*it); + it++; + } + + FT_Done_FreeType(this->fontLibrary); } \ No newline at end of file diff --git a/src/dawn/asset/assets/TrueTypeAsset.hpp b/src/dawn/asset/assets/TrueTypeAsset.hpp index d696adf6..8e0903c7 100644 --- a/src/dawn/asset/assets/TrueTypeAsset.hpp +++ b/src/dawn/asset/assets/TrueTypeAsset.hpp @@ -1,40 +1,72 @@ -// Copyright (c) 2022 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "../Asset.hpp" -#include "../AssetLoader.hpp" -#include "display/font/TrueTypeFont.hpp" - -namespace Dawn { - class TrueTypeAsset : public Asset { - protected: - AssetLoader loader; - uint8_t *buffer = nullptr; - truetypechar_t *characterData = nullptr; - uint8_t *pixels = nullptr; - int32_t width, height; - - public: - TrueTypeFont font; - - /** - * Constructs a new True Type Asset. As with all other assets you should - * instead use the AssetManaager.load method. - * - * @param assMan Asset manager that this asset belongs to. - * @param name Filename of this asset. - */ - TrueTypeAsset(AssetManager *assMan, std::string name); - - void updateSync() override; - void updateAsync() override; - - /** - * Disposes / Cleans up the truetype asset. - */ - ~TrueTypeAsset(); - }; +// Copyright (c) 2023 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "../Asset.hpp" +#include "../AssetLoader.hpp" +#include "util/flag.hpp" +#include "display/font/truetype/TrueTypeFaceTexture.hpp" + +namespace Dawn { + enum TrueTypeAssetState { + TRUE_TYPE_ASSET_STATE_INITIAL, + TRUE_TYPE_ASSET_STATE_OPEN, + TRUE_TYPE_ASSET_STATE_VALIDATE_HEADER, + TRUE_TYPE_ASSET_STATE_VALIDATE_VERSION, + TRUE_TYPE_ASSET_STATE_READ_VARIANT_COUNT, + TRUE_TYPE_ASSET_STATE_READ_VARIANT, + TRUE_TYPE_ASSET_STATE_ADJUSTING_OFFSETS, + TRUE_TYPE_ASSET_STATE_INIT_FREETYPE, + TRUE_TYPE_ASSET_STATE_READY + }; + + struct TrueTypeAssetStyle { + flag_t style; + size_t dataSize; + size_t dataOffset; + }; + + class TrueTypeAsset : public Asset { + protected: + AssetLoader loader; + FT_Library fontLibrary; + enum TrueTypeAssetState state = TRUE_TYPE_ASSET_STATE_INITIAL; + std::vector assetStyles; + std::vector textures; + std::map textureByLock; + std::map textureByStyle; + + public: + TrueTypeAsset(AssetManager *assMan, std::string name); + void updateSync() override; + void updateAsync() override; + + /** + * Create a lock for a specific style. Locks will ensure that the font is + * held loaded until it is no longer required. + * + * @param style Style to lock. + * @return A unique lock ID for this style. + */ + usagelockid_t lock(struct TrueTypeFaceTextureStyle style); + + /** + * Get a texture by a previous lock ID. + * + * @param lock Lock to get the texture of. + * @return Matching texture by this ID. + */ + TrueTypeFaceTexture * getTexture(usagelockid_t lock); + + /** + * Releases a previously held font lock. + * + * @param lock Lock to release/unlock. + */ + void unlock(usagelockid_t lock); + + ~TrueTypeAsset(); + }; } \ No newline at end of file diff --git a/src/dawn/display/font/truetype/CMakeLists.txt b/src/dawn/display/font/truetype/CMakeLists.txt index 24e1acfd..bc30cf56 100644 --- a/src/dawn/display/font/truetype/CMakeLists.txt +++ b/src/dawn/display/font/truetype/CMakeLists.txt @@ -6,5 +6,5 @@ # Sources target_sources(${DAWN_TARGET_NAME} PRIVATE - NewTrueTypeFaceTexture.cpp + TrueTypeFaceTexture.cpp ) \ No newline at end of file diff --git a/src/dawn/display/font/truetype/NewTrueTypeFaceTexture.cpp b/src/dawn/display/font/truetype/TrueTypeFaceTexture.cpp similarity index 83% rename from src/dawn/display/font/truetype/NewTrueTypeFaceTexture.cpp rename to src/dawn/display/font/truetype/TrueTypeFaceTexture.cpp index 3aacc33a..1ce998a2 100644 --- a/src/dawn/display/font/truetype/NewTrueTypeFaceTexture.cpp +++ b/src/dawn/display/font/truetype/TrueTypeFaceTexture.cpp @@ -3,13 +3,13 @@ // This software is released under the MIT License. // https://opensource.org/licenses/MIT -#include "NewTrueTypeFaceTexture.hpp" +#include "TrueTypeFaceTexture.hpp" using namespace Dawn; -NewTrueTypeFaceTexture::NewTrueTypeFaceTexture( +TrueTypeFaceTexture::TrueTypeFaceTexture( FT_Face face, - struct NewTrueTypeFaceTextureStyle style + struct TrueTypeFaceTextureStyle style ) { assertTrue(style.fontSize < 256); @@ -29,7 +29,7 @@ NewTrueTypeFaceTexture::NewTrueTypeFaceTexture( FT_ULong c; // First pass, determine the textures' dimensions. - for(c = NEW_TRUETYPE_CHAR_BEGIN; c < NEW_TRUETYPE_CHAR_END; c++) { + for(c = TRUE_TYPE_CHAR_BEGIN; c < TRUE_TYPE_CHAR_END; c++) { // Load the character auto ret = FT_Load_Char(face, c, FT_LOAD_BITMAP_METRICS_ONLY); if(ret) { @@ -52,8 +52,8 @@ NewTrueTypeFaceTexture::NewTrueTypeFaceTexture( uint8_t *buffer = (uint8_t *)memoryFillWithZero(w * h * sizeof(uint8_t)); size_t offset = 0; - struct NewTrueTypeCharacter info; - for(c = NEW_TRUETYPE_CHAR_BEGIN; c < NEW_TRUETYPE_CHAR_END; c++) { + struct TrueTypeCharacter info; + for(c = TRUE_TYPE_CHAR_BEGIN; c < TRUE_TYPE_CHAR_END; c++) { // Load the character if(FT_Load_Char(face, c, FT_LOAD_RENDER)) { assertUnreachable(); @@ -86,10 +86,10 @@ NewTrueTypeFaceTexture::NewTrueTypeFaceTexture( memoryFree(buffer); } -struct NewTrueTypeCharacter NewTrueTypeFaceTexture::getCharacterData(FT_ULong c) { +struct TrueTypeCharacter TrueTypeFaceTexture::getCharacterData(FT_ULong c) { return this->characterData[c]; } -NewTrueTypeFaceTexture::~NewTrueTypeFaceTexture() { +TrueTypeFaceTexture::~TrueTypeFaceTexture() { FT_Done_Face(this->face); } \ No newline at end of file diff --git a/src/dawn/display/font/truetype/NewTrueTypeFaceTexture.hpp b/src/dawn/display/font/truetype/TrueTypeFaceTexture.hpp similarity index 65% rename from src/dawn/display/font/truetype/NewTrueTypeFaceTexture.hpp rename to src/dawn/display/font/truetype/TrueTypeFaceTexture.hpp index 8c82e42c..2a968ce9 100644 --- a/src/dawn/display/font/truetype/NewTrueTypeFaceTexture.hpp +++ b/src/dawn/display/font/truetype/TrueTypeFaceTexture.hpp @@ -4,15 +4,15 @@ // https://opensource.org/licenses/MIT #pragma once -#include "display/font/truetype/NewTrueTypeShared.hpp" +#include "display/font/truetype/TrueTypeShared.hpp" #include "util/mathutils.hpp" #include "display/Texture.hpp" #include "util/UsageLock.hpp" namespace Dawn { - class NewTrueTypeAsset; + class TrueTypeAsset; - struct NewTrueTypeCharacter { + struct TrueTypeCharacter { float_t advanceX; float_t advanceY; glm::vec2 bitmapSize; @@ -20,20 +20,20 @@ namespace Dawn { float_t textureY; }; - struct NewTrueTypeFaceTextureStyle { + struct TrueTypeFaceTextureStyle { uint32_t fontSize; flag_t style; - bool operator < (const struct NewTrueTypeFaceTextureStyle& r) const { + bool operator < (const struct TrueTypeFaceTextureStyle& r) const { return std::tie(fontSize, style) < std::tie(r.fontSize, r.style); } }; - class NewTrueTypeFaceTexture { + class TrueTypeFaceTexture { public: FT_Face face; - std::map characterData; - struct NewTrueTypeFaceTextureStyle style; + std::map characterData; + struct TrueTypeFaceTextureStyle style; UsageLock locks; Texture texture; @@ -43,9 +43,9 @@ namespace Dawn { * @param face The freetype face object. * @param style Style that this font has, used for locking. */ - NewTrueTypeFaceTexture( + TrueTypeFaceTexture( FT_Face face, - struct NewTrueTypeFaceTextureStyle style + struct TrueTypeFaceTextureStyle style ); /** @@ -54,13 +54,13 @@ namespace Dawn { * @param c Character to get data for. * @return The Character data for the given character. */ - struct NewTrueTypeCharacter getCharacterData(FT_ULong c); + struct TrueTypeCharacter getCharacterData(FT_ULong c); /** * Destroys this true type face texture. */ - ~NewTrueTypeFaceTexture(); + ~TrueTypeFaceTexture(); - friend class NewTrueTypeAsset; + friend class TrueTypeAsset; }; } \ No newline at end of file diff --git a/src/dawn/scene/components/ui/text/UILabel.cpp b/src/dawn/scene/components/ui/text/UILabel.cpp index 12bd49dc..6287c5ee 100644 --- a/src/dawn/scene/components/ui/text/UILabel.cpp +++ b/src/dawn/scene/components/ui/text/UILabel.cpp @@ -89,7 +89,7 @@ void UILabel::rebufferQuads(const std::vector newTexts) { struct FontShaderBufferData fontData; quadCountTotal = 0; std::vector realNewTexts; - + // Reset lines.clear(); @@ -115,7 +115,7 @@ void UILabel::rebufferQuads(const std::vector newTexts) { // Lock the font assertNotNull(text.style.font); - realText.lockId = text.style.font->lock(NewTrueTypeFaceTextureStyle{ + realText.lockId = text.style.font->lock(TrueTypeFaceTextureStyle{ text.style.size, text.style.style }); @@ -189,7 +189,7 @@ void UILabel::rebufferQuads(const std::vector newTexts) { } // Validate characters - assertTrue(ch >= NEW_TRUETYPE_CHAR_BEGIN && ch < NEW_TRUETYPE_CHAR_END); + assertTrue(ch >= TRUE_TYPE_CHAR_BEGIN && ch < TRUE_TYPE_CHAR_END); assertTrue(ch != '\r'); assertTrue(ch != '\t'); assertTrue(ch != '\n'); diff --git a/src/dawn/scene/components/ui/text/UILabel.hpp b/src/dawn/scene/components/ui/text/UILabel.hpp index e274c9e3..f36ef39c 100644 --- a/src/dawn/scene/components/ui/text/UILabel.hpp +++ b/src/dawn/scene/components/ui/text/UILabel.hpp @@ -6,7 +6,7 @@ #pragma once #include "scene/components/ui/UIComponentRenderable.hpp" #include "display/mesh/QuadMesh.hpp" -#include "asset/assets/NewTrueTypeAsset.hpp" +#include "asset/assets/TrueTypeAsset.hpp" #include "util/Xml.hpp" #define UI_LABEL_MAX_WIDTH_NONE -1 @@ -16,7 +16,7 @@ namespace Dawn { struct Color color = COLOR_WHITE; flag_t style = 0; uint32_t size = 16; - NewTrueTypeAsset *font = nullptr; + TrueTypeAsset *font = nullptr; }; struct UILabelText { @@ -25,7 +25,7 @@ namespace Dawn { int32_t lineStart = 0; int32_t lineCount = 0; usagelockid_t lockId = -1; - struct NewTrueTypeFaceTexture *texture = nullptr; + struct TrueTypeFaceTexture *texture = nullptr; }; struct UILabelLine { @@ -38,13 +38,13 @@ namespace Dawn { private: Mesh mesh; FontShaderBuffer shaderBuffer; - std::map textureMap; + std::map textureMap; public: int32_t quadStart = 0; int32_t quadCount = -1; int32_t quadCountTotal = -1; - + std::vector texts; std::vector textsBuffered; std::vector lines; diff --git a/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp b/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp index 2c71b31b..ff02e905 100644 --- a/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp +++ b/src/dawn/scene/components/ui/text/UIRichTextLabel.cpp @@ -37,7 +37,7 @@ void UIRichTextLabel::onStart() { struct UILabelStyle style; if(child->attributes.contains("font")) { - style.font = this->getGame()->assetManager.get(child->attributes["font"]); + style.font = this->getGame()->assetManager.get(child->attributes["font"]); } else { style.font = current.font; } @@ -51,8 +51,8 @@ void UIRichTextLabel::onStart() { if(child->attributes.contains("style")) { std::string s = child->attributes["style"]; style.style = 0; - if(s.find("bold") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_BOLD; - if(s.find("italic") != std::string::npos) style.style |= NEW_TRUETYPE_VARIANT_ITALICS; + if(s.find("bold") != std::string::npos) style.style |= TRUE_TYPE_VARIANT_BOLD; + if(s.find("italic") != std::string::npos) style.style |= TRUE_TYPE_VARIANT_ITALICS; } else { style.style = current.style; } diff --git a/src/dawnliminal/CMakeLists.txt b/src/dawnliminal/CMakeLists.txt index 33052676..e30099e1 100644 --- a/src/dawnliminal/CMakeLists.txt +++ b/src/dawnliminal/CMakeLists.txt @@ -23,7 +23,7 @@ set(LIMINAL_ASSETS_DIR ${DAWN_ASSETS_DIR}/games/liminal) tool_texture(texture_eth FILE=${LIMINAL_ASSETS_DIR}/textures/eth.png) tool_texture(texture_border FILE=${LIMINAL_ASSETS_DIR}/textures/texture_test.png) -tool_newtruetype(font_arial +tool_truetype(font_arial REGULAR="/usr/share/fonts/TTF/arial.ttf" BOLD="/usr/share/fonts/TTF/arialbd.ttf" ITALICS="/usr/share/fonts/TTF/ariali.ttf" diff --git a/src/dawnliminal/scenes/HelloWorldScene.hpp b/src/dawnliminal/scenes/HelloWorldScene.hpp index 4482d7d0..29d17ed8 100644 --- a/src/dawnliminal/scenes/HelloWorldScene.hpp +++ b/src/dawnliminal/scenes/HelloWorldScene.hpp @@ -56,7 +56,7 @@ namespace Dawn { auto assMan = &this->game->assetManager; std::vector assets; vectorAppend(&assets, SimpleSpinningCubePrefab::getRequiredAssets(assMan)); - assets.push_back(assMan->get("font_arial")); + assets.push_back(assMan->get("font_arial")); return assets; } diff --git a/src/dawnshared/display/font/truetype/NewTrueTypeShared.hpp b/src/dawnshared/display/font/truetype/TrueTypeShared.hpp similarity index 50% rename from src/dawnshared/display/font/truetype/NewTrueTypeShared.hpp rename to src/dawnshared/display/font/truetype/TrueTypeShared.hpp index e2efc96f..8c43d72b 100644 --- a/src/dawnshared/display/font/truetype/NewTrueTypeShared.hpp +++ b/src/dawnshared/display/font/truetype/TrueTypeShared.hpp @@ -6,8 +6,8 @@ #pragma once #include "util/flag.hpp" -#define NEW_TRUETYPE_CHAR_BEGIN 32 -#define NEW_TRUETYPE_CHAR_END 192 +#define TRUE_TYPE_CHAR_BEGIN 32 +#define TRUE_TYPE_CHAR_END 192 -#define NEW_TRUETYPE_VARIANT_BOLD FLAG_DEFINE(0) -#define NEW_TRUETYPE_VARIANT_ITALICS FLAG_DEFINE(1) \ No newline at end of file +#define TRUE_TYPE_VARIANT_BOLD FLAG_DEFINE(0) +#define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1) \ No newline at end of file diff --git a/src/dawntools/CMakeLists.txt b/src/dawntools/CMakeLists.txt index a5531755..106d19e3 100644 --- a/src/dawntools/CMakeLists.txt +++ b/src/dawntools/CMakeLists.txt @@ -26,5 +26,4 @@ add_subdirectory(prefabtool) add_subdirectory(scenetool) add_subdirectory(texturetool) add_subdirectory(truetypetool) -add_subdirectory(vnscenetool) -add_subdirectory(newtruetypetool) \ No newline at end of file +add_subdirectory(vnscenetool) \ No newline at end of file diff --git a/src/dawntools/newtruetypetool/CMakeLists.txt b/src/dawntools/newtruetypetool/CMakeLists.txt deleted file mode 100644 index 59473257..00000000 --- a/src/dawntools/newtruetypetool/CMakeLists.txt +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) 2023 Dominic Msters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -project(newtruetypetool VERSION 3.0) -add_executable(newtruetypetool) - -target_sources(newtruetypetool - PRIVATE - ${DAWN_SHARED_SOURCES} - ${DAWN_TOOL_SOURCES} - NewTrueTypeTool.cpp -) - -target_include_directories(newtruetypetool - PUBLIC - ${DAWN_SHARED_INCLUDES} - ${DAWN_TOOL_INCLUDES} - ${CMAKE_CURRENT_LIST_DIR} -) - -# Definitions -target_compile_definitions(newtruetypetool - PUBLIC - ${DAWN_SHARED_DEFINITIONS} - DAWN_TOOL_INSTANCE=NewTrueTypeTool - DAWN_TOOL_HEADER="NewTrueTypeTool.hpp" -) - -# Libraries -target_link_libraries(newtruetypetool - PUBLIC - ${DAWN_BUILD_HOST_LIBS} -) - -# Tool Function -function(tool_newtruetype target) - # Defaults - set(FILE "" ) - - # Parse Args - foreach(_PAIR IN LISTS ARGN) - if (_PAIR MATCHES "^([^:]+)=(.*)$") - set(${CMAKE_MATCH_1} ${CMAKE_MATCH_2}) - else() - message(FATAL_ERROR "Invalid pair: ${_PAIR}") - endif() - endforeach() - - # Check for missing args - - set(DEPS "") - if(DAWN_BUILD_TOOLS) - set(DEPS truetypetool) - endif() - - - add_custom_target(${target} - COMMAND newtruetypetool - --output="${DAWN_ASSETS_BUILD_DIR}/${target}.newtruetype" - --regular="${REGULAR}" - --bold="${BOLD}" - --italics="${ITALICS}" - --bold-italics="${BOLD_ITALICS}" - COMMENT "Generating newtruetype" - DEPENDS ${DEPS} - ) - add_dependencies(${DAWN_TARGET_NAME} ${target}) -endfunction() \ No newline at end of file diff --git a/src/dawntools/newtruetypetool/NewTrueTypeTool.cpp b/src/dawntools/newtruetypetool/NewTrueTypeTool.cpp deleted file mode 100644 index f9e5b277..00000000 --- a/src/dawntools/newtruetypetool/NewTrueTypeTool.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "NewTrueTypeTool.hpp" - -using namespace Dawn; - -NewTrueTypeFile::NewTrueTypeFile(std::string path) : file(path) { - this->path = path; - - // Remove extension - size_t pos = path.find_last_of("."); - std::string filename = path.substr(0, pos); - - - style = 0; - if(path.find("bold") != std::string::npos || filename.ends_with("bd") || filename.ends_with("bi")) { - style |= NEW_TRUETYPE_VARIANT_BOLD; - } - if(path.find("italics") != std::string::npos || filename.ends_with("i") || filename.ends_with("bi")) { - style |= NEW_TRUETYPE_VARIANT_ITALICS; - } - - if(!file.exists()) { - std::cout << "File " << path << " does not exist!" << std::endl; - throw "File not found"; - } - - if(!file.open(FILE_MODE_READ)) { - std::cout << "Failed to open file " << path << " for reading!" << std::endl; - throw "Unable to open file for reading!"; - } -} - -NewTrueTypeFile::~NewTrueTypeFile() { -} - - -std::vector NewTrueTypeTool::getRequiredFlags() { - return { "output" }; -} - -std::map NewTrueTypeTool::getOptionalFlags() { - return { - { "regular", "" }, - { "italics", "" }, - { "bold", "" }, - { "bold-italics", "" } - }; -} - -int32_t NewTrueTypeTool::start() { - std::vector files; - std::vector flags = { "regular", "italics", "bold", "bold-italics" }; - - auto cleanupFiles = [&]() { - auto itFile = files.begin(); - while(itFile != files.end()) { - auto file = *itFile; - delete file; - ++itFile; - } - }; - - // For each flag - auto itFlag = flags.begin(); - while(itFlag != flags.end()) { - std::string flag = *itFlag; - std::string path = this->flags[flag]; - - if(path.empty()) { - ++itFlag; - continue; - } - - try { - auto n = new NewTrueTypeFile(path); - files.push_back(n); - } catch(const char *e) { - cleanupFiles(); - return 1; - } - ++itFlag; - } - - if(files.size() == 0) { - std::cout << "No valid TTF files provided!" << std::endl; - cleanupFiles(); - return 1; - } - - // Create the output file - File fileOut = File(this->flags["output"]); - if(!fileOut.mkdirp()) { - std::cout << "Failed to create output directory!" << std::endl; - cleanupFiles(); - return 1; - } - if(!fileOut.open(FILE_MODE_WRITE)) { - std::cout << "Failed to open output file for writing!" << std::endl; - cleanupFiles(); - return 1; - } - - // Prepare to write data - std::string header = "DE_TTF|3.00|"; - - // Write file count - header += std::to_string(files.size()) + "|"; - - // For each file - auto itFile = files.begin(); - while(itFile != files.end()) { - auto file = *itFile; - // Style - header += std::to_string(file->style); - header += ":"; - // File length - header += std::to_string(file->file.length); - header += "|"; - ++itFile; - } - - if(!fileOut.writeRaw((char *)header.c_str(), header.length())) { - std::cout << "Failed to write TTF Header to " << fileOut.filename << std::endl; - cleanupFiles(); - return 1; - } - - // Now write the data for each file - itFile = files.begin(); - while(itFile != files.end()) { - auto file = *itFile; - - // Write the file data - file->file.setPosition(0); - if(!fileOut.copyRaw(&file->file, file->file.length)) { - std::cout << "Failed copy output data of " << file->file.filename << std::endl; - cleanupFiles(); - return 1; - } - - // Write vertical bar - char sep[1]; - sep[0] = '|'; - fileOut.writeRaw(sep, 1); - - ++itFile; - } - - // Cleanup - itFile = files.begin(); - while(itFile != files.end()) { - auto file = *itFile; - delete file; - ++itFile; - } - - // Done - fileOut.close(); - return 0; -} \ No newline at end of file diff --git a/src/dawntools/newtruetypetool/NewTrueTypeTool.hpp b/src/dawntools/newtruetypetool/NewTrueTypeTool.hpp deleted file mode 100644 index c9225b82..00000000 --- a/src/dawntools/newtruetypetool/NewTrueTypeTool.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2023 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "util/DawnTool.hpp" -#include "util/File.hpp" -#include "display/font/truetype/NewTrueTypeShared.hpp" - -namespace Dawn { - class NewTrueTypeFile { - public: - flag_t style; - std::string path; - File file; - - NewTrueTypeFile(std::string path); - ~NewTrueTypeFile(); - }; - - class NewTrueTypeTool : public DawnTool { - protected: - std::vector getRequiredFlags() override; - std::map getOptionalFlags() override; - - public: - int32_t start(); - }; -} \ No newline at end of file diff --git a/src/dawntools/truetypetool/CMakeLists.txt b/src/dawntools/truetypetool/CMakeLists.txt index 0a53ca29..f29a225c 100644 --- a/src/dawntools/truetypetool/CMakeLists.txt +++ b/src/dawntools/truetypetool/CMakeLists.txt @@ -1,9 +1,9 @@ -# Copyright (c) 2021 Dominic Msters +# Copyright (c) 2023 Dominic Msters # # This software is released under the MIT License. # https://opensource.org/licenses/MIT -project(truetypetool VERSION 2.0) +project(truetypetool VERSION 3.0) add_executable(truetypetool) target_sources(truetypetool @@ -32,7 +32,6 @@ target_compile_definitions(truetypetool target_link_libraries(truetypetool PUBLIC ${DAWN_BUILD_HOST_LIBS} - stb ) # Tool Function @@ -50,20 +49,21 @@ function(tool_truetype target) endforeach() # Check for missing args - if(NOT DEFINED FILE) - message(FATAL_ERROR "Missing FILE input") - endif() set(DEPS "") if(DAWN_BUILD_TOOLS) set(DEPS truetypetool) endif() + add_custom_target(${target} COMMAND truetypetool - --input="${DAWN_ASSETS_SOURCE_DIR}/${FILE}" - --output="${DAWN_ASSETS_BUILD_DIR}/${target}" - COMMENT "Generating truetype font ${target} from ${in}" + --output="${DAWN_ASSETS_BUILD_DIR}/${target}.truetype" + --regular="${REGULAR}" + --bold="${BOLD}" + --italics="${ITALICS}" + --bold-italics="${BOLD_ITALICS}" + COMMENT "Generating truetype" DEPENDS ${DEPS} ) add_dependencies(${DAWN_TARGET_NAME} ${target}) diff --git a/src/dawntools/truetypetool/TrueTypeTool.cpp b/src/dawntools/truetypetool/TrueTypeTool.cpp index b17fef47..166ddc3c 100644 --- a/src/dawntools/truetypetool/TrueTypeTool.cpp +++ b/src/dawntools/truetypetool/TrueTypeTool.cpp @@ -4,69 +4,161 @@ // https://opensource.org/licenses/MIT #include "TrueTypeTool.hpp" -#ifndef STB_TRUETYPE_IMPLEMENTATION - #define STB_TRUETYPE_IMPLEMENTATION - #include -#endif using namespace Dawn; +TrueTypeFile::TrueTypeFile(std::string path) : file(path) { + this->path = path; + + // Remove extension + size_t pos = path.find_last_of("."); + std::string filename = path.substr(0, pos); + + + style = 0; + if(path.find("bold") != std::string::npos || filename.ends_with("bd") || filename.ends_with("bi")) { + style |= TRUE_TYPE_VARIANT_BOLD; + } + if(path.find("italics") != std::string::npos || filename.ends_with("i") || filename.ends_with("bi")) { + style |= TRUE_TYPE_VARIANT_ITALICS; + } + + if(!file.exists()) { + std::cout << "File " << path << " does not exist!" << std::endl; + throw "File not found"; + } + + if(!file.open(FILE_MODE_READ)) { + std::cout << "Failed to open file " << path << " for reading!" << std::endl; + throw "Unable to open file for reading!"; + } +} + +TrueTypeFile::~TrueTypeFile() { +} + + std::vector TrueTypeTool::getRequiredFlags() { - return { "input", "output" }; + return { "output" }; +} + +std::map TrueTypeTool::getOptionalFlags() { + return { + { "regular", "" }, + { "italics", "" }, + { "bold", "" }, + { "bold-italics", "" } + }; } int32_t TrueTypeTool::start() { - File fileIn(flags["input"]); - char *ttfData = nullptr; - if(!fileIn.readToBuffer(&ttfData)) { - std::cout << "Failed to read file to buffer!" << std::endl; + std::vector files; + std::vector flags = { "regular", "italics", "bold", "bold-italics" }; + + auto cleanupFiles = [&]() { + auto itFile = files.begin(); + while(itFile != files.end()) { + auto file = *itFile; + delete file; + ++itFile; + } + }; + + // For each flag + auto itFlag = flags.begin(); + while(itFlag != flags.end()) { + std::string flag = *itFlag; + std::string path = this->flags[flag]; + + if(path.empty()) { + ++itFlag; + continue; + } + + try { + auto n = new TrueTypeFile(path); + files.push_back(n); + } catch(const char *e) { + cleanupFiles(); + return 1; + } + ++itFlag; + } + + if(files.size() == 0) { + std::cout << "No valid TTF files provided!" << std::endl; + cleanupFiles(); return 1; } - // Create bitmap data. This is a single channel color (alpha). - size_t width = 1024; - size_t height = 1024; - float_t fontSize = 128.0f; - size_t textureSize = width * height; - stbi_uc *bitmapData = new stbi_uc[textureSize]; - stbtt_bakedchar characterData[TRUETYPE_NUM_CHARS]; - - // Now parse the TTF itself. - stbtt_BakeFontBitmap( - (uint8_t*)ttfData, 0, (float)fontSize, bitmapData, - width, height, - TRUETYPE_FIRST_CHAR, TRUETYPE_NUM_CHARS, - characterData - ); - - // Prepare output file for writing. - File fileOut(flags["output"] + ".truetype"); + // Create the output file + File fileOut = File(this->flags["output"]); if(!fileOut.mkdirp()) { - free(ttfData); - delete bitmapData; std::cout << "Failed to create output directory!" << std::endl; + cleanupFiles(); return 1; } if(!fileOut.open(FILE_MODE_WRITE)) { - free(ttfData); - delete bitmapData; std::cout << "Failed to open output file for writing!" << std::endl; + cleanupFiles(); + return 1; + } + + // Prepare to write data + std::string header = "DE_TTF|3.00|"; + + // Write file count + header += std::to_string(files.size()) + "|"; + + // For each file + auto itFile = files.begin(); + while(itFile != files.end()) { + auto file = *itFile; + // Style + header += std::to_string(file->style); + header += ":"; + // File length + header += std::to_string(file->file.length); + header += "|"; + ++itFile; + } + + if(!fileOut.writeRaw((char *)header.c_str(), header.length())) { + std::cout << "Failed to write TTF Header to " << fileOut.filename << std::endl; + cleanupFiles(); return 1; } - // Write data - fileOut.writeString(std::to_string(width) + "|" + std::to_string(height) + "|" + std::to_string(fontSize) + "|"); - uint8_t pixels[1]; - for(size_t i = 0; i < textureSize; i++) { - pixels[0] = bitmapData[i]; - fileOut.writeRaw((char*)pixels, 1); + // Now write the data for each file + itFile = files.begin(); + while(itFile != files.end()) { + auto file = *itFile; + + // Write the file data + file->file.setPosition(0); + if(!fileOut.copyRaw(&file->file, file->file.length)) { + std::cout << "Failed copy output data of " << file->file.filename << std::endl; + cleanupFiles(); + return 1; + } + + // Write vertical bar + char sep[1]; + sep[0] = '|'; + fileOut.writeRaw(sep, 1); + + ++itFile; } - // Write quads - fileOut.writeRaw((char*)characterData, sizeof(stbtt_bakedchar) * TRUETYPE_NUM_CHARS); - free(ttfData); - delete bitmapData; + // Cleanup + itFile = files.begin(); + while(itFile != files.end()) { + auto file = *itFile; + delete file; + ++itFile; + } + + // Done fileOut.close(); - return 0; } \ No newline at end of file diff --git a/src/dawntools/truetypetool/TrueTypeTool.hpp b/src/dawntools/truetypetool/TrueTypeTool.hpp index 2c35530e..9121c219 100644 --- a/src/dawntools/truetypetool/TrueTypeTool.hpp +++ b/src/dawntools/truetypetool/TrueTypeTool.hpp @@ -6,15 +6,23 @@ #pragma once #include "util/DawnTool.hpp" #include "util/File.hpp" -#include "util/Image.hpp" - -#define TRUETYPE_FIRST_CHAR 32 -#define TRUETYPE_NUM_CHARS 96 +#include "display/font/truetype/TrueTypeShared.hpp" namespace Dawn { + class TrueTypeFile { + public: + flag_t style; + std::string path; + File file; + + TrueTypeFile(std::string path); + ~TrueTypeFile(); + }; + class TrueTypeTool : public DawnTool { protected: std::vector getRequiredFlags() override; + std::map getOptionalFlags() override; public: int32_t start();