From 65ca48275c23705678981adfac0e12f3a389e0e4 Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Sun, 16 Apr 2023 17:20:54 +0200 Subject: [PATCH] slight refactor of utility types, improve mom-child relationship --- src/AtlasLayerCombo.h | 10 ----- src/GPUFontAtlasLayerCombo.cpp | 26 +++++++------ src/GPUFontLayer.cpp | 19 +++++++++- src/GPUFontLayer.h | 11 +++++- src/Layer.h | 14 +++---- src/LayerComposition.cpp | 69 +++++++++++++++++++++++++++------- src/LayerComposition.h | 2 + src/MsdfAtlasLayerCombo.cpp | 5 ++- src/MsdfLayer.cpp | 14 ++++++- src/MsdfLayer.h | 11 +++++- src/Utils.h | 21 +++++++++++ 11 files changed, 152 insertions(+), 50 deletions(-) diff --git a/src/AtlasLayerCombo.h b/src/AtlasLayerCombo.h index 3003d34..71b31a0 100644 --- a/src/AtlasLayerCombo.h +++ b/src/AtlasLayerCombo.h @@ -22,16 +22,6 @@ namespace ofxVariableLab { struct AtlasLayerComboSettings { }; -struct ComboIdentifier { - std::string fontPath = "data/celines-fonts/Version-2-var.ttf"; - Layer::Type type = Layer::MSDFGEN; - - bool operator==(const ComboIdentifier & other) const { - return (this->fontPath == other.fontPath - && this->type == other.type); - } -}; - class AtlasLayerCombo { public: virtual void setup(const ComboIdentifier & identifier, diff --git a/src/GPUFontAtlasLayerCombo.cpp b/src/GPUFontAtlasLayerCombo.cpp index ea40bc4..f2226b6 100644 --- a/src/GPUFontAtlasLayerCombo.cpp +++ b/src/GPUFontAtlasLayerCombo.cpp @@ -96,9 +96,11 @@ void GPUFontAtlasLayerCombo::update(){ } } void GPUFontAtlasLayerCombo::careForChild(shared_ptr layer){ - if(layer->getType() == Layer::GPUFONT){ + if(layer->getType() == LayerType::GPUFONT){ shared_ptr gpuFontLayer = static_pointer_cast (layer); - layers.push_back(gpuFontLayer); + gpuFontLayer->setMomsComboIdentifier(identifier); + gpuFontLayer->isWithNewMom(); + gpuFontLayer->setDirtyDirty(true); std::string oldText = mainText; std::string layerText = gpuFontLayer->getProps().text; std::string text = oldText + layerText; @@ -110,6 +112,7 @@ void GPUFontAtlasLayerCombo::careForChild(shared_ptr layer){ mainText = text; isDirty = true; } + layers.push_back(std::move(gpuFontLayer)); }else{ ofLogError("GPUFontAtlasLayerCombo::careForChild()") << __LINE__ << ": child is not recognized as Layer::GPUFONT"; } @@ -126,18 +129,19 @@ void GPUFontAtlasLayerCombo::abandonChild(shared_ptr layer){ return l == gpuFontLayer; }), layers.end()); + isDirty = true; // update the text // this doesn't happen very often, so let's just // iterate over all layers and calculate fresh - std::string text = ""; - totalCharacters = 0; - for(const auto & layer : layers){ - std::string layerText = layer->getProps().text; - totalCharacters += layerText.length(); - text += layerText; - } - removeDuplicateCharacters(text); - mainText = text; + //std::string text = ""; + //totalCharacters = 0; + //for(const auto & layer : layers){ + // std::string layerText = layer->getProps().text; + // totalCharacters += layerText.length(); + // text += layerText; + //} + //removeDuplicateCharacters(text); + //mainText = text; // NOTE: we do not want to update buffers now, // as it's probably more costly than just keeping // the old glyphs around... diff --git a/src/GPUFontLayer.cpp b/src/GPUFontLayer.cpp index 37ab4df..dcc6641 100644 --- a/src/GPUFontLayer.cpp +++ b/src/GPUFontLayer.cpp @@ -1,5 +1,6 @@ #include "GPUFontLayer.h" #include "Atlas.h" +#include "AtlasLayerCombo.h" #include "Utils.h" #include "font.hpp" #include "fwd.hpp" @@ -28,7 +29,7 @@ void GPUFontLayer::drawCharacter(const char character, float scale, ofxVariableLab::FontVariation fontVariation){ } -const Layer::Type & GPUFontLayer::getType() const { +const LayerType & GPUFontLayer::getType() const { return type; } void GPUFontLayer::setVFlip(const VFlipState vFlip){ @@ -43,6 +44,19 @@ void GPUFontLayer::setDirtyDirty(bool dirtyDirty){ isDirty = dirtyDirty; } +bool GPUFontLayer::wantsNewMom(){ + return notHappyWithMom; +} +void GPUFontLayer::isWithNewMom(){ + notHappyWithMom = false; +} +const ComboIdentifier & GPUFontLayer::getMomsComboIdentifier() const { + return momsComboIdentifier; +} +void GPUFontLayer::setMomsComboIdentifier(const ComboIdentifier & identifier){ + momsComboIdentifier = identifier; +} + void GPUFontLayer::setProps(const Props & props){ if(propsBuffer.size() == 0 || props.text != propsBuffer[0].text || propsBuffer[0].fontVariations != props.fontVariations){ @@ -64,6 +78,9 @@ void GPUFontLayer::setProps(const Props & props){ i++; } } + if(props.fontPath != propsBuffer[0].fontPath){ + notHappyWithMom = true; + } while(propsBuffer.size() > max(0, int(settings.maxBufferSize - 1))){ propsBuffer.pop_back(); diff --git a/src/GPUFontLayer.h b/src/GPUFontLayer.h index b212a0a..38143a0 100644 --- a/src/GPUFontLayer.h +++ b/src/GPUFontLayer.h @@ -1,5 +1,6 @@ #pragma once +#include "AtlasLayerCombo.h" #include "font.hpp" #include "ofMain.h" #include "ofxGPUFont.h" @@ -33,10 +34,14 @@ class GPUFontLayer : public Layer { return NULL; // evil? } - const Type & getType() const override; + const LayerType & getType() const override; void setVFlip(const VFlipState vFlip) override; bool isDirtyDirty() const override; void setDirtyDirty(bool dirtyDirty) override; + bool wantsNewMom() override; + void isWithNewMom() override; + const ComboIdentifier & getMomsComboIdentifier() const override; + void setMomsComboIdentifier(const ComboIdentifier & identifier) override; const vector & getVariationText(); @@ -55,6 +60,8 @@ class GPUFontLayer : public Layer { vector variationText; private: - Layer::Type type = GPUFONT; + ComboIdentifier momsComboIdentifier; + bool notHappyWithMom = false; + LayerType type = GPUFONT; }; } diff --git a/src/Layer.h b/src/Layer.h index cce9d00..5f4aa58 100644 --- a/src/Layer.h +++ b/src/Layer.h @@ -11,10 +11,6 @@ namespace ofxVariableLab { -// TODO: proper ID management and generation -// what do we have this fancy random_id for? -using LayerID = string; - struct LayerSettings { uint32_t maxBufferSize = 100; VFlipBehaviour vFlipBehaviour = V_FLIP_ONCE_AUTO; @@ -22,10 +18,6 @@ struct LayerSettings { class Layer { public: - enum Type { - MSDFGEN = 0, - GPUFONT - }; struct Props { float x = 200; float y = 200; @@ -72,10 +64,14 @@ class Layer { virtual const LayerID & getId() = 0; virtual void setShader(shared_ptr _shader) = 0; virtual shared_ptr getShader() const = 0; - virtual const Type & getType() const = 0; + virtual const LayerType & getType() const = 0; virtual void setVFlip(const VFlipState vFlip) = 0; virtual bool isDirtyDirty() const = 0; virtual void setDirtyDirty(bool dirtyDirty) = 0; + virtual bool wantsNewMom() = 0; + virtual void isWithNewMom() = 0; + virtual const ComboIdentifier & getMomsComboIdentifier() const = 0; + virtual void setMomsComboIdentifier(const ComboIdentifier & identifier) = 0; static int n_layers; }; } diff --git a/src/LayerComposition.cpp b/src/LayerComposition.cpp index 555fe25..fb4bb31 100644 --- a/src/LayerComposition.cpp +++ b/src/LayerComposition.cpp @@ -16,23 +16,65 @@ void LayerComposition::setup(){ } void LayerComposition::update(){ + for(auto & l: layers){ + if(l.second->wantsNewMom()){ + const auto momIdentifier = l.second->getMomsComboIdentifier(); + atlasLayerCombos[momIdentifier]->abandonChild(l.second); + ComboIdentifier idealMom{ + l.second->getProps().fontPath, + momIdentifier.type + }; + cout << "ideal mom looks like this: " << l.second->getProps().fontPath + << (momIdentifier.type == LayerType::GPUFONT ? "gpufont" : "msdfgen") + << endl; + findOrCreateNewMomForLayer(l.second, idealMom); + } + } for(const auto & atlasLayerCombo : atlasLayerCombos){ atlasLayerCombo.second->update(); } } +void LayerComposition::findOrCreateNewMomForLayer(shared_ptr layer, + ComboIdentifier idealMom){ + auto comboIterator = atlasLayerCombos.find(idealMom); + if(comboIterator != atlasLayerCombos.end()){ + comboIterator->second->careForChild(layer); + }else{ + switch(idealMom.type){ + case LayerType::GPUFONT: { + auto combo = make_shared (); + GPUFontAtlasLayerComboSettings settings; + settings.gpuTextureOffset = nextGpuTextureOffset; + combo->setup(idealMom, settings); + nextGpuTextureOffset++; + combo->careForChild(layer); + atlasLayerCombos[idealMom] = std::move(combo); + break; + } + + default: + case LayerType::MSDFGEN: { + auto combo = make_shared (); + combo->setup(idealMom); + std::vector msdfVariations; + for(const auto & v : layer->getProps().fontVariations){ + msdfVariations.push_back({v.name, v.value}); + } + combo->atlas->addVariations(msdfVariations); + combo->careForChild(layer); + atlasLayerCombos[idealMom] = std::move(combo); + } + } + } +} LayerID LayerComposition::addLayer(const Layer::Props & props, LayerID layerID){ ComboIdentifier identifier; identifier.fontPath = props.fontPath; - identifier.type = Layer::GPUFONT; - string text = props.text; - std::vector variations = { - {"Weight", 100.0}, - {"Weight", 700.0} - }; + identifier.type = LayerType::GPUFONT; return addLayer(identifier, - text, - variations, + props, + props.fontVariations, layerID); } @@ -46,7 +88,8 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, props.fontPath = identifier.fontPath; return addLayer(identifier, props, - variations); + variations, + layerID); } LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, @@ -54,7 +97,7 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, const std::vector & variations, LayerID layerID){ switch(identifier.type){ - case Layer::GPUFONT: { + case LayerType::GPUFONT: { shared_ptr combo; auto comboIterator = atlasLayerCombos.find(identifier); if(comboIterator == atlasLayerCombos.end()){ @@ -88,7 +131,7 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, } default: - case Layer::MSDFGEN: { + case LayerType::MSDFGEN: { // TODO: put most stuff in combo setup auto combo = make_shared (); combo->setup(identifier); // TODO: add here text and variations @@ -131,12 +174,12 @@ shared_ptr LayerComposition::getLayer(const LayerID & layerID){ void LayerComposition::draw() const { for(const auto & layer_it : layers){ - if(layer_it.second->getType() == Layer::MSDFGEN){ + if(layer_it.second->getType() == LayerType::MSDFGEN){ layer_it.second->draw(glm::vec3(200, 200, 0)); } } for(const auto & combo_it : atlasLayerCombos){ - if(combo_it.first.type == Layer::GPUFONT){ + if(combo_it.first.type == LayerType::GPUFONT){ auto combo = static_pointer_cast (combo_it.second); combo->draw(); diff --git a/src/LayerComposition.h b/src/LayerComposition.h index 8e0165d..5841ad0 100644 --- a/src/LayerComposition.h +++ b/src/LayerComposition.h @@ -25,6 +25,8 @@ class LayerComposition { const Layer::Props & props, const std::vector & variations, LayerID layerID = ""); + void findOrCreateNewMomForLayer(shared_ptr layer, + ComboIdentifier idealMom); void removeLayer(const LayerID & id); // TODO: make bool, to catch nonexisting shared_ptr getLayer(const LayerID & layerID); const unordered_map > & getAtlasLayerCombos() const; diff --git a/src/MsdfAtlasLayerCombo.cpp b/src/MsdfAtlasLayerCombo.cpp index a0ac914..2742378 100644 --- a/src/MsdfAtlasLayerCombo.cpp +++ b/src/MsdfAtlasLayerCombo.cpp @@ -36,6 +36,9 @@ void MsdfAtlasLayerCombo::update(){ void MsdfAtlasLayerCombo::careForChild(shared_ptr layer){ shared_ptr msdfLayer = dynamic_pointer_cast (layer); + msdfLayer->setMomsComboIdentifier(identifier); + msdfLayer->isWithNewMom(); + msdfLayer->setDirtyDirty(true); msdfLayer->setAtlas(this->atlas); msdfLayer->setShader(msdfShader); auto & as = atlas->settings; @@ -46,7 +49,7 @@ void MsdfAtlasLayerCombo::careForChild(shared_ptr layer){ isDirty = true; } } - layers.push_back(msdfLayer); + layers.push_back(std::move(msdfLayer)); } void MsdfAtlasLayerCombo::abandonChild(shared_ptr layer){ shared_ptr msdfLayer = dynamic_pointer_cast (layer); diff --git a/src/MsdfLayer.cpp b/src/MsdfLayer.cpp index a4738fb..dc0cc43 100644 --- a/src/MsdfLayer.cpp +++ b/src/MsdfLayer.cpp @@ -268,7 +268,7 @@ void MsdfLayer::setShader(shared_ptr _shader){ shared_ptr MsdfLayer::getShader() const { return shader; } -const Layer::Type & MsdfLayer::getType() const { +const LayerType & MsdfLayer::getType() const { return type; } void MsdfLayer::setVFlip(const VFlipState vFlip){ @@ -280,6 +280,18 @@ bool MsdfLayer::isDirtyDirty() const { void MsdfLayer::setDirtyDirty(bool dirtyDirty){ isDirty = dirtyDirty; } +bool MsdfLayer::wantsNewMom(){ + return notHappyWithMom; +} +void MsdfLayer::isWithNewMom(){ + notHappyWithMom = false; +} +const ComboIdentifier & MsdfLayer::getMomsComboIdentifier() const { + return momsComboIdentifier; +} +void MsdfLayer::setMomsComboIdentifier(const ComboIdentifier & identifier){ + momsComboIdentifier = identifier; +} void MsdfLayer::setAtlas(shared_ptr _atlas){ atlas = _atlas; // TODO: this does not seem proper diff --git a/src/MsdfLayer.h b/src/MsdfLayer.h index 6ae7d6d..509c687 100644 --- a/src/MsdfLayer.h +++ b/src/MsdfLayer.h @@ -1,5 +1,6 @@ #pragma once +#include "AtlasLayerCombo.h" #include "ofMain.h" #include "ofxMsdfgen.h" #include "Atlas.h" @@ -26,10 +27,14 @@ class MsdfLayer : public Layer { const LayerID & getId() override; void setShader(shared_ptr _shader) override; shared_ptr getShader() const override; - const Type & getType() const override; + const LayerType & getType() const override; void setVFlip(const VFlipState vFlip) override; bool isDirtyDirty() const override; void setDirtyDirty(bool dirtyDirty) override; + bool wantsNewMom() override; + void isWithNewMom() override; + const ComboIdentifier & getMomsComboIdentifier() const override; + void setMomsComboIdentifier(const ComboIdentifier & identifier) override; void setAtlas(shared_ptr _atlas); shared_ptr getAtlas() const; @@ -46,6 +51,8 @@ class MsdfLayer : public Layer { VFlipState vFlip = V_FLIP_UNKNOWN; private: - Layer::Type type = MSDFGEN; + bool notHappyWithMom = false; + ComboIdentifier momsComboIdentifier; + LayerType type = MSDFGEN; }; } diff --git a/src/Utils.h b/src/Utils.h index a74026a..0f29988 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -27,6 +27,27 @@ struct FontVariation { } }; +// TODO: proper ID management and generation +// what do we have this fancy random_id for? +using LayerID = std::string; + +enum LayerType { + MSDFGEN = 0, + GPUFONT +}; + +struct ComboIdentifier { + std::string fontPath = "data/celines-fonts/Version-2-var.ttf"; + LayerType type = LayerType::MSDFGEN; + + public: + bool operator==(const ComboIdentifier & other) const { + return (this->fontPath == other.fontPath + && this->type == other.type); + } +}; + + #ifndef F26DOT6_TO_DOUBLE #define F26DOT6_TO_DOUBLE(x) (1 / 64. * double(x)) #endif