drawFittedText - Am I misunderstanding something?

Either I am misunderstanding something or drawFittedText is somewhat flawed. It’s probably me :slight_smile:

My test component size is;

setSize (576, 270);
void MainComponent::paint (Graphics& g)
{
    g.fillAll (Colour::fromRGB(0, 0, 64));
	
	g.setColour (Colours::white);
	
	g.setFont (15);
	g.drawText ("Width " + String (getWidth()), 0, 0, 100, 15, 1);
	g.drawLine (0, 40, getWidth (), 40, 3);

	g.drawFittedText ("Control your paddle to steer a ball toward the bricks; Lime colored gives a bonus life, yellow gives ball breakthrough power and are worth 20 points, dark blue are solid's that are initially worth 5 points, but increases in value, brightens and eventually turns into regular bricks worth 10 points. Each cleared level increases ball speed! Use the 'Spacebar' to pause the game.", 
    0, 50, getWidth(), 75, Justification::left, 5, 1.0f);
}

As can be seen I am giving the width of the screen (app component) as a parameter, but as one can see below, there is lots of unused space on the right, which could clear fit more text. Note it does not matter what I set last parameter, “minimumHorizontalScale” to.

drawFittedText

This problem continues if I resize the width during app run, all the way up to 599, but at width 600 it looks great using entire width.

Instead of

Justification::left

use

Justification::horizontallyJustified

and you’re good to go.

Yes it does use the full width with that, but not only is the large word spacing ugly, it is now also very unreadable. Justified is normally only used for print (books and magazines), not screen text as the uneven right margin makes it easier to follow which line you were on and where your eyes need to go next.

Yeah, I’m gonna call BS on that. Justify is used on like 95% of all websites. We use it for our error-dialogs etc.

What you describe may work better for people who have dyslexia and need additional hints.

So you find the below easily readable, and even pretty to look at?

drawFittedText2

I sure don’t!

“Can justified text be justified for the web? The answer, in case you were wondering, is no! As you continue to read this article I will explain the disadvantages of justified text, and when it should be used.”

No, but that is because your overall design of that textbox already is “suboptimal” ( = it sucks). There should be a margin around the text in all directions. The text should be split into paragraphs and the font looks cheap too.

Congrats on finding an article that reinforces your opinion.

This was just a quick example trying to illustrate the problem with DrawFittedText. In my app I do have a margin!

But still with a margin justified text, in my opinion looks horrible!

Anyways it does not matter that we have different opinions about screen text aesthetics, your solution does NOT solve my problem!

Here I just slapped on a 10 pixel margin to proof to me and most other people, that it looks horrible!

drawFittedText3

Everybody who thinks that looks pleasingly aesthetic raise their hand!

Damn why it is only you are raising your hand?

If the text looks horrible it’s because its to wide. It will look better if displayed in a narrower area in my opinion.

Yes I believe you are right it will probably look less ugly with a larger margin. However I still think justified text does not belong, in most cases, for web pages, and apps. I can’t even find one single news website that does not use left justification.

Anyways for this particular simple app I want to keep this simple menu with simple brief instructions, as small as possible so the user can see what is behind, as when the setting buttons and sliders, which are, in my app, right under the instructions, are changed they reflect immediately underneath. So I rather not make the menu window larger so I can have larger margins, plus paragraphs.

So I am still trying to figure why left justification is leaving so much space on the right. It seems the code that tries to make the text fit needs to be corrected a bit.

You have the source code to JUCE, dig in and find out! :nerd_face:

Minimum raggedness? (just guessing)

I won’t judge on the quality of what drawFittedText does, but here is what happens in your case:

  • compute the total width of the text (2315.03223)
  • compare to the width of the area (576.0) and figure out that it has to be split (GlyphArrangement::splitLines)
  • compute on how many lines the text can fit, respecting the given upper bound (5)
  • compute the “reference” width by dividing the total width by the number of lines (2315.03223 / 5 = 463.006439)
  • layout the text using this “reference” width to decide where to wrap

Basically, drawFittedText will layout the text like this:
image
not like this:
image

3 Likes

Thank you very much for taking the time to check what the function actually does. I was now able to get an acceptable result by setting number of lines to 4 and scale to 0.0f.

A better function, in case of left and right justification, should perhaps lay out n-1 lines using total width.

1 Like

Layout is a task, where we often put assumptions in, that an algorithm cannot do.
It is unknown, if it should align the outer borders of your text block anywhere.

In your specific case, I think it should have a centre and grow around, and produce a block, that has something close to the “golden ratio” width to height.

So the cleanest solution would be to create a TextLayout, get its width and height and draw it in a centred box.
untested:

TextLayout layout;
layout.createLayout (AttributedString ("Your long text"));
auto box = getLocalBounds().withSizeKeepingCentre (layout.getWidth(), layout.getHeight());
layout.draw (g, box.toFloat());

And have a look into the options you can have with TextLayout, there are probably more refinements possible…

Alright I’ll try TextLayout, but I disagree that you are claiming the algorithm does not know the outer border, as the function is specifically given a width parameter. I am 100% sure I can, if I had the time, write a better function that will fully take into consideration the width, and in case of left and right justification, will then use the full width, much better than currently, for the first n-1 lines. Perhaps after my app, just to proof to myself I will try and improve that function.

I didn’t claim the original is perfect, I have no stakes in that… Merely wanted to give some inspiration about how to tackle the problem…

Enjoy hacking :slight_smile: