About 3/4 done with new font system

This commit is contained in:
2023-06-09 23:12:10 -07:00
parent 8b3ecc88a6
commit 1af1f9ef14
23 changed files with 383 additions and 332 deletions

View File

@ -12,6 +12,7 @@
#include "assets/TextureAsset.hpp"
#include "assets/TilesetAsset.hpp"
#include "assets/TrueTypeAsset.hpp"
#include "assets/NewTrueTypeAsset.hpp"
namespace Dawn {
class AssetManager {

View File

@ -11,4 +11,5 @@ target_sources(${DAWN_TARGET_NAME}
TextureAsset.cpp
TilesetAsset.cpp
TrueTypeAsset.cpp
NewTrueTypeAsset.cpp
)

View File

@ -4,6 +4,7 @@
// https://opensource.org/licenses/MIT
#include "NewTrueTypeAsset.hpp"
#include "asset/AssetManager.hpp"
using namespace Dawn;
@ -21,20 +22,19 @@ 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;
char buffer[1024];
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(buffer) == "DE_TTF");
assertTrue(std::string((char *)buffer) == "DE_TTF");
// Vertical bar
this->loader.read(buffer, 1);
@ -50,6 +50,7 @@ void NewTrueTypeAsset::updateAsync() {
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);
@ -58,16 +59,121 @@ void NewTrueTypeAsset::updateAsync() {
size_t i = 0;
while(buffer[i] != '|' && i < 64) i++;
assertTrue(buffer[i] == '|');
styleListBegin += i + 1;
buffer[i] = '\0';
int32_t count = atoi(buffer);
int32_t count = atoi((char *)buffer);
assertTrue(count > 0);
// Now begin parsing each font style
while(true) {
// 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);
// Convert to truetype faces
this->state = NEW_TRUE_TYPE_ASSET_STATE_CONVERTING_TO_FACES;
itStyle = assetStyles.begin();
while(itStyle != assetStyles.end()) {
struct NewTrueTypeAssetStyle &style = (*itStyle);
uint8_t *dataBuffer = (uint8_t*)memoryAllocate(sizeof(uint8_t) * style.dataSize);
this->loader.rewind();
this->loader.setPosition(style.dataOffset);
read = this->loader.read(dataBuffer, style.dataSize);
assertTrue(read == style.dataSize);
// Create the face
NewTrueTypeFace *face = new NewTrueTypeFace();
ret = FT_New_Memory_Face(this->fontLibrary, (FT_Byte*)dataBuffer, style.dataSize, 0, &face->face);
memoryFree(dataBuffer);
assertTrue(ret == 0);
// Push
this->faces[style.style] = face;
++itStyle;
}
// Done parsing!
this->state = NEW_TRUE_TYPE_ASSET_STATE_READY;
this->loaded = true;
}
usagelockid_t NewTrueTypeAsset::lock(struct NewTrueTypeFaceTextureStyle style) {
// Try find style
auto it = this->faces.find(style.style);
assertTrue(it != this->faces.end());
auto lock = it->second->lock(style);
this->locks[lock] = style;
return lock;
}
NewTrueTypeFaceTexture * NewTrueTypeAsset::getTexture(usagelockid_t id) {
auto existing = this->locks.find(id);
assertTrue(existing != this->locks.end());
return this->faces[existing->second.style]->getTexture(id);
}
void NewTrueTypeAsset::unlock(usagelockid_t id) {
auto existing = this->locks.find(id);
assertTrue(existing != this->locks.end());
this->faces[existing->second.style]->unlock(id);
this->locks.erase(existing);
}
NewTrueTypeAsset::~NewTrueTypeAsset() {
auto it = this->faces.begin();
while(it != this->faces.end()) {
FT_Done_Face(it->second->face);
delete it->second;
it++;
}
FT_Done_FreeType(this->fontLibrary);
}

View File

@ -6,26 +6,55 @@
#pragma once
#include "../Asset.hpp"
#include "../AssetLoader.hpp"
#include "util/flag.hpp"
#include "display/font/truetype/NewTrueTypeFace.hpp"
namespace Dawn {
enum NewTrueTypeAssetState {
NEW_TRUE_TYPE_ASSET_STATE_INITIAL,
NEW_TRUE_TYPE_ASSET_STATE_OPEN,
// NEW_TRUE_TYPE_ASSET_STATE_LOAD_RAW,
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_CONVERTING_TO_FACES,
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<struct NewTrueTypeAssetStyle> assetStyles;
std::map<flag_t, NewTrueTypeFace*> faces;
std::map<usagelockid_t, struct NewTrueTypeFaceTextureStyle> locks;
public:
NewTrueTypeAsset(AssetManager *assMan, std::string name);
void updateSync() override;
void updateAsync() override;
/**
* Locks a specific style for use later.
*
* @param style Style you want to lock.
* @return A unique lock ID for this style.
*/
usagelockid_t lock(struct NewTrueTypeFaceTextureStyle style);
NewTrueTypeFaceTexture * getTexture(usagelockid_t lock);
void unlock(usagelockid_t lock);
~NewTrueTypeAsset();
};
}