From af30d07a90f4c64baedcc383b7e5ee572de56aee Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Wed, 19 Apr 2023 17:50:24 +0100 Subject: text panel compiles --- nextus/src/ofApp.h | 2 +- nextus/src/vectorPlugin.h | 81 +++++++++- nextus/src/vectorText.h | 366 ++++++++++++++++++++++++++++++++++++++++++++++ nextus/src/vectortext.h | 366 ---------------------------------------------- 4 files changed, 446 insertions(+), 369 deletions(-) create mode 100644 nextus/src/vectorText.h delete mode 100644 nextus/src/vectortext.h (limited to 'nextus') diff --git a/nextus/src/ofApp.h b/nextus/src/ofApp.h index a549ff2..e2c90dd 100644 --- a/nextus/src/ofApp.h +++ b/nextus/src/ofApp.h @@ -58,7 +58,7 @@ class ofApp: public ofBaseApp, public ofxMidiListener { defaultPanel networkinput; svgPanel svginput; - defaultPanel textinput; + textPanel textinput; //======================================= //output diff --git a/nextus/src/vectorPlugin.h b/nextus/src/vectorPlugin.h index e20be8f..d772b0b 100644 --- a/nextus/src/vectorPlugin.h +++ b/nextus/src/vectorPlugin.h @@ -7,6 +7,7 @@ #include "ofxPONK.h" #include "lineTransformer.h" #include "lineSegmenter.h" +#include "vectorText.h" static ofVec2f DISPLAYSIZE(200,200); @@ -183,5 +184,81 @@ class textPanel: public vectorPanel{ string _title="", ofVec2f _size=DISPLAYSIZE, ofVec2f _pos=ofPoint(5,5) - ) : vectorPanel(_title,_size,_pos){} -} \ No newline at end of file + ) : vectorPanel(_title,_size,_pos){ + panel.add(use_beat.set("use beat", false)); + panel.add(beat_duration.set("duration factor", 0.5f, 0.0f, 1.0f)); + panel.add(text_speed.set("speed", 5.0f, 0.0f, 25.0f)); + panel.add(text_scale.set("scale", 0.1f, 0.0f, 0.5f)); + panel.add(enable_anim.set("animate", false)); + panel.add(anim_rev.set("reverse", false)); + panel.add(vert_pos.set("vert_pos", 0.0f, -0.3f, 0.3f)); + panel.add(vert_spread.set("vert_spread", 0.0f, -0.3f, 0.3f)); + } + vector getLines(){ + vector output; + return output; + } + protected: + ofParameter use_beat; + ofParameter beat_duration; + ofParameter text_speed; + ofParameter text_scale; + ofParameter enable_anim; + ofParameter anim_rev; + ofParameter vert_pos; + ofParameter vert_spread; + glyphbanner text; +}; +/* +class textgui : public ofxPanel{ + public: + ofParameter use_beat; + ofParameter beat_duration; + ofParameter text_speed; + ofParameter text_scale; + ofParameter enable_anim; + ofParameter anim_rev; + ofParameter vert_pos; + ofParameter vert_spread; + glyphbanner text; + int onset_frame; + void loadfile(const string & f){ + if (!strcmp(strchr(f.c_str(), '\0') - 4, ".plt")){ + text.loadPalette(f); + } + else { + text.load(f); + } + } + void setup(int x, int y){ + //text.loadFont("fonts/EMSSpaceRocks.svg"); + text.loadFont("fonts/EMSOsmotron.svg"); + + ofxPanel::setup("text","",x,y); + ofxPanel::add(use_beat.set("use beat", false)); + ofxPanel::add(beat_duration.set("duration factor", 0.5f, 0.0f, 1.0f)); + ofxPanel::add(text_speed.set("speed", 5.0f, 0.0f, 25.0f)); + ofxPanel::add(text_scale.set("scale", 0.1f, 0.0f, 0.5f)); + ofxPanel::add(enable_anim.set("animate", false)); + ofxPanel::add(anim_rev.set("reverse", false)); + ofxPanel::add(vert_pos.set("vert_pos", 0.0f, -0.3f, 0.3f)); + ofxPanel::add(vert_spread.set("vert_spread", 0.0f, -0.3f, 0.3f)); + + } + void update(int oframe=0){ + onset_frame=oframe; + text.update(text_speed,true); + } + void drawgui(int oframe=0){ + onset_frame=oframe; + ofxPanel::draw(); + } + void createWords(string t){ + text.createWords(t); + } + vector& getOutlines(float x=0, float y=0){ + return text.getOutlines(text_scale,STYLE_OVERLAPPING,x,y+(ofGetHeight()*vert_pos),enable_anim,anim_rev,vert_spread,use_beat,beat_duration); + } + +}; +*/ \ No newline at end of file diff --git a/nextus/src/vectorText.h b/nextus/src/vectorText.h new file mode 100644 index 0000000..4625989 --- /dev/null +++ b/nextus/src/vectorText.h @@ -0,0 +1,366 @@ +#pragma once + +#include "ofMain.h" +#include "ofxSvg.h" +#include "lineTransformer.h" +#include "colourPolyline.h" +#include "ofxXmlSettings.h" + +class glyph{ +public: + glyph(char c,float w,vector lines){ + glyph(c,w,lines,ofColor(0,0,0)); + } + glyph(char c,float w,vector lines,ofColor col){ + code=c; + width=w; + outline=lines; + colour=col; + } + void draw(float x, float y){ + ofSetColor(colour); + ofPushMatrix(); + ofTranslate(x,y); + for (auto& v:outline) v.draw(); + ofPopMatrix(); + } + void randomiseColour(){ + colour=ofColor::fromHsb(ofRandom(255.0),225,255); + } + char code; + float width; + vector outline; + ofColor colour; +}; + +class glyphWord{ +public: + glyphWord(){ + amount=1.0f; + val=ofRandom(1.0f); + val2=ofRandom(1.0f); + width=0; + } + vector glyphs; + float amount; + float val; //a random float used for word parameters + float val2; + float width; +}; + +#define STYLE_SENTENCE 1 +#define STYLE_OVERLAPPING 2 + +class glyphbanner{ + ofXml SVGFont; + vector words; + vector outlines; + ofVec2f centre; + float lastUpdateTime; + float playhead; + float enspace; + float last_beat; + float last_beat_duration; + vector palette; + struct { + vector balanced={ + ofColor::fromHex(0xE27D60), + ofColor::fromHex(0x085DCB), + ofColor::fromHex(0xE8A87C), + ofColor::fromHex(0xC38D9E), + ofColor::fromHex(0x41B3A3) + }; + vector uneasy={ + ofColor::fromHex(0x2154B9), + ofColor::fromHex(0xC45A62), + ofColor::fromHex(0x95A28A), + ofColor::fromHex(0x98546D), + ofColor::fromHex(0xE9DADA), + ofColor::fromHex(0x9FF3E9), + ofColor::fromHex(0xD07B37), + ofColor::fromHex(0x741710), + ofColor::fromHex(0x102ADC), + ofColor::fromHex(0x9FA1AC) + }; + vector stark={ + ofColor::fromHex(0xFFFFFF), + ofColor::fromHex(0x000000), + ofColor::fromHex(0x000000), + ofColor::fromHex(0x000000) + }; + }palettes; + vector split(string s) { + size_t pos_start = 0, pos_end; + string token; + vector res; + + while ((pos_end = s.find (" ", pos_start)) != string::npos) { + token = s.substr (pos_start, pos_end - pos_start); + pos_start = pos_end + 1; + res.push_back (token); + } + + res.push_back (s.substr (pos_start)); + return res; + } + float segment; //the fraction that the word has displayed +public: + glyphbanner(){ + palette=palettes.stark; + }; + void init(string message){ + createWords(message); + lastUpdateTime=ofGetElapsedTimef(); + playhead=0.0f; + } + int length(){ + int l=0; + for (auto& w:words) { + l+=w.glyphs.size(); + } + return l+max(0,(int)words.size()-1); + } + float width(){ + float _w=0.0f; + for (auto& w:words) { + for (auto& g:w.glyphs) _w+=g.width; + } + return _w+max((float)(words.size()-1)*enspace,0.0f); + } + int glyphCount(){ + int c=0; + for (auto& w:words){ + c+=w.glyphs.size(); + } + return c; + } + string text(){ + string s; + for (auto& w:words) { + for (auto& g:w.glyphs) s+=ofToString(g.code); + } + return s; + } + void loadFont(filesystem::path path){ + if( SVGFont.load(path) ){ + vector w=words; + clear(); + createWords(w); + enspace=getGlyph(' ').width; + ofLog()<<"loaded "< p){ + palette=p; + } + void loadPalette(string path){ + ofxXmlSettings xml; + if (xml.load(path)){ + ofLog()< palette; + for (int i=0;i m=split(message); + for (auto& word: m){ + glyphWord w; + for (auto& c: word){ + glyph g=getGlyph(c, + usePalette? + palette[ofRandom(palette.size())]: + //112->231 hue sat 0->255 brightness 255 + ofColor::fromHsb(ofRandom(119)+112,ofRandom(255),255) + ); + w.width+=g.width; + w.glyphs.push_back(g); + } + words.push_back(w); + } + ofLog()<<"glyphbanner created "< _words){ + clear(); + for (auto& _w:_words) { + glyphWord w; + for (auto& g: _w.glyphs){ + w.glyphs.push_back(getGlyph(g.code,g.colour)); + } + words.push_back(w); + } + } + glyph getGlyph(char c,ofColor col=ofColor(255,255,255)){ + vector shapes; + ofPolyline shape; + string elementPath = "/svg/defs/font/glyph[@unicode='"+ofToString(c)+"']"; + + if(SVGFont.findFirst(elementPath) == 0 ){ + elementPath = "/svg/defs/font/glyph[@unicode='?']"; + } + + ofXml xmlElement = SVGFont.findFirst(elementPath); + + float charWidth = ofToFloat(xmlElement.getAttribute("horiz-adv-x").getValue()); + + vector splitGlyphPath = ofSplitString(xmlElement.getAttribute("d").getValue(), " ");//glyph path data in SVG looks like this: "M 139 -9.45 L 230 18.9 L 299 22.1 L 227 25.2" + + for(int i=0; iwords[theword].glyphs.size()){ + theletter-=words[theword].glyphs.size(); + theword++; + } + float playfraction=playhead-int(playhead); + + //segment=(((float)theletter+words[theword].glyphs.size()+playhead-int(playhead))/words[theword].glyphs.size()); + segment=(((float)theletter+playfraction-1)/words[theword].glyphs.size()); + } + //calculate params for word/letter anim + for (int i=0;i& getOutlines(float s=1.0f,int style=STYLE_SENTENCE,float x=0,float y=0,bool anim=false,bool reverse=false, float vert_spread=0.0f, bool use_beat=false, float beat_duration=0.0f){ + outlines.clear(); + + if (beat_duration>segment){ //I don't think this is what segment is + return outlines; + } + switch (style){ + case STYLE_SENTENCE:{ + float p=((-width())/2); + for (auto& w:words){ + for (auto& g:w.glyphs){ + if (w.amount>0.0f&&g.colour.getBrightness()>0){ + for (auto& o:g.outline){ + auto q=o; + q.scale(s,-s); + q.translate(glm::vec3((p*s)+x,y,0)); + outlines.push_back(colourPolyline(q,g.colour*w.amount)); + } + } + p+=g.width; + } + p+=enspace; + } + break; + } + case STYLE_OVERLAPPING:{ + for (auto& w:words){ + float p=(w.val*(ofGetWidth()-w.width)); + float v=y+(vert_spread*w.val*(ofGetHeight())); + for (auto& g:w.glyphs){ + if (w.amount>0.0f&&g.colour.getBrightness()>0){ + for (auto& o:g.outline){ + auto q=o; + float a=anim?reverse?1.0f-segment:segment:1.0; + q.scale(s*a,-s*a); + q.translate(glm::vec3((p*s*a)+x,v,0)); + outlines.push_back(colourPolyline(q,g.colour*w.amount)); + } + } + p+=g.width*(anim?reverse?1.0f-segment:segment:1.0); + } + } + } + default:{ + break; + } + } + return outlines; + } +}; \ No newline at end of file diff --git a/nextus/src/vectortext.h b/nextus/src/vectortext.h deleted file mode 100644 index 4625989..0000000 --- a/nextus/src/vectortext.h +++ /dev/null @@ -1,366 +0,0 @@ -#pragma once - -#include "ofMain.h" -#include "ofxSvg.h" -#include "lineTransformer.h" -#include "colourPolyline.h" -#include "ofxXmlSettings.h" - -class glyph{ -public: - glyph(char c,float w,vector lines){ - glyph(c,w,lines,ofColor(0,0,0)); - } - glyph(char c,float w,vector lines,ofColor col){ - code=c; - width=w; - outline=lines; - colour=col; - } - void draw(float x, float y){ - ofSetColor(colour); - ofPushMatrix(); - ofTranslate(x,y); - for (auto& v:outline) v.draw(); - ofPopMatrix(); - } - void randomiseColour(){ - colour=ofColor::fromHsb(ofRandom(255.0),225,255); - } - char code; - float width; - vector outline; - ofColor colour; -}; - -class glyphWord{ -public: - glyphWord(){ - amount=1.0f; - val=ofRandom(1.0f); - val2=ofRandom(1.0f); - width=0; - } - vector glyphs; - float amount; - float val; //a random float used for word parameters - float val2; - float width; -}; - -#define STYLE_SENTENCE 1 -#define STYLE_OVERLAPPING 2 - -class glyphbanner{ - ofXml SVGFont; - vector words; - vector outlines; - ofVec2f centre; - float lastUpdateTime; - float playhead; - float enspace; - float last_beat; - float last_beat_duration; - vector palette; - struct { - vector balanced={ - ofColor::fromHex(0xE27D60), - ofColor::fromHex(0x085DCB), - ofColor::fromHex(0xE8A87C), - ofColor::fromHex(0xC38D9E), - ofColor::fromHex(0x41B3A3) - }; - vector uneasy={ - ofColor::fromHex(0x2154B9), - ofColor::fromHex(0xC45A62), - ofColor::fromHex(0x95A28A), - ofColor::fromHex(0x98546D), - ofColor::fromHex(0xE9DADA), - ofColor::fromHex(0x9FF3E9), - ofColor::fromHex(0xD07B37), - ofColor::fromHex(0x741710), - ofColor::fromHex(0x102ADC), - ofColor::fromHex(0x9FA1AC) - }; - vector stark={ - ofColor::fromHex(0xFFFFFF), - ofColor::fromHex(0x000000), - ofColor::fromHex(0x000000), - ofColor::fromHex(0x000000) - }; - }palettes; - vector split(string s) { - size_t pos_start = 0, pos_end; - string token; - vector res; - - while ((pos_end = s.find (" ", pos_start)) != string::npos) { - token = s.substr (pos_start, pos_end - pos_start); - pos_start = pos_end + 1; - res.push_back (token); - } - - res.push_back (s.substr (pos_start)); - return res; - } - float segment; //the fraction that the word has displayed -public: - glyphbanner(){ - palette=palettes.stark; - }; - void init(string message){ - createWords(message); - lastUpdateTime=ofGetElapsedTimef(); - playhead=0.0f; - } - int length(){ - int l=0; - for (auto& w:words) { - l+=w.glyphs.size(); - } - return l+max(0,(int)words.size()-1); - } - float width(){ - float _w=0.0f; - for (auto& w:words) { - for (auto& g:w.glyphs) _w+=g.width; - } - return _w+max((float)(words.size()-1)*enspace,0.0f); - } - int glyphCount(){ - int c=0; - for (auto& w:words){ - c+=w.glyphs.size(); - } - return c; - } - string text(){ - string s; - for (auto& w:words) { - for (auto& g:w.glyphs) s+=ofToString(g.code); - } - return s; - } - void loadFont(filesystem::path path){ - if( SVGFont.load(path) ){ - vector w=words; - clear(); - createWords(w); - enspace=getGlyph(' ').width; - ofLog()<<"loaded "< p){ - palette=p; - } - void loadPalette(string path){ - ofxXmlSettings xml; - if (xml.load(path)){ - ofLog()< palette; - for (int i=0;i m=split(message); - for (auto& word: m){ - glyphWord w; - for (auto& c: word){ - glyph g=getGlyph(c, - usePalette? - palette[ofRandom(palette.size())]: - //112->231 hue sat 0->255 brightness 255 - ofColor::fromHsb(ofRandom(119)+112,ofRandom(255),255) - ); - w.width+=g.width; - w.glyphs.push_back(g); - } - words.push_back(w); - } - ofLog()<<"glyphbanner created "< _words){ - clear(); - for (auto& _w:_words) { - glyphWord w; - for (auto& g: _w.glyphs){ - w.glyphs.push_back(getGlyph(g.code,g.colour)); - } - words.push_back(w); - } - } - glyph getGlyph(char c,ofColor col=ofColor(255,255,255)){ - vector shapes; - ofPolyline shape; - string elementPath = "/svg/defs/font/glyph[@unicode='"+ofToString(c)+"']"; - - if(SVGFont.findFirst(elementPath) == 0 ){ - elementPath = "/svg/defs/font/glyph[@unicode='?']"; - } - - ofXml xmlElement = SVGFont.findFirst(elementPath); - - float charWidth = ofToFloat(xmlElement.getAttribute("horiz-adv-x").getValue()); - - vector splitGlyphPath = ofSplitString(xmlElement.getAttribute("d").getValue(), " ");//glyph path data in SVG looks like this: "M 139 -9.45 L 230 18.9 L 299 22.1 L 227 25.2" - - for(int i=0; iwords[theword].glyphs.size()){ - theletter-=words[theword].glyphs.size(); - theword++; - } - float playfraction=playhead-int(playhead); - - //segment=(((float)theletter+words[theword].glyphs.size()+playhead-int(playhead))/words[theword].glyphs.size()); - segment=(((float)theletter+playfraction-1)/words[theword].glyphs.size()); - } - //calculate params for word/letter anim - for (int i=0;i& getOutlines(float s=1.0f,int style=STYLE_SENTENCE,float x=0,float y=0,bool anim=false,bool reverse=false, float vert_spread=0.0f, bool use_beat=false, float beat_duration=0.0f){ - outlines.clear(); - - if (beat_duration>segment){ //I don't think this is what segment is - return outlines; - } - switch (style){ - case STYLE_SENTENCE:{ - float p=((-width())/2); - for (auto& w:words){ - for (auto& g:w.glyphs){ - if (w.amount>0.0f&&g.colour.getBrightness()>0){ - for (auto& o:g.outline){ - auto q=o; - q.scale(s,-s); - q.translate(glm::vec3((p*s)+x,y,0)); - outlines.push_back(colourPolyline(q,g.colour*w.amount)); - } - } - p+=g.width; - } - p+=enspace; - } - break; - } - case STYLE_OVERLAPPING:{ - for (auto& w:words){ - float p=(w.val*(ofGetWidth()-w.width)); - float v=y+(vert_spread*w.val*(ofGetHeight())); - for (auto& g:w.glyphs){ - if (w.amount>0.0f&&g.colour.getBrightness()>0){ - for (auto& o:g.outline){ - auto q=o; - float a=anim?reverse?1.0f-segment:segment:1.0; - q.scale(s*a,-s*a); - q.translate(glm::vec3((p*s*a)+x,v,0)); - outlines.push_back(colourPolyline(q,g.colour*w.amount)); - } - } - p+=g.width*(anim?reverse?1.0f-segment:segment:1.0); - } - } - } - default:{ - break; - } - } - return outlines; - } -}; \ No newline at end of file -- cgit v1.2.3