ofRectangle ofxFontStash::drawMultiLineColumn( string & text, float size, float x, float y, float maxW, int &numLines, bool dontDraw, int maxLines, bool giveBackNewLinedText, bool* wordsWereTruncated){ ofRectangle totalArea = ofRectangle(x,y,0,0); if(wordsWereTruncated){ *wordsWereTruncated = false; } if (stash != NULL){ numLines = 0; if(!dontDraw){ glPushMatrix(); glTranslatef(x, y, 0.0f); } //ofLine(0, 0, maxW, 0); vector<string>splitLines; ofRectangle r; //ofUTF8Ptr start = ofUTF8::beginPtr(text); ofUTF8Ptr iter = ofUTF8::beginPtr(text); ofUTF8Ptr lineStart = iter; ofUTF8Ptr lastSpace; ofUTF8Ptr stop = ofUTF8::endPtr(text); string thisLine = ""; bool foundSpace = false; bool foundNewLine = false; while(iter < stop) { ofUniChar c = ofUTF8::getNext(iter); // get the next unichar and iterate if ( ofUnicode::isSpace(c) ){ foundSpace = true; lastSpace = iter; } if ( ofTextConverter::toUTF8(c) == "\n" ){ foundNewLine = true; } thisLine += ofTextConverter::toUTF8(c); r = getBBox(thisLine.c_str(), size, 0,0); if ( r.width > maxW || foundNewLine ) { //we went too far, lets jump back to our closest space if(foundNewLine){ if (thisLine == "\n"){ //if the whole line is only \n, replace with a space to avoid weird things thisLine = " "; }else{ //otherwise remove the "\n" thisLine = thisLine.substr(0, thisLine.length()-1); } splitLines.push_back(thisLine); }else{ if (foundSpace){ //cout << "## foundSpace! (" << thisLine << ")" << endl; string finalLine = walkAndFill(lineStart, iter, lastSpace); splitLines.push_back(finalLine); iter = lastSpace; }else{ //cout << "## no Space! (" << thisLine << ")" << endl; splitLines.push_back(thisLine); if(wordsWereTruncated){ *wordsWereTruncated = true; } } } //reset counter vars lineStart = iter; r.width = 0; thisLine = ""; foundSpace = foundNewLine = false; }else{ if(iter == stop){ //last line! string finalLine = walkAndFill(lineStart, iter, stop); splitLines.push_back(finalLine); break; } } } if(!dontDraw) beginBatch(); numLines = splitLines.size(); int linesToDraw = 0; if (maxLines > 0 ){ linesToDraw = MIN(splitLines.size(), maxLines); numLines = splitLines.size(); } for(int i = 0; i < linesToDraw; i++){ float yy = lineHeight * OFX_FONT_STASH_LINE_HEIGHT_MULT * size * i; if(!dontDraw){ ofPushMatrix(); ofTranslate(0, yy); drawBatch(splitLines[i], size, 0, 0 ); ofPopMatrix(); } #if OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR == 8 totalArea = totalArea.getUnion( getBBox(splitLines[i], size, x, y + yy)); #else totalArea = getBBox(splitLines[i], size, x, y + yy); //TODO! #endif } if(!dontDraw){ endBatch(); glPopMatrix(); } //return through reference the edited text (with newLines!) if(giveBackNewLinedText){ text = ""; for (int i = 0; i < numLines; i++){ text += splitLines[i]; if (i != numLines-1) text += "\n"; } } }else{ ofLogError("ofxFontStash", "can't drawMultiLine() without having been setup first!"); } return totalArea; }
ofRectangle EngineFont::drawMultiLineColumn( string text, float x, float y, float columnWidth) { ofRectangle totalArea = ofRectangle(x,y,0,0); if(!m_trueTypeFont.isLoaded()){ return totalArea; } int fontSize = m_trueTypeFont.getSize(); vector<string>splitLines; ofRectangle r; ofUTF8Ptr start = ofUTF8::beginPtr(text); ofUTF8Ptr iter = ofUTF8::beginPtr(text); ofUTF8Ptr lineStart = iter; ofUTF8Ptr lastSpace; ofUTF8Ptr stop = ofUTF8::endPtr(text); string thisLine = ""; bool foundSpace = false; bool foundNewLine = false; while(iter < stop) { ofUniChar c = ofUTF8::getNext(iter); // get the next unichar and iterate if ( ofUnicode::isSpace(c) ){ foundSpace = true; lastSpace = iter; } if ( ofTextConverter::toUTF8(c) == "\n" ){ foundNewLine = true; } thisLine += ofTextConverter::toUTF8(c); r = m_trueTypeFont.getStringBoundingBox(thisLine.c_str(), 0,0); if ( r.width > columnWidth || foundNewLine ) { //we went too far, lets jump back to our closest space if(foundNewLine){ if (thisLine == "\n"){ //if the whole line is only \n, replace for space to avoid weird things thisLine = " "; }else{ //otherwise remove the "\n" thisLine = thisLine.substr(0, thisLine.length()-1); } splitLines.push_back(thisLine); }else{ if (foundSpace){ //cout << "## foundSpace! (" << thisLine << ")" << endl; string finalLine = walkAndFill(lineStart, iter, lastSpace); splitLines.push_back(finalLine); iter = lastSpace; }else{ //cout << "## no Space! (" << thisLine << ")" << endl; splitLines.push_back(thisLine); } } //reset counter vars lineStart = iter; r.width = 0; thisLine = ""; foundSpace = foundNewLine = false; }else{ if(iter == stop){ //last line! string finalLine = walkAndFill(lineStart, iter, stop); splitLines.push_back(finalLine); break; } } } for(int i = 0; i < splitLines.size(); i++) { float yy = m_lineHeight * FONT_HEIGHT_MULT * fontSize * i; ofPushMatrix(); if(m_textBlockAlignment == OF_TEXT_ALIGN_LEFT) { ofTranslate(0, yy); } else if(m_textBlockAlignment == OF_TEXT_ALIGN_CENTER) { ofRectangle r = m_trueTypeFont.getStringBoundingBox(splitLines[i], 0,0); ofTranslate(-r.getWidth()*0.5, yy); } else if(m_textBlockAlignment == OF_TEXT_ALIGN_RIGHT) { ofRectangle r = m_trueTypeFont.getStringBoundingBox(splitLines[i], 0,0); ofTranslate(-r.getWidth(), yy); } else { ofTranslate(0, yy); } m_trueTypeFont.drawString(splitLines[i],x,y); ofPopMatrix(); totalArea = totalArea.getUnion( m_trueTypeFont.getStringBoundingBox(splitLines[i], x, y + yy)); } return totalArea; }
ofRectangle ofxFontStash::drawMultiLineColumn( string & _text, float size, float x, float y, float maxW, int &numLines, bool dontDraw, int maxLines, bool giveBackNewLinedText, bool* wordsWereTruncated){ string text = _text; if (!utf8::is_valid(text.begin(), text.end())){ text = LocaleToUtf8(text); } ofRectangle totalArea = ofRectangle(x,y,0,0); if(wordsWereTruncated){ *wordsWereTruncated = false; } if (stash != NULL){ numLines = 0; if(!dontDraw){ glPushMatrix(); glTranslatef(x, y, 0.0f); } //ofLine(0, 0, maxW, 0); vector<string>splitLines; ofRectangle r; const char * iter = text.c_str(); const char * lineStart = iter; const char * lastSpace; const char * stop = text.c_str() + text.length(); string thisLine = ""; bool foundSpace = false; bool foundNewLine = false; while(iter < stop) { unsigned int c = utf8::unchecked::next(iter); // get the next unichar and iterate if ( isSpace(c) ){ foundSpace = true; lastSpace = iter; } if ( toUTF8(c) == "\n" ){ foundNewLine = true; } thisLine += toUTF8(c); r = getBBox(thisLine.c_str(), size, 0,0); if ( r.width > maxW || foundNewLine ) { //we went too far, lets jump back to our closest space if(foundNewLine){ if (thisLine == "\n"){ //if the whole line is only \n, replace with a space to avoid weird things thisLine = " "; }else{ //otherwise remove the "\n" thisLine = thisLine.substr(0, thisLine.length()-1); } splitLines.push_back(thisLine); }else{ if (foundSpace){ string finalLine = walkAndFill(lineStart, iter, lastSpace); splitLines.push_back(finalLine); // Edge case where if max width is met and first character is space if(!(utf8::unchecked::next(lineStart) == 0x20)){ iter = lastSpace; } }else{ splitLines.push_back(thisLine); if(wordsWereTruncated){ *wordsWereTruncated = true; } } } //reset counter vars lineStart = iter; r.width = 0; thisLine = ""; foundSpace = foundNewLine = false; }else{ if(iter == stop){ //last line! string finalLine = walkAndFill(lineStart, iter, stop); splitLines.push_back(finalLine); break; } } } if(!dontDraw) beginBatch(); numLines = splitLines.size(); int linesToDraw = 0; if (maxLines > 0 ){ linesToDraw = MIN(splitLines.size(), maxLines); numLines = splitLines.size(); }else{ linesToDraw = splitLines.size(); } for(int i = 0; i < linesToDraw; i++){ float yy = lineHeight * OFX_FONT_STASH_LINE_HEIGHT_MULT * size * i; if(!dontDraw){ ofPushMatrix(); ofTranslate(0, yy); drawBatch(splitLines[i], size, 0, 0 ); ofPopMatrix(); } #if OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR >= 8 totalArea = totalArea.getUnion( getBBox(splitLines[i], size, x, y + yy)); #else totalArea = getBBox(splitLines[i], size, x, y + yy); //TODO! #endif } if(!dontDraw){ endBatch(); glPopMatrix(); } //return through reference the edited text (with newLines!) if(giveBackNewLinedText){ text = ""; for (int i = 0; i < numLines; i++){ if (i < maxLines || maxLines == 0){ text += splitLines[i]; if (i != numLines-1) text += "\n"; } } } }else{ ofLogError("ofxFontStash") << "can't draw() without having been setup first!"; } return totalArea; }