identify glyphs by character and variations

This commit is contained in:
jrkb 2023-04-16 14:52:37 +02:00
parent c071d3bd9c
commit 99f2055553
6 changed files with 63 additions and 41 deletions

View file

@ -28,9 +28,8 @@ void GPUFontAtlasLayerCombo::setup(const ComboIdentifier & identifier,
ofExit(); ofExit();
} }
} }
ofxGPUFont::tryUpdateMainFont(library, ofxGPUFont::initializeFont(library,
this->identifier.fontPath, this->identifier.fontPath,
mainText,
font, font,
this->settings.gpuTextureOffset); this->settings.gpuTextureOffset);
@ -71,19 +70,16 @@ void GPUFontAtlasLayerCombo::update(){
} }
} }
if(isDirty){ 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 = ""; std::string text = "";
totalCharacters = 0; totalCharacters = 0;
std::vector <ofxGPUFont::GlyphIdentity> _variationText;
for(const auto & layer : layers){ for(const auto & layer : layers){
std::string layerText = layer->getProps().text; std::string layerText = layer->getProps().text;
totalCharacters += layerText.length(); totalCharacters += layerText.length();
_variationText.insert(_variationText.end(),
layer->getVariationText().begin(),
layer->getVariationText().end());
text += layerText; text += layerText;
layer->setDirtyDirty(false); // technically not clean yet layer->setDirtyDirty(false); // technically not clean yet
// but this is synchronous // but this is synchronous
@ -92,7 +88,10 @@ void GPUFontAtlasLayerCombo::update(){
} }
removeDuplicateCharacters(text); removeDuplicateCharacters(text);
mainText = text; mainText = text;
font->prepareGlyphsForText(mainText, true); variationText = std::move(_variationText);
font->prepareGlyphsForText(variationText,
library,
true);
isDirty = false; isDirty = false;
} }
} }
@ -152,7 +151,6 @@ void GPUFontAtlasLayerCombo::setVFlip(VFlipState vFlipState){
const vector <shared_ptr <GPUFontLayer> > & GPUFontAtlasLayerCombo::getLayers(){ const vector <shared_ptr <GPUFontLayer> > & GPUFontAtlasLayerCombo::getLayers(){
return layers; return layers;
} }
bool lalala = false;
void GPUFontAtlasLayerCombo::draw(){ void GPUFontAtlasLayerCombo::draw(){
GLuint location; GLuint location;
@ -227,17 +225,10 @@ void GPUFontAtlasLayerCombo::draw(){
font->collectVerticesAndIndices(glm::vec3(layer->getProps().x, font->collectVerticesAndIndices(glm::vec3(layer->getProps().x,
layer->getProps().y, layer->getProps().y,
0), 0),
layer->getProps().text, layer->getVariationText(),
vertices, indices, true, vertices, indices, true,
layer->getProps().fontSize_px); 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); vertices.resize(totalCharacters * 4);
indices.resize(totalCharacters * 6); indices.resize(totalCharacters * 6);
//cx = 0.5f * (bb.minX + bb.maxX); //cx = 0.5f * (bb.minX + bb.maxX);

View file

@ -69,6 +69,7 @@ class GPUFontAtlasLayerCombo : public AtlasLayerCombo {
shared_ptr <ofxGPUFont::Font> font; shared_ptr <ofxGPUFont::Font> font;
string mainText = ""; string mainText = "";
std::vector <ofxGPUFont::GlyphIdentity> variationText;
bool isDirty = false; bool isDirty = false;
private: private:

View file

@ -1,6 +1,7 @@
#include "GPUFontLayer.h" #include "GPUFontLayer.h"
#include "Atlas.h" #include "Atlas.h"
#include "Utils.h" #include "Utils.h"
#include "font.hpp"
#include "fwd.hpp" #include "fwd.hpp"
#include "ofGraphics.h" #include "ofGraphics.h"
#include "ofUtils.h" #include "ofUtils.h"
@ -43,11 +44,27 @@ void GPUFontLayer::setDirtyDirty(bool dirtyDirty){
} }
void GPUFontLayer::setProps(const Props & props){ void GPUFontLayer::setProps(const Props & props){
// TODO: for now only check text, if(propsBuffer.size() == 0 || props.text != propsBuffer[0].text
// but we should of course check also variations || propsBuffer[0].fontVariations != props.fontVariations){
if(propsBuffer.size() == 0 || props.text != propsBuffer[0].text){
setDirtyDirty(true); 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))){ while(propsBuffer.size() > max(0, int(settings.maxBufferSize - 1))){
propsBuffer.pop_back(); propsBuffer.pop_back();
} }
@ -65,4 +82,7 @@ void GPUFontLayer::setId(const LayerID & id){
const LayerID & GPUFontLayer::getId(){ const LayerID & GPUFontLayer::getId(){
return id; return id;
} }
const vector <ofxGPUFont::GlyphIdentity> & GPUFontLayer::getVariationText(){
return variationText;
}
} }

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "font.hpp"
#include "ofMain.h" #include "ofMain.h"
#include "ofxGPUFont.h" #include "ofxGPUFont.h"
#include "Atlas.h" #include "Atlas.h"
@ -37,6 +38,8 @@ class GPUFontLayer : public Layer {
bool isDirtyDirty() const override; bool isDirtyDirty() const override;
void setDirtyDirty(bool dirtyDirty) override; void setDirtyDirty(bool dirtyDirty) override;
const vector <ofxGPUFont::GlyphIdentity> & getVariationText();
//void setAtlas(shared_ptr <ofxGPUFont::Atlas> _atlas); //void setAtlas(shared_ptr <ofxGPUFont::Atlas> _atlas);
//shared_ptr <ofxGPUFont::Atlas> getAtlas() const; //shared_ptr <ofxGPUFont::Atlas> getAtlas() const;
@ -49,6 +52,7 @@ class GPUFontLayer : public Layer {
/// \brief hashed id, or just counting up /// \brief hashed id, or just counting up
string id = ""; string id = "";
VFlipState vFlip = V_FLIP_UNKNOWN; VFlipState vFlip = V_FLIP_UNKNOWN;
vector <ofxGPUFont::GlyphIdentity> variationText;
private: private:
Layer::Type type = GPUFONT; Layer::Type type = GPUFONT;

View file

@ -37,21 +37,23 @@ class Layer {
bool mirror_y = false; bool mirror_y = false;
float mirror_y_distance = 0; float mirror_y_distance = 0;
float letterDelay = 0; float letterDelay = 0;
std::vector <ofxVariableLab::FontVariation> fontVariations;
string text = "abc"; string text = "abc";
string fontPath = "data/celines-fonts/Version-2-var.ttf"; string fontPath = "data/celines-fonts/Version-2-var.ttf";
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Props, //NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Props,
x, //x,
y, //y,
rotation, //rotation,
fontSize_px, //fontSize_px,
color, //color,
mirror_x, //mirror_x,
mirror_x_distance, //mirror_x_distance,
mirror_y, //mirror_y,
mirror_y_distance, //mirror_y_distance,
letterDelay, //letterDelay,
text, //fontVariations,
fontPath) //text,
//fontPath)
}; };
virtual void setup(const LayerSettings & settings = LayerSettings()) = 0; virtual void setup(const LayerSettings & settings = LayerSettings()) = 0;

View file

@ -5,6 +5,7 @@
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "json.hpp"
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include FT_MULTIPLE_MASTERS_H #include FT_MULTIPLE_MASTERS_H
@ -12,15 +13,18 @@
namespace ofxVariableLab { namespace ofxVariableLab {
struct FontVariationAxis { struct FontVariationAxis {
char * name; std::string name;
float minValue; float minValue;
float maxValue; float maxValue;
float defaultValue; float defaultValue;
}; };
struct FontVariation { struct FontVariation {
char * name; std::string name;
float value; float value;
bool operator==(const FontVariation & other) const {
return name == other.name && value == other.value;
}
}; };
#ifndef F26DOT6_TO_DOUBLE #ifndef F26DOT6_TO_DOUBLE