[Bug] Font's HorizontalScale ignored in DrawFittedText() in several cases

JUCE 8.0.1 - Mac/Windows

Let’s say: you don’t want the text in any labels or ComboBoxes to auto-squish; you always want it full-size, and you want an ellipsis when it’s too long.

So you use Font::setDefaultMinimumHorizontalScaleFactor(1.0f);

Then, you want to horizontally scale your font a bit (to your own taste). So you override LookAndFeel::getLabelFont():

    Font getLabelFont(Label &label) override
    {
        return label.getFont().withHorizontalScale(horizontalScale);
    }
    float horizontalScale = 1.0f;

When Graphics::drawFittedText() is used (as in drawLabel(), which handles both labels and the display state of ComboBoxes), if an ellipsis is displayed (or the name in the label is greater than half the width of the label), using Font::setHorizontalScale() has no effect. This is because of a bug in GlyphArrangement::addFittedText().

Example project demonstrating the bug:
HorizScaleBug.zip (13.0 KB)

So in this example, we have two ComboBoxes with menu items of varying length. The last item “An Even Longer Name” will cause an ellipsis. The Slider controls the horizontalScale value above.

The second last item “A Longer Name” is wider than half the width of the comboBox.

Here it is with horizontal scale at 1.0f (normal):

Now change the slider to 1.2f. The top ComboBox, Slider and Label horizontally scale, but the ComboBox with the ellipsis does not.

Here is 1.4f:

Here is 0.8f:

Now set the top ComboBox to item 3 “A Longer Name” and the slider to 1.4f. Even though no ellipsis is displayed on the top ComboBox, because this item is greater than half the width (I think?) of the label, it also has no horizontal scaling applied.

The culprit (or one of them) appears to be line 286 of juce_GlyphArrangement.cpp:

     .withFont (f.withHorizontalScale (minimumHorizontalScale))

Here, the font is being used while replacing the (passed in) font’s horizontal scale value.

If you call like this, the problem is fixed (although it’s probably not that simple):

    if (maximumLines <= 1)
    {
        ShapedText squashed { trimmed,
                              ShapedText::Options{}
                                 // .withFont (f.withHorizontalScale (minimumHorizontalScale))
			                      .withFont(f)
                                  .withMaxWidth (width)
                                  .withHeight (height)
                                  .withJustification (layout)
                                  .withMaxNumLines (1)
                                  .withEllipsis() };

        addGlyphsFromShapedText (*this, squashed, x, y);
        return;
    }

I used large horizontal scaling factors here to illustrate the problem; but in my project I want to tweak the width of the font slightly, and what happens is: that change is carried across all displayed text EXCEPT in some comboBoxes when an ellipsis is displayed or the width of the text displayed is greater than some arbitrary value. Thanks.

1 Like

Here’s a little movie of it (working correctly) with the one line fix in:

Have you tried the tip? There were changes in this area recently:

1 Like

Thank you, I’m not on the most recent tip, that definitely does seem related, will check it out.

Thank you for the detailed report and repro. I think this could be still affecting the latest version, I’m investigating this now.

1 Like

So I did investigate the latest develop, and you are right - the bug is still there. Any progress on this? Thanks!

We have a fix in the pipeline for this issue restoring the JUCE 7 behaviour of not changing the horizontal squashing amount if minimumHorizontalScale == 1. This would make your example project behave identically to JUCE 7.

It’s likely though that this fix will only be released after the next JUCE point release, because there is some chance for introducing a regression. This behavioural change layed dormant since the introduction of JUCE 8, and one could even argue that the new behaviour is reasonable, in that text will be fitted into a space if possible.

All in all we do agree about restoring the JUCE 7 behaviour, I just mentioned these thoughts to explain why we may only release the fix after the point release.

The fix is likely to land on the develop branch in the second half of next week.

1 Like

Thank you! But I would argue that, even if minimumHorizontalScale does NOT equal 1.0f, that the horizontalScale of the Font should still be factored in. It sounds like you are saying it might not be.

Font::setHorizontalScale() is, to me, a largely cosmetic setting that is totally separate from auto-squishing.

If you’ve made the font appear to be narrower globally in your app, say horizontalScale = .90f, then even when the text is auto-squished to fit inside a ComboBox, it should be scaled by 0.90f before the width is computed and then finally squished. IMO. :slight_smile:

1 Like

Yes, I agree.

I’m sharing a patch relative to our current develop, because it’s easy to overlook details verbally when complex logic is involved. This is our planned fix.

If you feel like it, please give this a look, I think it is in line with your suggestions.

fittedtext.patch (5.1 KB)

@attila - yes, I’d like to try it, but sadly I have not learned to use git (one of these days…) Any chance you can just post or send me the new code, and I can use FileMerge to put the changes into the current develop? If not, that’s ok, I can wait…

A fix is now out on develop

1 Like