AttributedStrings Not Displaying Properly


#1

I have a strange problem with AttributedStrings not displaying properly in my app. This is reproducible using the very basic test app provided.

On OSX, if you use a custom typeface and a native title bar AttributedStrings draw with a very large size and overlapping layout. Strangely enough this can be avoided by using a Juce titlebar or by calling Graphics::setFont () with a blank or valid font name before drawing the string. Perhaps this refreshes some internal Font cache?

[attachment=2]Without calling setFont.png[/attachment]
should be
[attachment=1]With calling setFont.png[/attachment]

This is very easily demonstrated by uncommenting line 31 of MainComponent in the test app.
This is tested using the tip from this morning with MixerAudioSource updates.
[attachment=0]JuceFontTest.zip[/attachment]


#2

There seems to be more amiss here. Even when using a Juce title bar the Justifications don’t seem to work on AttributedStrings anymore. Setting two strings to draw in the same Rectangle one with a Justification::topRight and the other Justification::bottomRight, they both overlap and get drawn top right. The horizontal flags seem to be working, but not the vertical.


#3

CustomTypefaces aren’t going to work out of the box with AttributedStrings. See the following link for more details:
http://www.juce.com/viewtopic.php?f=2&t=8647&hilit=AttributedStrings&sid=dd911acd99c34b6b0fd93d58e783d11f#p48840

I don’t believe vertical justification was ever working with the new TextLayout classes.


#4

Yeh I know they won’t be able to use the CustomTypeface but they should still use the system supplied font shouldn’t they?

My point is that as soon as you have a CustomTypeface being generated from a LookAndFeel all attributed strings are now broken which is a shame as they are very useful. Also there is the inconsistant behaviour between native/Juce title bars and setting fonts pre-AttributedString::draw() peculiarities which suggest a bug to me.

Did you check out the demo app I made? I don’t think its doing anything unusual or reasonable.


#5

I finally took a look at your demo app Dave. Everything you are doing is perfectly reasonable.

You have definitely stumbled onto some odd behaviour. As you suspected, Core Text is failing to do Text Layout properly when the Core Graphics context font has been set to a CustomTypeface. When you use the software renderer instead of the Core Graphics renderer, this doesn’t happen. I’m not sure why, but the Core Graphics context font must be set to a system font prior to using TextLayout with the Core Graphics renderer.

I’m guessing that this is why everything looks fine with Juce title bars, the Juce title bar is probably changing the graphics context font to a system font after you initialized your CustomLookAndFeel.

The only workaround I can suggest is the one you figured out, wrap your TextLayout calls with calls to g.setFont to make sure the graphics context font is set to a system font prior to layout.
If you set a CustomTypface for your CustomLookAndFeel, make sure not to do g.setFont to the default font, since the default font is your CustomTypeface.


#6

Hi Sonic, thanks for taking a look, I really appreciate it. Glad you agree I’m not being daft and this is a issue. I guess for the time being I can do as suggested and make sure I call g.setFont. However, I do think others will find the same problems so I wonder if we could put something inside TextLayout to make sure its using a system font? Is that even possible?


#7

The issue is specific to using TextLayout with the Core Graphics renderer. If you made any changes, it wouldn’t be to the TextLayout class, it would be to either:

CoreGraphicsContext::drawTextLayout
CoreTextTypeLayout::drawToCGContext

You could store the current context font, change the context font to a system font, do the layout and finally set the context font back to the original font.
All these extra calls would be unnecessary if you weren’t using a CustomTypeface.
I suppose it may be possible to detect if the current context font was a CustomTypeface then avoid the remaining two calls if it wasn’t.

I’m not sure if you actually need to reset the context font back to the original font. It’s possible that the controls will do that automatically when they repaint themselves. Its probably worth testing out since you could cut those 3 lines into just one (change the context font to a system font).