2023-02-22 19:31:17 +01:00
|
|
|
#include "ofApp.h"
|
|
|
|
#include "generator-config.h"
|
2023-02-27 16:10:16 +01:00
|
|
|
#include "ofFileUtils.h"
|
2023-02-22 19:31:17 +01:00
|
|
|
#include "ofGraphics.h"
|
|
|
|
#include "ofUtils.h"
|
|
|
|
#include "save-bmp.h"
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::setup(){
|
2023-08-04 10:03:07 +02:00
|
|
|
string fontName = "TonkaFlowers.ttf";
|
|
|
|
fontPath = "data/celines-fonts/" + fontName;
|
|
|
|
|
|
|
|
char character = characters[currentCharacter];
|
|
|
|
makeCharacter(character);
|
|
|
|
|
|
|
|
#ifdef TARGET_EMSCRIPTEN
|
|
|
|
shader.load("ofxMsdfgen/shaders/simple/ES3/shader");
|
|
|
|
#else
|
|
|
|
shader.load("ofxMsdfgen/shaders/simple/GL3/shader");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::update(){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::draw(){
|
|
|
|
ofBackground(ofColor::lightGreen);
|
|
|
|
|
|
|
|
shader.begin();
|
|
|
|
float pxRange = ofMap(sin(ofGetElapsedTimeMillis() * 0.001),
|
|
|
|
-1, 1,
|
|
|
|
1, 100);
|
|
|
|
shader.setUniform1f("pxRange", pxRange);
|
|
|
|
shader.setUniformTexture("msdf", image.getTexture(), 0);
|
|
|
|
shader.setUniform4f("fontColor", ofFloatColor::white);
|
|
|
|
|
|
|
|
image.draw(ofGetWidth() - ofGetHeight(), 0, ofGetHeight(), ofGetHeight());
|
|
|
|
|
|
|
|
shader.end();
|
|
|
|
ofPushStyle();
|
|
|
|
ofSetColor(ofColor::purple);
|
|
|
|
ofDrawBitmapString("pxRange: " + ofToString(pxRange), 20, 20);
|
|
|
|
ofPopStyle();
|
|
|
|
|
|
|
|
image.draw(0, 0, 64 * 4, 64 * 4);
|
|
|
|
|
|
|
|
string msg = fontPath + "\n" + characters[currentCharacter];
|
|
|
|
ofDrawBitmapStringHighlight(msg, 20, 20);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ofApp::makeCharacter(char character){
|
2023-02-22 19:31:17 +01:00
|
|
|
|
|
|
|
int dimension = 64;
|
|
|
|
int width = dimension;
|
|
|
|
int height = dimension;
|
|
|
|
FreetypeHandle * ft = initializeFreetype();
|
|
|
|
if(ft){
|
|
|
|
const char * fontPath_c_str = fontPath.c_str();
|
|
|
|
FontHandle * font = loadFont(ft, fontPath_c_str);
|
|
|
|
if(font){
|
|
|
|
Shape shape;
|
2023-08-04 10:03:07 +02:00
|
|
|
if(loadGlyph(shape, font, character)){
|
2023-02-22 19:31:17 +01:00
|
|
|
shape.normalize();
|
|
|
|
Shape::Bounds bounds = shape.getBounds();
|
|
|
|
|
|
|
|
double pxRange = 2;
|
|
|
|
Vector2 translate;
|
|
|
|
Vector2 scale = 1;
|
|
|
|
double range = 1;
|
|
|
|
double avgScale = .5 * (scale.x + scale.y);
|
|
|
|
|
|
|
|
// Auto-frame
|
|
|
|
double l = bounds.l, b = bounds.b, r = bounds.r, t = bounds.t;
|
|
|
|
Vector2 frame(width, height);
|
|
|
|
double m = .5 + (double)0;
|
|
|
|
frame -= 2 * m * pxRange;
|
|
|
|
if(l >= r || b >= t){
|
|
|
|
l = 0, b = 0, r = 1, t = 1;
|
|
|
|
}
|
|
|
|
if(frame.x <= 0 || frame.y <= 0){
|
|
|
|
ofLogError("Cannot fit the specified pixel range.");
|
|
|
|
}
|
|
|
|
Vector2 dims(r - l, t - b);
|
|
|
|
if(dims.x * frame.y < dims.y * frame.x){
|
|
|
|
translate.set(.5 * (frame.x / frame.y * dims.y - dims.x) - l, -b);
|
|
|
|
scale = avgScale = frame.y / dims.y;
|
|
|
|
}else{
|
|
|
|
translate.set(-l, .5 * (frame.y / frame.x * dims.x - dims.y) - b);
|
|
|
|
scale = avgScale = frame.x / dims.x;
|
|
|
|
}
|
|
|
|
translate += m * pxRange / scale;
|
|
|
|
range = pxRange / std::min(scale.x, scale.y);
|
|
|
|
|
|
|
|
// max. angle
|
|
|
|
edgeColoringSimple(shape, 3.0);
|
|
|
|
// image width, height
|
|
|
|
Bitmap <float, 3> msdf(dimension, dimension);
|
|
|
|
msdfgen::Projection projection(scale, translate);
|
|
|
|
msdfgen::MSDFGeneratorConfig generatorConfig;
|
|
|
|
generateMSDF(msdf, shape, projection, range, generatorConfig);
|
|
|
|
|
|
|
|
ofxMsdfgen::toOfImage(msdf, image);
|
|
|
|
|
|
|
|
msdfgen::saveBmp(msdf, "data/outpurt.bmp");
|
|
|
|
|
|
|
|
}
|
|
|
|
destroyFont(font);
|
|
|
|
}
|
|
|
|
deinitializeFreetype(ft);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::keyPressed(int key){
|
|
|
|
if(key == 's'){
|
|
|
|
ofSaveImage(image, "output.png");
|
|
|
|
ofSaveImage(image, "output.jpg");
|
|
|
|
image.save("outerput.png");
|
|
|
|
}
|
2023-08-04 10:03:07 +02:00
|
|
|
if(key == 'n'){
|
|
|
|
currentCharacter++;
|
|
|
|
currentCharacter %= characters.length();
|
|
|
|
makeCharacter(characters[currentCharacter]);
|
|
|
|
}else if(key == 'p'){
|
|
|
|
currentCharacter = characters.length() + currentCharacter - 1;
|
|
|
|
currentCharacter %= characters.length();
|
|
|
|
makeCharacter(characters[currentCharacter]);
|
|
|
|
}
|
|
|
|
if(key == 'a'){
|
|
|
|
showAtlas = !showAtlas;
|
|
|
|
if(showAtlas){
|
|
|
|
image.load("atlascache/celines-fonts/TonkaFlowers.ttf/msdfgen/256_256_10Weight_0_Weight_400_.png");
|
|
|
|
}
|
|
|
|
cout << "show tlas " << (showAtlas ? "yes" : "no") << endl;
|
|
|
|
}
|
2023-02-22 19:31:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::keyReleased(int key){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::mouseMoved(int x, int y){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::mouseDragged(int x, int y, int button){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::mousePressed(int x, int y, int button){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::mouseReleased(int x, int y, int button){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::mouseEntered(int x, int y){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::mouseExited(int x, int y){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::windowResized(int w, int h){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::gotMessage(ofMessage msg){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------
|
|
|
|
void ofApp::dragEvent(ofDragInfo dragInfo){
|
|
|
|
|
|
|
|
}
|