void ofApp::update(){ float dt = 1./60.; //upate TextureObject:: for all our objects (to handle load & unload textures) float time = ofGetElapsedTimef(); TS_START("update CH objects"); for(auto chObj : chObjects){ chObj->TexturedObject::update(time); } TS_STOP("update CH objects"); TS_START("update CWRU objects"); for(auto cwruO : cwruObjects){ cwruO->TexturedObject::update(time); } TS_STOP("update CWRU objects"); //update ofxInterface if(scene){ TS_START("update scene"); scene->updateSubtree(dt); TS_STOP("update scene"); } }
//-------------------------------------------------------------- void ofApp::draw(){ // ofSetColor(255,0,0); // ofDrawRectangle(0, 0, 100, 100); ofxFontStashStyle style; style.fontID = "veraMono"; style.fontSize = 22; style.color = ofColor::white; if(ofGetFrameNum()%60 < 30) style.blur = 4; // // ofSetColor(255); // // string formattedText = "<style font=veraMono size=17 color=#ff0000>This is: red! veramono 12.</style> <style blur=2 font=veraMonoBold size=15 color=#00ff00>Lorem ipsum</style> <style font=veraMono size=15 color=#00ff00> dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</style>"; // string formattedText = "<style font=veraMono size=20 color=#ff0000>this is: red! veramono 12 this is: red! veramono 12</style> "; string formattedText = "<style id=\"banana\">this is banana style.</style> "; formattedText += "<style id=monkey>This is monkey style</style>"; // formattedText += "<style font=Helvetica size=17 color=#bbbbbb>Lorem ipsum ad his scripta blandit partiendo, eum fastidii accumsan euripidis in, eum liber hendrerit an. Qui ut wisi </style><style font=Helvetica size=33 color=#bbbbbb>vocibus suscipiantur, </style><style font=Helvetica size=15 color=#bbbbbb>quo dicit ridens inciderint id. Quo mundi lobortis reformidans eu, legimus senserit definiebas an eos. Eu sit tincidunt incorrupte definitionem, vis mutat affert percipit cu, eirmod consectetuer signiferumque eu per. In usu latine equidem dolores. Quo no falli viris intellegam, ut fugit veritus placerat per. \n Ius id vidit volumus mandamus, vide veritus democritum te nec, ei eos debet libris consulatu. No mei ferri graeco dicunt, ad cum veri accommodare. Sed at malis omnesque delicata, usu et iusto zzril meliore. Dicunt maiorum eloquentiam cum cu, sit summo dolor essent te. Ne quodsi nusquam legendos has, ea dicit voluptua eloquentiam pro, ad sit quas qualisque. Eos vocibus deserunt quaestio ei. \n Blandit incorrupte quaerendum in quo, nibh impedit id vis, vel no nullam semper audiam. Ei populo graeci consulatu mei, has ea stet modus phaedrum. Inani oblique ne has, duo et veritus detraxit. Tota ludus oratio ea mel, offendit persequeris ei vim. Eos dicat oratio partem ut, id cum ignota senserit intellegat. Sit inani ubique graecis ad, quando graecis liberavisse et cum, dicit option eruditi at duo. Homero salutatus suscipiantur eum id, tamquam voluptaria expetendis ad sed, nobis feugiat similique usu ex.</style> "; // formattedText += "<style font=Helvetica blur=2 size=18 color=#00ffff>Lorem ipsum ad his scripta blandit partiendo, eum fastidii accumsan euripidis in, eum liber hendrerit an. Qui ut wisi vocibus suscipiantur, quo dicit ridens inciderint id. Quo mundi lobortis reformidans eu, legimus senserit definiebas an eos. Eu sit tincidunt incorrupte definitionem, vis mutat affert percipit cu, eirmod consectetuer signiferumque eu per. In usu latine equidem dolores. Quo no falli viris intellegam, ut fugit veritus placerat per. \n Ius id vidit volumus mandamus, vide veritus democritum te nec, ei eos debet libris consulatu. No mei ferri graeco dicunt, ad cum veri accommodare. Sed at malis omnesque delicata, usu et iusto zzril meliore. Dicunt maiorum eloquentiam cum cu, sit summo dolor essent te. Ne quodsi nusquam legendos has, ea dicit voluptua eloquentiam pro, ad sit quas qualisque. Eos vocibus deserunt quaestio ei. \n Blandit incorrupte quaerendum in quo, nibh impedit id vis, vel no nullam semper audiam. Ei populo graeci consulatu mei, has ea stet modus phaedrum. Inani oblique ne has, duo et veritus detraxit. Tota ludus oratio ea mel, offendit persequeris ei vim. Eos dicat oratio partem ut, id cum ignota senserit intellegat. Sit inani ubique graecis ad, quando graecis liberavisse et cum, dicit option eruditi at duo. Homero salutatus suscipiantur eum id, tamquam voluptaria expetendis ad sed, nobis feugiat similique usu ex.</style> "; // formattedText += "<style font=veraMono size=99 color=#00ff00>giant 99 text on vera mono</style> "; // formattedText += "<style font=Helvetica size=44 color=#0000ff>this is blue Helvetica 44</style> "; // fonts.drawFormatted(formattedText, 200, 300); // // ofSetColor(0,255,0,64); // ofDrawRectangle(50, 0, 200, 100); int x = 100; int y = 100; TS_START("drawFormattedColumn"); fonts.drawFormattedColumn(formattedText, x, y, mouseX - x, debug); TS_STOP("drawFormattedColumn"); TS_START("drawText"); fonts.draw(formattedText, style, mouseX, mouseY); TS_STOP("drawText"); ofSetColor(255,22); ofTranslate(0.5, 0.5); ofDrawLine(x, y, ofGetWidth(), y); ofDrawLine(x, 0, x, ofGetHeight()); ofDrawLine(mouseX, 0, mouseX, ofGetHeight()); // ofSetColor(255); // float t = ofGetElapsedTimef();; // for(int i = 0; i < 1000; i++){ // TS_START_ACC("test"); // TS_STOP_ACC("test"); // } // ofDrawBitmapString(ofToString((ofGetElapsedTimef()-t) * 1000.0f), 30, 30); }
void testApp::threadedFunction(){ getPocoThread().setName("MyLoopingThread"); while(isThreadRunning()){ TS_START("task"); ofSleepMillis(30); TS_START("subtask1"); ofSleepMillis(300); TS_STOP("subtask1"); TS_STOP("task"); ofSleepMillis(100); } }
void ofApp::draw(){ if(ofxApp::get().getState() == ofxApp::State::RUNNING){ TS_START("Scene Node D"); scene->render(); if(GLOB.debug){ scene->renderDebug(true); } TS_STOP("Scene Node D"); if(selectedObject){ CH_Object * chO = dynamic_cast<CH_Object*>(selectedObject); CWRU_Object * cwruO = dynamic_cast<CWRU_Object*>(selectedObject); string info; if(chO){ info = "ObjectID: " + chO->objectID + "\nTitle: " + chO->title + "\nDescription: " + chO->description + "\nNum Images: " + ofToString(chO->images.size()) + "\nImg Size: " + ofToString(chO->getTextureDimensions(TEXTURE_ORIGINAL,0)); } if(cwruO){ info = "UUID: " + cwruO->getObjectUUID() + "\nTitle: " + cwruO->title + "\nDescription: " + cwruO->description + "\nNum Images: 1" + "\nImg Size: " + ofToString(cwruO->getTextureDimensions(TEXTURE_ORIGINAL,0)); } G_FONT_MONO_BOLD().drawMultiLine(info, 16, 20, 682); } } }
void ARtest::update(float dt){ if(!bEnabled) return; TS_START("artest U"); vidGrabber.update(); if(!vidGrabber.isFrameNew()) return; colorImage.setFromPixels(vidGrabber.getPixels(), width, height); TS_START("conversion"); // convert our camera image to grayscale grayImage = colorImage; if(bMirror) grayImage.mirror(false /* vertically */, true /* horizontally */); // apply a threshold so we can see what is going on grayThres = grayImage; grayThres.threshold(threshold); TS_STOP("conversion"); TS_START("artk U"); // Pass in the new image pixels to artk artk.update(grayImage.getPixels()); TS_STOP("artk U"); if(artk.getNumDetectedMarkers() > 0){ ofVec3f pos = artk.getCameraPosition(0); plot1->update(pos.x); plot2->update(pos.y); float val = abs(pos.x) * RUI_VAR(float, "artest-cursor-accuracy"); int curval = (int)val % RUI_VAR(int, "artest-cursor-max"); cursor.set(curval); plot3->update(cursor.get()); //pos.z); // LOG << "cam pos: " << pos; } else {
void ofApp::update(){ TS_START("simple measurement"); ofSleepMillis(1); TS_STOP("simple measurement"); TS_START("nested measurement1"); TS_START("nested measurement11"); TS_START("nested measurement111"); ofSleepMillis(1); TS_STOP("nested measurement111"); TS_STOP("nested measurement11"); TS_START("nested measurement12"); ofSleepMillis(1); TS_STOP("nested measurement12"); TS_STOP("nested measurement1"); if (ofGetFrameNum()%60 == 1){ TS_START_NIF("sample across frames"); } if (ofGetFrameNum()%60 == 3){ TS_STOP_NIF("sample across frames"); } if (ofGetFrameNum()%600 == 30 || ofGetFrameNum() == 1){ TS_START("some uncommon method") ofSleepMillis(ofRandom(3)); TS_STOP("some uncommon method"); } //test accumulation time sampling for(int i = 0; i < 3; i++){ TS_START_ACC("accum test"); ofSleepMillis(1); TS_STOP_ACC("accum test"); { TS_SCOPE_ACC("scope measurement acc"); ofSleepMillis(1); } } for(int i = myThreads.size() - 1; i >= 0 ; i--){ if (!myThreads[i]->isThreadRunning()){ delete myThreads[i]; myThreads.erase(myThreads.begin() + i); } } { TS_SCOPE("scope measurement"); ofSleepMillis(1); } }
int main( int argc, char ** argv ) { mpz_t n, d, e; char * out; int t, r, bits; TS_VAR ts; if ( argc != 2 ) { usage: printf( "usage: g bits, where 32<=bits<=2048\n" ); return 1; } bits = atoi( argv[1] ); if ( bits < 32 || bits > 2048 ) goto usage; mpz_init( n ); mpz_init( d ); mpz_init( e ); TS_START(ts); r = makersa( n, d, e, bits ); t = TS_END(ts); printf( "makersa time = %d ms\n", t ); printf( "reps = %d\n", r ); if ( putkeys( n, d, e, (bits*2/8)-1 ) < 0 ) printf( "error writing keys to disk: %s\n", strerror(errno) ); mpz_clear( n ); mpz_clear( d ); mpz_clear( e ); return 0; }
// input parser: Parse a TS packet Documentation at iso13818-1.pdf SSIZE_T TSDemuxer::parse( Buffer *buf, SSIZE_T parsed ) { BYTE *ptr = (BYTE *)buf->buffer(); SIZE_T size = buf->length(); //printf( "[TSDemuxer] Begin parse: offset=%ld, bufLen=%ld, local=%d\n", parsed, size, (_local == buf) ); while (parsed < size) { { // Find TS SYNC byte SSIZE_T begin=parsed; while (ptr[parsed] != TS_SYNC && parsed < size) { parsed++; } if (parsed - begin) { Buffer show( buf->buffer()+begin, parsed+10, false ); printf( "[TSDemuxer] Warning: Sync lost offset=%ld, size=%ld, count=%ld, isLocal=%d, data=%s\n", begin, size, parsed-begin, (_local == buf), show.asHexa().c_str() ); } } // is the begin of TS packet! if (parsed < size) { int len = size - parsed; BYTE *ts = ptr + parsed; // is ths TS complete? if (len >= TS_PACKET_SIZE) { ID pid = TS_PID(ts); // Check for Transport Error Indicator (TES), payload exist, and null packets!! if (!TS_HAS_ERROR(ts) && TS_HAS_PAYLOAD(ts) && pid != TS_PID_NULL) { int payloadOffset = TS_HEAD_SIZE; // Adaptation field exists? if (TS_HAS_ADAPTATION(ts)) { // Only calculate payload offset if adaptation field exist payloadOffset += TSA_LEN(ts); } // Check payload offset if (payloadOffset < TS_PACKET_SIZE) { bool startFlag = TS_START(ts); // Find filter (and check continuity bit) _mutex.lock(); PSIFilter *filter = checkContinuity( pid, startFlag, TS_CONTINUITY(ts) ); if (filter) { BYTE *tsPayload = ts+payloadOffset; int tsPayloadLen = TS_PACKET_SIZE-payloadOffset; // Begin of a section? if (startFlag) { // Get pointer field, skip them in payload and len BYTE pointerField = tsPayload[0]; tsPayload++; tsPayloadLen--; // Check pointer field if (!pointerField || pointerField < tsPayloadLen) { if (pointerField) { // Append last block of a section filter->pushData( tsPayload, pointerField ); // Skip data marked via pointer field tsPayload += pointerField; tsPayloadLen -= pointerField; } // TODO: Can start more than one section/pes packet // Start a new section filter->startData( tsPayload, tsPayloadLen ); } else { printf( "[TSDemuxer] Warning: Pointer field invalid pointer=%d, tsPayloadLen=%d\n", pointerField, tsPayloadLen ); } } else { // Add payload to current section filter->pushData( tsPayload, tsPayloadLen ); } if (TS_PRIORITY(ts)) { // TODO: Priority not processed printf( "[TSDemuxer] Warning: Priority not processed\n" ); } } _mutex.unlock(); } else { printf( "[TSDemuxer] Warning: Transport stream payload not valid\n" ); } } parsed += TS_PACKET_SIZE; } else { // break loop break; } } } //printf( "[TSDemuxer] End parse: parsed=%ld\n", parsed ); return parsed; }
//-------------------------------------------------------------- void ofApp::update(){ //app timebase, to send to all animatable objects float dt = 1.0f / 60.0f; for ( int i = 0; i < NUM_ANIM_CURVES; i++ ){ pos[i].update( dt ); } ball.update( dt ); colorAnim.update( dt ); pointAnim.update( dt ); // if ( !pointAnim.isOrWillBeAnimating() ){ // pointAnim.animateToAfterDelay( ofPoint( ofRandom(0, ofGetWidth()), ofRandom(0, ofGetHeight())), 0.5); // } float t = ofGetFrameNum(); //animate our parametric curves float a = 0.5 + 0.5 * sin( 0.06 * t); float b = 0.5 + 0.5 * sin( 0.04 * t + 400); pos[QUADRATIC_BEZIER_PARAM].setQuadraticBezierParams(a, b); float steep = 0.5 + 0.5 * sin( 0.1 * t); pos[EXPONENTIAL_SIGMOID_PARAM].setDoubleExpSigmoidParam( steep ); a = 0.5 + 0.5 * sin( 0.05 * t); b = 0.5 + 0.5 * sin( -0.03 * t + 3); float c = 0.5 + 0.5 * sin( 0.04 * t + 6.4); float d = 0.5 + 0.5 * sin( 0.06 * t + 44); pos[CUBIC_BEZIER_PARAM].setCubicBezierParams(a, b, c, d); float elastG = 1.0 + 0.5 * sinf(t * 0.05); float elastFreq = 1.0 + 0.5 * sinf(t * 0.075 + 1.0); float elastDecay = 0.5 + 0.25 * sinf(t * 0.0375 - 1.0); pos[EASE_IN_ELASTIC].setElasticParams(elastG, elastFreq, elastDecay); pos[EASE_OUT_ELASTIC].setElasticParams(elastG, elastFreq, elastDecay); pos[EASE_IN_OUT_ELASTIC].setElasticParams(elastG, elastFreq, elastDecay); pos[EASE_OUT_IN_ELASTIC].setElasticParams(elastG, elastFreq, elastDecay); float easeOutOffset = 1.5 * sinf(t * 0.07); pos[EASE_IN_BACK].setEaseBackOffset(easeOutOffset); pos[EASE_OUT_BACK].setEaseBackOffset(easeOutOffset); pos[EASE_IN_OUT_BACK].setEaseBackOffset(easeOutOffset); pos[EASE_OUT_IN_BACK].setEaseBackOffset(easeOutOffset); int numBounces = 1 + 6 * fabs(sinf(t * 0.005)); float bounceElast = 0.2 + 0.5 * fabs(sinf(-t * 0.02)); pos[BOUNCE_IN_CUSTOM].setCustomBounceParams(numBounces, bounceElast); pos[BOUNCE_OUT_CUSTOM].setCustomBounceParams(numBounces, bounceElast); //benchmark the curves individually, report through ofxTimeMeasurements #ifdef TIME_SAMPLE for ( int i = 0 ; i < NUM_ANIM_CURVES; i++ ){ AnimCurve curve = (AnimCurve) (EASE_IN_EASE_OUT + i); string curveName = ofxAnimatable::getCurveName(curve); TS_START(curveName); int nIterations = 3000; float buffer1[20]; float buffer2[20]; for(int k = 0; k < nIterations; k++){ float percent = k / float(nIterations - 1); ofxAnimatable::calcCurveAt(percent, curve, 0.5f, 0.5f, 0.5f, 0.5f, &buffer1[0], &buffer2[0]); } TS_STOP(curveName); } #endif }
float ofxFontStash2::drawLines(const vector<StyledLine> &lines, float x, float y, bool debug){ // if possible get rid of this translate: #ifndef GL_VERSION_3 ofPushMatrix(); ofTranslate(x, y); #endif ofVec2f offset; #ifdef GL_VERSION_3 offset.x = x * pixelDensity; offset.y = y * pixelDensity; #endif // TS_START("count words"); // int nDrawnWords; // for(int i = 0; i < lines.size(); i++){ // for(int j = 0; j < lines[i].elements.size(); j++){ // nDrawnWords ++; // } // } // TS_STOP("count words"); //debug line heights! if(debug){ TS_START("draw line Heights"); ofSetColor(0,255,0,32); float yy = 0; for( const StyledLine &line : lines ){ ofDrawLine(offset.x + 0.5f, offset.y + yy + 0.5f, offset.x + line.lineW + 0.5f, offset.y + yy + 0.5f); yy += line.lineH; } TS_STOP("draw line Heights"); } ofxFontStashStyle drawStyle; drawStyle.fontSize = -1; float offY = 0.0f; // only track for return value TS_START("draw all lines"); FONT_STASH_PRE_DRAW; #ifndef GL_VERSION_3 if (pixelDensity != 1.0f){ //hmmmm ofScale(1.0f/pixelDensity, 1.0f/pixelDensity); } #endif for(int i = 0; i < lines.size(); i++){ y += lines[i].lineH; for(int j = 0; j < lines[i].elements.size(); j++){ if(lines[i].elements[j].content.type != SEPARATOR_INVISIBLE ){ //no need to draw the invisible chars const StyledLine &l = lines[i]; const LineElement &el = l.elements[j]; const string & texttt = el.content.styledText.text; if (el.content.styledText.style.valid && drawStyle != el.content.styledText.style ){ drawStyle = el.content.styledText.style; TS_START_ACC("applyStyle"); applyStyle(drawStyle); TS_STOP_ACC("applyStyle"); } //lines[i].elements[j].area.y += lines[i].lineH -lines[0].lineH; //TS_START_ACC("fonsDrawText"); fonsDrawText(fs, el.x * pixelDensity + offset.x, (el.baseLineY + l.lineH - lines[0].lineH) * pixelDensity + offset.y, texttt.c_str(), NULL); //TS_STOP_ACC("fonsDrawText"); //debug rects if(debug){ //TS_START_ACC("debug rects"); if(el.content.type == BLOCK_WORD) ofSetColor(70 * i, 255 - 70 * i, 0, 200); else ofSetColor(50 * i,255 - 50 * i, 0, 100); const ofRectangle &r = el.area; ofDrawRectangle(pixelDensity * r.x, pixelDensity * r.y, pixelDensity * r.width, pixelDensity * r.height); ofFill(); } } } } TS_STOP("draw all lines"); #ifndef GL_VERSION_3 ofPopMatrix(); #endif FONT_STASH_POST_DRAW; if(debug){ ofSetColor(255); } return offY; }
const vector<StyledLine> ofxFontStash2::layoutLines(const vector<StyledText> &blocks, float targetWidth, bool debug ){ float x = 0; float y = 0; if (targetWidth < 0) return vector<StyledLine>(); float xx = x; float yy = y; TS_START_NIF("split words"); vector<SplitTextBlock> words = splitWords(blocks); TS_STOP_NIF("split words"); if (words.size() == 0) return vector<StyledLine>(); vector<StyledLine> lines; // here we create the first line. a few things to note: // - in general, like in a texteditor, the line exists first, then content is added to it. // - 'line' here refers to the visual representation. even a line with no newline (\n) can span multiple lines lines.push_back(StyledLine()); ofxFontStashStyle currentStyle; currentStyle.fontSize = -1; // this makes sure the first style is actually applied, even if it's the default style float lineWidth = 0; int wordsThisLine = 0; vector<float> lineHeigts; float currentLineH = 0; float bounds[4]; float dx; LineElement le; TS_START("walk words"); for(int i = 0; i < words.size(); i++){ StyledLine ¤tLine = lines.back(); //TS_START_ACC("word style"); if(words[i].styledText.style.valid && currentStyle != words[i].styledText.style ){ //cout << " new style!" << endl; currentStyle = words[i].styledText.style; if(applyStyle(currentStyle)){ fonsVertMetrics(fs, NULL, NULL, ¤tLineH); currentLineH/=pixelDensity; }else{ ofLogError() << "no style font defined!"; } } //TS_STOP_ACC("word style"); bool stayOnCurrentLine = true; if( words[i].type == SEPARATOR_INVISIBLE && words[i].styledText.text == "\n" ){ stayOnCurrentLine = false; dx = 0; // add a zero-width enter mark. this is used to keep track // of the vertical spacing of empty lines. le = LineElement(words[i], ofRectangle(xx,yy,0,currentLineH)); le.baseLineY = yy; le.x = xx; le.lineHeight = currentLineH; currentLine.elements.push_back(le); float lineH = calcLineHeight(currentLine); currentLine.lineH = lineH; currentLine.lineW = xx - x + dx; // no! //i--; //re-calc dimensions of this word on a new line! yy += lineH; lineWidth = 0; wordsThisLine = 0; xx = x; lines.push_back(StyledLine()); continue; } else{ //TS_START_ACC("fonsTextBounds"); // applyStyle() already upscaled the font size for the display resolution. // Here we do the same for x/y. // The result gets the inverse treatment. dx = fonsTextBounds( fs, xx*pixelDensity, yy*pixelDensity, words[i].styledText.text.c_str(), NULL, &bounds[0] )/pixelDensity; bounds[0]/=pixelDensity; bounds[1]/=pixelDensity; bounds[2]/=pixelDensity; bounds[3]/=pixelDensity; //TS_STOP_ACC("fonsTextBounds"); //hansi: using dx instead of bounds[2]-bounds[0] //dx is the right size for spacing out text. bounds give exact area of the char, which isn't so useful here. ofRectangle where = ofRectangle(bounds[0], bounds[1] , dx, bounds[3] - bounds[1]); le = LineElement(words[i], where); le.baseLineY = yy; le.x = xx; le.lineHeight = currentLineH; float nextWidth = lineWidth + dx; //if not wider than targetW // || //this is the 1st word in this line but even that doesnt fit stayOnCurrentLine = nextWidth < targetWidth || (wordsThisLine == 0 && (nextWidth >= targetWidth)); } if (stayOnCurrentLine){ //TS_START_ACC("stay on line"); currentLine.elements.push_back(le); lineWidth += dx; xx += dx; wordsThisLine++; //TS_STOP_ACC("stay on line"); } else if( words[i].type == SEPARATOR_INVISIBLE && words[i].styledText.text == " " ){ // ignore spaces when moving into the next line! continue; } else{ //too long, start a new line //TS_START_ACC("new line"); //calc height for this line - taking in account all words in the line float lineH = lineHeightMultiplier * calcLineHeight(currentLine); currentLine.lineH = lineH; currentLine.lineW = xx - x; i--; //re-calc dimensions of this word on a new line! yy += lineH; lineWidth = 0; wordsThisLine = 0; xx = x; lines.push_back(StyledLine()); //TS_STOP_ACC("new line"); } } //TS_START_ACC("last line"); // update dimensions of the last line StyledLine ¤tLine = lines.back(); if( currentLine.elements.size() == 0 ){ // but at least one spacing character, so we have a line height. le = LineElement(SplitTextBlock(SEPARATOR_INVISIBLE,"",currentStyle), ofRectangle(xx,yy,0,currentLineH)); le.baseLineY = yy; le.x = xx; le.lineHeight = currentLineH; currentLine.elements.push_back(le); } float lineH = calcLineHeight(currentLine); currentLine.lineH = lineH; currentLine.lineW = xx - x + dx; //TS_STOP_ACC("last line"); TS_STOP("walk words"); return lines; }