示例#1
0
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 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;
}