Font size for text width


#1

Hi,

Is there a way to determine quickly the best font size to draw a string within a rectangle ensuring it is as big as possible?

I would like something as static Font fromStringAndArea(const String& text, const float maxwidth, const float maxheight) :wink:

Thx


#2

juce::Font::getStringWidth() could help, though it could be a slow process.


#3

Yes sure, but it just gives the string width for a specific font size. I just want the reverse :smiley:


#4

Yeah, so the brute force way is to iterate through sizes till it fits tightly …not quick, but does the job. :smiley:

I don’t think there’s an easy way of doing it…

Edit: Unless you somehow use Path and Font::getOutlineForGlyph(), where the font size is 1.0f (for easy scaling of the paths). With a bit of math, it could be faster than my first suggestion.


#5

Yep, I’m doing this iteration stuff for the moment… it works… but… :roll:

Your idea using the path is interesting! I’ll try it, thanks! :!:


#6

here’s a couple of functions i use. note that you can also affect the horizontal scale when making a fitting.

Note, here `_font’, you’ll have to pass in or get from your class as i do here.

[code] void setFontSizeForBounds(int w, int h, const String& text, int margin = 0)
{
_font.setHeight(h);
_font.setHorizontalScale(1);

    // round up to pixel
    int fw = _font.getStringWidthFloat(text) + 0.5f;

    if (fw + margin > w)
    {
        float s = (w - margin)/(float)fw;
        h = h*s; // round down to pixel
    }
    setFontHeight(h);
}[/code]

and this one does the same (without a margin) but with a min horizontal scale

[code] void setFontSizeAndScaleForBounds(int w, int h,
const String& text,
float minScale = 0.8f)
{
_font.setHeight(h);
_font.setHorizontalScale(1);

    float scale = 1;
    float fw = _font.getStringWidth(text);
    if (fw > w)
        scale = w/fw;

    if (scale < minScale)
    {
        int h2 = (int)((w/minScale)/fw * h);
        _font.setHeight(h2);

        fw = _font.getStringWidth(text);
        if (fw > w)
            scale = w/fw;
    }

    _font.setHorizontalScale(scale);
}[/code]

#7

Cool!

If you use getOutlineForGlyph(), do know that codepoint != character index in string (of any kind).