Resizing text doesn't work

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Resizing text doesn't work

nophead
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.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.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.




_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

JordanBrown
[ 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.



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

JordanBrown
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.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

JordanBrown
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.)


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

nophead
In reply to this post by JordanBrown
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, <[hidden email]> 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.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

JordanBrown
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.)


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

MichaelAtOz
Administrator

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:[hidden email]] 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.)


Virus-free. www.avg.com

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Admin - email* me if you need anything, or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

Troberg
In reply to this post by nophead
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/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
tp3
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

tp3
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.



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Screenshot from 2020-04-23 16-40-46.png (215K) Download Attachment
-- Torsten
Reply | Threaded
Open this post in threaded view
|

Re: Resizing text doesn't work

Troberg
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/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org