diff --git a/src/GPUFontAtlasLayerCombo.cpp b/src/GPUFontAtlasLayerCombo.cpp index ace80a3..1fd8a0a 100644 --- a/src/GPUFontAtlasLayerCombo.cpp +++ b/src/GPUFontAtlasLayerCombo.cpp @@ -64,12 +64,34 @@ void GPUFontAtlasLayerCombo::update(){ //font->prepareGlyphsForText(mainText, true); //} //} + for(const auto & layer : layers){ + if(layer->isDirtyDirty()){ + isDirty = true; + break; + } + } if(isDirty){ //ofxGPUFont::tryUpdateMainFont(library, //this->identifier.fontPath, //mainText, //font, //this->settings.gpuTextureOffset); + // 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; + layer->setDirtyDirty(false); // technically not clean yet + // but this is synchronous + // and will happen, so we can avoid + // another loop + } + removeDuplicateCharacters(text); + mainText = text; font->prepareGlyphsForText(mainText, true); isDirty = false; } @@ -130,6 +152,7 @@ void GPUFontAtlasLayerCombo::setVFlip(VFlipState vFlipState){ const vector > & GPUFontAtlasLayerCombo::getLayers(){ return layers; } +bool lalala = false; void GPUFontAtlasLayerCombo::draw(){ GLuint location; @@ -207,7 +230,14 @@ void GPUFontAtlasLayerCombo::draw(){ layer->getProps().text, vertices, indices, true, layer->getProps().fontSize_px); + if(!lalala){ + nlohmann::json json; + auto props = layer->getProps(); + props.to_json(json, props); + cout << "prooops:" << json.dump(2); + } } + lalala = true; vertices.resize(totalCharacters * 4); indices.resize(totalCharacters * 6); //cx = 0.5f * (bb.minX + bb.maxX); diff --git a/src/GPUFontLayer.cpp b/src/GPUFontLayer.cpp index 5afc846..4ff194e 100644 --- a/src/GPUFontLayer.cpp +++ b/src/GPUFontLayer.cpp @@ -10,15 +10,12 @@ namespace ofxVariableLab { void GPUFontLayer::setup(const LayerSettings & settings){ this->settings = settings; if(id == ""){ - id = ofToString(Layer::n_layers); + id = "layer-" + ofToString(Layer::n_layers); n_layers++; } } void GPUFontLayer::update(){ - if(isDirty){ - isDirty = false; - } } void GPUFontLayer::draw(glm::vec3 position){ @@ -37,22 +34,27 @@ void GPUFontLayer::setVFlip(const VFlipState vFlip){ this->vFlip = vFlip; } -//void GPUFontLayer::setAtlas(shared_ptr _atlas){ -//atlas = _atlas; -//// TODO: this does not seem proper -//propsBuffer[0].fontSize_px = atlas->settings.scale; -//} -//shared_ptr GPUFontLayer::getAtlas() const { -//return atlas; -//} +bool GPUFontLayer::isDirtyDirty() const { + return isDirty; +} + +void GPUFontLayer::setDirtyDirty(bool dirtyDirty){ + isDirty = dirtyDirty; +} + void GPUFontLayer::setProps(const Props & props){ + // TODO: for now only check text, + // but we should of course check also variations + if(propsBuffer.size() == 0 || props.text != propsBuffer[0].text){ + setDirtyDirty(true); + } while(propsBuffer.size() > max(0, int(settings.maxBufferSize - 1))){ propsBuffer.pop_back(); } propsBuffer.push_front(props); } const Layer::Props & GPUFontLayer::getProps() const { - return propsBuffer[0]; + return propsBuffer[0]; // gets newest } void GPUFontLayer::clearPropsBuffer(){ propsBuffer.clear(); diff --git a/src/GPUFontLayer.h b/src/GPUFontLayer.h index a4cb792..2a266be 100644 --- a/src/GPUFontLayer.h +++ b/src/GPUFontLayer.h @@ -34,6 +34,8 @@ class GPUFontLayer : public Layer { const Type & getType() const override; void setVFlip(const VFlipState vFlip) override; + bool isDirtyDirty() const override; + void setDirtyDirty(bool dirtyDirty) override; //void setAtlas(shared_ptr _atlas); //shared_ptr getAtlas() const; diff --git a/src/Layer.h b/src/Layer.h index d2e0401..d5061b1 100644 --- a/src/Layer.h +++ b/src/Layer.h @@ -11,6 +11,8 @@ namespace ofxVariableLab { +// TODO: proper ID management and generation +// what do we have this fancy random_id for? using LayerID = string; struct LayerSettings { @@ -25,10 +27,10 @@ class Layer { GPUFONT }; struct Props { - float x = 0; - float y = 0; + float x = 200; + float y = 200; float rotation = 0; - float fontSize_px = 24; + float fontSize_px = 42; float color[4]; bool mirror_x = false; float mirror_x_distance = 0; @@ -36,7 +38,20 @@ class Layer { float mirror_y_distance = 0; float letterDelay = 0; string text = "abc"; - string fontPath; + string fontPath = "data/celines-fonts/Version-2-var.ttf"; + NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Props, + x, + y, + rotation, + fontSize_px, + color, + mirror_x, + mirror_x_distance, + mirror_y, + mirror_y_distance, + letterDelay, + text, + fontPath) }; virtual void setup(const LayerSettings & settings = LayerSettings()) = 0; @@ -57,6 +72,8 @@ class Layer { virtual shared_ptr getShader() const = 0; virtual const Type & getType() const = 0; virtual void setVFlip(const VFlipState vFlip) = 0; + virtual bool isDirtyDirty() const = 0; + virtual void setDirtyDirty(bool dirtyDirty) = 0; static int n_layers; }; } diff --git a/src/LayerComposition.cpp b/src/LayerComposition.cpp index db8be95..555fe25 100644 --- a/src/LayerComposition.cpp +++ b/src/LayerComposition.cpp @@ -20,10 +20,27 @@ void LayerComposition::update(){ atlasLayerCombo.second->update(); } } +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} + }; + return addLayer(identifier, + text, + variations, + layerID); + +} LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, const string & text, - const std::vector & variations){ + const std::vector & variations, + LayerID layerID){ auto props = Layer::Props(); props.text = text; props.fontPath = identifier.fontPath; @@ -34,8 +51,8 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, const Layer::Props & props, - const std::vector & variations){ - string layerID = ""; + const std::vector & variations, + LayerID layerID){ switch(identifier.type){ case Layer::GPUFONT: { shared_ptr combo; @@ -55,9 +72,16 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, } auto layer = make_shared (); + layer->vFlip = vFlipState; layer->setProps(props); + layer->setup(); + if(layerID == ""){ + layerID = layer->getId(); + cout << "yess layerID is now " << layerID << "!" << endl; + }else{ + layer->setId(layerID); + } combo->careForChild(layer); - layerID = layer->getId(); layers[layerID] = layer; break; @@ -72,6 +96,11 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, layer->vFlip = vFlipState; layer->setProps(props); layer->setup(); + if(layerID == ""){ + layerID = layer->getId(); + }else{ + layer->setId(layerID); + } std::vector msdfVariations; for(const auto & v : variations){ msdfVariations.push_back({v.name, v.value}); diff --git a/src/LayerComposition.h b/src/LayerComposition.h index 61672de..8e0165d 100644 --- a/src/LayerComposition.h +++ b/src/LayerComposition.h @@ -15,12 +15,16 @@ class LayerComposition { void setup(); void update(); void draw() const; + LayerID addLayer(const Layer::Props & props, + LayerID layerID = ""); LayerID addLayer(const ComboIdentifier & identifier, const string & text, - const std::vector & variations); + const std::vector & variations, + LayerID layerID = ""); LayerID addLayer(const ComboIdentifier & identifier, const Layer::Props & props, - const std::vector & variations); + const std::vector & variations, + LayerID layerID = ""); 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/MsdfLayer.cpp b/src/MsdfLayer.cpp index f2fed8f..a4738fb 100644 --- a/src/MsdfLayer.cpp +++ b/src/MsdfLayer.cpp @@ -10,15 +10,12 @@ namespace ofxVariableLab { void MsdfLayer::setup(const LayerSettings & settings){ this->settings = settings; if(id == ""){ - id = ofToString(Layer::n_layers); + id = "layer-" + ofToString(Layer::n_layers); n_layers++; } } void MsdfLayer::update(){ - if(isDirty){ - isDirty = false; - } } void MsdfLayer::draw(glm::vec3 position){ @@ -277,7 +274,12 @@ const Layer::Type & MsdfLayer::getType() const { void MsdfLayer::setVFlip(const VFlipState vFlip){ this->vFlip = vFlip; } - +bool MsdfLayer::isDirtyDirty() const { + return isDirty; +} +void MsdfLayer::setDirtyDirty(bool dirtyDirty){ + isDirty = dirtyDirty; +} void MsdfLayer::setAtlas(shared_ptr _atlas){ atlas = _atlas; // TODO: this does not seem proper @@ -287,6 +289,11 @@ shared_ptr MsdfLayer::getAtlas() const { return atlas; } void MsdfLayer::setProps(const Props & props){ + // TODO: for now only check text, + // but we should of course check also variations + if(propsBuffer.size() == 0 || props.text != propsBuffer[0].text){ + setDirtyDirty(true); + } while(propsBuffer.size() > max(0, int(settings.maxBufferSize - 1))){ propsBuffer.pop_back(); } diff --git a/src/MsdfLayer.h b/src/MsdfLayer.h index 4fc72a7..6ae7d6d 100644 --- a/src/MsdfLayer.h +++ b/src/MsdfLayer.h @@ -28,6 +28,8 @@ class MsdfLayer : public Layer { shared_ptr getShader() const override; const Type & getType() const override; void setVFlip(const VFlipState vFlip) override; + bool isDirtyDirty() const override; + void setDirtyDirty(bool dirtyDirty) override; void setAtlas(shared_ptr _atlas); shared_ptr getAtlas() const; diff --git a/src/Utils.h b/src/Utils.h index 765d374..60a3ce6 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -4,6 +4,9 @@ #include #include #include +#include +#include FT_FREETYPE_H +#include FT_MULTIPLE_MASTERS_H namespace ofxVariableLab { @@ -24,18 +27,6 @@ inline void hash_combine(std::size_t & seed, const T & v){ std::hash hasher; seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); } -//template -//ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p){ -//first = std::find_if(first, last, p); -//if(first != last){ -//for(ForwardIt i = first; ++i != last;){ -//if(!p(*i)){ -//*first++ = std::move(*i); -//} -//} -//} -//return first; -//} inline void removeDuplicateCharacters(std::string & str){ std::set chars; @@ -79,4 +70,5 @@ void getVFlip(const VFlipBehaviour & vFlipBehaviour, const glm::mat4 & orientationMatrix, VFlipState & vFlip); + }