From 99f20555532f91167c241ae4f01be1d1a679ad25 Mon Sep 17 00:00:00 2001 From: themancalledjakob Date: Sun, 16 Apr 2023 14:52:37 +0200 Subject: [PATCH] identify glyphs by character and variations --- src/GPUFontAtlasLayerCombo.cpp | 37 +++++++++++++--------------------- src/GPUFontAtlasLayerCombo.h | 1 + src/GPUFontLayer.cpp | 26 +++++++++++++++++++++--- src/GPUFontLayer.h | 4 ++++ src/Layer.h | 28 +++++++++++++------------ src/Utils.h | 8 ++++++-- 6 files changed, 63 insertions(+), 41 deletions(-) diff --git a/src/GPUFontAtlasLayerCombo.cpp b/src/GPUFontAtlasLayerCombo.cpp index 1fd8a0a..ea40bc4 100644 --- a/src/GPUFontAtlasLayerCombo.cpp +++ b/src/GPUFontAtlasLayerCombo.cpp @@ -28,11 +28,10 @@ void GPUFontAtlasLayerCombo::setup(const ComboIdentifier & identifier, ofExit(); } } - ofxGPUFont::tryUpdateMainFont(library, - this->identifier.fontPath, - mainText, - font, - this->settings.gpuTextureOffset); + ofxGPUFont::initializeFont(library, + this->identifier.fontPath, + font, + this->settings.gpuTextureOffset); font->listFontVariationAxes(fontVariationAxesParameters, library); cout << this->identifier.fontPath << " : fontVariationAxes :" << endl; @@ -71,19 +70,16 @@ void GPUFontAtlasLayerCombo::update(){ } } 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; + std::vector _variationText; for(const auto & layer : layers){ std::string layerText = layer->getProps().text; totalCharacters += layerText.length(); + _variationText.insert(_variationText.end(), + layer->getVariationText().begin(), + layer->getVariationText().end()); + text += layerText; layer->setDirtyDirty(false); // technically not clean yet // but this is synchronous @@ -92,7 +88,10 @@ void GPUFontAtlasLayerCombo::update(){ } removeDuplicateCharacters(text); mainText = text; - font->prepareGlyphsForText(mainText, true); + variationText = std::move(_variationText); + font->prepareGlyphsForText(variationText, + library, + true); isDirty = false; } } @@ -152,7 +151,6 @@ void GPUFontAtlasLayerCombo::setVFlip(VFlipState vFlipState){ const vector > & GPUFontAtlasLayerCombo::getLayers(){ return layers; } -bool lalala = false; void GPUFontAtlasLayerCombo::draw(){ GLuint location; @@ -227,17 +225,10 @@ void GPUFontAtlasLayerCombo::draw(){ font->collectVerticesAndIndices(glm::vec3(layer->getProps().x, layer->getProps().y, 0), - layer->getProps().text, + layer->getVariationText(), 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/GPUFontAtlasLayerCombo.h b/src/GPUFontAtlasLayerCombo.h index 2bcb974..dd1a9c5 100644 --- a/src/GPUFontAtlasLayerCombo.h +++ b/src/GPUFontAtlasLayerCombo.h @@ -69,6 +69,7 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo { shared_ptr font; string mainText = ""; + std::vector variationText; bool isDirty = false; private: diff --git a/src/GPUFontLayer.cpp b/src/GPUFontLayer.cpp index 4ff194e..37ab4df 100644 --- a/src/GPUFontLayer.cpp +++ b/src/GPUFontLayer.cpp @@ -1,6 +1,7 @@ #include "GPUFontLayer.h" #include "Atlas.h" #include "Utils.h" +#include "font.hpp" #include "fwd.hpp" #include "ofGraphics.h" #include "ofUtils.h" @@ -43,11 +44,27 @@ void GPUFontLayer::setDirtyDirty(bool 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){ + if(propsBuffer.size() == 0 || props.text != propsBuffer[0].text + || propsBuffer[0].fontVariations != props.fontVariations){ setDirtyDirty(true); + variationText.clear(); + variationText.resize(props.text.size()); + int i = 0; + for(const char c : props.text){ + ofxGPUFont::GlyphIdentity glyphIdentity; + glyphIdentity.charcode = ofxGPUFont::decodeCharcode(&c); + for(const auto & fv : props.fontVariations){ + glyphIdentity.coords.push_back( + std::move(ofxGPUFont::float2f16dot16(round(fv.value))) // convert to FT + // NOTE: we are also rounding here, since in practice a variation + // of 100.0 will not look much different than 100.124 + ); + } + variationText[i] = std::move(glyphIdentity); + i++; + } } + while(propsBuffer.size() > max(0, int(settings.maxBufferSize - 1))){ propsBuffer.pop_back(); } @@ -65,4 +82,7 @@ void GPUFontLayer::setId(const LayerID & id){ const LayerID & GPUFontLayer::getId(){ return id; } +const vector & GPUFontLayer::getVariationText(){ + return variationText; +} } diff --git a/src/GPUFontLayer.h b/src/GPUFontLayer.h index 2a266be..b212a0a 100644 --- a/src/GPUFontLayer.h +++ b/src/GPUFontLayer.h @@ -1,5 +1,6 @@ #pragma once +#include "font.hpp" #include "ofMain.h" #include "ofxGPUFont.h" #include "Atlas.h" @@ -37,6 +38,8 @@ class GPUFontLayer : public Layer { bool isDirtyDirty() const override; void setDirtyDirty(bool dirtyDirty) override; + const vector & getVariationText(); + //void setAtlas(shared_ptr _atlas); //shared_ptr getAtlas() const; @@ -49,6 +52,7 @@ class GPUFontLayer : public Layer { /// \brief hashed id, or just counting up string id = ""; VFlipState vFlip = V_FLIP_UNKNOWN; + vector variationText; private: Layer::Type type = GPUFONT; diff --git a/src/Layer.h b/src/Layer.h index d5061b1..cce9d00 100644 --- a/src/Layer.h +++ b/src/Layer.h @@ -37,21 +37,23 @@ class Layer { bool mirror_y = false; float mirror_y_distance = 0; float letterDelay = 0; + std::vector fontVariations; string text = "abc"; 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) + //NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Props, + //x, + //y, + //rotation, + //fontSize_px, + //color, + //mirror_x, + //mirror_x_distance, + //mirror_y, + //mirror_y_distance, + //letterDelay, + //fontVariations, + //text, + //fontPath) }; virtual void setup(const LayerSettings & settings = LayerSettings()) = 0; diff --git a/src/Utils.h b/src/Utils.h index 971c954..a74026a 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -5,6 +5,7 @@ #include #include #include +#include "json.hpp" #include #include FT_FREETYPE_H #include FT_MULTIPLE_MASTERS_H @@ -12,15 +13,18 @@ namespace ofxVariableLab { struct FontVariationAxis { - char * name; + std::string name; float minValue; float maxValue; float defaultValue; }; struct FontVariation { - char * name; + std::string name; float value; + bool operator==(const FontVariation & other) const { + return name == other.name && value == other.value; + } }; #ifndef F26DOT6_TO_DOUBLE