add rudimentary variation animation
This commit is contained in:
parent
3be6c9ddb5
commit
2fdec44c3a
3 changed files with 83 additions and 26 deletions
|
@ -61,6 +61,22 @@ class Font {
|
|||
};
|
||||
|
||||
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){
|
||||
bool success = false;
|
||||
|
@ -89,24 +105,34 @@ class Font {
|
|||
return success;
|
||||
}
|
||||
|
||||
//bool listFontVariationAxes(std::vector<FontVariationAxis> &axes, FreetypeHandle *library, FontHandle *font) {
|
||||
//if (font->face->face_flags&FT_FACE_FLAG_MULTIPLE_MASTERS) {
|
||||
//FT_MM_Var *master = NULL;
|
||||
//if (FT_Get_MM_Var(font->face, &master))
|
||||
//return false;
|
||||
//axes.resize(master->num_axis);
|
||||
//for (FT_UInt i = 0; i < master->num_axis; i++) {
|
||||
//FontVariationAxis &axis = axes[i];
|
||||
//axis.name = master->axis[i].name;
|
||||
//axis.minValue = master->axis[i].minimum;
|
||||
//axis.maxValue = master->axis[i].maximum;
|
||||
//axis.defaultValue = master->axis[i].def;
|
||||
//}
|
||||
//FT_Done_MM_Var(library->library, master);
|
||||
//return true;
|
||||
//}
|
||||
//return false;
|
||||
//}
|
||||
bool setFontVariationAxis(FT_Library & library, const std::string & name, float coordinate){
|
||||
return Font::setFontVariationAxis(library, face, name.c_str(), coordinate);
|
||||
}
|
||||
|
||||
static bool listFontVariationAxes(std::vector <FontVariationAxisParameters> & axes, FT_Library & library, FT_Face & face){
|
||||
if(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS){
|
||||
FT_MM_Var * master = NULL;
|
||||
if(FT_Get_MM_Var(face, &master)){
|
||||
return false;
|
||||
}
|
||||
axes.resize(master->num_axis);
|
||||
for(FT_UInt i = 0; i < master->num_axis; i++){
|
||||
FontVariationAxisParameters & axis = axes[i];
|
||||
axis.name = master->axis[i].name;
|
||||
axis.minValue = F16DOT16_TO_DOUBLE(master->axis[i].minimum);
|
||||
axis.maxValue = F16DOT16_TO_DOUBLE(master->axis[i].maximum);
|
||||
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){
|
||||
FT_Face face = NULL;
|
||||
|
||||
|
@ -291,10 +317,16 @@ class Font {
|
|||
uploadBuffers();
|
||||
}
|
||||
|
||||
void prepareGlyphsForText(const std::string & text){
|
||||
void prepareGlyphsForText(const std::string & text, bool forceChange = false){
|
||||
// TODO: do not duplicate glyphs
|
||||
bool changed = false;
|
||||
|
||||
if(forceChange){
|
||||
bufferGlyphs.clear();
|
||||
bufferCurves.clear();
|
||||
glyphs.clear();
|
||||
}
|
||||
|
||||
for(const char * textIt = text.c_str(); *textIt != '\0';){
|
||||
uint32_t charcode = decodeCharcode(&textIt);
|
||||
|
||||
|
@ -328,9 +360,6 @@ class Font {
|
|||
// dynamic, the buffers could be overallocated and only the added
|
||||
// data could be uploaded.
|
||||
uploadBuffers();
|
||||
//cout << "glyphs changed" << endl;
|
||||
}else{
|
||||
//cout << "glyphs not changed" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "ofRectangle.h"
|
||||
#include "ofTexture.h"
|
||||
#include "ofUtils.h"
|
||||
#include <iomanip>
|
||||
|
||||
#ifdef TARGET_EMSCRIPTEN
|
||||
#include <GLES/gl.h>
|
||||
|
@ -36,9 +37,9 @@ bla bla bla
|
|||
void ofApp::setup(){
|
||||
mainText_full = "A";
|
||||
mainText = R"DONE(abcdefghijklmnopqrstuvqxyz
|
||||
ABCDEFGHIJKLMNOP)DONE";
|
||||
//QRSTUVWXYZ
|
||||
//0123456789",.!@#$%^&*()_+=-[]{})DONE";
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
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,
|
||||
for instance. Soil, Oxford dictionary reads, “is the
|
||||
upper layer of earth in which plants grow, a black or
|
||||
|
@ -106,6 +107,15 @@ start. I hope to capture something essential.)DONE";
|
|||
font,
|
||||
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();
|
||||
|
||||
|
@ -135,7 +145,20 @@ start. I hope to capture something essential.)DONE";
|
|||
|
||||
//--------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
|
|
@ -89,6 +89,7 @@ class ofApp : public ofBaseApp {
|
|||
string currentFontPath;
|
||||
string mainText;
|
||||
string mainText_full;
|
||||
string mainText_hitch;
|
||||
|
||||
float helpFontBaseSize = 20.0f;
|
||||
|
||||
|
@ -150,4 +151,8 @@ class ofApp : public ofBaseApp {
|
|||
"data/celines-fonts/tonkaflowers-Regular.otf",
|
||||
"data/celines-fonts/Version-3-var.ttf"
|
||||
};
|
||||
|
||||
std::vector <Font::FontVariationAxisParameters> fontVariationAxesParameters;
|
||||
std::vector <Font::FontVariationAxis> fontVariationAxes;
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue