[ofTTF]How to accurately find the center position of each letter

Hi, I’m trying to find the center x,y position of each drawn letter.

For example, if I draw “Hello” on the screen, I want to find out 5 different positions that points to center of each character.

I tried to simply get the bounding box of the text and divide it by the number of letters but it doesn’t seem to be accurate enough.

Here’s my test code.

//--------------------------------------------------------------
void ofApp::setup(){
    
    ofSetBackgroundColor(255);
    font.load("/Users/cuinjune/Library/Pd/ofelia/DejaVuSansMono.ttf", 30);
}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){

    string text = "Hello World";
    
    ofSetColor(0);
    font.drawString(text, 100, 100);
    
    ofNoFill();
    ofSetColor(255, 0, 0);
    
    ofRectangle bb = font.getStringBoundingBox(text, 100, 100);
    ofDrawRectangle(bb);
    
    float startingX = bb.x;
    float startingY = bb.y;
    float letterWidth = bb.width / text.length();
    float letterHeight = bb.height;
    
    for (int i=0; i<text.length(); ++i) {
        
        ofDrawRectangle(startingX + (i*letterWidth), startingY, letterWidth, letterHeight);
    }
}

And this is the result.


But as you can see, the letters are not evenly distributed so my method isn’t really accurate.

Any idea how to do it more accurately?

Thanks in advance!

Hi,
there is the following method in ofTrueTypeFont
std::vector<ofTTFCharacter> getStringAsPoints(const std::string & str, bool vflip=true, bool filled=true) const;
Just use it and iterate through the returned vector. ofTTFCharacter is just typedef of ofPath. then for each element call getOutline(), this will return a vector of ofPolylines, call getCentroid2D() for the first element and that would be.
hope this helps

2 Likes

That seems like a perfect solution. Thanks!