add rudimentary variation animation

This commit is contained in:
jrkb 2023-04-04 11:30:54 +02:00
parent 3be6c9ddb5
commit 2fdec44c3a
3 changed files with 83 additions and 26 deletions

View file

@ -61,6 +61,22 @@ class Font {
}; };
public: public:
/// A structure to model a given axis of a variable font.
struct FontVariationAxisParameters {
/// The name of the variation axis.
const char * name;
/// The axis's minimum coordinate value.
double minValue;
/// The axis's maximum coordinate value.
double maxValue;
/// The axis's default coordinate value. FreeType computes meaningful default values for Adobe MM fonts.
double defaultValue;
};
struct FontVariationAxis {
const char * name;
double value;
};
static bool setFontVariationAxis(FT_Library & library, FT_Face & face, const char * name, double coordinate){ static bool setFontVariationAxis(FT_Library & library, FT_Face & face, const char * name, double coordinate){
bool success = false; bool success = false;
@ -89,24 +105,34 @@ class Font {
return success; return success;
} }
//bool listFontVariationAxes(std::vector<FontVariationAxis> &axes, FreetypeHandle *library, FontHandle *font) { bool setFontVariationAxis(FT_Library & library, const std::string & name, float coordinate){
//if (font->face->face_flags&FT_FACE_FLAG_MULTIPLE_MASTERS) { return Font::setFontVariationAxis(library, face, name.c_str(), coordinate);
//FT_MM_Var *master = NULL; }
//if (FT_Get_MM_Var(font->face, &master))
//return false; static bool listFontVariationAxes(std::vector <FontVariationAxisParameters> & axes, FT_Library & library, FT_Face & face){
//axes.resize(master->num_axis); if(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS){
//for (FT_UInt i = 0; i < master->num_axis; i++) { FT_MM_Var * master = NULL;
//FontVariationAxis &axis = axes[i]; if(FT_Get_MM_Var(face, &master)){
//axis.name = master->axis[i].name; return false;
//axis.minValue = master->axis[i].minimum; }
//axis.maxValue = master->axis[i].maximum; axes.resize(master->num_axis);
//axis.defaultValue = master->axis[i].def; for(FT_UInt i = 0; i < master->num_axis; i++){
//} FontVariationAxisParameters & axis = axes[i];
//FT_Done_MM_Var(library->library, master); axis.name = master->axis[i].name;
//return true; axis.minValue = F16DOT16_TO_DOUBLE(master->axis[i].minimum);
//} axis.maxValue = F16DOT16_TO_DOUBLE(master->axis[i].maximum);
//return false; axis.defaultValue = F16DOT16_TO_DOUBLE(master->axis[i].def);
//} }
FT_Done_MM_Var(library, master);
return true;
}
return false;
}
bool listFontVariationAxes(std::vector <FontVariationAxisParameters> & axes, FT_Library & library){
return Font::listFontVariationAxes(axes, library, face);
}
static FT_Face loadFace(FT_Library library, const std::string & filename, std::string & error){ static FT_Face loadFace(FT_Library library, const std::string & filename, std::string & error){
FT_Face face = NULL; FT_Face face = NULL;
@ -291,10 +317,16 @@ class Font {
uploadBuffers(); uploadBuffers();
} }
void prepareGlyphsForText(const std::string & text){ void prepareGlyphsForText(const std::string & text, bool forceChange = false){
// TODO: do not duplicate glyphs // TODO: do not duplicate glyphs
bool changed = false; bool changed = false;
if(forceChange){
bufferGlyphs.clear();
bufferCurves.clear();
glyphs.clear();
}
for(const char * textIt = text.c_str(); *textIt != '\0';){ for(const char * textIt = text.c_str(); *textIt != '\0';){
uint32_t charcode = decodeCharcode(&textIt); uint32_t charcode = decodeCharcode(&textIt);
@ -328,9 +360,6 @@ class Font {
// dynamic, the buffers could be overallocated and only the added // dynamic, the buffers could be overallocated and only the added
// data could be uploaded. // data could be uploaded.
uploadBuffers(); uploadBuffers();
//cout << "glyphs changed" << endl;
}else{
//cout << "glyphs not changed" << endl;
} }
} }

View file

@ -5,6 +5,7 @@
#include "ofRectangle.h" #include "ofRectangle.h"
#include "ofTexture.h" #include "ofTexture.h"
#include "ofUtils.h" #include "ofUtils.h"
#include <iomanip>
#ifdef TARGET_EMSCRIPTEN #ifdef TARGET_EMSCRIPTEN
#include <GLES/gl.h> #include <GLES/gl.h>
@ -36,9 +37,9 @@ bla bla bla
void ofApp::setup(){ void ofApp::setup(){
mainText_full = "A"; mainText_full = "A";
mainText = R"DONE(abcdefghijklmnopqrstuvqxyz mainText = R"DONE(abcdefghijklmnopqrstuvqxyz
ABCDEFGHIJKLMNOP)DONE"; ABCDEFGHIJKLMNOPQRSTUVWXYZ
//QRSTUVWXYZ 0123456789",.!@#$%^&*()_+=-[]{})DONE";
//0123456789",.!@#$%^&*()_+=-[]{})DONE"; mainText = "something is a sentence if words are being concerning which";
mainText_full = R"DONE(Some things are hard to write about. Take soil, mainText_full = R"DONE(Some things are hard to write about. Take soil,
for instance. Soil, Oxford dictionary reads, is the for instance. Soil, Oxford dictionary reads, is the
upper layer of earth in which plants grow, a black or upper layer of earth in which plants grow, a black or
@ -106,6 +107,15 @@ start. I hope to capture something essential.)DONE";
font, font,
bb); bb);
font->listFontVariationAxes(fontVariationAxesParameters, library);
cout << currentFontPath << " : fontVariationAxes :" << endl;
for(const auto & axis : fontVariationAxesParameters){
cout << std::fixed << std::setprecision(10) << axis.name << " :\n"
<< "\tmin: " << std::to_string(axis.minValue)
<< "\tmax: " << std::to_string(axis.maxValue)
<< "\tdefault: " << std::to_string(axis.defaultValue) << endl;
fontVariationAxes.push_back({axis.name, axis.defaultValue});
}
transform = Transform(); transform = Transform();
@ -135,7 +145,20 @@ start. I hope to capture something essential.)DONE";
//-------------------------------------------------------------- //--------------------------------------------------------------
void ofApp::update(){ void ofApp::update(){
float animationSpeed = ofMap(sin(ofGetElapsedTimef() * 0.01), -1, 1, 0.0, 2);
float threshold = 5.0;
for(int i = 0; i < fontVariationAxes.size(); i++){
Font::FontVariationAxis & axis = fontVariationAxes[i];
Font::FontVariationAxisParameters & axisParams = fontVariationAxesParameters[i];
double newValue = ofMap(sin(ofGetElapsedTimef() * animationSpeed),
-1, 1,
axisParams.minValue, axisParams.maxValue);
if(abs(newValue - axis.value) > threshold){
font->setFontVariationAxis(library, axis.name, newValue);
axis.value = newValue;
font->prepareGlyphsForText(mainText, true);
}
}
} }
//-------------------------------------------------------------- //--------------------------------------------------------------

View file

@ -89,6 +89,7 @@ class ofApp : public ofBaseApp {
string currentFontPath; string currentFontPath;
string mainText; string mainText;
string mainText_full; string mainText_full;
string mainText_hitch;
float helpFontBaseSize = 20.0f; float helpFontBaseSize = 20.0f;
@ -150,4 +151,8 @@ class ofApp : public ofBaseApp {
"data/celines-fonts/tonkaflowers-Regular.otf", "data/celines-fonts/tonkaflowers-Regular.otf",
"data/celines-fonts/Version-3-var.ttf" "data/celines-fonts/Version-3-var.ttf"
}; };
std::vector <Font::FontVariationAxisParameters> fontVariationAxesParameters;
std::vector <Font::FontVariationAxis> fontVariationAxes;
}; };