Multiple

Every character has a reference point. Most typefaces are not monospaced, so you can only know the position of these reference points if you know the characters you are dealing with. Furthermore, reference points are mostly in the bottom left of the character, sometimes not. Things are complicated. Basically, you need to give something a string and it needs to tell you where the reference points of each character are.

So, I came up with getReferencePoints(), my very own, openFrameworks method. This method, which belongs to the TrueTypeFont class takes two arguments, a string and a STL vector of ofPoints, which is passed by reference. It then fills the vector with the reference points. As if by magic. The results look like this:

multiple

Great, so now we have a nice set of points to go to, it's easy. Just go to each reference point and draw the character, repeat until you get to the end of the string. Ok, let's do it.

hello wrong 1

Ok, not great, let's have another go.

hello wrong 2

I couldn't see where the problems were coming from and it was obvious that some kind of error was accumulating. So more head scratching and fiddling lead me here:

hello wrong 3

I was getting close but the pen was wondering off and then coming back. Eventually I fixed the problem and we were looking good. The way I have chosen to do it is have one huge array with where the pen should go. These values are never bigger than 1 so i can put in numbers for the pen up and pen down. As I go from character to character, I just adding to the array. Then the pen just goes through the points. I wrote a method to put all this in one place it looks like this:

void testApp::getFullPath(string source, vector<ofxVec2f> &p) {
	
	p.clear(); //clear the array
	
	int refn = 0;
	vector<ofPoint> refs;
	font.getReferencePoints(source, refs);
	
	ofPoint tempPoint;
	tempPoint.set(0, 0, 0);
	
	//add each character
	int n = 0;
	while (n < source.size()) {		

		//get letter
		ofTTFCharacter letter = font.getCharacterAsPoints(source[n]);
		
		//do each contour of character
		for (int i = 0; i < letter.contours.size(); i++) {
			
			p.push_back(ofxVec2f(10, 0)); //move pen up
			addToPath(p, tempPoint, letter.contours[i].pts[0]+refs[refn]); //add all previous points here
			p.push_back(ofxVec2f(11, 0)); //move pen down
									
			int k = 0;
			//do all - 1 points
			for (int j = 0; j < letter.contours[i].pts.size()-1; j++) {							
				addToPath(p, letter.contours[i].pts[j]+refs[refn], letter.contours[i].pts[j+1]+refs[refn]);
				k++;
			}
			
			//do from the last point to the first, so we go full circle...
			addToPath(p, letter.contours[i].pts[k]+refs[refn], letter.contours[i].pts[0]+refs[refn]);
			tempPoint = letter.contours[i].pts[0]+refs[refn];
		}//end contour
	
		refn++;
		//this is so it doesn't go back to the 1st position at the end
		if(refn != (int)refs.size()){
			p.push_back(ofxVec2f(10, 0)); //move pen up
			addToPath(p, tempPoint, refs[refn]); //add all previous points here
			//p.push_back(ofxVec2f(11, 0)); //move pen down
		}
		tempPoint = refs[refn];
		
		n++;
		
		if(source[n] == '\n' || source[n] == ' ') {
			n++;
		}
		
	} //end character
	
}

Finally done. Now it was time to test it out. The alphabet in the Georgia typeface looks like this:

alphabet

And to conclude, a full paragraph containing spaces (this was a bit tricky as a space has no reference point), new lines and all the rest of it (basically nothing else).