[SOLVED] Font color change at runtime ?!?!?

Hi, I’m new, and I’m really happy with this beautiful framework :slight_smile:
But, I cannot for some reason change or set the font color of a
ofTrueTypeFont variable

example:
ofTrueTypeFont myFont; //declared at start

in ::setup()
myFont.loadFont(“arial.ttf”,30,true);

in ::draw()
ofSetHexColor(0x000000); //black
myFont.drawString(“helloworld”,50,50);

to change the font color in runtime? I’ve tried a lot of things, and none has worked so far :frowning:

For example:
in ::keyPressed(int key)

if (key == ‘c’){
bColorChanged = !bColorChanged;
if (bColorChanged){
ofSetHexColor(0x000000); //return to black
myFont.loadFont(“arial.ttf”,30,true); //i’ve tried to reload font
myFont.drawString(“helloworld”, 50,50); //redraw
//myFont.setHex(0x000000); //desperate setHex (i know… not present in class so can’t be called)
}else{
ofSetHexColor(0xff0000); //change to red
myFont.loadFont(“arial.ttf”,30,true);
myFont.drawString(“helloworld”, 50,50);
//myFont.setHex(0xff0000);
}
}

How I can do to change color at runtime? Even “mastering openframeworks” book that I’ve found easy to follow don’t have enlightened me :frowning:

Please please please help me :slight_smile:

Once you load the font in setup, you won’t need to load it again in the key pressed function, since all of the properties on the myFont are staying the same. The draw function is what renders the font to the screen, so it is probably overwriting the drawing in the keyPressed function. Try moving the font drawing in the key pressed function to the draw function. So try something like:

setup() {
     myFont.loadFont("arial.ttf",30,true);
     bColorChanged = false;
}

draw() {
     if (bColorChanged){
          ofSetHexColor(0x000000); //return to black
     }else{
         ofSetHexColor(0xff0000); //change to red
     }
     myFont.drawString("helloworld", 50,50); 
}

keyPressed( int key ) {
     if (key == 'c'){
          bColorChanged = !bColorChanged;
     }
}

Ok, this works?!? I cannot explain this behavior, even this correctly changing the color… on display.

  1. I’m curious, what this do internally?
  2. I mean every time i press “c” button a new string is created? after 2000 press of c button I will create 2000 strings? or maybe I will always allocate same myFont variable auto-canceling the previous one?
  3. and how the hell I’ve done a call to the myFont var for change his color when ofSetHexColor var is a global one?

Work like:
ofSetHexColor(color) //tell which color you want
myFont.drawString(“helloworld”,50,50); //overwrite previous one or directly delete and recreate?

but in the ofApp::draw()
you’ve excluded the drawString from being included in the change, if I want to include only a myFont, myFont2, myFont3 variable for being “colored” I have to include the drawString INSIDE the if-else statement, right?

  1. If for some reason a destructor or something is not called when drawString is called, how I can remedy for avoiding system memory leaking?

If you wish to have different font sizes, then you need an ofTrueTypeFont for each size. And you should call loadFont on each one with the different font and/or size in the setup function. Since the rendering is handled in the font, you would need to place the font.drawString() call in the if/else statement if you wish to render using different fonts.

Calling ofSetHexColor() / ofSetColor sets the glColor for the application. Once you call ofSetColor(), gl rendering calls after that will render in that color (tinted by that color in the case of textures / images). So you could call ofSetColor( 255, 0, 0) and all subsequent drawing of images, circles, fonts, rectangles, etc. will be rendered in red (the image will be tinted red).

ofTrueTypeFont only allocates resources when calling loadFont. The texture that is created for the alphabet is allocated and maybe some other meshes / paths if you load it with vector options. Every time that drawString is called on the font, it adjusts meshes that are handled internally to render each character accordingly. The font handles if the texture is already bound or not.

The drawString() method inside ofTrueTypeFont handles its own resources. Calling the de-constructor would clear all of the textures and should only be called when you will no longer need the font.

That was kind of a long-winded answer, but hopefully it cleared up some of the questions that you posted.

1 Like

Yeah,

Perfect response :smile:
I have already modified my code for have drawString in the if else statement, for change the color, but when a variable on keypress is called.

setup()

bColorChanged = false;

draw()
if(bColorChanged){
    ofSetHexColor(0xff0000); //red
    myFont.drawString("helloworld",50,50);
}else{
   ofSetHexColor(0x000000); //black
    myFont.drawString("helloworld",50,50);
}

keyPressed()
if (key == 'c'){
  bColorChanged = true;
}

now I imagine that draw() function is like an update function, so If I will set a movement of the font this can be called from here? or I will have to write the code on update()? but if I will do an animation on ‘c’ press what I’ve to use? And I have to use drawStringAsShapes for make the string become a 2d mesh or something? (If I’m going off-topic please tell me, it’s just that the documentation on this is missing something)

In any case I’ve put ‘solved’ on topic, because the arg was change font color at runtime, the only thing I cannot understand now is how to use the ofPushMatrix and popmatrix for create an animation of myFont, like

draw() //or update() i don’t know
ofPushMatrix();
ofTranslate(0, 0, 500);
ofPopMatrix();

Is that right? Or I’ve to use vectors?

You can use translate to animate your type. Something like:

ofTranslate( 250 + sin(ofGetElapsedTimef()) * 200, 200, 0);

Have you checked out the examples/graphics/fontsExample/ project? There are a bunch of examples in there.

Yeah, but I was using ofTranslate without an “animation” code like yours, but I was about to tell you that I know that code but the animations was move all the things like squares images and all, when I understand that I’ve to set all INSIDE the matrix (push and pop) like:

draw()

ofSetHexColor(0xff0000);
//translate myFont ONLY not whole screen
ofPushMatrix();
ofTranslate(sin(ofGetElapsedTimef()*50,0,0);
myFont.drawString(“helloworld”,50,50);
ofPopMatrix();

so I understand that OF works like a sort of cascade, until something “block his way”, like ofPushMatrix and ofPopMatrix, that avoid do things to other elements.

Ok perfect but why is not the drawed string referenceable? I start to fear that drawString or ever worster ofTrueTypeFont don’t create a referenceable object, but a something that you cannot interact with, only at drawing…

I have done this for an animation an keep restarting, maybe I’m done something wrong? In the fontExample there’s continuous motion so I can’t know if there’s some way to to the animation at the end, not looping that.

setup()

position = 0;
amount = 0;

draw()

ofPushMatrix();
string aniStr = "anim: "+ofToString(position, 2);
ofDrawBitmapString(aniStr,500,80);

if(amount < 50){
ofTranslate( position,0,0);
position++;
amount++;
}
myFont.drawString(“helloworld”, 50,50);
ofPopMatrix();

//here I have tried to call myFont.unloadTextures() for delete the animation but the function is only a prototype

//and try to move myFont (object?|!’!’?)
myFont.drawString(“helloworld”,50,50); //but there’s nothings like myFont.x or myFont.y or myFont.position(x,y) ?!?!?!?

How can I stop the myFont after the animation (amount) has reached the zone (position) and if for example I press ‘1’ how to redo this animation at runtime? or move with keyboard arrows?

Most of the problems are the way openFrameworks is designed I fear, because I cannot reference to an object, I am wrong?

a little improvement was doing:

if(position < 50){
ofTranslate(position,0,0);
position++;
}
myFont.drawString(“helloworld”,position,50);

but keep going again backward even on it’s updated position, worse is if I put:
drawString(“helloworld”, 50 + position, 50); // 50px + the updated final position)…

Don’t know what to do…

Maybe I have to create my own classes for have the x and y and maybe I have to use update() instead of draw() ?
I ask for being pointed in the right direction :smile:

There is not a position reference in ofTrueTypeFont. You can store the position in a variable like the position one you are using. When calling ofTranslate(x,y) it will affect everything after it that is within the push and pop matrices calls.
Calling myFont.drawString( “string”, x, y); will render the string using the font at the x and y position, so you don’t need to call ofTranslate if you want to use that method.

I’m unclear about what you are trying trying to accomplish. But you might just want to use the drawString method and update the position variable for simplicity using myFont.drawString(“hello world”, position, 50);

1 Like

Trank you for your reply :smile:
I want to do an animation with start and end. if you tell me that no reference is created I imagine that is just a bunch of pixel.

Maybe if a myFont.move(x,y) exists I would had called in the keyPress but I fear that I have to extend the class for positioning right? But I with of translate I’ve done an animation with that code, but only at drawString, if I call another time the function create another string (it’s legit of course).
But I have to delete the string? Why is the documentation of the framework so unclear :frowning: but I imagine that practice will make me stronger