Patch to allow Cairo-based software to print to laser cutters on Windows

Submitted by Rick Yorgason on Oct. 18, 2018, 2:12 a.m.

Details

Message ID 479214d8-7d8e-9a3d-34b8-ff9f5314a7ce@firefang.com
State New
Headers show
Series "Patch to allow Cairo-based software to print to laser cutters on Windows" ( rev: 1 ) in Cairo

Not browsing as part of any series.

Commit Message

Rick Yorgason Oct. 18, 2018, 2:12 a.m.
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-

Patch hide | download patch | download mbox

--- D:/scratch/Cairo/cairo-1.15.14.orig/src/win32/cairo-win32-printing-surface.c	Wed Sep 19 13:02:10 2018
+++ D:/scratch/Cairo/cairo-1.15.14/src/win32/cairo-win32-printing-surface.c	Wed Oct 17 18:48:02 2018
@@ -1469,0 +1470 @@  _cairo_win32_printing_surface_stroke (void			*abst
+    cairo_bool_t cosmetic;
@@ -1523 +1524,10 @@  _cairo_win32_printing_surface_stroke (void			*abst
-    pen_style = PS_GEOMETRIC;
+    /* If (0 < line_width <= 1 printer unit), we should use PS_COSMETIC instead of PS_GEOMETRIC,
+       because that's what some CNC machines, like laser cutters, expect.
+       There might be some value to using PS_COSMETIC for zero-width lines as well (hairlines), but some
+       applications might be relying on drawing invisible zero-width lines, so we'll leave that use case as is.
+       We're still using geometric pens if we have dashes, because calculating dash lengths for cosmetic pens
+       requires them to be specified in device-specific "style units", and I can't find any documentation on
+       how to query that. */
+    cosmetic = scale * style->line_width > 0 && scale * style->line_width <= 1 && !style->num_dashes;
+
+    pen_style = cosmetic ? PS_COSMETIC : PS_GEOMETRIC;
@@ -1549,2 +1559,6 @@  _cairo_win32_printing_surface_stroke (void			*abst
-    pen_style |= _cairo_win32_line_cap (style->line_cap);
-    pen_style |= _cairo_win32_line_join (style->line_join);
+    /* Only geometric pens accept cap/join styles, which is fine, because you can't see them at <= 1
+       printer unit anyway. */
+    if (!cosmetic) {
+        pen_style |= _cairo_win32_line_cap (style->line_cap);
+        pen_style |= _cairo_win32_line_join (style->line_join);
+    }
@@ -1552 +1566 @@  _cairo_win32_printing_surface_stroke (void			*abst
-		       scale * style->line_width,
+		       cosmetic ? 1 : scale * style->line_width,

Comments

On Wed, Oct 17 2018, Rick Yorgason wrote:
> 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
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.

On Thu, Oct 18, 2018 at 9:18 AM Carl Worth <cworth@cworth.org> wrote:

> On Wed, Oct 17 2018, Rick Yorgason wrote:
> > 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
> cairo@cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo
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-

On October 18, 2018 9:10:07 AM PDT, Carl Worth <cworth@cworth.org> wrote:
>On Wed, Oct 17 2018, Rick Yorgason wrote:
>> 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
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.

On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason <rick@firefang.com> wrote:

> 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-
>
> On October 18, 2018 9:10:07 AM PDT, Carl Worth <cworth@cworth.org> wrote:
>>
>> On Wed, Oct 17 2018, Rick Yorgason wrote:
>>
>>> 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
> cairo@cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo
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-


On 2018-10-18 12:09, Bill Spitzak wrote:
> 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.
>
> On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason <rick@firefang.com 
> <mailto:rick@firefang.com>> wrote:
>
>     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-
>
>     On October 18, 2018 9:10:07 AM PDT, Carl Worth <cworth@cworth.org
>     <mailto:cworth@cworth.org>> wrote:
>
>         On Wed, Oct 17 2018, Rick Yorgason wrote:
>
>             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
>     cairo@cairographics.org <mailto:cairo@cairographics.org>
>     https://lists.cairographics.org/mailman/listinfo/cairo
>
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.


On 19/10/18 07:32, Rick Yorgason wrote:
> 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-
> 
> 
> On 2018-10-18 12:09, Bill Spitzak wrote:
>> 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.
>>
>> On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason <rick@firefang.com
>> <mailto:rick@firefang.com>> wrote:
>>
>>     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-
>>
>>     On October 18, 2018 9:10:07 AM PDT, Carl Worth <cworth@cworth.org
>>     <mailto:cworth@cworth.org>> wrote:
>>
>>         On Wed, Oct 17 2018, Rick Yorgason wrote:
>>
>>             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
>>     cairo@cairographics.org <mailto:cairo@cairographics.org>
>>     https://lists.cairographics.org/mailman/listinfo/cairo
>>
> 
> 
>
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-


On 2018-10-19 00:56, Adrian Johnson wrote:
> 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.
>
>
> On 19/10/18 07:32, Rick Yorgason wrote:
>> 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-
>>
>>
>> On 2018-10-18 12:09, Bill Spitzak wrote:
>>> 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.
>>>
>>> On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason <rick@firefang.com
>>> <mailto:rick@firefang.com>> wrote:
>>>
>>>      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-
>>>
>>>      On October 18, 2018 9:10:07 AM PDT, Carl Worth <cworth@cworth.org
>>>      <mailto:cworth@cworth.org>> wrote:
>>>
>>>          On Wed, Oct 17 2018, Rick Yorgason wrote:
>>>
>>>              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
>>>      cairo@cairographics.org <mailto:cairo@cairographics.org>
>>>      https://lists.cairographics.org/mailman/listinfo/cairo
>>>
>>
>>
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 <rick@firefang.com> wrote:

> 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-
>
>
> On 2018-10-19 00:56, Adrian Johnson wrote:
> > 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.
> >
> >
> > On 19/10/18 07:32, Rick Yorgason wrote:
> >> 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-
> >>
> >>
> >> On 2018-10-18 12:09, Bill Spitzak wrote:
> >>> 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.
> >>>
> >>> On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason <rick@firefang.com
> >>> <mailto:rick@firefang.com>> wrote:
> >>>
> >>>      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-
> >>>
> >>>      On October 18, 2018 9:10:07 AM PDT, Carl Worth <cworth@cworth.org
> >>>      <mailto:cworth@cworth.org>> wrote:
> >>>
> >>>          On Wed, Oct 17 2018, Rick Yorgason wrote:
> >>>
> >>>              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
> >>>      cairo@cairographics.org <mailto:cairo@cairographics.org>
> >>>      https://lists.cairographics.org/mailman/listinfo/cairo
> >>>
> >>
> >>
>
> --
> cairo mailing list
> cairo@cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo
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-


On 2018-10-19 09:27, Bill Spitzak wrote:
> 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 <rick@firefang.com 
> <mailto:rick@firefang.com>> wrote:
>
>     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-
>
>
>     On 2018-10-19 00:56, Adrian Johnson wrote:
>     > 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.
>     >
>     >
>     > On 19/10/18 07:32, Rick Yorgason wrote:
>     >> 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-
>     >>
>     >>
>     >> On 2018-10-18 12:09, Bill Spitzak wrote:
>     >>> 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.
>     >>>
>     >>> On Thu, Oct 18, 2018 at 11:12 AM Rick Yorgason
>     <rick@firefang.com <mailto:rick@firefang.com>
>     >>> <mailto:rick@firefang.com <mailto:rick@firefang.com>>> wrote:
>     >>>
>     >>>      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-
>     >>>
>     >>>      On October 18, 2018 9:10:07 AM PDT, Carl Worth
>     <cworth@cworth.org <mailto:cworth@cworth.org>
>     >>>      <mailto:cworth@cworth.org <mailto:cworth@cworth.org>>> wrote:
>     >>>
>     >>>          On Wed, Oct 17 2018, Rick Yorgason wrote:
>     >>>
>     >>>              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
>     >>> cairo@cairographics.org <mailto:cairo@cairographics.org>
>     <mailto:cairo@cairographics.org <mailto:cairo@cairographics.org>>
>     >>> https://lists.cairographics.org/mailman/listinfo/cairo
>     >>>
>     >>
>     >>
>
>     -- 
>     cairo mailing list
>     cairo@cairographics.org <mailto:cairo@cairographics.org>
>     https://lists.cairographics.org/mailman/listinfo/cairo
>