From 8d75d080e27f0ea48ca58f55f5d8e950c7d8deaf Mon Sep 17 00:00:00 2001 From: tim Date: Tue, 28 Mar 2017 23:04:46 +0100 Subject: include altered ofxTestBlock --- menuApp/src/ofxTextBlock.cpp | 525 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100755 menuApp/src/ofxTextBlock.cpp (limited to 'menuApp/src/ofxTextBlock.cpp') diff --git a/menuApp/src/ofxTextBlock.cpp b/menuApp/src/ofxTextBlock.cpp new file mode 100755 index 0000000..6fe00d0 --- /dev/null +++ b/menuApp/src/ofxTextBlock.cpp @@ -0,0 +1,525 @@ + /*********************************************************************** + + Copyright (c) 2009, Luke Malcolm, www.lukemalcolm.com + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + ***********************************************************************/ + +#include "ofxTextBlock.h" + +ofxTextBlock::ofxTextBlock() +{ + + scale = 1.0f; + +} + +ofxTextBlock::~ofxTextBlock() +{ + //dtor +} + +void ofxTextBlock::init(string fontLocation, float fontSize ,const char spacechar){ + + defaultFont.loadFont(fontLocation, fontSize, true, true); + + std:string _space(&spacechar,1); + + //Set up the blank space word + blankSpaceWord.rawWord = " "; + blankSpaceWord.width = defaultFont.stringWidth(_space); + blankSpaceWord.height = defaultFont.stringHeight("i"); + blankSpaceWord.color.r = blankSpaceWord.color.g = blankSpaceWord.color.b = 255; + +} + +void ofxTextBlock::setText(string _inputText){ + rawText = _inputText; + _loadWords(); + wrapTextForceLines(1); +} + +void ofxTextBlock::draw(float x, float y){ + + drawLeft(x, y); + +} + +void ofxTextBlock::drawLeft(float x, float y, int numlines){ + + string strToDraw; + int currentWordID; + float drawX; + float drawY; + + float currX = 0; + + if (words.size() > 0) { + + for(int l=0;l < min((int)lines.size(),numlines); l++) + { + for(int w=0;w < lines[l].wordsID.size(); w++) + { + currentWordID = lines[l].wordsID[w]; + + drawX = x + currX; + drawY = y + (defaultFont.getLineHeight() * (l + 1)); + + ofSetColor(words[currentWordID].color.r, words[currentWordID].color.g, words[currentWordID].color.b, words[currentWordID].color.a); + glPushMatrix(); + //glTranslatef(drawX, drawY, 0.0f); + glScalef(scale, scale, scale); + + defaultFont.drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); + currX += words[currentWordID].width; + + glPopMatrix(); + + } + currX = 0; + + } + } +} + +void ofxTextBlock::drawCenter(float x, float y, int numlines ){ + + string strToDraw; + int currentWordID; + float drawX; + float drawY; + float lineWidth; + + float currX = 0; + + if (words.size() > 0) { + + for(int l=0;l < min((int)lines.size(),numlines); l++) + { + + //Get the length of the line. + lineWidth = 0; + for(int w=0;w < lines[l].wordsID.size(); w++) + { + currentWordID = lines[l].wordsID[w]; + lineWidth += words[currentWordID].width; + } + + for(int w=0;w < lines[l].wordsID.size(); w++) + { + currentWordID = lines[l].wordsID[w]; + + drawX = -(lineWidth / 2) + currX; + drawY = defaultFont.getLineHeight() * (l + 1); + + ofSetColor(words[currentWordID].color.r, words[currentWordID].color.g, words[currentWordID].color.b, words[currentWordID].color.a); + + glPushMatrix(); + + //Move to central point using pre-scaled co-ordinates + glTranslatef(x, y, 0.0f); + + glScalef(scale, scale, scale); + + defaultFont.drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); + currX += words[currentWordID].width; + + glPopMatrix(); + + } + currX = 0; + + } + } +} + +void ofxTextBlock::drawJustified(float x, float y, float boxWidth, int numlines){ + + string strToDraw; + int currentWordID; + float drawX; + float drawY; + int spacesN; + float nonSpaceWordWidth; + float pixelsPerSpace; + + float currX = 0; + + if (words.size() > 0) { + + + for(int l=0;l < min((int)lines.size(),numlines); l++) + { + //Find number of spaces and width of other words; + spacesN = 0; + nonSpaceWordWidth = 0; + + for(int w=0;w < lines[l].wordsID.size(); w++) + { + currentWordID = lines[l].wordsID[w]; + if (words[currentWordID].rawWord == " ") spacesN++; + else nonSpaceWordWidth += words[currentWordID].width; + } + + pixelsPerSpace = ((boxWidth / scale) - (x / scale) - nonSpaceWordWidth) / spacesN; + + for(int w=0;w < lines[l].wordsID.size(); w++) + { + currentWordID = lines[l].wordsID[w]; + + drawX = currX; + drawY = defaultFont.getLineHeight() * (l + 1); + + ofSetColor(words[currentWordID].color.r, words[currentWordID].color.g, words[currentWordID].color.b, words[currentWordID].color.a); + glPushMatrix(); + //Move to top left point using pre-scaled co-ordinates + glTranslatef(x, y, 0.0f); + glScalef(scale, scale, scale); + + if (words[currentWordID].rawWord != " ") { + defaultFont.drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); + currX += words[currentWordID].width; + } + else { + currX += pixelsPerSpace; + } + + + glPopMatrix(); + + } + currX = 0; + + } + } +} + +void ofxTextBlock::drawRight(float x, float y, int numlines){ + + string strToDraw; + int currentWordID; + float drawX; + float drawY; + + float currX = 0; + + if (words.size() > 0) { + + for(int l=0;l < min((int)lines.size(),numlines); l++) + { + + for(int w=lines[l].wordsID.size() - 1; w >= 0; w--) + { + + currentWordID = lines[l].wordsID[w]; + + drawX = -currX - words[currentWordID].width; + drawY = defaultFont.getLineHeight() * (l + 1); + + ofSetColor(words[currentWordID].color.r, words[currentWordID].color.g, words[currentWordID].color.b, words[currentWordID].color.a); + + glPushMatrix(); + + //Move to top left point using pre-scaled co-ordinates + glTranslatef(x, y, 0.0f); + glScalef(scale, scale, scale); + + defaultFont.drawString(words[currentWordID].rawWord.c_str(), drawX, drawY); + currX += words[currentWordID].width; + + glPopMatrix(); + + } + currX = 0; + + } + } +} + +void ofxTextBlock::_trimLineSpaces() +{ + if (words.size() > 0) { + //Now delete all leading or ending spaces on each line + for(int l=0;l < lines.size(); l++) + { + //Delete the first word if it is a blank + if (lines[l].wordsID.size() > 0){ + if (words[lines[l].wordsID[0]].rawWord == " ") lines[l].wordsID.erase(lines[l].wordsID.begin()); + } + + //Delete the last word if it is a blank + if (lines[l].wordsID.size() > 0){ + if (words[lines[l].wordsID[lines[l].wordsID.size() - 1]].rawWord == " ") lines[l].wordsID.erase(lines[l].wordsID.end() - 1); + } + } + } + +} + +int ofxTextBlock::_getLinedWords(){ + + int wordCount = 0; + + if (words.size() > 0) { + + for(int l=0;l < lines.size(); l++) + { + wordCount += lines[l].wordsID.size(); + } + return wordCount; + } + else return 0; +} + +void ofxTextBlock::wrapTextArea(float rWidth, float rHeight){ + + float tmpScale = 0.0f; + float maxIterations = _getLinedWords(); + float scales[1000]; + scale = 1.0f; //Reset the scale for the height and width calculations. + + if (words.size() > 0) { + + //Check each possible line layout and check it will fit vertically + for (int iteration=1; iteration <= maxIterations; iteration++){ + + //printf("Iteration %i...\n", iteration); + wrapTextForceLines(iteration); + + tmpScale = rWidth / getWidth(); + if ((tmpScale * getHeight()) < rHeight) { + scales[iteration] = tmpScale; + } + else { + scales[iteration] = -1; + } + } + + //Now see which is biggest + int maxIndex = 1; + bool bScaleAvailable = false; + + for (int i=1; i <= maxIterations; i++) { + ofLog(OF_LOG_VERBOSE,"Scales %i = %f\n", i, scales[maxIndex]); + if (scales[i] != -1) bScaleAvailable = true; + + if (scales[i] > scales[maxIndex]) { + maxIndex = i; + } + } + + //When only one line is needed an appropriate on the Y scale can sometimes not be found. In these occasions scale the size to the Y dimension + if (bScaleAvailable) { + scale = scales[maxIndex]; + } + else { + scale = (float)rHeight / (float)getHeight(); + } + + float persistScale = scale; //Need to persist the scale as the wrapTextForceLines will overwrite. + wrapTextForceLines(maxIndex); + scale = persistScale; + + ofLog(OF_LOG_VERBOSE,"Scaling with %i at scale %f...\n", maxIndex, scale); + } + + +} + + +bool ofxTextBlock::wrapTextForceLines(int linesN){ + + if (words.size() > 0) { + + if (linesN > words.size()) linesN = words.size(); + + float lineWidth = _getWidthOfWords() * (1.1f / (float)linesN); + + int curLines = 0; + bool bGotLines = false; + + //keep increasing the line width until we get the desired number of lines. + while (!bGotLines) { + + curLines = wrapTextX(lineWidth); + if (curLines == linesN) return true; + if (curLines > linesN) return false; + lineWidth-=10; + + } + + } + +} + + +int ofxTextBlock::wrapTextX(float lineWidth){ + + scale = 1.0f; + + if (words.size() > 0) { + + float runningWidth = 0.0f; + + lines.clear(); + + bool newLine = true; + lineBlock tmpLine; + tmpLine.wordsID.clear(); + int activeLine = 0; + + for(int i=0;i < words.size(); i++) + { + + runningWidth += words[i].width; + + if (runningWidth <= lineWidth) { + newLine = false; + } + else { + + newLine = true; + lines.push_back(tmpLine); + tmpLine.wordsID.clear(); + runningWidth = 0.0f + words[i].width;; + activeLine++; + } + + tmpLine.wordsID.push_back(i); + } + + //Push in the final line. + lines.push_back(tmpLine); + _trimLineSpaces(); //Trim the leading and trailing spaces. + + } + + return lines.size(); + +} + +void ofxTextBlock::_loadWords(){ + + wordBlock tmpWord; + + istringstream iss(rawText); + + vector tokens; + copy(istream_iterator(iss), + istream_iterator(), + back_inserter >(tokens)); + + words.clear(); + + for(int i=0;i < tokens.size(); i++) + { + tmpWord.rawWord = tokens.at(i); + tmpWord.width = defaultFont.stringWidth(tmpWord.rawWord); + tmpWord.height = defaultFont.stringHeight(tmpWord.rawWord); + tmpWord.color.r = tmpWord.color.g = tmpWord.color.b = 150; + words.push_back(tmpWord); + //add spaces into the words vector if it is not the last word. + if (i != tokens.size()) words.push_back(blankSpaceWord); + } + + for(int i=0;i < words.size(); i++) + { + ofLog(OF_LOG_VERBOSE, "Loaded word: %i, %s\n", i, words[i].rawWord.c_str()); + } + + +} + +float ofxTextBlock::_getWidthOfWords(){ + + float widthTotal = 0.0f; + + if (words.size() > 0) { + for(int i=0;i < words.size(); i++) + { + widthTotal += words[i].width; + + } + return widthTotal; + } + else { + return 0.0f; + } + +} + +float ofxTextBlock::getWidth(){ + + int currentWordID; + + float currX = 0.0f; + float maxWidth = 0.0f; + + if (words.size() > 0) { + + for(int l=0;l < lines.size(); l++) + { + for(int w=0;w < lines[l].wordsID.size(); w++) + { + currentWordID = lines[l].wordsID[w]; + currX += words[currentWordID].width; + } + maxWidth = MAX(maxWidth, currX); + currX = 0.0f; + } + return maxWidth * scale; + } + else return 0; + +} + +float ofxTextBlock::getHeight(){ + + if (words.size() > 0) { + return defaultFont.getLineHeight() * scale * lines.size(); + } + else return 0; + +} + +void ofxTextBlock::setLineHeight(float lineHeight){ + + defaultFont.setLineHeight(lineHeight); + +} + +void ofxTextBlock::setColor(int r, int g, int b, int a){ + + ofColor tmpColor; + tmpColor.r = r; + tmpColor.g = g; + tmpColor.b = b; + tmpColor.a = a; + + if (words.size() > 0) { + for(int i=0;i < words.size(); i++) + { + words[i].color = tmpColor; + + } + } + +} + +void ofxTextBlock::forceScale(float _scale){ + scale = _scale; +} + + -- cgit v1.2.3