Flickering text drawing with unicode characters

Code used to paint the text:

void paint(Graphics& g)
{
    Rectangle<int> textRect = ... // constant - this doesn't change 
    g.drawFittedText("myMessage", textRect, Justification::centered, 5, 1.0f /* don't squash */);
}

Observed behaviour on OSX Catalina using the Noto Sans JP font and JUCE 5.4.5:
Jan-31-2020 13-38-01

Apparently, from one paint() to another, the font type is changed during the actual drawing. It seems like the size and position of the text is calculated correctly, but then during drawing the wrong font (or spacing?) is selected. This is apparent when you look at individual frames of the flickering text:


As you can see, when the text is squashed, it doesn’t seem centered anymore which makes me think that the calculation of the text placement rectangle in drawFittedText() is done with the correct font but then during actual drawing the wrong font is (randomly) used - resulting in narrower text which is not centered anymore.

I debugged through some of the JUCE code but couldn’t find anything suspicious. I’m searching for a needle in a haystack here.

Does anyone have an idea what’s happening or where I might find a hint?

Does the flickering go away if you set the font you want to use before every call to drawFittedText?

{
    Rectangle<int> textRect = ... // constant - this doesn't change 
    g.setFont (Font{}); // set the font here on the context before drawing
    g.drawFittedText("myMessage", textRect, Justification::centered, 5, 1.0f /* don't squash */);
}
1 Like

I’m impressed. I added

g.setFont(Font("Noto Sans JP", 12, Font::plain));

That fixes it. Right now, we were setting the font via the Look&Feel:

LookAndFeel::getDefaultLookAndFeel().setDefaultSansSerifTypefaceName("Noto Sans JP");

Interesting. I would expect this to work. Are we using the L&F wrong?

1 Like

Setting the default typeface name like that is fine, but you’ll need to set the font on the context every time. Other components might have set a different size/style for the font or another typeface entirely during their paint call.

If you want to use the default, I think this should work:

// set the default typeface name like you were before
LookAndFeel::getDefaultLookAndFeel().setDefaultSansSerifTypefaceName("Noto Sans JP");
...
// set the default font with a height of 12 before each draw call
g.setFont (Font{}.withHeight (12.f));
g.drawFittedText (...);
1 Like

Thank you.
I still think there is something odd happening in the JUCE code. I stepped through it with the debugger and inspected the Font that was used to arrange the glyphs, and it was the right Font (at least it had the right name). Also, if all parts of the rendering process used the same font, the text should have been centered, which wasn’t the case. I guess there is some inconsistency in how the current Font is determined but I wasn’t able to find out what’s wrong.

Anyway, I have a solution now so I guess it’s fine. Maybe this is still something a JUCE dev should take a look at.