[cairo] Patch to allow Cairo-based software to print to laser cutters on Windows
Rick Yorgason
rick at firefang.com
Thu Oct 18 02:12:23 UTC 2018
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-
-------------- next part --------------
--- 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,
More information about the cairo
mailing list