discuss@lists.openscad.org

OpenSCAD general discussion

View all threads

textmetrics preview

JB
Jordan Brown
Sat, Jul 17, 2021 2:30 AM

I happened to need something simple and stupid - label plates to go on a
bunch of similar print jobs - and so threw together a small
customizer-friendly program to make them.  It takes advantage of my
soon-to-integrate (fingers crossed) text metrics functions to
automatically size the plate around the text.

Here's that program, a preview of what you can do with that function:

// Note this requires a textmetrics() capable OpenSCAD.
// Text to print
text = "Hello";
baseplate = true;
base_t = 0.3;
text_t = 0.3;

if (baseplate) {
    tm = textmetrics(text);
    translate(tm.position - [1,1]) cube(concat(tm.size + [2,2], base_t));
}
linear_extrude(height=text_t+(baseplate ? base_t : 0)) text(text);

and what that program defaults to producing:

I happened to need something simple and stupid - label plates to go on a bunch of similar print jobs - and so threw together a small customizer-friendly program to make them.  It takes advantage of my soon-to-integrate (fingers crossed) text metrics functions to automatically size the plate around the text. Here's that program, a preview of what you can do with that function: // Note this requires a textmetrics() capable OpenSCAD. // Text to print text = "Hello"; baseplate = true; base_t = 0.3; text_t = 0.3; if (baseplate) { tm = textmetrics(text); translate(tm.position - [1,1]) cube(concat(tm.size + [2,2], base_t)); } linear_extrude(height=text_t+(baseplate ? base_t : 0)) text(text); and what that program defaults to producing:
FH
Father Horton
Sat, Jul 17, 2021 2:32 AM

I'm really looking forward to this feature! It will let me take an ugly
hack out of my text-to-ellipse implementation.

On Fri, Jul 16, 2021 at 9:30 PM Jordan Brown openscad@jordan.maileater.net
wrote:

I happened to need something simple and stupid - label plates to go on a
bunch of similar print jobs - and so threw together a small
customizer-friendly program to make them.  It takes advantage of my
soon-to-integrate (fingers crossed) text metrics functions to automatically
size the plate around the text.

Here's that program, a preview of what you can do with that function:

// Note this requires a textmetrics() capable OpenSCAD.
// Text to print
text = "Hello";
baseplate = true;
base_t = 0.3;
text_t = 0.3;

if (baseplate) {
tm = textmetrics(text);
translate(tm.position - [1,1]) cube(concat(tm.size + [2,2], base_t));
}
linear_extrude(height=text_t+(baseplate ? base_t : 0)) text(text);

and what that program defaults to producing:


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I'm really looking forward to this feature! It will let me take an ugly hack out of my text-to-ellipse implementation. On Fri, Jul 16, 2021 at 9:30 PM Jordan Brown <openscad@jordan.maileater.net> wrote: > I happened to need something simple and stupid - label plates to go on a > bunch of similar print jobs - and so threw together a small > customizer-friendly program to make them. It takes advantage of my > soon-to-integrate (fingers crossed) text metrics functions to automatically > size the plate around the text. > > Here's that program, a preview of what you can do with that function: > > // Note this requires a textmetrics() capable OpenSCAD. > // Text to print > text = "Hello"; > baseplate = true; > base_t = 0.3; > text_t = 0.3; > > if (baseplate) { > tm = textmetrics(text); > translate(tm.position - [1,1]) cube(concat(tm.size + [2,2], base_t)); > } > linear_extrude(height=text_t+(baseplate ? base_t : 0)) text(text); > > and what that program defaults to producing: > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
I
info@hjcreations.nl
Sat, Jul 17, 2021 5:54 AM

Do you know this one https://www.thingiverse.com/thing:739573
There is a part of automatic plate around the text.

Father Horton schreef op 2021-07-17 04:32:

I'm really looking forward to this feature! It will let me take an
ugly hack out of my text-to-ellipse implementation.

On Fri, Jul 16, 2021 at 9:30 PM Jordan Brown
openscad@jordan.maileater.net wrote:

I happened to need something simple and stupid - label plates to go
on a bunch of similar print jobs - and so threw together a small
customizer-friendly program to make them.  It takes advantage of my
soon-to-integrate (fingers crossed) text metrics functions to
automatically size the plate around the text.

Here's that program, a preview of what you can do with that
function:

// Note this requires a textmetrics() capable OpenSCAD.
// Text to print
text = "Hello";
baseplate = true;
base_t = 0.3;
text_t = 0.3;

if (baseplate) {
tm = textmetrics(text);
translate(tm.position - [1,1]) cube(concat(tm.size + [2,2],
base_t));
}
linear_extrude(height=text_t+(baseplate ? base_t : 0)) text(text);

and what that program defaults to producing:


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Do you know this one https://www.thingiverse.com/thing:739573 There is a part of automatic plate around the text. Father Horton schreef op 2021-07-17 04:32: > I'm really looking forward to this feature! It will let me take an > ugly hack out of my text-to-ellipse implementation. > > On Fri, Jul 16, 2021 at 9:30 PM Jordan Brown > <openscad@jordan.maileater.net> wrote: > >> I happened to need something simple and stupid - label plates to go >> on a bunch of similar print jobs - and so threw together a small >> customizer-friendly program to make them. It takes advantage of my >> soon-to-integrate (fingers crossed) text metrics functions to >> automatically size the plate around the text. >> >> Here's that program, a preview of what you can do with that >> function: >> >>> // Note this requires a textmetrics() capable OpenSCAD. >>> // Text to print >>> text = "Hello"; >>> baseplate = true; >>> base_t = 0.3; >>> text_t = 0.3; >>> >>> if (baseplate) { >>> tm = textmetrics(text); >>> translate(tm.position - [1,1]) cube(concat(tm.size + [2,2], >>> base_t)); >>> } >>> linear_extrude(height=text_t+(baseplate ? base_t : 0)) text(text); >> >> and what that program defaults to producing: >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Sat, Jul 17, 2021 3:21 PM

On 7/16/2021 10:54 PM, info@hjcreations.nl wrote:

Do you know this one https://www.thingiverse.com/thing:739573
There is a part of automatic plate around the text.

Not in particular.

It uses some very clever hull, offset, and intersection tricks to
simulate some of the same effects.  Interestingly, it does not
actually know how large the text is!

As a tidbit about the trickery it has to go through, to generate this image:

it has to generate the "MM" text 18 times.

When I have a little more time, I'll see what it would be like if it
used textmetrics().

This is the basic trick that it uses to get a box that's the right width:

big = 1000;
height = 10;	// font size
s = "Hello";
intersection() {
    square([big, height]);
    hull() {
        translate([0,-big]) text(s);
        translate([0, big]) text(s);
    }
}

You can do additional variations on that by shifting the text left and
right to make a margin, and by doing an offset on the result to round
the corners of the box.

On 7/16/2021 10:54 PM, info@hjcreations.nl wrote: > Do you know this one https://www.thingiverse.com/thing:739573 > There is a part of automatic plate around the text. Not in particular. It uses some very clever hull, offset, and intersection tricks to simulate some of the same effects.  Interestingly, it does *not* actually know how large the text is! As a tidbit about the trickery it has to go through, to generate this image: it has to generate the "MM" text 18 times. When I have a little more time, I'll see what it would be like if it used textmetrics(). This is the basic trick that it uses to get a box that's the right width: big = 1000; height = 10; // font size s = "Hello"; intersection() { square([big, height]); hull() { translate([0,-big]) text(s); translate([0, big]) text(s); } } You can do additional variations on that by shifting the text left and right to make a margin, and by doing an offset on the result to round the corners of the box.
JB
Jordan Brown
Sat, Jul 17, 2021 3:29 PM

On 7/17/2021 8:21 AM, Jordan Brown wrote:

big = 1000;
height = 10; // font size
s = "Hello";
intersection() {
square([big, height]);
hull() {
translate([0,-big]) text(s);
translate([0, big]) text(s);
}
}

You can use a similar trick to "measure" the height, and then intersect
the two to get a precise bounding box.  (But note:  your program still
doesn't really know the dimensions.)

By way of contrast, with textmetrics() drawing a square that exactly
surrounds the text is

s = "Hello";
tm = textmetrics(s);
translate(tm.position) square(tm.size);

and since you've got the actual positions and dimensions you can do
other things with them.

On 7/17/2021 8:21 AM, Jordan Brown wrote: > big = 1000; > height = 10; // font size > s = "Hello"; > intersection() { > square([big, height]); > hull() { > translate([0,-big]) text(s); > translate([0, big]) text(s); > } > } You can use a similar trick to "measure" the height, and then intersect the two to get a precise bounding box.  (But note:  your program still doesn't really *know* the dimensions.) By way of contrast, with textmetrics() drawing a square that exactly surrounds the text is s = "Hello"; tm = textmetrics(s); translate(tm.position) square(tm.size); and since you've got the actual positions and dimensions you can do other things with them.
TP
Torsten Paul
Sat, Jul 17, 2021 3:56 PM

On 17.07.21 17:21, Jordan Brown wrote:

It uses some very clever hull, offset, and intersection tricks
to simulate some of the same effects.  Interestingly, it does
not actually know how large the text is!

A much simpler example based on the bounding box code shown on
the Tips&Tricks page:

https://cadhub.xyz/u/Torsten/name-plate/ide

While that's cool, the text- and font-metrics are much more
flexible and should allow for many additional use cases.

So big thanks to Jordan for working on this, and also fixing
a number of subtle issues in the current text() implementation.

As this is also bringing some additional extra feature which
may not be that obvious, the results of those calls are:

fm = fontmetrics(20, "Liberation Sans:style=Regular");
echo(fm);
// {
//  nominal = {
//    ascent = 25.1466;
//    descent = -5.8866;
//  };
//  max = {
//    ascent = 27.2218;
//    descent = -8.4228;
//  };
//  interline = 31.9418;
//  font = {
//    family = "Liberation Sans";
//    style = "Regular";
//  };
// }

tm = textmetrics("Hallo", 20, "Liberation Sans:style=Regular");
echo(tm);
// {
//  position = [2.2784, -0.2816];
//  size = [59.858, 20.416];
//  ascent = 20.1344;
//  descent = -0.2816;
//  offset = [0, 0];
//  advance = [63.3002, 0];
// }

So as example, I'll just use a snippet similar to what's been
posted earlier in this thread:

s = "Hello";
tm = textmetrics(s);
linear_extrude(2) text(s);
linear_extrude(1) translate(tm.position) square(tm.size);

As it will become much more difficult to change those result
structures later, please help by having a close look and give
feedback if there's anything that could be improved or should
be changed.

ciao,
Torsten.

On 17.07.21 17:21, Jordan Brown wrote: > It uses some very clever hull, offset, and intersection tricks > to simulate some of the same effects.  Interestingly, it does > *not* actually know how large the text is! A much simpler example based on the bounding box code shown on the Tips&Tricks page: https://cadhub.xyz/u/Torsten/name-plate/ide While that's cool, the text- and font-metrics are much more flexible and should allow for many additional use cases. So big thanks to Jordan for working on this, and also fixing a number of subtle issues in the current text() implementation. As this is also bringing some additional extra feature which may not be that obvious, the results of those calls are: fm = fontmetrics(20, "Liberation Sans:style=Regular"); echo(fm); // { // nominal = { // ascent = 25.1466; // descent = -5.8866; // }; // max = { // ascent = 27.2218; // descent = -8.4228; // }; // interline = 31.9418; // font = { // family = "Liberation Sans"; // style = "Regular"; // }; // } tm = textmetrics("Hallo", 20, "Liberation Sans:style=Regular"); echo(tm); // { // position = [2.2784, -0.2816]; // size = [59.858, 20.416]; // ascent = 20.1344; // descent = -0.2816; // offset = [0, 0]; // advance = [63.3002, 0]; // } So as example, I'll just use a snippet similar to what's been posted earlier in this thread: s = "Hello"; tm = textmetrics(s); linear_extrude(2) text(s); linear_extrude(1) translate(tm.position) square(tm.size); As it will become much more difficult to change those result structures later, please help by having a close look and give feedback if there's anything that could be improved or should be changed. ciao, Torsten.
DM
Douglas Miller
Sun, Jul 18, 2021 4:37 PM

I must be missing something here. When I try this code below, I get the
message

WARNING: Ignoring unknown function 'textmetrics', in file ./, line 2.

On 7/17/2021 11:29 AM, Jordan Brown wrote:

On 7/17/2021 8:21 AM, Jordan Brown wrote:

big = 1000;
height = 10; // font size
s = "Hello";
intersection() {
square([big, height]);
hull() {
translate([0,-big]) text(s);
translate([0, big]) text(s);
}
}

You can use a similar trick to "measure" the height, and then
intersect the two to get a precise bounding box.  (But note:  your
program still doesn't really know the dimensions.)

By way of contrast, with textmetrics() drawing a square that exactly
surrounds the text is

 s = "Hello";
 tm = textmetrics(s);
 translate(tm.position) square(tm.size);

and since you've got the actual positions and dimensions you can do
other things with them.

I must be missing something here. When I try this code below, I get the message WARNING: Ignoring unknown function 'textmetrics', in file ./, line 2. On 7/17/2021 11:29 AM, Jordan Brown wrote: > On 7/17/2021 8:21 AM, Jordan Brown wrote: >> big = 1000; >> height = 10; // font size >> s = "Hello"; >> intersection() { >> square([big, height]); >> hull() { >> translate([0,-big]) text(s); >> translate([0, big]) text(s); >> } >> } > You can use a similar trick to "measure" the height, and then > intersect the two to get a precise bounding box.  (But note:  your > program still doesn't really *know* the dimensions.) > > By way of contrast, with textmetrics() drawing a square that exactly > surrounds the text is > > s = "Hello"; > tm = textmetrics(s); > translate(tm.position) square(tm.size); > > and since you've got the actual positions and dimensions you can do > other things with them. >
JB
Jordan Brown
Sun, Jul 18, 2021 8:29 PM

On 7/18/2021 9:37 AM, Douglas Miller wrote:

I must be missing something here. When I try this code below, I get
the message

WARNING: Ignoring unknown function 'textmetrics', in file ./, line 2.

You are missing that textmetrics() is a not-yet integrated feature that
I'm working on; this is a preview of functionality that will soon
(fingers crossed) be available.

On 7/18/2021 9:37 AM, Douglas Miller wrote: > I must be missing something here. When I try this code below, I get > the message > > WARNING: Ignoring unknown function 'textmetrics', in file ./, line 2. You are missing that textmetrics() is a not-yet integrated feature that I'm working on; this is a preview of functionality that will soon (fingers crossed) be available.
TP
Torsten Paul
Sun, Jul 18, 2021 8:38 PM

On 18.07.21 22:29, Jordan Brown wrote:

On 7/18/2021 9:37 AM, Douglas Miller wrote:

I must be missing something here. When I try this code below, I get the message

WARNING: Ignoring unknown function 'textmetrics', in file ./, line 2.

You are missing that textmetrics() is a not-yet integrated feature
that I'm working on; this is a preview of functionality that will
soon (fingers crossed) be available.

On 18.07.21 22:29, Jordan Brown wrote: > On 7/18/2021 9:37 AM, Douglas Miller wrote: >> I must be missing something here. When I try this code below, I get the message >> >> WARNING: Ignoring unknown function 'textmetrics', in file ./, line 2. > > You are missing that textmetrics() is a not-yet integrated feature > that I'm working on; this is a preview of functionality that will > soon (fingers crossed) be available. In the meantime it's possible to try the feature via the automated builds for Windows and Linux. Linux AppImage (x86/64-bit) https://8305-1049088-gh.circle-artifacts.com/0/64-bit/OpenSCAD-2021.07.08.ai8305-_PR36842021.07.08.ai8305-x86_64.AppImage Windows (32-bit) https://8306-1049088-gh.circle-artifacts.com/0/32-bit/OpenSCAD-2021.07.08.ci8306-x86-32_PR3684.zip https://8306-1049088-gh.circle-artifacts.com/0/32-bit/OpenSCAD-2021.07.08.ci8306-x86-32_PR3684-Installer.exe Windows (64-bit) https://8304-1049088-gh.circle-artifacts.com/0/64-bit/OpenSCAD-2021.07.08.ci8304-x86-64_PR3684.zip https://8304-1049088-gh.circle-artifacts.com/0/64-bit/OpenSCAD-2021.07.08.ci8304-x86-64_PR3684-Installer.exe ciao, Torsten.
JB
Jordan Brown
Sun, Jul 18, 2021 8:42 PM

On 7/18/2021 1:38 PM, Torsten Paul wrote:

On 18.07.21 22:29, Jordan Brown wrote:

You are missing that textmetrics() is a not-yet integrated feature
that I'm working on; this is a preview of functionality that will
soon (fingers crossed) be available.

In the meantime it's possible to try the feature via the automated
builds for Windows and Linux.

Ah... I hadn't realized that the PR automated builds produced persistent
results that are publicly available.  (There's nothing wrong with that
and it's not really surprising; I just hadn't thought about it.)

If you grab those builds to play with the feature, note that it's an
"experimental" feature and you must enable it at Edit / Preferences /
Features.

On 7/18/2021 1:38 PM, Torsten Paul wrote: > On 18.07.21 22:29, Jordan Brown wrote: >> You are missing that textmetrics() is a not-yet integrated feature >> that I'm working on; this is a preview of functionality that will >> soon (fingers crossed) be available. > > In the meantime it's possible to try the feature via the automated > builds for Windows and Linux. > Ah... I hadn't realized that the PR automated builds produced persistent results that are publicly available.  (There's nothing wrong with that and it's not really surprising; I just hadn't thought about it.) If you grab those builds to play with the feature, note that it's an "experimental" feature and you must enable it at Edit / Preferences / Features.