ofTrueTypeFont -> Dynamic Sizing

Heyoo,

I’m trying to make a UI text object that can display any string I put into it but has some nice little animation on it. Basically, I want it to start super small, grow up to its intended size, and then shrink away. Here’s my current code in update on my NameDisplay object which extends ofTrueTypeFont.

if (!APPEARED)
    {
        if (displayTimer < timeToAppear)
        {
            fontSize = ((12*drawScale) * displayTimer / timeToAppear);
            displayTimer++;
        }
        else
        {
            APPEARED = true;
            displayTimer = 0;
        }
    }
    
    if (APPEARED && !FADING)
    {
        if (displayTimer < timeDisplayed)
        {
            fontSize = (12 * drawScale);
            displayTimer++;
        }
        else
        {
            FADING = true;
            displayTimer = timeToFade;
        }
    }
    
    if (FADING)
    {
        if (displayTimer > 0)
        {
            fontSize = ((12 * drawScale) * displayTimer / timeToFade);
            displayTimer--;
        }
        else
        {
            DEAD = true;
        }
    }

I also tried using setLineHeight instead of fontSize, but neither seemed to do anything. As is, it appears at its full size (which is what I create it at as well) and then disappears when set to DEAD as intended.

Anyone have any experience with this?

1 Like

@Radstronomical

When you call loadFont(...), I believe that the characters of your font are rendered, at a specified size, to a texture. So you can think of that as meaning that this is snapshot of the characters of your font living inside your ofTrueTypeFont object. When you call something like drawString(...), the pieces of your snapshot that represent the appropriate characters are drawn to the screen in the right order to form your desired text. There is no way to change the font size of your text after it has been created because that font exists as a snapshot. You would need to reload your font at a new size using loadFont(...) to have a font of a different size.

But you can rescale a picture. Are you familiar with ofScale(...) (openFrameworks documentation)? This processing tutorial does a nice job of explaining the concepts involved. Here’s some example code to get you started. If something doesn’t make sense, let me know.

#include "testApp.h"

ofTrueTypeFont font;
float scale = 1.0;
bool isShrinking = true;

//--------------------------------------------------------------
void testApp::setup(){
   ofSetFrameRate(60);
   font.loadFont("verdana.ttf", 30);
}

//--------------------------------------------------------------
void testApp::update(){
    if (isShrinking) {
        scale -= 0.025;
        if (scale < 0.1) {
            isShrinking = false;
        }
    }
    else {
        scale += 0.025;
        if (scale > 1) {
            isShrinking = true;
        }
    }
}

//--------------------------------------------------------------
void testApp::draw(){
   ofBackground(0);
   ofSetColor(255);

   ofPushMatrix();
        ofTranslate(ofGetWidth()/2, ofGetHeight()/2);
        ofScale(scale, scale, 1);

        string text = "Growing and Shrinking!";
        float fontWidth = font.stringWidth(text);
        font.drawString(text, -fontWidth/2, 0);
   ofPopMatrix();
}

But be warned - scaling an image, particularly enlarging it, doesn’t increase the resolution of your font. So if you scale a font up, it will look distorted and blurry. That’s why I loaded a large font and kept the scale less than or equal to 1.0 in the code snippet above. Shrinking an image will have less noticeable distortions than enlarging an image.

You can draw your strings as geometry shapes using drawStringAsShapes(...). Just remember to set makeContours to true when you call loadFont(...). Geometry can scale without losing resolution. I posted some sample code with some more explanation in this thread.

Lastly, a more costly solution would be to call loadFont(...) with a new font size on every frame of your animation. It will probably be slow, but you could try that.

Didn’t occur to me to use ofScale. Works like a dream! Thanks Mike.

1 Like

No problem - glad it helped

That is what i was looking for, thanks!