Understanding text sizes

I’m a little confused about exactly how the size of a piece of text is calculated and what would affect it.

A user settable piece of text needs to fit in a box of user settable size. The user can also specify the preferred font size.
The aim is to get the font size as close to that requested as possible but to shrink it a little if it doesn’t fit very well. The idea being that they’ll specify something that fits most texts in the boxes and the occasional long text will use a slightly smaller font

----------------------------------------------------------------------------------------- -- -- main.lua -- ----------------------------------------------------------------------------------------- -- where we are drawing our example box local nBoxLeft = 60 local nBoxTop = 60 -- the size of the box local nBoxSize = 58 -- how much space to leave at the edges local nTextMargin = 2 -- so the size of the box teh text needs to fit in is local nTextBoxSize = nBoxSize - nTextMargin - nTextMargin -- a long word, the longest one in the piece of text, we need to fit this on a single line local longword = "VOORGERECHTEN" local longTexts = "VOORGERECHTEN MONSTERS" -- this should end up split over two lines at the space -- a font size to start from local nFontSize = 15 -- a box we need to fit the text into local theBox = display.newRect(nBoxLeft,nBoxTop,nBoxSize,nBoxSize) -- colour that in so we can see it and the text theBox:setFillColor(0.25,0.25,0.25,1) print("width of the box is ".. theBox.width) -- a text object containing just the longest word in our text, this would be thrown away local tempText = display.newText({text=longword, fontSize = nFontSize, font=native.systemFont}) print("text width for long word is "..tempText.width) -- work out the ratio of the actual drawn text and the box it has to fit inside local nCorrFac = (nTextBoxSize / tempText.width) print((tempText.width \* nCorrFac)) -- and calculate the font size that should then give us that text width local newFontSize = nFontSize \* nCorrFac print("font resized from "..nFontSize.. " to "..newFontSize) -- now that we know how big it needs to be make the text the calculated size in the right place inside the box local finalText = display.newText({text=longTexts, fontSize = newFontSize, x = nBoxLeft + nTextMargin, y = nBoxTop + nTextMargin, width=nTextBoxSize, height = nTextBoxSize, font=native.systemFont}) print("width of the fitted text is "..finalText.width)

If you run that in the simulator and pick a few different bits of hardware to view as you’ll see that the width of the initial text varies, the calculated required font size then varies and so does the end result
In extreme cases in the real world it varies so much that the longest word doesn’t fit in the box at the calculated font size and gets split mid word.

What causes the text size to change? What should I be looking at to anticipate this, measure the difference to what I expect and make it draw the size I want?

your using native.systemFont on your example, it’s normal that it will have different behavior on different devices. each device will have different fonts.

if you want more control you should use your own fonts.

Does the simulator know that though?
It changes the size just by selecting different options in the view as menu.

The size of the drawn text in WhateverWeAreMeasuringTheScreenIn does not appear to scale linearly with the font size passed to display.newText
That’s the bit that causes me an issue, if native.systemFont is slightly larger on one device than another that should only affect the size of tempText, not the size of finalText

your config.lua is a big part of the way the objects are drawn/created on the app. try there first, different combinations.

on theory you are right, the native.systemFont should only affect tempText, but on practice, i’ve learned that different font needed different positions on different devices and SOs, mostly I only had height problems, not width like your having, so it’s better to have only 1 and test it from there. fewer variables are better to understand the problem and try to correct it. don’t forget also that different devices have different resolutions, with the conjunction of you config.lua it can create the problem, or resolve it.

The simulator should use the OS’s default font, on macOS it’s likely Helvetica Neue or San Fransisco (not sure what Sierra uses). On Windows it’s Arial and this should be consistent across skins.

Rob

fractional point sizes (like 15 * nCorrFac) might lead to a bit of “slop” in napkin-calcs. (ie, you may not be able to exactly reproduce Corona’s internal use of font metrics as a simple function of linear scale)  what might work is rendering larger at a simple integral font size that’s known-to-fit, then simply scale the texture result instead of the fontSize by your correction factor, pseudo-code:

local tooBigText = display.newText({ width=200, height=200, fontSize=15, ..etc.. local actualWidth = tooBigText.width local desiredWidth = 50 local correctionFactor = desiredWidth / actualWidth tooBigText.xScale = correctionFactor tooBigText.yScale = correctionFactor

your using native.systemFont on your example, it’s normal that it will have different behavior on different devices. each device will have different fonts.

if you want more control you should use your own fonts.

Does the simulator know that though?
It changes the size just by selecting different options in the view as menu.

The size of the drawn text in WhateverWeAreMeasuringTheScreenIn does not appear to scale linearly with the font size passed to display.newText
That’s the bit that causes me an issue, if native.systemFont is slightly larger on one device than another that should only affect the size of tempText, not the size of finalText

your config.lua is a big part of the way the objects are drawn/created on the app. try there first, different combinations.

on theory you are right, the native.systemFont should only affect tempText, but on practice, i’ve learned that different font needed different positions on different devices and SOs, mostly I only had height problems, not width like your having, so it’s better to have only 1 and test it from there. fewer variables are better to understand the problem and try to correct it. don’t forget also that different devices have different resolutions, with the conjunction of you config.lua it can create the problem, or resolve it.

The simulator should use the OS’s default font, on macOS it’s likely Helvetica Neue or San Fransisco (not sure what Sierra uses). On Windows it’s Arial and this should be consistent across skins.

Rob

fractional point sizes (like 15 * nCorrFac) might lead to a bit of “slop” in napkin-calcs. (ie, you may not be able to exactly reproduce Corona’s internal use of font metrics as a simple function of linear scale)  what might work is rendering larger at a simple integral font size that’s known-to-fit, then simply scale the texture result instead of the fontSize by your correction factor, pseudo-code:

local tooBigText = display.newText({ width=200, height=200, fontSize=15, ..etc.. local actualWidth = tooBigText.width local desiredWidth = 50 local correctionFactor = desiredWidth / actualWidth tooBigText.xScale = correctionFactor tooBigText.yScale = correctionFactor