discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Text and font metrics

JB
Jordan Brown
Mon, Dec 28, 2020 4:55 AM

I was making From/To cards for Christmas, and there was no way to make
them automatically size to fit the text.  What the heck, I'm off work
for the next week and this seems like a more or less straightforward
project.

I have it mostly working, give or take the halign/valign issues I
discussed in a separate message.

tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir);

yields

[
     [ minx, miny ],            // bounding box lower left corner
     [ width, height ],         // bounding box size
     [ advance_x, advance_y],   // translation for next text block
     [ ascent, descent ]        // Distance above/below baseline
]

I'm debating whether I need to add a width result, for vertical layouts,
that would be the maximum character width.  This is distinct from
bounding box; as noted in another message, some glyphs have ink outside
the box that's used for spacing.  The bounding box above is intended to
enclose all ink, while this width would be based on the spacing box.

Similarly,

fm = fontmetrics(font=f, size=size);

returns font-global information:

[
     [ ascent, descent ],	// Typographic ascent and descent
     [ max-ascent, max-descent],	// actual maximums
     leading			// inter-line spacing
]

These allow you to do things like this:

s = "Hello World!";
valign = "baseline";
halign = "left";
f = "Freestyle Script";
dir = "ltr";
size = 20;

tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir);
translate(tm[0]) cube(concat(tm[1],1));
color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign, font=f, direction=dir);

Note that that yellow cube will track whatever text you put in, with
whatever layout parameters you give.

Any additional ideas?  Any additional parameters to return? Bikeshedding
names or return values?

Issues:

  • Cleanup, error handling
  • Commonize measurement functionality with render function.
  • ttb/btt layout issues as described in another thread.
  • There's a 2.4% error between the size you give and the size you
    get.  I think I've compensated for it correctly, but need to
    analyze it more.  (Ref issue #2436
    https://github.com/openscad/openscad/issues/2436.)
  • There appears to be a very small error somewhere that causes the
    very edges of glyphs to go outside the bounding box, or maybe to not
    quite make it to the edge of the bounding box. This might be an
    error that the FreeType documentation mentions associated with font
    hinting that makes the actual points not quite match the bounding
    box.  They describe it as up to a one-pixel error, whatever that
    means for a vector environment.

(That 2.4% error is a real nuisance.  Font metrics are already complex,
and there are something like four or five different scales used for the
various values.  Adding another makes things just that much more
complicated.)

I was making From/To cards for Christmas, and there was no way to make them automatically size to fit the text.  What the heck, I'm off work for the next week and this seems like a more or less straightforward project. I have it mostly working, give or take the halign/valign issues I discussed in a separate message. tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir); yields [ [ minx, miny ], // bounding box lower left corner [ width, height ], // bounding box size [ advance_x, advance_y], // translation for next text block [ ascent, descent ] // Distance above/below baseline ] I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum character width.  This is distinct from bounding box; as noted in another message, some glyphs have ink outside the box that's used for spacing.  The bounding box above is intended to enclose all ink, while this width would be based on the spacing box. Similarly, fm = fontmetrics(font=f, size=size); returns font-global information: [ [ ascent, descent ], // Typographic ascent and descent [ max-ascent, max-descent], // actual maximums leading // inter-line spacing ] These allow you to do things like this: s = "Hello World!"; valign = "baseline"; halign = "left"; f = "Freestyle Script"; dir = "ltr"; size = 20; tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir); translate(tm[0]) cube(concat(tm[1],1)); color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign, font=f, direction=dir); Note that that yellow cube will track whatever text you put in, with whatever layout parameters you give. Any additional ideas?  Any additional parameters to return? Bikeshedding names or return values? Issues: * Cleanup, error handling * Commonize measurement functionality with render function. * ttb/btt layout issues as described in another thread. * There's a 2.4% error between the size you give and the size you get.  I *think* I've compensated for it correctly, but need to analyze it more.  (Ref issue #2436 <https://github.com/openscad/openscad/issues/2436>.) * There appears to be a *very small* error somewhere that causes the very edges of glyphs to go outside the bounding box, or maybe to not quite make it to the edge of the bounding box. This might be an error that the FreeType documentation mentions associated with font hinting that makes the actual points not quite match the bounding box.  They describe it as up to a one-pixel error, whatever that means for a vector environment. (That 2.4% error is a real nuisance.  Font metrics are already complex, and there are something like four or five different scales used for the various values.  Adding another makes things just that much more complicated.)
JB
Jordan Brown
Tue, Dec 29, 2020 3:47 AM

In IRC, Torsten asked about whether my font metrics stuff could handle
حرف‌باز, HarfBuzz in Persian.  Yes, it can.

In IRC, Torsten asked about whether my font metrics stuff could handle حرف‌باز, HarfBuzz in Persian.  Yes, it can.
MM
Michael Marx
Wed, Dec 30, 2020 1:29 AM

As mentioned elsewhere, space= & alignment has peculiarities.

I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what
the textmetrics produce.

The following shows "XX" with, top down, space=2, space=1, space=0.5.

The easy one is halign="left", looks normal:

The red blocks show the advance with space=2.

The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue
the (back) advance of the second X.

Should BB include the right red space, or exclude the light blue. Because...

halign="right":

Again the red block shows the advance, and why 'X X' is not butted-up to the axis.

Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually.

halign="center":

Again centred including the forward/back advance.

i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred.

Given backward compatibility, we should not change this behaviour (??), so to be useful the output
from textmetrics() should

present enough information to be able to correct this to get actual alignment.

That was all with direction="ltr", I need to look at "rtl" and also ttb/btt.

The three .scad files are attached if anyone wants to play.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown
Sent: Mon, 28 Dec 2020 15:55
To: OpenSCAD general discussion
Subject: [OpenSCAD] Text and font metrics

I was making From/To cards for Christmas, and there was no way to make them automatically size to
fit the text.  What the heck, I'm off work for the next week and this seems like a more or less
straightforward project.

I have it mostly working, give or take the halign/valign issues I discussed in a separate message.

tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir);

yields

[
[ minx, miny ],            // bounding box lower left corner
[ width, height ],        // bounding box size
[ advance_x, advance_y],  // translation for next text block
[ ascent, descent ]        // Distance above/below baseline
]

I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum
character width.  This is distinct from bounding box; as noted in another message, some glyphs have
ink outside the box that's used for spacing.  The bounding box above is intended to enclose all
ink, while this width would be based on the spacing box.

Similarly,

fm = fontmetrics(font=f, size=size);

returns font-global information:

[
[ ascent, descent ],      // Typographic ascent and descent
[ max-ascent, max-descent], // actual maximums
leading                    // inter-line spacing
]

These allow you to do things like this:

s = "Hello World!";
valign = "baseline";
halign = "left";
f = "Freestyle Script";
dir = "ltr";
size = 20;

tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir);
translate(tm[0]) cube(concat(tm[1],1));
color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign,
font=f, direction=dir);

Note that that yellow cube will track whatever text you put in, with whatever layout parameters you
give.

Any additional ideas?  Any additional parameters to return?  Bikeshedding names or return values?

Issues:

  • Cleanup, error handling
  • Commonize measurement functionality with render function.
  • ttb/btt layout issues as described in another thread.
  • There's a 2.4% error between the size you give and the size you get.  I think I've
    compensated for it correctly, but need to analyze it more.  (Ref issue #2436
    https://github.com/openscad/openscad/issues/2436 .)
  • There appears to be a very small error somewhere that causes the very edges of glyphs to
    go outside the bounding box, or maybe to not quite make it to the edge of the bounding box.  This
    might be an error that the FreeType documentation mentions associated with font hinting that makes
    the actual points not quite match the bounding box.  They describe it as up to a one-pixel error,
    whatever that means for a vector environment.

(That 2.4% error is a real nuisance.  Font metrics are already complex, and there are something
like four or five different scales used for the various values.  Adding another makes things just
that much more complicated.)

--
This email has been checked for viruses by AVG.
https://www.avg.com

As mentioned elsewhere, space= & alignment has peculiarities. I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what the textmetrics produce. The following shows "XX" with, top down, space=2, space=1, space=0.5. The easy one is halign="left", looks normal: The red blocks show the advance with space=2. The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue the (back) advance of the second X. Should BB include the right red space, or exclude the light blue. Because... halign="right": Again the red block shows the advance, and why 'X X' is not butted-up to the axis. Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually. halign="center": Again centred including the forward/back advance. i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred. Given backward compatibility, we should not change this behaviour (??), so to be useful the output from textmetrics() should present enough information to be able to correct this to get actual alignment. That was all with direction="ltr", I need to look at "rtl" and also ttb/btt. The three .scad files are attached if anyone wants to play. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown Sent: Mon, 28 Dec 2020 15:55 To: OpenSCAD general discussion Subject: [OpenSCAD] Text and font metrics I was making From/To cards for Christmas, and there was no way to make them automatically size to fit the text. What the heck, I'm off work for the next week and this seems like a more or less straightforward project. I have it mostly working, give or take the halign/valign issues I discussed in a separate message. tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir); yields [ [ minx, miny ], // bounding box lower left corner [ width, height ], // bounding box size [ advance_x, advance_y], // translation for next text block [ ascent, descent ] // Distance above/below baseline ] I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum character width. This is distinct from bounding box; as noted in another message, some glyphs have ink outside the box that's used for spacing. The bounding box above is intended to enclose all ink, while this width would be based on the spacing box. Similarly, fm = fontmetrics(font=f, size=size); returns font-global information: [ [ ascent, descent ], // Typographic ascent and descent [ max-ascent, max-descent], // actual maximums leading // inter-line spacing ] These allow you to do things like this: s = "Hello World!"; valign = "baseline"; halign = "left"; f = "Freestyle Script"; dir = "ltr"; size = 20; tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir); translate(tm[0]) cube(concat(tm[1],1)); color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign, font=f, direction=dir); Note that that yellow cube will track whatever text you put in, with whatever layout parameters you give. Any additional ideas? Any additional parameters to return? Bikeshedding names or return values? Issues: * Cleanup, error handling * Commonize measurement functionality with render function. * ttb/btt layout issues as described in another thread. * There's a 2.4% error between the size you give and the size you get. I *think* I've compensated for it correctly, but need to analyze it more. (Ref issue #2436 <https://github.com/openscad/openscad/issues/2436> .) * There appears to be a *very small* error somewhere that causes the very edges of glyphs to go outside the bounding box, or maybe to not quite make it to the edge of the bounding box. This might be an error that the FreeType documentation mentions associated with font hinting that makes the actual points not quite match the bounding box. They describe it as up to a one-pixel error, whatever that means for a vector environment. (That 2.4% error is a real nuisance. Font metrics are already complex, and there are something like four or five different scales used for the various values. Adding another makes things just that much more complicated.) -- This email has been checked for viruses by AVG. https://www.avg.com
M
MichaelAtOz
Wed, Dec 30, 2020 1:38 AM

direction="rtl" is also broken, as like the ttb/btt broken, I'll post pictures, but they are
effectively the same.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx
Sent: Wed, 30 Dec 2020 12:30
To: 'OpenSCAD general discussion'
Subject: Re: [OpenSCAD] Text and font metrics

As mentioned elsewhere, space= & alignment has peculiarities.

I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what
the textmetrics produce.

The following shows "XX" with, top down, space=2, space=1, space=0.5.

The easy one is halign="left", looks normal:

The red blocks show the advance with space=2.

The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue
the (back) advance of the second X.

Should BB include the right red space, or exclude the light blue. Because...

halign="right":

Again the red block shows the advance, and why 'X X' is not butted-up to the axis.

Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually.

halign="center":

Again centred including the forward/back advance.

i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred.

Given backward compatibility, we should not change this behaviour (??), so to be useful the output
from textmetrics() should

present enough information to be able to correct this to get actual alignment.

That was all with direction="ltr", I need to look at "rtl" and also ttb/btt.

The three .scad files are attached if anyone wants to play.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown
Sent: Mon, 28 Dec 2020 15:55
To: OpenSCAD general discussion
Subject: [OpenSCAD] Text and font metrics

I was making From/To cards for Christmas, and there was no way to make them automatically size to
fit the text.  What the heck, I'm off work for the next week and this seems like a more or less
straightforward project.

I have it mostly working, give or take the halign/valign issues I discussed in a separate message.

tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir);

yields

[
[ minx, miny ],            // bounding box lower left corner
[ width, height ],        // bounding box size
[ advance_x, advance_y],  // translation for next text block
[ ascent, descent ]        // Distance above/below baseline
]

I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum
character width.  This is distinct from bounding box; as noted in another message, some glyphs have
ink outside the box that's used for spacing.  The bounding box above is intended to enclose all
ink, while this width would be based on the spacing box.

Similarly,

fm = fontmetrics(font=f, size=size);

returns font-global information:

[
[ ascent, descent ],      // Typographic ascent and descent
[ max-ascent, max-descent], // actual maximums
leading                    // inter-line spacing
]

These allow you to do things like this:

s = "Hello World!";
valign = "baseline";
halign = "left";
f = "Freestyle Script";
dir = "ltr";
size = 20;

tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir);
translate(tm[0]) cube(concat(tm[1],1));
color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign,
font=f, direction=dir);

Note that that yellow cube will track whatever text you put in, with whatever layout parameters you
give.

Any additional ideas?  Any additional parameters to return?  Bikeshedding names or return values?

Issues:

  • Cleanup, error handling
  • Commonize measurement functionality with render function.
  • ttb/btt layout issues as described in another thread.
  • There's a 2.4% error between the size you give and the size you get.  I think I've
    compensated for it correctly, but need to analyze it more.  (Ref issue #2436
    https://github.com/openscad/openscad/issues/2436 .)
  • There appears to be a very small error somewhere that causes the very edges of glyphs to
    go outside the bounding box, or maybe to not quite make it to the edge of the bounding box.  This
    might be an error that the FreeType documentation mentions associated with font hinting that makes
    the actual points not quite match the bounding box.  They describe it as up to a one-pixel error,
    whatever that means for a vector environment.

(That 2.4% error is a real nuisance.  Font metrics are already complex, and there are something
like four or five different scales used for the various values.  Adding another makes things just
that much more complicated.)

<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con
tent=emailclient>

Virus-free.
<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con
tent=emailclient> www.avg.com

--
This email has been checked for viruses by AVG.
https://www.avg.com

direction="rtl" is also broken, as like the ttb/btt broken, I'll post pictures, but they are effectively the same. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx Sent: Wed, 30 Dec 2020 12:30 To: 'OpenSCAD general discussion' Subject: Re: [OpenSCAD] Text and font metrics As mentioned elsewhere, space= & alignment has peculiarities. I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what the textmetrics produce. The following shows "XX" with, top down, space=2, space=1, space=0.5. The easy one is halign="left", looks normal: The red blocks show the advance with space=2. The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue the (back) advance of the second X. Should BB include the right red space, or exclude the light blue. Because... halign="right": Again the red block shows the advance, and why 'X X' is not butted-up to the axis. Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually. halign="center": Again centred including the forward/back advance. i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred. Given backward compatibility, we should not change this behaviour (??), so to be useful the output from textmetrics() should present enough information to be able to correct this to get actual alignment. That was all with direction="ltr", I need to look at "rtl" and also ttb/btt. The three .scad files are attached if anyone wants to play. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown Sent: Mon, 28 Dec 2020 15:55 To: OpenSCAD general discussion Subject: [OpenSCAD] Text and font metrics I was making From/To cards for Christmas, and there was no way to make them automatically size to fit the text. What the heck, I'm off work for the next week and this seems like a more or less straightforward project. I have it mostly working, give or take the halign/valign issues I discussed in a separate message. tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir); yields [ [ minx, miny ], // bounding box lower left corner [ width, height ], // bounding box size [ advance_x, advance_y], // translation for next text block [ ascent, descent ] // Distance above/below baseline ] I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum character width. This is distinct from bounding box; as noted in another message, some glyphs have ink outside the box that's used for spacing. The bounding box above is intended to enclose all ink, while this width would be based on the spacing box. Similarly, fm = fontmetrics(font=f, size=size); returns font-global information: [ [ ascent, descent ], // Typographic ascent and descent [ max-ascent, max-descent], // actual maximums leading // inter-line spacing ] These allow you to do things like this: s = "Hello World!"; valign = "baseline"; halign = "left"; f = "Freestyle Script"; dir = "ltr"; size = 20; tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir); translate(tm[0]) cube(concat(tm[1],1)); color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign, font=f, direction=dir); Note that that yellow cube will track whatever text you put in, with whatever layout parameters you give. Any additional ideas? Any additional parameters to return? Bikeshedding names or return values? Issues: * Cleanup, error handling * Commonize measurement functionality with render function. * ttb/btt layout issues as described in another thread. * There's a 2.4% error between the size you give and the size you get. I *think* I've compensated for it correctly, but need to analyze it more. (Ref issue #2436 <https://github.com/openscad/openscad/issues/2436> .) * There appears to be a *very small* error somewhere that causes the very edges of glyphs to go outside the bounding box, or maybe to not quite make it to the edge of the bounding box. This might be an error that the FreeType documentation mentions associated with font hinting that makes the actual points not quite match the bounding box. They describe it as up to a one-pixel error, whatever that means for a vector environment. (That 2.4% error is a real nuisance. Font metrics are already complex, and there are something like four or five different scales used for the various values. Adding another makes things just that much more complicated.) <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con tent=emailclient> Virus-free. <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con tent=emailclient> www.avg.com -- This email has been checked for viruses by AVG. https://www.avg.com
MM
Michael Marx
Wed, Dec 30, 2020 2:41 AM

direction="rtl" - appears to me to be wrong, in the way ttb/btt is wrong.

Changed to "XY" to show the direction.

Note I did not change the position of the red blocks, but added green for rtl advance, I moved the
blue. (I think correctly)

If it goes rtl the space=2 Y should have the advance on the left, and

if behaving similarly the Y should be positioned more to the right with an advance space to its
left,

ie axis|<advance gap>Y<advance gap>X, like a mirror of the ltr/halign-right in previous post.

Basically it should be shifted right so the light green is on the right of the axis. Dark green is
the X advance.

Similarly the space=0.5 should have ½ Y to the left of the axis.

The right side of light blue is the Y (back) advance, should be on the axis.

Basically the bounding box should be looked at backwards, trailing advance (or back) on the left.

The space=2 should have the X butted-up to the axis. Green shows the advances.

Ditto space=0.5 butted-up to X

The space=2 BB should be right side of X to left side of light green advance,

i.e. a mirror of the non-centred 'X X' of ltr.

space=0.5 should actually look centred on 'YX' (visually).

Again rtl advance should nudge the BB to the right.

Given this is probably broken, rather than an interpretation of glyph v's advance, maybe this

reverse direction should be fixed. ??

I'll think about ttb/btt tomorrow.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of MichaelAtOz
Sent: Wed, 30 Dec 2020 12:39
To: 'OpenSCAD general discussion'
Subject: Re: [OpenSCAD] Text and font metrics

direction="rtl" is also broken, as like the ttb/btt broken, I'll post pictures, but they are
effectively the same.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx
Sent: Wed, 30 Dec 2020 12:30
To: 'OpenSCAD general discussion'
Subject: Re: [OpenSCAD] Text and font metrics

As mentioned elsewhere, space= & alignment has peculiarities.

I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what
the textmetrics produce.

The following shows "XX" with, top down, space=2, space=1, space=0.5.

The easy one is halign="left", looks normal:

The red blocks show the advance with space=2.

The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue
the (back) advance of the second X.

Should BB include the right red space, or exclude the light blue. Because...

halign="right":

Again the red block shows the advance, and why 'X X' is not butted-up to the axis.

Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually.

halign="center":

Again centred including the forward/back advance.

i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred.

Given backward compatibility, we should not change this behaviour (??), so to be useful the output
from textmetrics() should

present enough information to be able to correct this to get actual alignment.

That was all with direction="ltr", I need to look at "rtl" and also ttb/btt.

The three .scad files are attached if anyone wants to play.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown
Sent: Mon, 28 Dec 2020 15:55
To: OpenSCAD general discussion
Subject: [OpenSCAD] Text and font metrics

I was making From/To cards for Christmas, and there was no way to make them automatically size to
fit the text.  What the heck, I'm off work for the next week and this seems like a more or less
straightforward project.

I have it mostly working, give or take the halign/valign issues I discussed in a separate message.

tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir);

yields

[
[ minx, miny ],            // bounding box lower left corner
[ width, height ],        // bounding box size
[ advance_x, advance_y],  // translation for next text block
[ ascent, descent ]        // Distance above/below baseline
]

I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum
character width.  This is distinct from bounding box; as noted in another message, some glyphs have
ink outside the box that's used for spacing.  The bounding box above is intended to enclose all
ink, while this width would be based on the spacing box.

Similarly,

fm = fontmetrics(font=f, size=size);

returns font-global information:

[
[ ascent, descent ],      // Typographic ascent and descent
[ max-ascent, max-descent], // actual maximums
leading                    // inter-line spacing
]

These allow you to do things like this:

s = "Hello World!";
valign = "baseline";
halign = "left";
f = "Freestyle Script";
dir = "ltr";
size = 20;

tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir);
translate(tm[0]) cube(concat(tm[1],1));
color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign,
font=f, direction=dir);

Note that that yellow cube will track whatever text you put in, with whatever layout parameters you
give.

Any additional ideas?  Any additional parameters to return?  Bikeshedding names or return values?

Issues:

  • Cleanup, error handling
  • Commonize measurement functionality with render function.
  • ttb/btt layout issues as described in another thread.
  • There's a 2.4% error between the size you give and the size you get.  I think I've
    compensated for it correctly, but need to analyze it more.  (Ref issue #2436
    https://github.com/openscad/openscad/issues/2436 .)
  • There appears to be a very small error somewhere that causes the very edges of glyphs to
    go outside the bounding box, or maybe to not quite make it to the edge of the bounding box.  This
    might be an error that the FreeType documentation mentions associated with font hinting that makes
    the actual points not quite match the bounding box.  They describe it as up to a one-pixel error,
    whatever that means for a vector environment.

(That 2.4% error is a real nuisance.  Font metrics are already complex, and there are something
like four or five different scales used for the various values.  Adding another makes things just
that much more complicated.)

<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con
tent=emailclient>

Virus-free.
<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con
tent=emailclient> www.avg.com

--
This email has been checked for viruses by AVG.
https://www.avg.com

direction="rtl" - appears to me to be wrong, in the way ttb/btt is wrong. Changed to "XY" to show the direction. Note I did not change the position of the red blocks, but added green for rtl advance, I moved the blue. (I think correctly) If it goes rtl the space=2 Y should have the advance on the left, and if behaving similarly the Y should be positioned more to the right with an advance space to its left, ie axis|<advance gap>Y<advance gap>X, like a mirror of the ltr/halign-right in previous post. Basically it should be shifted right so the light green is on the right of the axis. Dark green is the X advance. Similarly the space=0.5 should have ½ Y to the left of the axis. The right side of light blue is the Y (back) advance, should be on the axis. Basically the bounding box should be looked at backwards, trailing advance (or back) on the left. The space=2 should have the X butted-up to the axis. Green shows the advances. Ditto space=0.5 butted-up to X The space=2 BB should be right side of X to left side of light green advance, i.e. a mirror of the non-centred 'X X' of ltr. space=0.5 should actually look centred on 'YX' (visually). Again rtl advance should nudge the BB to the right. Given this is probably broken, rather than an interpretation of glyph v's advance, maybe this reverse direction should be fixed. ?? I'll think about ttb/btt tomorrow. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of MichaelAtOz Sent: Wed, 30 Dec 2020 12:39 To: 'OpenSCAD general discussion' Subject: Re: [OpenSCAD] Text and font metrics direction="rtl" is also broken, as like the ttb/btt broken, I'll post pictures, but they are effectively the same. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx Sent: Wed, 30 Dec 2020 12:30 To: 'OpenSCAD general discussion' Subject: Re: [OpenSCAD] Text and font metrics As mentioned elsewhere, space= & alignment has peculiarities. I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what the textmetrics produce. The following shows "XX" with, top down, space=2, space=1, space=0.5. The easy one is halign="left", looks normal: The red blocks show the advance with space=2. The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue the (back) advance of the second X. Should BB include the right red space, or exclude the light blue. Because... halign="right": Again the red block shows the advance, and why 'X X' is not butted-up to the axis. Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually. halign="center": Again centred including the forward/back advance. i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred. Given backward compatibility, we should not change this behaviour (??), so to be useful the output from textmetrics() should present enough information to be able to correct this to get actual alignment. That was all with direction="ltr", I need to look at "rtl" and also ttb/btt. The three .scad files are attached if anyone wants to play. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown Sent: Mon, 28 Dec 2020 15:55 To: OpenSCAD general discussion Subject: [OpenSCAD] Text and font metrics I was making From/To cards for Christmas, and there was no way to make them automatically size to fit the text. What the heck, I'm off work for the next week and this seems like a more or less straightforward project. I have it mostly working, give or take the halign/valign issues I discussed in a separate message. tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir); yields [ [ minx, miny ], // bounding box lower left corner [ width, height ], // bounding box size [ advance_x, advance_y], // translation for next text block [ ascent, descent ] // Distance above/below baseline ] I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum character width. This is distinct from bounding box; as noted in another message, some glyphs have ink outside the box that's used for spacing. The bounding box above is intended to enclose all ink, while this width would be based on the spacing box. Similarly, fm = fontmetrics(font=f, size=size); returns font-global information: [ [ ascent, descent ], // Typographic ascent and descent [ max-ascent, max-descent], // actual maximums leading // inter-line spacing ] These allow you to do things like this: s = "Hello World!"; valign = "baseline"; halign = "left"; f = "Freestyle Script"; dir = "ltr"; size = 20; tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir); translate(tm[0]) cube(concat(tm[1],1)); color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign, font=f, direction=dir); Note that that yellow cube will track whatever text you put in, with whatever layout parameters you give. Any additional ideas? Any additional parameters to return? Bikeshedding names or return values? Issues: * Cleanup, error handling * Commonize measurement functionality with render function. * ttb/btt layout issues as described in another thread. * There's a 2.4% error between the size you give and the size you get. I *think* I've compensated for it correctly, but need to analyze it more. (Ref issue #2436 <https://github.com/openscad/openscad/issues/2436> .) * There appears to be a *very small* error somewhere that causes the very edges of glyphs to go outside the bounding box, or maybe to not quite make it to the edge of the bounding box. This might be an error that the FreeType documentation mentions associated with font hinting that makes the actual points not quite match the bounding box. They describe it as up to a one-pixel error, whatever that means for a vector environment. (That 2.4% error is a real nuisance. Font metrics are already complex, and there are something like four or five different scales used for the various values. Adding another makes things just that much more complicated.) <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con tent=emailclient> Virus-free. <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con tent=emailclient> www.avg.com -- This email has been checked for viruses by AVG. https://www.avg.com
L
lar3ry
Wed, Dec 30, 2020 3:42 AM

Talkative, you are!

--
Sent from: http://forum.openscad.org/

Talkative, you are! -- Sent from: http://forum.openscad.org/
M
MichaelAtOz
Thu, Dec 31, 2020 3:06 AM

direction= ttb/btt has similar alignment issues with space!=0

Given the abnormal behaviour of ttb/bbt with valign that Jordan first raised,

the valign="center" is the only one I could test.

ttb has the same relative behaviour as ltr, ie the 'incorrect' centre due to the trailing advance.

Hence textmetrics() likewise could provide info to allow manually 'correctly' centring.

Likewise btt & space=2 does not correctly handle the reverse direction advance,

'X Y ' is in the same position.

It should handle the advance being 'after' Y in btt direction, and

produce the 'incorrect' centre, ie the above should be shifted down by one red block.

And space=0.5 likewise, to behave the same as ltr, to do the 'incorrect' centre,

the middle of X should be on the axis.

That would be consistent with the ttb behaviour.

So to summarise for space!=0 alignment if off, but really off in the other direction.

In 'forward'* processing the valign/halign# appropriate to 'forward' uses the position of

the last advance (which will be different to the edge of the last glyph) to do the BB which

is used to apply the alignment offset. Resulting in misalignment. [current behaviour]

*'forward' ie intrinsic direction, ltr or ttb

halign for ltr/rtl, valign for ttb/btt

But with 'reverse' processing it doesn't consider the advance should apply to the 'other' end.

BB is the same as 'forward' so the misalignment is not in the correct direction to be consistent.

Well that is how it appears from the output, I have yet to look at the code, but that may be beyond
me.

So the 'forward' misalignment is an unfortunate choice at the time, and unless

we choose to break backward compatibility, it should stay that way, but textmetrics() could

provide something like the advance, so text() could be manually positioned correctly.

However, I believe the 'reverse' processing is a bug and should be fixed.

Doing so will still have a misalignment, but it will be in the consistent place relative to the
direction.

So again textmetrics() could provide the info to manually correct it.

That concludes my investigation.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx
Sent: Wed, 30 Dec 2020 13:42
To: 'OpenSCAD general discussion'
Subject: Re: [OpenSCAD] Text and font metrics

direction="rtl" - appears to me to be wrong, in the way ttb/btt is wrong.

Changed to "XY" to show the direction.

Note I did not change the position of the red blocks, but added green for rtl advance, I moved the
blue. (I think correctly)

If it goes rtl the space=2 Y should have the advance on the left, and

if behaving similarly the Y should be positioned more to the right with an advance space to its
left,

ie axis|<advance gap>Y<advance gap>X, like a mirror of the ltr/halign-right in previous post.

Basically it should be shifted right so the light green is on the right of the axis. Dark green is
the X advance.

Similarly the space=0.5 should have ½ Y to the left of the axis.

The right side of light blue is the Y (back) advance, should be on the axis.

Basically the bounding box should be looked at backwards, trailing advance (or back) on the left.

The space=2 should have the X butted-up to the axis. Green shows the advances.

Ditto space=0.5 butted-up to X

The space=2 BB should be right side of X to left side of light green advance,

i.e. a mirror of the non-centred 'X X' of ltr.

space=0.5 should actually look centred on 'YX' (visually).

Again rtl advance should nudge the BB to the right.

Given this is probably broken, rather than an interpretation of glyph v's advance, maybe this

reverse direction should be fixed. ??

I'll think about ttb/btt tomorrow.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of MichaelAtOz
Sent: Wed, 30 Dec 2020 12:39
To: 'OpenSCAD general discussion'
Subject: Re: [OpenSCAD] Text and font metrics

direction="rtl" is also broken, as like the ttb/btt broken, I'll post pictures, but they are
effectively the same.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx
Sent: Wed, 30 Dec 2020 12:30
To: 'OpenSCAD general discussion'
Subject: Re: [OpenSCAD] Text and font metrics

As mentioned elsewhere, space= & alignment has peculiarities.

I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what
the textmetrics produce.

The following shows "XX" with, top down, space=2, space=1, space=0.5.

The easy one is halign="left", looks normal:

The red blocks show the advance with space=2.

The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue
the (back) advance of the second X.

Should BB include the right red space, or exclude the light blue. Because...

halign="right":

Again the red block shows the advance, and why 'X X' is not butted-up to the axis.

Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually.

halign="center":

Again centred including the forward/back advance.

i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred.

Given backward compatibility, we should not change this behaviour (??), so to be useful the output
from textmetrics() should

present enough information to be able to correct this to get actual alignment.

That was all with direction="ltr", I need to look at "rtl" and also ttb/btt.

The three .scad files are attached if anyone wants to play.


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown
Sent: Mon, 28 Dec 2020 15:55
To: OpenSCAD general discussion
Subject: [OpenSCAD] Text and font metrics

I was making From/To cards for Christmas, and there was no way to make them automatically size to
fit the text.  What the heck, I'm off work for the next week and this seems like a more or less
straightforward project.

I have it mostly working, give or take the halign/valign issues I discussed in a separate message.

tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir);

yields

[
[ minx, miny ],            // bounding box lower left corner
[ width, height ],        // bounding box size
[ advance_x, advance_y],  // translation for next text block
[ ascent, descent ]        // Distance above/below baseline
]

I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum
character width.  This is distinct from bounding box; as noted in another message, some glyphs have
ink outside the box that's used for spacing.  The bounding box above is intended to enclose all
ink, while this width would be based on the spacing box.

Similarly,

fm = fontmetrics(font=f, size=size);

returns font-global information:

[
[ ascent, descent ],      // Typographic ascent and descent
[ max-ascent, max-descent], // actual maximums
leading                    // inter-line spacing
]

These allow you to do things like this:

s = "Hello World!";
valign = "baseline";
halign = "left";
f = "Freestyle Script";
dir = "ltr";
size = 20;

tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir);
translate(tm[0]) cube(concat(tm[1],1));
color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign,
font=f, direction=dir);

Note that that yellow cube will track whatever text you put in, with whatever layout parameters you
give.

Any additional ideas?  Any additional parameters to return?  Bikeshedding names or return values?

Issues:

  • Cleanup, error handling
  • Commonize measurement functionality with render function.
  • ttb/btt layout issues as described in another thread.
  • There's a 2.4% error between the size you give and the size you get.  I think I've
    compensated for it correctly, but need to analyze it more.  (Ref issue #2436
    https://github.com/openscad/openscad/issues/2436 .)
  • There appears to be a very small error somewhere that causes the very edges of glyphs to
    go outside the bounding box, or maybe to not quite make it to the edge of the bounding box.  This
    might be an error that the FreeType documentation mentions associated with font hinting that makes
    the actual points not quite match the bounding box.  They describe it as up to a one-pixel error,
    whatever that means for a vector environment.

(That 2.4% error is a real nuisance.  Font metrics are already complex, and there are something
like four or five different scales used for the various values.  Adding another makes things just
that much more complicated.)

<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con
tent=emailclient>

Virus-free.
<http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con
tent=emailclient> www.avg.com

--
This email has been checked for viruses by AVG.
https://www.avg.com

direction= ttb/btt has similar alignment issues with space!=0 Given the abnormal behaviour of ttb/bbt with valign that Jordan first raised, the valign="center" is the only one I could test. ttb has the same relative behaviour as ltr, ie the 'incorrect' centre due to the trailing advance. Hence textmetrics() likewise could provide info to allow manually 'correctly' centring. Likewise btt & space=2 does not correctly handle the reverse direction advance, 'X Y ' is in the same position. It should handle the advance being 'after' Y in btt direction, and produce the 'incorrect' centre, ie the above should be shifted down by one red block. And space=0.5 likewise, to behave the same as ltr, to do the 'incorrect' centre, the middle of X should be on the axis. That would be consistent with the ttb behaviour. So to summarise for space!=0 alignment if off, but really off in the other direction. In 'forward'* processing the valign/halign# appropriate to 'forward' uses the position of the last advance (which will be different to the edge of the last glyph) to do the BB which is used to apply the alignment offset. Resulting in misalignment. [current behaviour] *'forward' ie intrinsic direction, ltr or ttb # halign for ltr/rtl, valign for ttb/btt But with 'reverse' processing it doesn't consider the advance should apply to the 'other' end. BB is the same as 'forward' so the misalignment is not in the correct direction to be consistent. Well that is how it appears from the output, I have yet to look at the code, but that may be beyond me. So the 'forward' misalignment is an unfortunate choice at the time, and unless we choose to break backward compatibility, it should stay that way, but textmetrics() could provide something like the advance, so text() could be manually positioned correctly. However, I believe the 'reverse' processing is a bug and should be fixed. Doing so will still have a misalignment, but it will be in the consistent place relative to the direction. So again textmetrics() could provide the info to manually correct it. That concludes my investigation. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx Sent: Wed, 30 Dec 2020 13:42 To: 'OpenSCAD general discussion' Subject: Re: [OpenSCAD] Text and font metrics direction="rtl" - appears to me to be wrong, in the way ttb/btt is wrong. Changed to "XY" to show the direction. Note I did not change the position of the red blocks, but added green for rtl advance, I moved the blue. (I think correctly) If it goes rtl the space=2 Y should have the advance on the left, and if behaving similarly the Y should be positioned more to the right with an advance space to its left, ie axis|<advance gap>Y<advance gap>X, like a mirror of the ltr/halign-right in previous post. Basically it should be shifted right so the light green is on the right of the axis. Dark green is the X advance. Similarly the space=0.5 should have ½ Y to the left of the axis. The right side of light blue is the Y (back) advance, should be on the axis. Basically the bounding box should be looked at backwards, trailing advance (or back) on the left. The space=2 should have the X butted-up to the axis. Green shows the advances. Ditto space=0.5 butted-up to X The space=2 BB should be right side of X to left side of light green advance, i.e. a mirror of the non-centred 'X X' of ltr. space=0.5 should actually look centred on 'YX' (visually). Again rtl advance should nudge the BB to the right. Given this is probably broken, rather than an interpretation of glyph v's advance, maybe this reverse direction should be fixed. ?? I'll think about ttb/btt tomorrow. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of MichaelAtOz Sent: Wed, 30 Dec 2020 12:39 To: 'OpenSCAD general discussion' Subject: Re: [OpenSCAD] Text and font metrics direction="rtl" is also broken, as like the ttb/btt broken, I'll post pictures, but they are effectively the same. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Michael Marx Sent: Wed, 30 Dec 2020 12:30 To: 'OpenSCAD general discussion' Subject: Re: [OpenSCAD] Text and font metrics As mentioned elsewhere, space= & alignment has peculiarities. I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what the textmetrics produce. The following shows "XX" with, top down, space=2, space=1, space=0.5. The easy one is halign="left", looks normal: The red blocks show the advance with space=2. The dark blue, the 0.5 advance, ie goes back, the second X starts at the left edge, the light blue the (back) advance of the second X. Should BB include the right red space, or exclude the light blue. Because... halign="right": Again the red block shows the advance, and why 'X X' is not butted-up to the axis. Similarly the (back) advance light blue shows why it is in-effect butted up, but not actually. halign="center": Again centred including the forward/back advance. i.e BB with red block included is centred, BB from left of 1st X to left of light blue is centred. Given backward compatibility, we should not change this behaviour (??), so to be useful the output from textmetrics() should present enough information to be able to correct this to get actual alignment. That was all with direction="ltr", I need to look at "rtl" and also ttb/btt. The three .scad files are attached if anyone wants to play. _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown Sent: Mon, 28 Dec 2020 15:55 To: OpenSCAD general discussion Subject: [OpenSCAD] Text and font metrics I was making From/To cards for Christmas, and there was no way to make them automatically size to fit the text. What the heck, I'm off work for the next week and this seems like a more or less straightforward project. I have it mostly working, give or take the halign/valign issues I discussed in a separate message. tm = textmetrics(text=s, size=size, valign=valign, halign=halign, font=f, direction=dir); yields [ [ minx, miny ], // bounding box lower left corner [ width, height ], // bounding box size [ advance_x, advance_y], // translation for next text block [ ascent, descent ] // Distance above/below baseline ] I'm debating whether I need to add a width result, for vertical layouts, that would be the maximum character width. This is distinct from bounding box; as noted in another message, some glyphs have ink outside the box that's used for spacing. The bounding box above is intended to enclose all ink, while this width would be based on the spacing box. Similarly, fm = fontmetrics(font=f, size=size); returns font-global information: [ [ ascent, descent ], // Typographic ascent and descent [ max-ascent, max-descent], // actual maximums leading // inter-line spacing ] These allow you to do things like this: s = "Hello World!"; valign = "baseline"; halign = "left"; f = "Freestyle Script"; dir = "ltr"; size = 20; tm = textmetrics(s, size=size, valign=valign, halign=halign, font=f, direction=dir); translate(tm[0]) cube(concat(tm[1],1)); color("lightgreen") linear_extrude(height=2) text(s, size=size, valign=valign, halign=halign, font=f, direction=dir); Note that that yellow cube will track whatever text you put in, with whatever layout parameters you give. Any additional ideas? Any additional parameters to return? Bikeshedding names or return values? Issues: * Cleanup, error handling * Commonize measurement functionality with render function. * ttb/btt layout issues as described in another thread. * There's a 2.4% error between the size you give and the size you get. I *think* I've compensated for it correctly, but need to analyze it more. (Ref issue #2436 <https://github.com/openscad/openscad/issues/2436> .) * There appears to be a *very small* error somewhere that causes the very edges of glyphs to go outside the bounding box, or maybe to not quite make it to the edge of the bounding box. This might be an error that the FreeType documentation mentions associated with font hinting that makes the actual points not quite match the bounding box. They describe it as up to a one-pixel error, whatever that means for a vector environment. (That 2.4% error is a real nuisance. Font metrics are already complex, and there are something like four or five different scales used for the various values. Adding another makes things just that much more complicated.) <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con tent=emailclient> Virus-free. <http://www.avg.com/email-signature?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_con tent=emailclient> www.avg.com -- This email has been checked for viruses by AVG. https://www.avg.com
JB
Jordan Brown
Thu, Dec 31, 2020 7:21 PM

On 12/29/2020 7:42 PM, lar3ry wrote:

Talkative, you are!

Indeed.

However, there's a lot of subtlety in text layout, and even more once
you introduce some of the slightly-to-very strange behavior that
OpenSCAD introduces.

If we're going to add new features to the language, and especially if we
tweak the existing behavior of the language, it's important that the
stakeholders understand all of the issues.  If you don't care about
exactly how text is placed, and you're happy with your existing ability
to place it, and you're not doing anything particularly exotic with it,
you can probably ignore the whole discussion.  You won't be using the
new functions, and any (as yet hypothetical) changes will either be
small or will be in exotic cases.  If, on the other hand, you do care
about these things, if it's really important that your text fit
exactly where you want it to, if you've had to work around OpenSCAD's
...interesting... behaviors, then you should probably follow the
conversation and chime in when you see something that you think might
cause you trouble.

On 12/29/2020 7:42 PM, lar3ry wrote: > Talkative, you are! Indeed. However, there's a lot of subtlety in text layout, and even more once you introduce some of the slightly-to-very strange behavior that OpenSCAD introduces. If we're going to add new features to the language, and especially if we tweak the existing behavior of the language, it's important that the stakeholders understand all of the issues.  If you don't care about exactly how text is placed, and you're happy with your existing ability to place it, and you're not doing anything particularly exotic with it, you can probably ignore the whole discussion.  You won't be using the new functions, and any (as yet hypothetical) changes will either be small or will be in exotic cases.  If, on the other hand, you *do* care about these things, if it's really important that your text fit *exactly* where you want it to, if you've had to work around OpenSCAD's ...interesting... behaviors, then you should probably follow the conversation and chime in when you see something that you think might cause you trouble.
JB
Jordan Brown
Thu, Dec 31, 2020 7:57 PM

[ Combined a couple of replies. ]

On 12/29/2020 5:29 PM, Michael Marx wrote:

As mentioned elsewhere, space= & alignment has peculiarities.

Yes, that's all pretty well aligned with my understanding of what's
going on.  Plus there are some related and more subtle effects.

The "spacing" issues are related to the fact that halign is with respect
to the difference between the origin and the total advance of the
string, and the total advance is scaled up by the value of "spacing".

Definition:  "advance" is the amount that the origin is moved before
the next glyph is drawn.

Suppose that we have an M that has eight units of ink in a ten-unit box:

.MMMMMMMM.

With just that, you'll get some subtle effects.  When you align it, it's
the total width of the box that's used, not the size of the ink. 
Thus, with | as the Y axis:

          |.MMMMMMMM.
.MMMMMMMM.|
     .MMMM|MMMM.

with halign=right, the ink starts slightly right of the origin, and with
halign=left it stops slightly left of the origin - for this hypothetical
glyph, one unit left/right.  This is easy to see:

When we add in "spacing", the behavior changes.  "spacing" scales up the
advance value.  If we set spacing to 2, the advance for our M becomes 20:

.MMMMMMMM...........

and that is what halign uses for its alignment:

                    |.MMMMMMMM...........
.MMMMMMMM...........|
          .MMMMMMMM.|..........

The rightest answer to this sub-problem is to apply "spacing" on all but
the last glyph in the string, so that the "extra" spacing on the end
isn't counted in alignment.

However, there are other issues that also need to be considered:

  • Note that even without "spacing", the alignment isn't quite what you
    might expect, because it's based on a character box and the ink is
    generally inset from the box.  (Note, though, that in some fonts the
    ink extends outside the box and so there are the opposite results,
    with ink extending on the "wrong" side of the origin.)
  • I'll discuss it in more detail in a standalone message, but a few of
    the metrics (advance, offset, ascent, descent, but not the glyphs
    themselves) are scaled down by 2.4%, further confusing the issue.

While we're talking about halign and I have the images handy, there's a
difference that I'm pretty sure is that 2.4% scaling effect.  Consider
these images of the top-left corner of a left-aligned W and the
top-right corner of a right-aligned W:


With respect to RTL:  the big question there is whether the effect
should be to mirror the LTR behavior, or if it should be roughly as if
the order of the characters was reversed.  Spacing introduces a relevant
asymmetry, which is (I think) what you're describing:  in LTR, there's
"extra" space on the right; in RTL should that "extra" space remain on
the right or move to the left?  (Mostly I think the answer is that it
doesn't matter, because the "extra" space is wrong no matter where you
put it.)  Another relevant asymmetry can come from font design:  for
instance, the "a" in Freestyle Script protrudes to the left of its
nominal box, but has space to its right in the box.  With halign=left,
it protrudes slightly left of the Y axis; with halign=right there is
space between the Y axis and the ink.  What should happen in RTL? 
Should that asymmetry be mirrored?  Current behavior is that the spacing
is not mirrored; an RTL presentation of a single letter appears to be
exactly the same as the LTR presentation of that letter, no matter how
it's aligned.

BTW, the reversal associated with RTL happens before ligature
processing, so you don't end up with silliness when you lay out a word
like "Official".  If it was just reordering the glyphs, that would end
up as "l a i c ffi O", and that would be silly.  Instead, it ends up as
"l a i c i ff O".  Ligature processing is still done, so "different"
rendered RTL is rendered as "t n e r e ffi d", with the reversed "iff"
being rendered as an "ffi" ligature.  (In fonts with ligature support. 
I'm using Calibri for most of those tests.)


With respect to TTB/BTT:  I think the issues there are basically similar
to the LTR/RTL issues, with the added confusion of the other problems
with TTB/BTT.


[ And back to the original message for the bottom line... ]

I raise it here as it seems to be bounding box (BB) related, it would
be interesting to know what the textmetrics produce.

Indeed.  As the old joke
https://sites.google.com/site/funnyenglishjokes/work-jokes/accountant-statistician-mathematician-joke
goes, what do you want it to produce?

I have been thinking about it more in the context of the 2.4% scaling
mismatch, but there is a question of what textmetrics() should return: 
should it return values that are compatible with existing OpenSCAD
behavior, or should it return values that match the font design and ink
placement?

Matching OpenSCAD behavior lets you better understand what halign and
valign are doing.  Matching the font design lets you do things that are
perhaps artistically correct.  Matching the actual ink placement lets
you control exactly where the ink goes.

Part of that is easy:  it should report both the font design metrics and
the ink placement.  Beyond that, perhaps it should additionally report
what OpenSCAD does.

As an example of the difference, in the M example above what is the
width of the string?  Is it eight (the width of the ink), ten (the width
of the character box), or twenty (the value OpenSCAD uses for alignment)?

Or maybe we should (optionally?) break backward compatibility and try to
iron out these issues as much as is possible, so as to have a future
that is as consistent and correct as possible.  (I am not optimistic
about fixing all of the "spacing" issues.  Some of them are too hard.)

BTW, setting spacing=1024/1000 should cancel out the 2.4% scaling
mismatch, at least with respect to horizontal alignment.

[ Combined a couple of replies. ] On 12/29/2020 5:29 PM, Michael Marx wrote: > > As mentioned elsewhere, space= & alignment has peculiarities. > Yes, that's all pretty well aligned with my understanding of what's going on.  Plus there are some related and more subtle effects. The "spacing" issues are related to the fact that halign is with respect to the difference between the origin and the total advance of the string, and the total advance is scaled up by the value of "spacing". Definition:  "advance" is the amount that the origin is moved before the next glyph is drawn. Suppose that we have an M that has eight units of ink in a ten-unit box: .MMMMMMMM. With just that, you'll get some subtle effects.  When you align it, it's the total width of the box that's used, *not* the size of the ink.  Thus, with | as the Y axis: |.MMMMMMMM. .MMMMMMMM.| .MMMM|MMMM. with halign=right, the ink starts slightly right of the origin, and with halign=left it stops slightly left of the origin - for this hypothetical glyph, one unit left/right.  This is easy to see: When we add in "spacing", the behavior changes.  "spacing" scales up the advance value.  If we set spacing to 2, the advance for our M becomes 20: .MMMMMMMM........... and *that* is what halign uses for its alignment: |.MMMMMMMM........... .MMMMMMMM...........| .MMMMMMMM.|.......... The rightest answer to this sub-problem is to apply "spacing" on all but the last glyph in the string, so that the "extra" spacing on the end isn't counted in alignment. However, there are other issues that also need to be considered: * Note that even without "spacing", the alignment isn't quite what you might expect, because it's based on a character box and the ink is generally inset from the box.  (Note, though, that in some fonts the ink extends *outside* the box and so there are the opposite results, with ink extending on the "wrong" side of the origin.) * I'll discuss it in more detail in a standalone message, but a few of the metrics (advance, offset, ascent, descent, but *not* the glyphs themselves) are scaled down by 2.4%, further confusing the issue. While we're talking about halign and I have the images handy, there's a difference that I'm pretty sure is that 2.4% scaling effect.  Consider these images of the top-left corner of a left-aligned W and the top-right corner of a right-aligned W: --- With respect to RTL:  the big question there is whether the effect should be to mirror the LTR behavior, or if it should be roughly as if the order of the characters was reversed.  Spacing introduces a relevant asymmetry, which is (I think) what you're describing:  in LTR, there's "extra" space on the right; in RTL should that "extra" space remain on the right or move to the left?  (Mostly I think the answer is that it doesn't matter, because the "extra" space is wrong no matter where you put it.)  Another relevant asymmetry can come from font design:  for instance, the "a" in Freestyle Script protrudes to the left of its nominal box, but has space to its right in the box.  With halign=left, it protrudes slightly left of the Y axis; with halign=right there is space between the Y axis and the ink.  What should happen in RTL?  Should that asymmetry be mirrored?  Current behavior is that the spacing is *not* mirrored; an RTL presentation of a single letter appears to be exactly the same as the LTR presentation of that letter, no matter how it's aligned. BTW, the reversal associated with RTL happens before ligature processing, so you don't end up with silliness when you lay out a word like "Official".  If it was just reordering the glyphs, that would end up as "l a i c ffi O", and that would be silly.  Instead, it ends up as "l a i c i ff O".  Ligature processing is still done, so "different" rendered RTL is rendered as "t n e r e ffi d", with the reversed "iff" being rendered as an "ffi" ligature.  (In fonts with ligature support.  I'm using Calibri for most of those tests.) --- With respect to TTB/BTT:  I think the issues there are basically similar to the LTR/RTL issues, with the added confusion of the other problems with TTB/BTT. --- [ And back to the original message for the bottom line... ] > I raise it here as it seems to be bounding box (BB) related, it would > be interesting to know what the textmetrics produce. > Indeed.  As the old joke <https://sites.google.com/site/funnyenglishjokes/work-jokes/accountant-statistician-mathematician-joke> goes, what do you want it to produce? I have been thinking about it more in the context of the 2.4% scaling mismatch, but there is a question of what textmetrics() should return:  should it return values that are compatible with existing OpenSCAD behavior, or should it return values that match the font design and ink placement? Matching OpenSCAD behavior lets you better understand what halign and valign are doing.  Matching the font design lets you do things that are perhaps artistically correct.  Matching the actual ink placement lets you control *exactly* where the ink goes. Part of that is easy:  it should report both the font design metrics and the ink placement.  Beyond that, perhaps it should additionally report what OpenSCAD does. As an example of the difference, in the M example above what is the width of the string?  Is it eight (the width of the ink), ten (the width of the character box), or twenty (the value OpenSCAD uses for alignment)? Or maybe we should (optionally?) break backward compatibility and try to iron out these issues as much as is possible, so as to have a future that is as consistent and correct as possible.  (I am not optimistic about fixing all of the "spacing" issues.  Some of them are too hard.) BTW, setting spacing=1024/1000 should cancel out the 2.4% scaling mismatch, at least with respect to horizontal alignment.
M
MichaelAtOz
Fri, Jan 1, 2021 7:24 AM

and that is what halign uses for its alignment:

Yes, I know.

Note that even without "spacing", the alignment isn't quite what you might expect,

because it's based on a character box and the ink is generally inset from the box.

This is a good picture:

bearingX is the left-inset, advance - bearingX - width = the right-inset (of import with space!=0).

So this is the font designers intent discussion (with space=1),

things may look like crap or alter meaning if the ink started at the origin,

particularly fancy or very-foreign fonts, or symbol fonts.

(I tried inserting some of my Cuneiform & Hieroglyphs* in this email - didn't work)

This is where it is typographically correct, but often graphically awkward.

[* no I'm not a language specialist, I use them for esoteric
<https://www.redbubble.com/i/t-shirt/Kissing-Fish-Pseudo-Assyrian-Cuneiform-by-MichaelAtOz/42916695
.QUQES>  graphics]

(Note, though, that in some fonts the ink extends outside the box

and so there are the opposite results, with ink extending on the "wrong" side of the origin.)

Again font designer intent, and alignment of multiple text() calls.

If the text() is jiggled to the 'correct' side you remove the fonts intent,

that information is lost, whereas having something in textmetrics telling you

how much 'wrongness' is there allows it to be compensated for if desired,

including adjusting subsequent text() calls to compensate the jiggle.

ie if you manually move your 'A',

you could apply that offset to a text() line below making 'a' inset to match the font intent.

This may seem trivial, but if you wanted to replicate some real world object which

uses typographic layout, having text() auto-jiggle means you can't match the real layout.

Perhaps an option in text() for those who don't care?

galign=true (glyph-align), purely uses the BB of the set-of-glyphs, moved to OpenSCAD origin,

(origin appropriate to ltr/rtl/ttb/btt).

The rightest answer to this sub-problem [extra advance] is to apply "spacing" on all but the last

glyph in the string

Spacing introduces a relevant asymmetry, which is (I think) what you're describing:

in LTR, there's "extra" space on the right;

in RTL should that "extra" space remain on the right or move to the left?

(Mostly I think the answer is that it doesn't matter, because the "extra" space is wrong no

matter where you put it.)

Yes that is what I'm describing, and its effect on alignment to origin etc.

The point is backward compatibility.

We could say

a.        heck fix it all

b.        The LTR 'extra' is a technically correct in a typesetting sense*, but

        unsuited to graphic layout, but is locked-in behaviour

c.        The RTL is just wrong, fix it (as proposed for TTB/BTT)

        to match the locked-in LTR behaviour, ie 'extra' on the proper-end (left)
  • on reflection, allowing 'extra' to cause valign to fail is not technically typeset correct.

So for b. & c. allow concerned people to correct it with textmetrics(),

or another text() option, trimtail=true??

The backward compatibility Force is Strong...

a few of the metrics (advance, offset, ascent, descent, but not the glyphs themselves) are

scaled down by 2.4%

I had presumed it was opposite (the glyphs were bigger) but that explains my observations.

valign=top, bottom of red boxes is the OpenSCAD origin. Eyeball says 2.4% could be it.

Perhaps we should ask the community (in a separate thread) what damage

the various fixes would do to their designs?


From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown
Sent: Fri, 1 Jan 2021 06:57
To: OpenSCAD general discussion; Michael Marx
Subject: Re: [OpenSCAD] Text and font metrics

[ Combined a couple of replies. ]

On 12/29/2020 5:29 PM, Michael Marx wrote:

As mentioned elsewhere, space= & alignment has peculiarities.

Yes, that's all pretty well aligned with my understanding of what's going on.  Plus there are some
related and more subtle effects.

The "spacing" issues are related to the fact that halign is with respect to the difference between
the origin and the total advance of the string, and the total advance is scaled up by the value of
"spacing".

Definition:  "advance" is the amount that the origin is moved before the next glyph is drawn.

Suppose that we have an M that has eight units of ink in a ten-unit box:

.MMMMMMMM.

With just that, you'll get some subtle effects.  When you align it, it's the total width of the box
that's used, not the size of the ink.  Thus, with | as the Y axis:

      |.MMMMMMMM.

.MMMMMMMM.|
.MMMM|MMMM.

with halign=right, the ink starts slightly right of the origin, and with halign=left it stops
slightly left of the origin - for this hypothetical glyph, one unit left/right.  This is easy to
see:

When we add in "spacing", the behavior changes.  "spacing" scales up the advance value.  If we set
spacing to 2, the advance for our M becomes 20:

.MMMMMMMM...........

and that is what halign uses for its alignment:

                |.MMMMMMMM...........

.MMMMMMMM...........|
.MMMMMMMM.|..........

The rightest answer to this sub-problem is to apply "spacing" on all but the last glyph in the
string, so that the "extra" spacing on the end isn't counted in alignment.

However, there are other issues that also need to be considered:

  • Note that even without "spacing", the alignment isn't quite what you might expect, because
    it's based on a character box and the ink is generally inset from the box.  (Note, though, that in
    some fonts the ink extends outside the box and so there are the opposite results, with ink
    extending on the "wrong" side of the origin.)
  • I'll discuss it in more detail in a standalone message, but a few of the metrics (advance,
    offset, ascent, descent, but not the glyphs themselves) are scaled down by 2.4%, further
    confusing the issue.

While we're talking about halign and I have the images handy, there's a difference that I'm pretty
sure is that 2.4% scaling effect.  Consider these images of the top-left corner of a left-aligned W
and the top-right corner of a right-aligned W:


With respect to RTL:  the big question there is whether the effect should be to mirror the LTR
behavior, or if it should be roughly as if the order of the characters was reversed.  Spacing
introduces a relevant asymmetry, which is (I think) what you're describing:  in LTR, there's
"extra" space on the right; in RTL should that "extra" space remain on the right or move to the
left?  (Mostly I think the answer is that it doesn't matter, because the "extra" space is wrong no
matter where you put it.)  Another relevant asymmetry can come from font design:  for instance, the
"a" in Freestyle Script protrudes to the left of its nominal box, but has space to its right in the
box.  With halign=left, it protrudes slightly left of the Y axis; with halign=right there is space
between the Y axis and the ink.  What should happen in RTL?  Should that asymmetry be mirrored?
Current behavior is that the spacing is not mirrored; an RTL presentation of a single letter
appears to be exactly the same as the LTR presentation of that letter, no matter how it's aligned.

BTW, the reversal associated with RTL happens before ligature processing, so you don't end up with
silliness when you lay out a word like "Official".  If it was just reordering the glyphs, that
would end up as "l a i c ffi O", and that would be silly.  Instead, it ends up as "l a i c i ff O".
Ligature processing is still done, so "different" rendered RTL is rendered as "t n e r e ffi d",
with the reversed "iff" being rendered as an "ffi" ligature.  (In fonts with ligature support.  I'm
using Calibri for most of those tests.)


With respect to TTB/BTT:  I think the issues there are basically similar to the LTR/RTL issues,
with the added confusion of the other problems with TTB/BTT.


[ And back to the original message for the bottom line... ]

I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what
the textmetrics produce.

Indeed.  As the old joke
<https://sites.google.com/site/funnyenglishjokes/work-jokes/accountant-statistician-mathematician-j
oke>  goes, what do you want it to produce?

I have been thinking about it more in the context of the 2.4% scaling mismatch, but there is a
question of what textmetrics() should return:  should it return values that are compatible with
existing OpenSCAD behavior, or should it return values that match the font design and ink
placement?

Matching OpenSCAD behavior lets you better understand what halign and valign are doing.  Matching
the font design lets you do things that are perhaps artistically correct.  Matching the actual ink
placement lets you control exactly where the ink goes.

Part of that is easy:  it should report both the font design metrics and the ink placement.  Beyond
that, perhaps it should additionally report what OpenSCAD does.

As an example of the difference, in the M example above what is the width of the string?  Is it
eight (the width of the ink), ten (the width of the character box), or twenty (the value OpenSCAD
uses for alignment)?

Or maybe we should (optionally?) break backward compatibility and try to iron out these issues as
much as is possible, so as to have a future that is as consistent and correct as possible.  (I am
not optimistic about fixing all of the "spacing" issues.  Some of them are too hard.)

BTW, setting spacing=1024/1000 should cancel out the 2.4% scaling mismatch, at least with respect
to horizontal alignment.

--
This email has been checked for viruses by AVG.
https://www.avg.com

> and *that* is what halign uses for its alignment: Yes, I know. > Note that even without "spacing", the alignment isn't quite what you might expect, > because it's based on a character box and the ink is generally inset from the box. This is a good picture: bearingX is the left-inset, advance - bearingX - width = the right-inset (of import with space!=0). So this is the font designers intent discussion (with space=1), things may look like crap or alter meaning if the ink started at the origin, particularly fancy or very-foreign fonts, or symbol fonts. (I tried inserting some of my Cuneiform & Hieroglyphs* in this email - didn't work) This is where it is typographically correct, but often graphically awkward. [* no I'm not a language specialist, I use them for esoteric <https://www.redbubble.com/i/t-shirt/Kissing-Fish-Pseudo-Assyrian-Cuneiform-by-MichaelAtOz/42916695 .QUQES> graphics] > (Note, though, that in some fonts the ink extends *outside* the box > and so there are the opposite results, with ink extending on the "wrong" side of the origin.) Again font designer intent, and alignment of multiple text() calls. If the text() is jiggled to the 'correct' side you remove the fonts intent, that information is lost, whereas having something in textmetrics telling you how much 'wrongness' is there allows it to be compensated for if desired, including adjusting subsequent text() calls to compensate the jiggle. ie if you manually move your 'A', you could apply that offset to a text() line below making 'a' inset to match the font intent. This may seem trivial, but if you wanted to replicate some real world object which uses typographic layout, having text() auto-jiggle means you can't match the real layout. Perhaps an option in text() for those who don't care? galign=true (glyph-align), purely uses the BB of the set-of-glyphs, moved to OpenSCAD origin, (origin appropriate to ltr/rtl/ttb/btt). > The rightest answer to this sub-problem [extra advance] is to apply "spacing" on all but the last glyph in the string > Spacing introduces a relevant asymmetry, which is (I think) what you're describing: > in LTR, there's "extra" space on the right; > in RTL should that "extra" space remain on the right or move to the left? > (Mostly I think the answer is that it doesn't matter, because the "extra" space is wrong no matter where you put it.) Yes that is what I'm describing, and its effect on alignment to origin etc. The point is backward compatibility. We could say a. heck fix it all b. The LTR 'extra' is a technically correct in a typesetting sense*, but unsuited to graphic layout, but is locked-in behaviour c. The RTL is just wrong, fix it (as proposed for TTB/BTT) to match the locked-in LTR behaviour, ie 'extra' on the proper-end (left) * on reflection, allowing 'extra' to cause valign to fail is not technically typeset correct. So for b. & c. allow concerned people to correct it with textmetrics(), or another text() option, trimtail=true?? The backward compatibility Force is Strong... > a few of the metrics (advance, offset, ascent, descent, but *not* the glyphs themselves) are scaled down by 2.4% I had presumed it was opposite (the glyphs were bigger) but that explains my observations. valign=top, bottom of red boxes is the OpenSCAD origin. Eyeball says 2.4% could be it. Perhaps we should ask the community (in a separate thread) what damage the various fixes would do to their designs? _____ From: Discuss [mailto:discuss-bounces@lists.openscad.org] On Behalf Of Jordan Brown Sent: Fri, 1 Jan 2021 06:57 To: OpenSCAD general discussion; Michael Marx Subject: Re: [OpenSCAD] Text and font metrics [ Combined a couple of replies. ] On 12/29/2020 5:29 PM, Michael Marx wrote: As mentioned elsewhere, space= & alignment has peculiarities. Yes, that's all pretty well aligned with my understanding of what's going on. Plus there are some related and more subtle effects. The "spacing" issues are related to the fact that halign is with respect to the difference between the origin and the total advance of the string, and the total advance is scaled up by the value of "spacing". Definition: "advance" is the amount that the origin is moved before the next glyph is drawn. Suppose that we have an M that has eight units of ink in a ten-unit box: .MMMMMMMM. With just that, you'll get some subtle effects. When you align it, it's the total width of the box that's used, *not* the size of the ink. Thus, with | as the Y axis: |.MMMMMMMM. .MMMMMMMM.| .MMMM|MMMM. with halign=right, the ink starts slightly right of the origin, and with halign=left it stops slightly left of the origin - for this hypothetical glyph, one unit left/right. This is easy to see: When we add in "spacing", the behavior changes. "spacing" scales up the advance value. If we set spacing to 2, the advance for our M becomes 20: .MMMMMMMM........... and *that* is what halign uses for its alignment: |.MMMMMMMM........... .MMMMMMMM...........| .MMMMMMMM.|.......... The rightest answer to this sub-problem is to apply "spacing" on all but the last glyph in the string, so that the "extra" spacing on the end isn't counted in alignment. However, there are other issues that also need to be considered: * Note that even without "spacing", the alignment isn't quite what you might expect, because it's based on a character box and the ink is generally inset from the box. (Note, though, that in some fonts the ink extends *outside* the box and so there are the opposite results, with ink extending on the "wrong" side of the origin.) * I'll discuss it in more detail in a standalone message, but a few of the metrics (advance, offset, ascent, descent, but *not* the glyphs themselves) are scaled down by 2.4%, further confusing the issue. While we're talking about halign and I have the images handy, there's a difference that I'm pretty sure is that 2.4% scaling effect. Consider these images of the top-left corner of a left-aligned W and the top-right corner of a right-aligned W: --- With respect to RTL: the big question there is whether the effect should be to mirror the LTR behavior, or if it should be roughly as if the order of the characters was reversed. Spacing introduces a relevant asymmetry, which is (I think) what you're describing: in LTR, there's "extra" space on the right; in RTL should that "extra" space remain on the right or move to the left? (Mostly I think the answer is that it doesn't matter, because the "extra" space is wrong no matter where you put it.) Another relevant asymmetry can come from font design: for instance, the "a" in Freestyle Script protrudes to the left of its nominal box, but has space to its right in the box. With halign=left, it protrudes slightly left of the Y axis; with halign=right there is space between the Y axis and the ink. What should happen in RTL? Should that asymmetry be mirrored? Current behavior is that the spacing is *not* mirrored; an RTL presentation of a single letter appears to be exactly the same as the LTR presentation of that letter, no matter how it's aligned. BTW, the reversal associated with RTL happens before ligature processing, so you don't end up with silliness when you lay out a word like "Official". If it was just reordering the glyphs, that would end up as "l a i c ffi O", and that would be silly. Instead, it ends up as "l a i c i ff O". Ligature processing is still done, so "different" rendered RTL is rendered as "t n e r e ffi d", with the reversed "iff" being rendered as an "ffi" ligature. (In fonts with ligature support. I'm using Calibri for most of those tests.) --- With respect to TTB/BTT: I think the issues there are basically similar to the LTR/RTL issues, with the added confusion of the other problems with TTB/BTT. --- [ And back to the original message for the bottom line... ] I raise it here as it seems to be bounding box (BB) related, it would be interesting to know what the textmetrics produce. Indeed. As the old joke <https://sites.google.com/site/funnyenglishjokes/work-jokes/accountant-statistician-mathematician-j oke> goes, what do you want it to produce? I have been thinking about it more in the context of the 2.4% scaling mismatch, but there is a question of what textmetrics() should return: should it return values that are compatible with existing OpenSCAD behavior, or should it return values that match the font design and ink placement? Matching OpenSCAD behavior lets you better understand what halign and valign are doing. Matching the font design lets you do things that are perhaps artistically correct. Matching the actual ink placement lets you control *exactly* where the ink goes. Part of that is easy: it should report both the font design metrics and the ink placement. Beyond that, perhaps it should additionally report what OpenSCAD does. As an example of the difference, in the M example above what is the width of the string? Is it eight (the width of the ink), ten (the width of the character box), or twenty (the value OpenSCAD uses for alignment)? Or maybe we should (optionally?) break backward compatibility and try to iron out these issues as much as is possible, so as to have a future that is as consistent and correct as possible. (I am not optimistic about fixing all of the "spacing" issues. Some of them are too hard.) BTW, setting spacing=1024/1000 should cancel out the 2.4% scaling mismatch, at least with respect to horizontal alignment. -- This email has been checked for viruses by AVG. https://www.avg.com