I saw a recommendation to use resize() to make text fit into a box the
other day, but it doesn't work with a mono-space font.
Here I am trying to fit three digits in a box but it fails if the first
digit is a one.
[image: image.png]
The text would fit if it was offset but resize doesn't offset, it only
scales. If the thing it is scaling isn't centred around the origin the
result isn't centred but it seems to be scaled around its centre. I bodged
it by adding a tiny square at the origin, which is too small to see.
[image: image.png]
Not quite correct because the one is slightly too tall when there are no
top segments. Since I don't know the height of the text I can't put a dummy
pixel at the top.
[ Pardon if you already figured out all of this on your own. ]
Just playing with it, it looks to me like resize measures the size of
the bounding box of the resulting object (not including translations),
determines the scale that would scale that bounding box to the specified
size, and then applies that scale to the object (including translations).
Thus, suppose that you had:
resize([2,2,2]) translate([10,0,0]) cube([1,1,1]);
The size of the bounding box is [1,1,1], so to resize that to [2,2,2]
requires a scale of [2,2,2]. Applying that scale to the object yields a
[2,2,2] cube at [20,0,0].
If you make the cube bigger but leave the translation in place:
resize([2,2,2]) translate([10,0,0]) cube([2,2,2]);
the bounding box is [2,2,2] and so the scale is [1,1,1], and you get a
[2,2,2] cube at [10,0,0].
I expect that your problem with text is that the text is laid out using
character cells, but the actual objects don't fill those character
cells. Viewed one-dimensionally, suppose that a character cell is 5
units wide, and that a max-width character is 4 units wide, with an
inter-character space of 1 unit. "18" would look like:
_ _ _ X _ X X X X _
^-------------------^ bounding box of character cells
^-----------^ bounding box of actual objects
Those two character cells are a total of 10 units wide, but the actual
objects are only 6 units wide.
If you said to resize that to 20 units, you might expect it to double in
size:
_ _ _ _ _ _ X X _ _ X X X X X X X X _ _
However, since resize only measures the actual objects, you're asking to
scale 6 units up to 20 units, and that's a factor of 3.333 (which I'll
round down to 3 since I can't show fractions here):
_ _ _ _ _ _ _ _ _ X X X _ _ _ X X X X X X X X X X X X _ _ _
The initial blank area doesn't get included in calculating the scale,
but does get scaled up.
It doesn't help you, but proportionally spaced fonts probably behave a
lot better because the "space at the end" is only the inter-character
space, presumably much smaller than the most-of-a-character-cell of a
right-justified '1' in a monospace font. If the font centers its glyphs
in the character cells, a centered piece of text probably gets resized
to precisely the specified size. The fact that the inter-character
spaces are outside the box is not important.
color("white")
square([10,5]);
translate([0,0,1]) color("black")
resize([10,0,0], auto=true)
text("hello");
versus centered:
color("white") translate([-5,0,0])
square([10,5]);
translate([0,0,1]) color("black")
resize([10,0,0], auto=true)
text("hello", halign="center");
Note that I've only specified an X dimension; I've let the Y dimension
float to match.
On 4/21/2020 3:44 PM, Jordan Brown wrote:
[...] the most-of-a-character-cell of a right-justified '1' in a
monospace font.
And... in a quick and incomplete survey, it looks like the monospace
fonts on a Windows system center their 1s in the character box, so if
you center the whole string it probably resizes fine. (No math, no
measuring, just eyeballing.)
Yes I understand why it doesn't work. I was just pointing out that resize
isn't a solution to not having text metrics.
A centre option on resize would sort of solve it in that it would fit the
text in the box but it would still not simulate a led.
On Tue, 21 Apr 2020, 23:44 Jordan Brown, openscad@jordan.maileater.net
wrote:
It doesn't help you, but proportionally spaced fonts probably behave a lot
better because the "space at the end" is only the inter-character space,
presumably much smaller than the most-of-a-character-cell of a
right-justified '1' in a monospace font. If the font centers its glyphs in
the character cells, a centered piece of text probably gets resized to
precisely the specified size. The fact that the inter-character spaces are
outside the box is not important.
color("white")
square([10,5]);
translate([0,0,1]) color("black")
resize([10,0,0], auto=true)
text("hello");
versus centered:
color("white") translate([-5,0,0])
square([10,5]);
translate([0,0,1]) color("black")
resize([10,0,0], auto=true)
text("hello", halign="center");
Note that I've only specified an X dimension; I've let the Y dimension
float to match.
On 4/21/2020 4:05 PM, nop head wrote:
Yes I understand why it doesn't work. I was just pointing out that
resize isn't a solution to not having text metrics.
A centre option on resize would sort of solve it in that it would fit
the text in the box but it would still not simulate a led.
And for some cases, especially monospace fonts and double-especially
your 7-segment font, there's no one set of text metrics that would make
everybody happy.
You would want a bounding box for the character cells (where 1 would
have the same width as 8), because you want to lay out the cells without
regard to what happens to be in them at the moment.
Somebody who wants to make the actual rendered text precisely fit
somewhere would want a bounding box for the glyphs, ignoring any space
on either side of them.
Without doing any research, I suspect that the simplistic text metric
mechanisms would only answer your question. I don't remember fonts
having metrics saying where the glyphs actually are in the character
cells, only the sizes of the character cells. (But again, that's
without doing research.)
there's no one set of text metrics that would make everybody happy.
You want the likes of:
(some nomenclature varies by source)
The first is from FreeType https://www.freetype.org/freetype2/docs/tutorial/step2.html
The second was me documenting other properties, some of which are font related rather than glyph.
(note the red dots are origin of M & g)
That stuff is available from FreeType per glyph, but when a sequence of glyphs are rendered
(FreeType render, not OpenSCAD)
due to kerning & hinting you need to measure the render, as shown in the above link.
Even then, there can be 'funnies' where glyph renders can go outside of such metrics. For example
part of the glyph could be in front of the origin.
So some combination of glyph metrics from FreeType, and measuring of the render would be needed.
For example, you may want bbox including the bearingX of the first glyph if you want it to layout
nicely,
or you may want it without bearingX & the equivalent blank at the end (advance-bearingX-width) so
you can absolutely align an edge.
This is not simple stuff.
From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown
Sent: Wed, 22 Apr 2020 12:37
To: OpenSCAD general discussion; nop head
Subject: Re: [OpenSCAD] Resizing text doesn't work
On 4/21/2020 4:05 PM, nop head wrote:
Yes I understand why it doesn't work. I was just pointing out that resize isn't a solution to not
having text metrics.
A centre option on resize would sort of solve it in that it would fit the text in the box but it
would still not simulate a led.
And for some cases, especially monospace fonts and double-especially your 7-segment font, there's
no one set of text metrics that would make everybody happy.
You would want a bounding box for the character cells (where 1 would have the same width as 8),
because you want to lay out the cells without regard to what happens to be in them at the moment.
Somebody who wants to make the actual rendered text precisely fit somewhere would want a bounding
box for the glyphs, ignoring any space on either side of them.
Without doing any research, I suspect that the simplistic text metric mechanisms would only answer
your question. I don't remember fonts having metrics saying where the glyphs actually are in the
character cells, only the sizes of the character cells. (But again, that's without doing
research.)
--
This email has been checked for viruses by AVG.
https://www.avg.com
I agree, there are many things you can't do without text metrics. Another
related thing not handled well today is characters sticking below the
baseline (example: pqj) or above the top of capitals (example ÅÄÖ), as it's
the bounding box that is used. If you try to line up these variants,
sometimes, there's trouble.
I'd like a simple, built-in function somewhat like this:
textsize(text, font, size)=[xsize,ysize]
That would allow us to do so much more.
nophead wrote
Yes I understand why it doesn't work. I was just pointing out that resize
isn't a solution to not having text metrics.
--
Sent from: http://forum.openscad.org/
On 23.04.20 15:58, Troberg wrote:
I'd like a simple, built-in function somewhat like this:
textsize(text, font, size)=[xsize,ysize]
That would allow us to do so much more.
But it would not solve any of the cases you mentioned. Also
note it's not just up/down.
Try http://pomax.github.io/Cursive-swash-typeface/
Interesting example: Clear the input field and type a lower
case 'g'... now type another one.
The glyph bounding box is not where you think it is, and
it gets more interesting with right-to-left scripting
languages, like Persian and Hebrew (see screenshot). I'm
not even looking at vertical ones :-).
The screenshot has 2 strings, each with 7 Unicode code
points. Maybe that's showing things are not as simple as
it looks at the first glance. It took quite some extra work
getting those to render correctly (as far as the font
allows), mainly thanks to the awesome HarfBuzz library.
I would not like to see that support for languages other
than those using Modern Latin Alphabet limited by adding
interfaces that don't work in general.
This all comes back to the discussion of data structures
which is currently a bit dormant. If we would be able to
figure out how to define those nicely, we are not limited
to return nested vectors.
ciao,
Torsten.
It would if you use valign=baseline.
It would be suffici
tp3 wrote
But it would not solve any of the cases you mentioned. Also
note it's not just up/down.
--
Sent from: http://forum.openscad.org/