red
red copied to clipboard
Cannot measure text for use in `draw` block without creating excess `face` object.
I want to measure a text, for usage inside a draw
block, so I don't have a face
object dedicated for this particular text. It should be possible to provide a font
only for this use case. In my opinion having to create excess objects only to carry some other objects, is unacceptable in serious programming.
Problematic code is a Windows implementation of get-text-size
function, which relies on face object. MacOS and Linux versions could probably be modified more easily.
"unacceptable in serious programming." is a bit strong IMO. Text measurement on Windows has historically been based on device contexts, so this is a cost of the platform. Use of modern APIs will require OS sniffing to avoid that. Another thing to keep in mind is that size-text
also measures rich text. If you eliminate the face aspect for basic text, you have to change the function spec as well (even if just to allow none
, which makes the call site look like size-text none ...
, effectively making the face a leading optional parameter).
As far as creating excess objects, you only need one. When Red supports concurrency, you'll need one per thread of execution or another way to serialize requests to a single, blocking, reference. For the time being, how unacceptable is it to reserve a single face to do this?
I should also remind everyone that size of text in a face doesn't equal size of text as a string:
- there's the size of the face, and if text doesn't fit it can be split by word or char boundary, depending on face settings
- there's para! object that defines wrapping and padding
- there's detabbing mode - usually in the shape of tab stops (in pixels)
Then there's OS scaling, which may be different for different displays (screens) if you have more than one (as they may have different DPI)
size-text
is there to tell you how your big paragraph will look in that particular face considering the settings I just mentioned. It must be the main driver behind face object requirement.
But there is of course a need for lower level dumb text measurement that would assume infinite canvas and ignore tabs, and it came up a year ago I think. But it still has to account for scaling, which is why I propose using system/view/screens/1
face. I don't think there's currently a way to determine the active screen, and the window may even appear on 2 screens at once, so it's more complicated that we use to think.
size-text
would be a measurement in a vacuum. It's okay if you want to ignore the DPI and maybe render a pdf or something. Where you really could care less about the display ;)
macOS and Linux get-text-size
implementations don't use face
parameter at all. So I assume, that they don't take into account any of these (wrapping, padding, detabbing, scaling)?
I'm totally for a low-level dumb font-only version. And for Windows system/view/screens/1
could be used behind the stage, somewhere in gui.reds
probably.
I've tried to create such dumb function in #4182 . Comments welcome, since probably it has lots of errors :-)
Part of this more general thought dump https://github.com/red/REP/issues/124