Discussion:
[cairo] Patch to allow Cairo-based software to print to laser cutters on Windows
Rick Yorgason
2018-10-18 02:12:23 UTC
Permalink
Hi there,

The current version of Cairo has problems with laser cutters (and maybe
some other CNC machines) on Windows because it prints all strokes with
PS_GEOMETRIC, and these devices expect hairline-width strokes (anything
<= the device's minimum unit size) to be drawn with a PS_COSMETIC pen.
Otherwise, it etches the material instead of cutting it.

With this patch, I can use Inkscape to set my stroke width to 0.001" and
it will cut through the material as expected.

This approach is standard across other Windows programs, like Corel or
Acrobat. Up until now, the workaround in Inkscape has been to export as
a PDF and then print it with Acrobat, which correctly uses PS_COSMETIC
for hairline strokes.

This patch should produce prints that look nearly identical to the old
approach. Any stroke which is larger than 1 unit will be printed with
the PS_GEOMETRIC pen, as always, and any stroke with a unit size of 0
will also be "printed" with a PS_GEOMETRIC pen, as always. (I don't know
if there's any value to printing zero-width strokes at all, but I didn't
want to assume that no applications exist which rely on that behaviour.)
Previously, anything between 0 and 1 would get rounded to one of those
values, and either get printed at the minimum size, or not at all. This
codifies that anything between the two will get drawn as a PS_COSMETIC
pen, which is only valid when printing 1 device unit thick.

Tested on an Epilog Fusion and an Epilog Zing.

Let me know if you have any questions!

-Rick-
Carl Worth
2018-10-18 16:10:07 UTC
Permalink
Post by Rick Yorgason
With this patch, I can use Inkscape to set my stroke width to 0.001" and
it will cut through the material as expected.
If we're going to have a magic value here, I think I'd be much happier
to have 0 be the magic value.

(I know that your code isn't actually making 0.001" be magic, but a
whole range of values. I think I would really prefer to have that range
include rather then exclude 0.0.)

Does anyone see any reason why a stroke width of 0 shouldn't be treated
this way?

I think that would make a much better way to be able to document
this. ("Use a value of 0 to get a PS_COSMETIC pen which is useful when
targeting devices such as laser cutters".)

And speaking of documentation, it seems this patch should also be
touching up the documentation, such as in cairo_set_line_width?

I know the code is specific to the Windows backend, but I think it's
reasonable to put a backend-specific note into the general documentation
in a case like this.

-Carl
Bill Spitzak
2018-10-18 17:43:17 UTC
Permalink
I would very much like to see line width of 0.0 mean "device dependent
hairline" and requested it several times, but I believe this idea was
rejected. Not sure if it should be implemented only for this one device.
Post by Carl Worth
Post by Rick Yorgason
With this patch, I can use Inkscape to set my stroke width to 0.001" and
it will cut through the material as expected.
If we're going to have a magic value here, I think I'd be much happier
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be magic, but a
whole range of values. I think I would really prefer to have that range
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't be treated
this way?
I think that would make a much better way to be able to document
this. ("Use a value of 0 to get a PS_COSMETIC pen which is useful when
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should also be
touching up the documentation, such as in cairo_set_line_width?
I know the code is specific to the Windows backend, but I think it's
reasonable to put a backend-specific note into the general documentation
in a case like this.
-Carl
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Rick Yorgason
2018-10-18 18:11:17 UTC
Permalink
Including zero-width strokes makes sense to me. After all, true hairlines are supposed to act as though they're zero-width.

The reason I implemented it this way it's because I was worried about two use cases:

1) Some applications might rely on zero-width lines being invisible. (Imagine an artist who selects all the lines he wants to hide and changes their line width to zero.)

2) Maybe some CNC machines rely on zero-width lines? PS_COSMETIC lines are always 1 unit wide, so there would be no way to send zero-width lines to the printer any more. This seems unlikely to be a problem, but it's possible.

(1) can be fixed by the calling application, and (2) isn't likely a real problem, and if we include zero-width strokes it would make it easier for developers to make true zero-width hairlines (since they don't need to know the target device's minimum unit size), so I'm down for it.

-Rick-
Post by Carl Worth
Post by Rick Yorgason
With this patch, I can use Inkscape to set my stroke width to 0.001"
and
Post by Rick Yorgason
it will cut through the material as expected.
If we're going to have a magic value here, I think I'd be much happier
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be magic, but a
whole range of values. I think I would really prefer to have that range
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't be treated
this way?
I think that would make a much better way to be able to document
this. ("Use a value of 0 to get a PS_COSMETIC pen which is useful when
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should also be
touching up the documentation, such as in cairo_set_line_width?
I know the code is specific to the Windows backend, but I think it's
reasonable to put a backend-specific note into the general
documentation
in a case like this.
-Carl
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Bill Spitzak
2018-10-18 19:09:47 UTC
Permalink
I suspect there is code in Cairo that assumes zero-width strokes are
invisible, so it may be difficult to fix it for only this device.

The main reason for using zero rather than any other number is that it
survives scaling, which is pretty important for a magic value.
Post by Rick Yorgason
Including zero-width strokes makes sense to me. After all, true hairlines
are supposed to act as though they're zero-width.
1) Some applications might rely on zero-width lines being invisible.
(Imagine an artist who selects all the lines he wants to hide and changes
their line width to zero.)
2) Maybe some CNC machines rely on zero-width lines? PS_COSMETIC lines are
always 1 unit wide, so there would be no way to send zero-width lines to
the printer any more. This seems unlikely to be a problem, but it's
possible.
(1) can be fixed by the calling application, and (2) isn't likely a real
problem, and if we include zero-width strokes it would make it easier for
developers to make true zero-width hairlines (since they don't need to know
the target device's minimum unit size), so I'm down for it.
-Rick-
Post by Carl Worth
Post by Rick Yorgason
With this patch, I can use Inkscape to set my stroke width to 0.001" and
it will cut through the material as expected.
If we're going to have a magic value here, I think I'd be much happier
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be magic, but a
whole range of values. I think I would really prefer to have that range
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't be treated
this way?
I think that would make a much better way to be able to document
this. ("Use a value of 0 to get a PS_COSMETIC pen which is useful when
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should also be
touching up the documentation, such as in cairo_set_line_width?
I know the code is specific to the Windows backend, but I think it's
reasonable to put a backend-specific note into the general documentation
in a case like this.
-Carl
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Rick Yorgason
2018-10-18 21:02:47 UTC
Permalink
Sure enough, Cairo seems to be culling zero-width lines somewhere, so it
doesn't matter whether or not I check for zero here.

For now, I propose that I get rid of the zero-check in my patch, so
anything <= 1 device unit is drawn with a PS_COSMETIC pen. This value
gets rounded to an integer, so this approach is consistent with the
definition of a hairline being the smallest thing a printer can print.

In the long run, it would be nice to track down where Cairo is culling
zero-width lines and allow them through, as I believe postscript and pdf
both treat zero-width lines as hairlines.

-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width strokes are
invisible, so it may be difficult to fix it for only this device.
The main reason for using zero rather than any other number is that it
survives scaling, which is pretty important for a magic value.
Including zero-width strokes makes sense to me. After all, true
hairlines are supposed to act as though they're zero-width.
The reason I implemented it this way it's because I was worried
1) Some applications might rely on zero-width lines being
invisible. (Imagine an artist who selects all the lines he wants
to hide and changes their line width to zero.)
2) Maybe some CNC machines rely on zero-width lines? PS_COSMETIC
lines are always 1 unit wide, so there would be no way to send
zero-width lines to the printer any more. This seems unlikely to
be a problem, but it's possible.
(1) can be fixed by the calling application, and (2) isn't likely
a real problem, and if we include zero-width strokes it would make
it easier for developers to make true zero-width hairlines (since
they don't need to know the target device's minimum unit size), so
I'm down for it.
-Rick-
With this patch, I can use Inkscape to set my stroke width
to 0.001" and it will cut through the material as expected.
If we're going to have a magic value here, I think I'd be much happier
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be magic, but a
whole range of values. I think I would really prefer to have that range
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't be treated
this way?
I think that would make a much better way to be able to document
this. ("Use a value of 0 to get a PS_COSMETIC pen which is useful when
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should also be
touching up the documentation, such as in cairo_set_line_width?
I know the code is specific to the Windows backend, but I think it's
reasonable to put a backend-specific note into the general documentation
in a case like this.
-Carl
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Adrian Johnson
2018-10-19 07:56:55 UTC
Permalink
There were some patches to fix the culling on narrow lines on vector
surfaces:

https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109

https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b

Those patches should allow zero width lines. I'm not sure what else
could be preventing zero width lines from getting through to the win32
print surface.

You code that sets the cosmetic flag is not checking the line width in
device units. The StrokePath() is called in user coordinates so that the
line width will be in user coordinates. The reason emitting the path in
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth

To check if the line width is < 1 device unit you would need to do
something line in the second commit above to find the line width in user
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines somewhere, so it
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in my patch, so
anything <= 1 device unit is drawn with a PS_COSMETIC pen. This value
gets rounded to an integer, so this approach is consistent with the
definition of a hairline being the smallest thing a printer can print.
In the long run, it would be nice to track down where Cairo is culling
zero-width lines and allow them through, as I believe postscript and pdf
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width strokes are
invisible, so it may be difficult to fix it for only this device.
The main reason for using zero rather than any other number is that it
survives scaling, which is pretty important for a magic value.
Including zero-width strokes makes sense to me. After all, true
hairlines are supposed to act as though they're zero-width.
The reason I implemented it this way it's because I was worried
1) Some applications might rely on zero-width lines being
invisible. (Imagine an artist who selects all the lines he wants
to hide and changes their line width to zero.)
2) Maybe some CNC machines rely on zero-width lines? PS_COSMETIC
lines are always 1 unit wide, so there would be no way to send
zero-width lines to the printer any more. This seems unlikely to
be a problem, but it's possible.
(1) can be fixed by the calling application, and (2) isn't likely
a real problem, and if we include zero-width strokes it would make
it easier for developers to make true zero-width hairlines (since
they don't need to know the target device's minimum unit size), so
I'm down for it.
-Rick-
With this patch, I can use Inkscape to set my stroke width
to 0.001" and it will cut through the material as expected.
If we're going to have a magic value here, I think I'd be much happier
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be magic, but a
whole range of values. I think I would really prefer to have that range
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't be treated
this way?
I think that would make a much better way to be able to document
this. ("Use a value of 0 to get a PS_COSMETIC pen which is useful when
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should also be
touching up the documentation, such as in cairo_set_line_width?
I know the code is specific to the Windows backend, but I think it's
reasonable to put a backend-specific note into the general documentation
in a case like this.
-Carl
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
***@cairographics.org
https://lists.cairo
Rick Yorgason
2018-10-19 13:19:29 UTC
Permalink
It looks like you're right about the device units. In cases where the
canvas DPI is lower than the device DPI, the "smallest printable line"
is 1, as in my original patch (because ExtCreatePen only accepts
integral pen widths), but when the canvas DPI is higher, the "smallest
printable line" is
`_cairo_matrix_transformed_circle_major_axis(stroke_ctm_inverse, 1.0)`.

I haven't looked any further into what's culling zero-width lines yet.
For now, I'm focusing on the "use PS_COSMETIC for smallest printable
lines" patch, which I believe should be separate from the "allow
printing zero-width lines" patch.

Tomorrow I'll post a new patch based on the feedback I've received so far.

-Rick-
Post by Adrian Johnson
There were some patches to fix the culling on narrow lines on vector
https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109
https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b
Those patches should allow zero width lines. I'm not sure what else
could be preventing zero width lines from getting through to the win32
print surface.
You code that sets the cosmetic flag is not checking the line width in
device units. The StrokePath() is called in user coordinates so that the
line width will be in user coordinates. The reason emitting the path in
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth
To check if the line width is < 1 device unit you would need to do
something line in the second commit above to find the line width in user
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines somewhere, so it
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in my patch, so
anything <= 1 device unit is drawn with a PS_COSMETIC pen. This value
gets rounded to an integer, so this approach is consistent with the
definition of a hairline being the smallest thing a printer can print.
In the long run, it would be nice to track down where Cairo is culling
zero-width lines and allow them through, as I believe postscript and pdf
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width strokes are
invisible, so it may be difficult to fix it for only this device.
The main reason for using zero rather than any other number is that it
survives scaling, which is pretty important for a magic value.
Including zero-width strokes makes sense to me. After all, true
hairlines are supposed to act as though they're zero-width.
The reason I implemented it this way it's because I was worried
1) Some applications might rely on zero-width lines being
invisible. (Imagine an artist who selects all the lines he wants
to hide and changes their line width to zero.)
2) Maybe some CNC machines rely on zero-width lines? PS_COSMETIC
lines are always 1 unit wide, so there would be no way to send
zero-width lines to the printer any more. This seems unlikely to
be a problem, but it's possible.
(1) can be fixed by the calling application, and (2) isn't likely
a real problem, and if we include zero-width strokes it would make
it easier for developers to make true zero-width hairlines (since
they don't need to know the target device's minimum unit size), so
I'm down for it.
-Rick-
With this patch, I can use Inkscape to set my stroke width
to 0.001" and it will cut through the material as expected.
If we're going to have a magic value here, I think I'd be much happier
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be magic, but a
whole range of values. I think I would really prefer to have that range
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't be treated
this way?
I think that would make a much better way to be able to document
this. ("Use a value of 0 to get a PS_COSMETIC pen which is useful when
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should also be
touching up the documentation, such as in cairo_set_line_width?
I know the code is specific to the Windows backend, but I think it's
reasonable to put a backend-specific note into the general documentation
in a case like this.
-Carl
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
***@cairographics.org
https://lists.cairographic
Bill Spitzak
2018-10-19 16:27:21 UTC
Permalink
Hairlines are not always 1 pixel wide. For Postscript setting the line
width to 0.0 gives you a hairline that seems to be about 1/150" which is
quite a few pixels on modern printers, and was > 1 even on the first Apple
Laserwriter.
Post by Rick Yorgason
It looks like you're right about the device units. In cases where the
canvas DPI is lower than the device DPI, the "smallest printable line"
is 1, as in my original patch (because ExtCreatePen only accepts
integral pen widths), but when the canvas DPI is higher, the "smallest
printable line" is
`_cairo_matrix_transformed_circle_major_axis(stroke_ctm_inverse, 1.0)`.
I haven't looked any further into what's culling zero-width lines yet.
For now, I'm focusing on the "use PS_COSMETIC for smallest printable
lines" patch, which I believe should be separate from the "allow
printing zero-width lines" patch.
Tomorrow I'll post a new patch based on the feedback I've received so far.
-Rick-
Post by Adrian Johnson
There were some patches to fix the culling on narrow lines on vector
https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109
https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b
Post by Adrian Johnson
Those patches should allow zero width lines. I'm not sure what else
could be preventing zero width lines from getting through to the win32
print surface.
You code that sets the cosmetic flag is not checking the line width in
device units. The StrokePath() is called in user coordinates so that the
line width will be in user coordinates. The reason emitting the path in
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth
To check if the line width is < 1 device unit you would need to do
something line in the second commit above to find the line width in user
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines somewhere, so it
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in my patch, so
anything <= 1 device unit is drawn with a PS_COSMETIC pen. This value
gets rounded to an integer, so this approach is consistent with the
definition of a hairline being the smallest thing a printer can print.
In the long run, it would be nice to track down where Cairo is culling
zero-width lines and allow them through, as I believe postscript and pdf
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width strokes are
invisible, so it may be difficult to fix it for only this device.
The main reason for using zero rather than any other number is that it
survives scaling, which is pretty important for a magic value.
Including zero-width strokes makes sense to me. After all, true
hairlines are supposed to act as though they're zero-width.
The reason I implemented it this way it's because I was worried
1) Some applications might rely on zero-width lines being
invisible. (Imagine an artist who selects all the lines he wants
to hide and changes their line width to zero.)
2) Maybe some CNC machines rely on zero-width lines? PS_COSMETIC
lines are always 1 unit wide, so there would be no way to send
zero-width lines to the printer any more. This seems unlikely to
be a problem, but it's possible.
(1) can be fixed by the calling application, and (2) isn't likely
a real problem, and if we include zero-width strokes it would make
it easier for developers to make true zero-width hairlines (since
they don't need to know the target device's minimum unit size), so
I'm down for it.
-Rick-
With this patch, I can use Inkscape to set my stroke width
to 0.001" and it will cut through the material as
expected.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
If we're going to have a magic value here, I think I'd be
much happier
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be magic,
but a
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
whole range of values. I think I would really prefer to have
that range
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't
be treated
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
this way?
I think that would make a much better way to be able to
document
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
this. ("Use a value of 0 to get a PS_COSMETIC pen which is
useful when
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should
also be
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
touching up the documentation, such as in
cairo_set_line_width?
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
I know the code is specific to the Windows backend, but I
think it's
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
reasonable to put a backend-specific note into the general
documentation
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
in a case like this.
-Carl
--
Sent from my Android device with K-9 Mail. Please excuse my
brevity.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Rick Yorgason
2018-10-19 19:12:07 UTC
Permalink
That shouldn't be. See page 675 of the Postscript Language Reference:
https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf
A line width of 0 is acceptable, and is interpreted as the thinnest
line that can be rendered at device resolution—1 device pixel wide.
However, some devices cannot reproduce 1-pixel lines, and on
high-resolution devices, they are nearly invisible.
-Rick-
Hairlines are not always 1 pixel wide. For Postscript setting the line
width to 0.0 gives you a hairline that seems to be about 1/150" which
is quite a few pixels on modern printers, and was > 1 even on the
first Apple Laserwriter.
It looks like you're right about the device units. In cases where the
canvas DPI is lower than the device DPI, the "smallest printable line"
is 1, as in my original patch (because ExtCreatePen only accepts
integral pen widths), but when the canvas DPI is higher, the "smallest
printable line" is
`_cairo_matrix_transformed_circle_major_axis(stroke_ctm_inverse, 1.0)`.
I haven't looked any further into what's culling zero-width lines yet.
For now, I'm focusing on the "use PS_COSMETIC for smallest printable
lines" patch, which I believe should be separate from the "allow
printing zero-width lines" patch.
Tomorrow I'll post a new patch based on the feedback I've received so far.
-Rick-
Post by Adrian Johnson
There were some patches to fix the culling on narrow lines on vector
https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109
https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b
Post by Adrian Johnson
Those patches should allow zero width lines. I'm not sure what else
could be preventing zero width lines from getting through to the
win32
Post by Adrian Johnson
print surface.
You code that sets the cosmetic flag is not checking the line
width in
Post by Adrian Johnson
device units. The StrokePath() is called in user coordinates so
that the
Post by Adrian Johnson
line width will be in user coordinates. The reason emitting the
path in
Post by Adrian Johnson
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth
To check if the line width is < 1 device unit you would need to do
something line in the second commit above to find the line width
in user
Post by Adrian Johnson
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines
somewhere, so it
Post by Adrian Johnson
Post by Rick Yorgason
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in my patch, so
anything <= 1 device unit is drawn with a PS_COSMETIC pen. This
value
Post by Adrian Johnson
Post by Rick Yorgason
gets rounded to an integer, so this approach is consistent with the
definition of a hairline being the smallest thing a printer can
print.
Post by Adrian Johnson
Post by Rick Yorgason
In the long run, it would be nice to track down where Cairo is
culling
Post by Adrian Johnson
Post by Rick Yorgason
zero-width lines and allow them through, as I believe
postscript and pdf
Post by Adrian Johnson
Post by Rick Yorgason
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width
strokes are
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
invisible, so it may be difficult to fix it for only this device.
The main reason for using zero rather than any other number is
that it
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
survives scaling, which is pretty important for a magic value.
On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason
      Including zero-width strokes makes sense to me. After
all, true
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      hairlines are supposed to act as though they're zero-width.
      The reason I implemented it this way it's because I was
worried
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      1) Some applications might rely on zero-width lines being
      invisible. (Imagine an artist who selects all the lines
he wants
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      to hide and changes their line width to zero.)
      2) Maybe some CNC machines rely on zero-width lines?
PS_COSMETIC
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      lines are always 1 unit wide, so there would be no way to
send
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      zero-width lines to the printer any more. This seems
unlikely to
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      be a problem, but it's possible.
      (1) can be fixed by the calling application, and (2)
isn't likely
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      a real problem, and if we include zero-width strokes it
would make
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      it easier for developers to make true zero-width
hairlines (since
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      they don't need to know the target device's minimum unit
size), so
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      I'm down for it.
      -Rick-
      On October 18, 2018 9:10:07 AM PDT, Carl Worth
              With this patch, I can use Inkscape to set my
stroke width
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
              to 0.001" and it will cut through the material as
expected.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          If we're going to have a magic value here, I think
I'd be much happier
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          to have 0 be the magic value.
          (I know that your code isn't actually making 0.001"
be magic, but a
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          whole range of values. I think I would really prefer
to have that range
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          include rather then exclude 0.0.)
          Does anyone see any reason why a stroke width of 0
shouldn't be treated
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this way?
          I think that would make a much better way to be able
to document
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this. ("Use a value of 0 to get a PS_COSMETIC pen
which is useful when
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          targeting devices such as laser cutters".)
          And speaking of documentation, it seems this patch
should also be
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          touching up the documentation, such as in
cairo_set_line_width?
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          I know the code is specific to the Windows backend,
but I think it's
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          reasonable to put a backend-specific note into the
general documentation
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          in a case like this.
          -Carl
      --
      Sent from my Android device with K-9 Mail. Please excuse
my brevity.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      --
      cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Rick Yorgason
2018-10-24 18:34:02 UTC
Permalink
Apologies for the delay. Here's the promised updated patch.

The difference is now it considers the minimum size of both the canvas
and the printer instead of just the canvas, zero-width strokes count as
hairlines (although Cairo still seems to be culling strokes from getting
to this function — that's a separate bug) and the documentation was
updated for clarity.

Cheers,

-Rick-
Post by Rick Yorgason
https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf
A line width of 0 is acceptable, and is interpreted as the thinnest
line that can be rendered at device resolution—1 device pixel wide.
However, some devices cannot reproduce 1-pixel lines, and on
high-resolution devices, they are nearly invisible.
-Rick-
Hairlines are not always 1 pixel wide. For Postscript setting the
line width to 0.0 gives you a hairline that seems to be about 1/150"
which is quite a few pixels on modern printers, and was > 1 even on
the first Apple Laserwriter.
It looks like you're right about the device units. In cases where the
canvas DPI is lower than the device DPI, the "smallest printable line"
is 1, as in my original patch (because ExtCreatePen only accepts
integral pen widths), but when the canvas DPI is higher, the "smallest
printable line" is
`_cairo_matrix_transformed_circle_major_axis(stroke_ctm_inverse, 1.0)`.
I haven't looked any further into what's culling zero-width lines yet.
For now, I'm focusing on the "use PS_COSMETIC for smallest printable
lines" patch, which I believe should be separate from the "allow
printing zero-width lines" patch.
Tomorrow I'll post a new patch based on the feedback I've
received so far.
-Rick-
Post by Adrian Johnson
There were some patches to fix the culling on narrow lines on
vector
https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109
https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b
Post by Adrian Johnson
Those patches should allow zero width lines. I'm not sure what else
could be preventing zero width lines from getting through to
the win32
Post by Adrian Johnson
print surface.
You code that sets the cosmetic flag is not checking the line
width in
Post by Adrian Johnson
device units. The StrokePath() is called in user coordinates so
that the
Post by Adrian Johnson
line width will be in user coordinates. The reason emitting the
path in
Post by Adrian Johnson
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth
To check if the line width is < 1 device unit you would need to do
something line in the second commit above to find the line
width in user
Post by Adrian Johnson
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines
somewhere, so it
Post by Adrian Johnson
Post by Rick Yorgason
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in my
patch, so
Post by Adrian Johnson
Post by Rick Yorgason
anything <= 1 device unit is drawn with a PS_COSMETIC pen.
This value
Post by Adrian Johnson
Post by Rick Yorgason
gets rounded to an integer, so this approach is consistent
with the
Post by Adrian Johnson
Post by Rick Yorgason
definition of a hairline being the smallest thing a printer
can print.
Post by Adrian Johnson
Post by Rick Yorgason
In the long run, it would be nice to track down where Cairo is
culling
Post by Adrian Johnson
Post by Rick Yorgason
zero-width lines and allow them through, as I believe
postscript and pdf
Post by Adrian Johnson
Post by Rick Yorgason
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width
strokes are
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
invisible, so it may be difficult to fix it for only this device.
The main reason for using zero rather than any other number
is that it
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
survives scaling, which is pretty important for a magic value.
On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason
      Including zero-width strokes makes sense to me. After
all, true
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      hairlines are supposed to act as though they're zero-width.
      The reason I implemented it this way it's because I was
worried
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      1) Some applications might rely on zero-width lines being
      invisible. (Imagine an artist who selects all the lines
he wants
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      to hide and changes their line width to zero.)
      2) Maybe some CNC machines rely on zero-width lines?
PS_COSMETIC
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      lines are always 1 unit wide, so there would be no way
to send
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      zero-width lines to the printer any more. This seems
unlikely to
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      be a problem, but it's possible.
      (1) can be fixed by the calling application, and (2)
isn't likely
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      a real problem, and if we include zero-width strokes it
would make
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      it easier for developers to make true zero-width
hairlines (since
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      they don't need to know the target device's minimum unit
size), so
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      I'm down for it.
      -Rick-
      On October 18, 2018 9:10:07 AM PDT, Carl Worth
              With this patch, I can use Inkscape to set my
stroke width
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
              to 0.001" and it will cut through the material
as expected.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          If we're going to have a magic value here, I think
I'd be much happier
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          to have 0 be the magic value.
          (I know that your code isn't actually making 0.001"
be magic, but a
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          whole range of values. I think I would really prefer
to have that range
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          include rather then exclude 0.0.)
          Does anyone see any reason why a stroke width of 0
shouldn't be treated
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this way?
          I think that would make a much better way to be able
to document
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this. ("Use a value of 0 to get a PS_COSMETIC pen
which is useful when
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          targeting devices such as laser cutters".)
          And speaking of documentation, it seems this patch
should also be
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          touching up the documentation, such as in
cairo_set_line_width?
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          I know the code is specific to the Windows backend,
but I think it's
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          reasonable to put a backend-specific note into the
general documentation
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          in a case like this.
          -Carl
      --
      Sent from my Android device with K-9 Mail. Please excuse
my brevity.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      --
      cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Bill Spitzak
2018-10-29 17:12:20 UTC
Permalink
Seems like it would be better to consistently use one device unit rather
than the maximum of one device unit and one unit in the CTM.

The zero stuff is a real pain but I suspect trying to fix this in Cairo
(and also support hairlines on other output devices) will be a lot of work.
Post by Rick Yorgason
Apologies for the delay. Here's the promised updated patch.
The difference is now it considers the minimum size of both the canvas and
the printer instead of just the canvas, zero-width strokes count as
hairlines (although Cairo still seems to be culling strokes from getting to
this function — that's a separate bug) and the documentation was updated
for clarity.
Cheers,
-Rick-
https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf
A line width of 0 is acceptable, and is interpreted as the thinnest line
that can be rendered at device resolution—1 device pixel wide. However,
some devices cannot reproduce 1-pixel lines, and on high-resolution
devices, they are nearly invisible.
-Rick-
Hairlines are not always 1 pixel wide. For Postscript setting the line
width to 0.0 gives you a hairline that seems to be about 1/150" which is
quite a few pixels on modern printers, and was > 1 even on the first Apple
Laserwriter.
Post by Rick Yorgason
It looks like you're right about the device units. In cases where the
canvas DPI is lower than the device DPI, the "smallest printable line"
is 1, as in my original patch (because ExtCreatePen only accepts
integral pen widths), but when the canvas DPI is higher, the "smallest
printable line" is
`_cairo_matrix_transformed_circle_major_axis(stroke_ctm_inverse, 1.0)`.
I haven't looked any further into what's culling zero-width lines yet.
For now, I'm focusing on the "use PS_COSMETIC for smallest printable
lines" patch, which I believe should be separate from the "allow
printing zero-width lines" patch.
Tomorrow I'll post a new patch based on the feedback I've received so far.
-Rick-
Post by Adrian Johnson
There were some patches to fix the culling on narrow lines on vector
https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109
https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b
Post by Adrian Johnson
Those patches should allow zero width lines. I'm not sure what else
could be preventing zero width lines from getting through to the win32
print surface.
You code that sets the cosmetic flag is not checking the line width in
device units. The StrokePath() is called in user coordinates so that the
line width will be in user coordinates. The reason emitting the path in
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth
To check if the line width is < 1 device unit you would need to do
something line in the second commit above to find the line width in user
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines somewhere, so
it
Post by Adrian Johnson
Post by Rick Yorgason
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in my patch, so
anything <= 1 device unit is drawn with a PS_COSMETIC pen. This value
gets rounded to an integer, so this approach is consistent with the
definition of a hairline being the smallest thing a printer can print.
In the long run, it would be nice to track down where Cairo is culling
zero-width lines and allow them through, as I believe postscript and
pdf
Post by Adrian Johnson
Post by Rick Yorgason
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width strokes are
invisible, so it may be difficult to fix it for only this device.
The main reason for using zero rather than any other number is that it
survives scaling, which is pretty important for a magic value.
Including zero-width strokes makes sense to me. After all, true
hairlines are supposed to act as though they're zero-width.
The reason I implemented it this way it's because I was worried
1) Some applications might rely on zero-width lines being
invisible. (Imagine an artist who selects all the lines he wants
to hide and changes their line width to zero.)
2) Maybe some CNC machines rely on zero-width lines? PS_COSMETIC
lines are always 1 unit wide, so there would be no way to send
zero-width lines to the printer any more. This seems unlikely to
be a problem, but it's possible.
(1) can be fixed by the calling application, and (2) isn't likely
a real problem, and if we include zero-width strokes it would
make
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
it easier for developers to make true zero-width hairlines (since
they don't need to know the target device's minimum unit size),
so
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
I'm down for it.
-Rick-
On October 18, 2018 9:10:07 AM PDT, Carl Worth <
With this patch, I can use Inkscape to set my stroke
width
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
to 0.001" and it will cut through the material as
expected.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
If we're going to have a magic value here, I think I'd be
much happier
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
to have 0 be the magic value.
(I know that your code isn't actually making 0.001" be
magic, but a
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
whole range of values. I think I would really prefer to have
that range
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
include rather then exclude 0.0.)
Does anyone see any reason why a stroke width of 0 shouldn't
be treated
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
this way?
I think that would make a much better way to be able to
document
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
this. ("Use a value of 0 to get a PS_COSMETIC pen which is
useful when
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
targeting devices such as laser cutters".)
And speaking of documentation, it seems this patch should
also be
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
touching up the documentation, such as in
cairo_set_line_width?
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
I know the code is specific to the Windows backend, but I
think it's
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
reasonable to put a backend-specific note into the general
documentation
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
in a case like this.
-Carl
--
Sent from my Android device with K-9 Mail. Please excuse my
brevity.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Rick Yorgason
2018-10-29 20:29:14 UTC
Permalink
I think it makes sense to do both, but if we're only going to have one
check, it should be the CTM, like i originally had.

If we only test the device unit, then we run into weird scenarios. Let's
say 1 device pixel is 0.3 CTM units. That means anything from [0-0.3]
units *will* draw as a hairline, but anything from (0.3-1) will get
rounded to 0 and won't draw at all. (Remember, ExtCreatePen takes the
pen width as an integer.) So 0.3 and 1.0 draw, but 0.5 doesn't.

-Rick-
Post by Bill Spitzak
Seems like it would be better to consistently use one device unit
rather than the maximum of one device unit and one unit in the CTM.
The zero stuff is a real pain but I suspect trying to fix this in
Cairo (and also support hairlines on other output devices) will be a
lot of work.
Apologies for the delay. Here's the promised updated patch.
The difference is now it considers the minimum size of both the
canvas and the printer instead of just the canvas, zero-width
strokes count as hairlines (although Cairo still seems to be
culling strokes from getting to this function — that's a separate
bug) and the documentation was updated for clarity.
Cheers,
-Rick-
Post by Rick Yorgason
https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf
A line width of 0 is acceptable, and is interpreted as the
thinnest line that can be rendered at device resolution—1 device
pixel wide. However, some devices cannot reproduce 1-pixel
lines, and on high-resolution devices, they are nearly invisible.
-Rick-
Hairlines are not always 1 pixel wide. For Postscript setting
the line width to 0.0 gives you a hairline that seems to be
about 1/150" which is quite a few pixels on modern printers, and
was > 1 even on the first Apple Laserwriter.
It looks like you're right about the device units. In cases where the
canvas DPI is lower than the device DPI, the "smallest printable line"
is 1, as in my original patch (because ExtCreatePen only accepts
integral pen widths), but when the canvas DPI is higher, the "smallest
printable line" is
`_cairo_matrix_transformed_circle_major_axis(stroke_ctm_inverse, 1.0)`.
I haven't looked any further into what's culling zero-width lines yet.
For now, I'm focusing on the "use PS_COSMETIC for smallest printable
lines" patch, which I believe should be separate from the "allow
printing zero-width lines" patch.
Tomorrow I'll post a new patch based on the feedback I've
received so far.
-Rick-
Post by Adrian Johnson
There were some patches to fix the culling on narrow lines
on vector
https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109
https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b
Post by Adrian Johnson
Those patches should allow zero width lines. I'm not sure
what else
Post by Adrian Johnson
could be preventing zero width lines from getting through
to the win32
Post by Adrian Johnson
print surface.
You code that sets the cosmetic flag is not checking the
line width in
Post by Adrian Johnson
device units. The StrokePath() is called in user
coordinates so that the
Post by Adrian Johnson
line width will be in user coordinates. The reason
emitting the path in
Post by Adrian Johnson
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth
To check if the line width is < 1 device unit you would
need to do
Post by Adrian Johnson
something line in the second commit above to find the line
width in user
Post by Adrian Johnson
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines
somewhere, so it
Post by Adrian Johnson
Post by Rick Yorgason
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in my
patch, so
Post by Adrian Johnson
Post by Rick Yorgason
anything <= 1 device unit is drawn with a PS_COSMETIC
pen. This value
Post by Adrian Johnson
Post by Rick Yorgason
gets rounded to an integer, so this approach is
consistent with the
Post by Adrian Johnson
Post by Rick Yorgason
definition of a hairline being the smallest thing a
printer can print.
Post by Adrian Johnson
Post by Rick Yorgason
In the long run, it would be nice to track down where
Cairo is culling
Post by Adrian Johnson
Post by Rick Yorgason
zero-width lines and allow them through, as I believe
postscript and pdf
Post by Adrian Johnson
Post by Rick Yorgason
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes zero-width
strokes are
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
invisible, so it may be difficult to fix it for only
this device.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
The main reason for using zero rather than any other
number is that it
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
survives scaling, which is pretty important for a magic
value.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason
      Including zero-width strokes makes sense to me.
After all, true
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      hairlines are supposed to act as though they're
zero-width.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      The reason I implemented it this way it's because I
was worried
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      1) Some applications might rely on zero-width lines
being
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      invisible. (Imagine an artist who selects all the
lines he wants
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      to hide and changes their line width to zero.)
      2) Maybe some CNC machines rely on zero-width
lines? PS_COSMETIC
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      lines are always 1 unit wide, so there would be no
way to send
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      zero-width lines to the printer any more. This
seems unlikely to
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      be a problem, but it's possible.
      (1) can be fixed by the calling application, and
(2) isn't likely
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      a real problem, and if we include zero-width
strokes it would make
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      it easier for developers to make true zero-width
hairlines (since
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      they don't need to know the target device's minimum
unit size), so
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      I'm down for it.
      -Rick-
      On October 18, 2018 9:10:07 AM PDT, Carl Worth
              With this patch, I can use Inkscape to set
my stroke width
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
              to 0.001" and it will cut through the
material as expected.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          If we're going to have a magic value here, I
think I'd be much happier
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          to have 0 be the magic value.
          (I know that your code isn't actually making
0.001" be magic, but a
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          whole range of values. I think I would really
prefer to have that range
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          include rather then exclude 0.0.)
          Does anyone see any reason why a stroke width
of 0 shouldn't be treated
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this way?
          I think that would make a much better way to be
able to document
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this. ("Use a value of 0 to get a PS_COSMETIC
pen which is useful when
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          targeting devices such as laser cutters".)
          And speaking of documentation, it seems this
patch should also be
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          touching up the documentation, such as in
cairo_set_line_width?
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          I know the code is specific to the Windows
backend, but I think it's
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          reasonable to put a backend-specific note into
the general documentation
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          in a case like this.
          -Carl
      --
      Sent from my Android device with K-9 Mail. Please
excuse my brevity.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      --
      cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Rick Yorgason
2018-11-05 05:41:32 UTC
Permalink
If it's helpful, I've created a gitlab branch here:
https://gitlab.freedesktop.org/Skrapion/cairo/commit/9c81cdd255cd2553ff99cf11e086f905d577e4a0

Thanks for the reviews! Let me know if you would prefer for this to be
based on just the CTM instead of both the CTM and device pixel.

-Rick-
Post by Rick Yorgason
I think it makes sense to do both, but if we're only going to have one
check, it should be the CTM, like i originally had.
If we only test the device unit, then we run into weird scenarios.
Let's say 1 device pixel is 0.3 CTM units. That means anything from
[0-0.3] units *will* draw as a hairline, but anything from (0.3-1)
will get rounded to 0 and won't draw at all. (Remember, ExtCreatePen
takes the pen width as an integer.) So 0.3 and 1.0 draw, but 0.5 doesn't.
-Rick-
Post by Bill Spitzak
Seems like it would be better to consistently use one device unit
rather than the maximum of one device unit and one unit in the CTM.
The zero stuff is a real pain but I suspect trying to fix this in
Cairo (and also support hairlines on other output devices) will be a
lot of work.
Apologies for the delay. Here's the promised updated patch.
The difference is now it considers the minimum size of both the
canvas and the printer instead of just the canvas, zero-width
strokes count as hairlines (although Cairo still seems to be
culling strokes from getting to this function — that's a separate
bug) and the documentation was updated for clarity.
Cheers,
-Rick-
Post by Rick Yorgason
https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf
A line width of 0 is acceptable, and is interpreted as the
thinnest line that can be rendered at device resolution—1
device pixel wide. However, some devices cannot reproduce
1-pixel lines, and on high-resolution devices, they are nearly
invisible.
-Rick-
Hairlines are not always 1 pixel wide. For Postscript setting
the line width to 0.0 gives you a hairline that seems to be
about 1/150" which is quite a few pixels on modern printers,
and was > 1 even on the first Apple Laserwriter.
On Fri, Oct 19, 2018 at 6:21 AM Rick Yorgason
It looks like you're right about the device units. In cases where the
canvas DPI is lower than the device DPI, the "smallest
printable line"
is 1, as in my original patch (because ExtCreatePen only accepts
integral pen widths), but when the canvas DPI is higher,
the "smallest
printable line" is
`_cairo_matrix_transformed_circle_major_axis(stroke_ctm_inverse,
1.0)`.
I haven't looked any further into what's culling zero-width
lines yet.
For now, I'm focusing on the "use PS_COSMETIC for smallest printable
lines" patch, which I believe should be separate from the "allow
printing zero-width lines" patch.
Tomorrow I'll post a new patch based on the feedback I've
received so far.
-Rick-
Post by Adrian Johnson
There were some patches to fix the culling on narrow
lines on vector
https://gitlab.freedesktop.org/cairo/cairo/commit/b1192beac7c5b56a8ff356d20af5ebfb65404109
https://gitlab.freedesktop.org/cairo/cairo/commit/bec8c7508ebc0f69266f9aebe9903539391c519b
Post by Adrian Johnson
Those patches should allow zero width lines. I'm not sure
what else
Post by Adrian Johnson
could be preventing zero width lines from getting through
to the win32
Post by Adrian Johnson
print surface.
You code that sets the cosmetic flag is not checking the
line width in
Post by Adrian Johnson
device units. The StrokePath() is called in user
coordinates so that the
Post by Adrian Johnson
line width will be in user coordinates. The reason
emitting the path in
Post by Adrian Johnson
device space and stroking in user space is demonstrated here
https://cairographics.org/tutorial/#L2linewidth
To check if the line width is < 1 device unit you would
need to do
Post by Adrian Johnson
something line in the second commit above to find the
line width in user
Post by Adrian Johnson
space.
Post by Rick Yorgason
Sure enough, Cairo seems to be culling zero-width lines
somewhere, so it
Post by Adrian Johnson
Post by Rick Yorgason
doesn't matter whether or not I check for zero here.
For now, I propose that I get rid of the zero-check in
my patch, so
Post by Adrian Johnson
Post by Rick Yorgason
anything <= 1 device unit is drawn with a PS_COSMETIC
pen. This value
Post by Adrian Johnson
Post by Rick Yorgason
gets rounded to an integer, so this approach is
consistent with the
Post by Adrian Johnson
Post by Rick Yorgason
definition of a hairline being the smallest thing a
printer can print.
Post by Adrian Johnson
Post by Rick Yorgason
In the long run, it would be nice to track down where
Cairo is culling
Post by Adrian Johnson
Post by Rick Yorgason
zero-width lines and allow them through, as I believe
postscript and pdf
Post by Adrian Johnson
Post by Rick Yorgason
both treat zero-width lines as hairlines.
-Rick-
Post by Bill Spitzak
I suspect there is code in Cairo that assumes
zero-width strokes are
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
invisible, so it may be difficult to fix it for only
this device.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
The main reason for using zero rather than any other
number is that it
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
survives scaling, which is pretty important for a magic
value.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason
      Including zero-width strokes makes sense to me.
After all, true
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      hairlines are supposed to act as though they're
zero-width.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      The reason I implemented it this way it's because
I was worried
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      1) Some applications might rely on zero-width
lines being
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      invisible. (Imagine an artist who selects all the
lines he wants
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      to hide and changes their line width to zero.)
      2) Maybe some CNC machines rely on zero-width
lines? PS_COSMETIC
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      lines are always 1 unit wide, so there would be no
way to send
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      zero-width lines to the printer any more. This
seems unlikely to
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      be a problem, but it's possible.
      (1) can be fixed by the calling application, and
(2) isn't likely
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      a real problem, and if we include zero-width
strokes it would make
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      it easier for developers to make true zero-width
hairlines (since
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      they don't need to know the target device's
minimum unit size), so
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      I'm down for it.
      -Rick-
      On October 18, 2018 9:10:07 AM PDT, Carl Worth
              With this patch, I can use Inkscape to set
my stroke width
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
              to 0.001" and it will cut through the
material as expected.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          If we're going to have a magic value here, I
think I'd be much happier
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          to have 0 be the magic value.
          (I know that your code isn't actually making
0.001" be magic, but a
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          whole range of values. I think I would really
prefer to have that range
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          include rather then exclude 0.0.)
          Does anyone see any reason why a stroke width
of 0 shouldn't be treated
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this way?
          I think that would make a much better way to
be able to document
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          this. ("Use a value of 0 to get a PS_COSMETIC
pen which is useful when
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          targeting devices such as laser cutters".)
          And speaking of documentation, it seems this
patch should also be
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          touching up the documentation, such as in
cairo_set_line_width?
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          I know the code is specific to the Windows
backend, but I think it's
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          reasonable to put a backend-specific note into
the general documentation
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
          in a case like this.
          -Carl
      --
      Sent from my Android device with K-9 Mail. Please
excuse my brevity.
Post by Adrian Johnson
Post by Rick Yorgason
Post by Bill Spitzak
      --
      cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
--
cairo mailing list
https://lists.cairographics.org/mailman/listinfo/cairo
Loading...