About 3/4 done with new font system
This commit is contained in:
@ -12,6 +12,7 @@
|
||||
#include "assets/TextureAsset.hpp"
|
||||
#include "assets/TilesetAsset.hpp"
|
||||
#include "assets/TrueTypeAsset.hpp"
|
||||
#include "assets/NewTrueTypeAsset.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager {
|
||||
|
@ -11,4 +11,5 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
TextureAsset.cpp
|
||||
TilesetAsset.cpp
|
||||
TrueTypeAsset.cpp
|
||||
NewTrueTypeAsset.cpp
|
||||
)
|
@ -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);
|
||||
}
|
@ -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();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user