Пример #1
0
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");
	}
}
Пример #2
0
//--------------------------------------------------------------
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);

}
Пример #3
0
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);
	}
}
Пример #4
0
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);
		}
	}
}
Пример #5
0
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 {
Пример #6
0
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);
	}
}
Пример #7
0
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;
}
Пример #8
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;
}
Пример #9
0
//--------------------------------------------------------------
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
    
}
Пример #10
0
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;
}
Пример #11
0
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 &currentLine = 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, &currentLineH);
				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 &currentLine = 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; 
}