From ecec0419f8e178d71e449b52acfdfe9ac03aed37 Mon Sep 17 00:00:00 2001 From: Rick Yorgason Date: Sun, 15 Aug 2021 06:58:54 +0000 Subject: [PATCH] Added hairline support to cairo --- src/cairo-backend-private.h | 2 + src/cairo-compositor.c | 66 +++++-- src/cairo-default-context.c | 18 ++ src/cairo-gstate-private.h | 6 + src/cairo-gstate.c | 30 ++- src/cairo-script-surface.c | 22 +++ src/cairo-stroke-style.c | 4 + src/cairo-svg-surface.c | 24 ++- src/cairo-types-private.h | 2 + src/cairo.c | 61 ++++++ src/cairo.h | 6 + src/cairoint.h | 2 + src/win32/cairo-win32-printing-surface.c | 10 +- test/Makefile.sources | 1 + test/hairline.c | 175 ++++++++++++++++++ test/meson.build | 1 + ...line-anisotropic-incorrect.image16.ref.png | Bin 0 -> 1773 bytes ...hairline-anisotropic-incorrect.pdf.ref.png | Bin 0 -> 1856 bytes ...rline-anisotropic-incorrect.quartz.ref.png | Bin 0 -> 1987 bytes .../hairline-anisotropic-incorrect.ref.png | Bin 0 -> 1942 bytes ...anisotropic-incorrect.svg11.argb32.ref.png | Bin 0 -> 2033 bytes ...-anisotropic-incorrect.svg11.rgb24.ref.png | Bin 0 -> 2007 bytes ...-anisotropic-incorrect.xcb-window&.ref.png | Bin 0 -> 1864 bytes ...e-anisotropic-incorrect.xcb-window.ref.png | Bin 0 -> 1864 bytes ...hairline-anisotropic-incorrect.xcb.ref.png | Bin 0 -> 1864 bytes ...-anisotropic-incorrect.xlib-window.ref.png | Bin 0 -> 1863 bytes ...airline-anisotropic-incorrect.xlib.ref.png | Bin 0 -> 1863 bytes .../hairline-anisotropic.image16.ref.png | Bin 0 -> 1814 bytes .../hairline-anisotropic.pdf.ref.png | Bin 0 -> 2056 bytes .../hairline-anisotropic.quartz.ref.png | Bin 0 -> 2081 bytes test/reference/hairline-anisotropic.ref.png | Bin 0 -> 2040 bytes .../hairline-anisotropic.xcb-window&.ref.png | Bin 0 -> 1981 bytes .../hairline-anisotropic.xcb-window.ref.png | Bin 0 -> 1981 bytes .../hairline-anisotropic.xcb.ref.png | Bin 0 -> 1981 bytes .../hairline-anisotropic.xlib-window.ref.png | Bin 0 -> 1950 bytes .../hairline-anisotropic.xlib.ref.png | Bin 0 -> 1950 bytes test/reference/hairline-big.image16.ref.png | Bin 0 -> 2047 bytes test/reference/hairline-big.pdf.ref.png | Bin 0 -> 2363 bytes test/reference/hairline-big.quartz.ref.png | Bin 0 -> 2356 bytes test/reference/hairline-big.ref.png | Bin 0 -> 2348 bytes .../hairline-big.xcb-window&.ref.png | Bin 0 -> 2309 bytes .../reference/hairline-big.xcb-window.ref.png | Bin 0 -> 2309 bytes test/reference/hairline-big.xcb.ref.png | Bin 0 -> 2309 bytes .../hairline-big.xlib-window.ref.png | Bin 0 -> 2287 bytes test/reference/hairline-big.xlib.ref.png | Bin 0 -> 2287 bytes .../reference/hairline-scaled.image16.ref.png | Bin 0 -> 1532 bytes test/reference/hairline-scaled.pdf.ref.png | Bin 0 -> 1747 bytes test/reference/hairline-scaled.quartz.ref.png | Bin 0 -> 1683 bytes test/reference/hairline-scaled.ref.png | Bin 0 -> 1720 bytes test/reference/hairline-scaled.svg11.ref.png | Bin 0 -> 1709 bytes .../hairline-scaled.xcb-window&.ref.png | Bin 0 -> 1641 bytes .../hairline-scaled.xcb-window.ref.png | Bin 0 -> 1641 bytes test/reference/hairline-scaled.xcb.ref.png | Bin 0 -> 1641 bytes .../hairline-scaled.xlib-window.ref.png | Bin 0 -> 1597 bytes test/reference/hairline-scaled.xlib.ref.png | Bin 0 -> 1597 bytes test/reference/hairline.image16.ref.png | Bin 0 -> 884 bytes test/reference/hairline.pdf.ref.png | Bin 0 -> 1014 bytes test/reference/hairline.quartz.ref.png | Bin 0 -> 968 bytes test/reference/hairline.ref.png | Bin 0 -> 995 bytes test/reference/hairline.svg11.ref.png | Bin 0 -> 988 bytes test/reference/hairline.xcb-window&.ref.png | Bin 0 -> 950 bytes test/reference/hairline.xcb-window.ref.png | Bin 0 -> 950 bytes test/reference/hairline.xcb.ref.png | Bin 0 -> 950 bytes test/reference/hairline.xlib-window.ref.png | Bin 0 -> 943 bytes test/reference/hairline.xlib.ref.png | Bin 0 -> 943 bytes util/cairo-script/cairo-script-operators.c | 22 +++ 66 files changed, 427 insertions(+), 25 deletions(-) create mode 100644 test/hairline.c create mode 100644 test/reference/hairline-anisotropic-incorrect.image16.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.pdf.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.quartz.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.svg11.argb32.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.svg11.rgb24.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.xcb-window&.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.xcb-window.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.xcb.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.xlib-window.ref.png create mode 100644 test/reference/hairline-anisotropic-incorrect.xlib.ref.png create mode 100644 test/reference/hairline-anisotropic.image16.ref.png create mode 100644 test/reference/hairline-anisotropic.pdf.ref.png create mode 100644 test/reference/hairline-anisotropic.quartz.ref.png create mode 100644 test/reference/hairline-anisotropic.ref.png create mode 100644 test/reference/hairline-anisotropic.xcb-window&.ref.png create mode 100644 test/reference/hairline-anisotropic.xcb-window.ref.png create mode 100644 test/reference/hairline-anisotropic.xcb.ref.png create mode 100644 test/reference/hairline-anisotropic.xlib-window.ref.png create mode 100644 test/reference/hairline-anisotropic.xlib.ref.png create mode 100644 test/reference/hairline-big.image16.ref.png create mode 100644 test/reference/hairline-big.pdf.ref.png create mode 100644 test/reference/hairline-big.quartz.ref.png create mode 100644 test/reference/hairline-big.ref.png create mode 100644 test/reference/hairline-big.xcb-window&.ref.png create mode 100644 test/reference/hairline-big.xcb-window.ref.png create mode 100644 test/reference/hairline-big.xcb.ref.png create mode 100644 test/reference/hairline-big.xlib-window.ref.png create mode 100644 test/reference/hairline-big.xlib.ref.png create mode 100644 test/reference/hairline-scaled.image16.ref.png create mode 100644 test/reference/hairline-scaled.pdf.ref.png create mode 100644 test/reference/hairline-scaled.quartz.ref.png create mode 100644 test/reference/hairline-scaled.ref.png create mode 100644 test/reference/hairline-scaled.svg11.ref.png create mode 100644 test/reference/hairline-scaled.xcb-window&.ref.png create mode 100644 test/reference/hairline-scaled.xcb-window.ref.png create mode 100644 test/reference/hairline-scaled.xcb.ref.png create mode 100644 test/reference/hairline-scaled.xlib-window.ref.png create mode 100644 test/reference/hairline-scaled.xlib.ref.png create mode 100644 test/reference/hairline.image16.ref.png create mode 100644 test/reference/hairline.pdf.ref.png create mode 100644 test/reference/hairline.quartz.ref.png create mode 100644 test/reference/hairline.ref.png create mode 100644 test/reference/hairline.svg11.ref.png create mode 100644 test/reference/hairline.xcb-window&.ref.png create mode 100644 test/reference/hairline.xcb-window.ref.png create mode 100644 test/reference/hairline.xcb.ref.png create mode 100644 test/reference/hairline.xlib-window.ref.png create mode 100644 test/reference/hairline.xlib.ref.png diff --git a/src/cairo-backend-private.h b/src/cairo-backend-private.h index 67607c12f..86689c795 100644 --- a/src/cairo-backend-private.h +++ b/src/cairo-backend-private.h @@ -68,6 +68,7 @@ struct _cairo_backend { cairo_status_t (*set_line_cap) (void *cr, cairo_line_cap_t line_cap); cairo_status_t (*set_line_join) (void *cr, cairo_line_join_t line_join); cairo_status_t (*set_line_width) (void *cr, double line_width); + cairo_status_t (*set_hairline) (void *cr, cairo_bool_t set_hairline); cairo_status_t (*set_miter_limit) (void *cr, double limit); cairo_status_t (*set_opacity) (void *cr, double opacity); cairo_status_t (*set_operator) (void *cr, cairo_operator_t op); @@ -79,6 +80,7 @@ struct _cairo_backend { cairo_line_cap_t (*get_line_cap) (void *cr); cairo_line_join_t (*get_line_join) (void *cr); double (*get_line_width) (void *cr); + cairo_bool_t (*get_hairline) (void *cr); double (*get_miter_limit) (void *cr); double (*get_opacity) (void *cr); cairo_operator_t (*get_operator) (void *cr); diff --git a/src/cairo-compositor.c b/src/cairo-compositor.c index b31413b99..2f49f7f20 100644 --- a/src/cairo-compositor.c +++ b/src/cairo-compositor.c @@ -122,18 +122,18 @@ _cairo_compositor_mask (const cairo_compositor_t *compositor, return status; } -cairo_int_status_t -_cairo_compositor_stroke (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) +static cairo_int_status_t +_cairo_compositor_stroke_impl (const cairo_compositor_t *compositor, + cairo_surface_t *surface, + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_path_fixed_t *path, + const cairo_stroke_style_t *style, + const cairo_matrix_t *ctm, + const cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias, + const cairo_clip_t *clip) { cairo_composite_rectangles_t extents; cairo_int_status_t status; @@ -175,6 +175,48 @@ _cairo_compositor_stroke (const cairo_compositor_t *compositor, return status; } +cairo_int_status_t +_cairo_compositor_stroke (const cairo_compositor_t *compositor, + cairo_surface_t *surface, + cairo_operator_t op, + const cairo_pattern_t *source, + const cairo_path_fixed_t *path, + const cairo_stroke_style_t *style, + const cairo_matrix_t *ctm, + const cairo_matrix_t *ctm_inverse, + double tolerance, + cairo_antialias_t antialias, + const cairo_clip_t *clip) +{ + if (!style->is_hairline) + return _cairo_compositor_stroke_impl (compositor, surface, + op, source, path, + style, ctm, ctm_inverse, + tolerance, antialias, clip); + else { + cairo_stroke_style_t hairline_style; + cairo_status_t status; + cairo_matrix_t identity; + + status = _cairo_stroke_style_init_copy (&hairline_style, style); + if (unlikely (status)) + return status; + + hairline_style.line_width = 1.0; + + cairo_matrix_init_identity (&identity); + + status = _cairo_compositor_stroke_impl (compositor, surface, + op, source, path, + &hairline_style, &identity, &identity, + tolerance, antialias, clip); + + _cairo_stroke_style_fini (&hairline_style); + + return status; + } +} + cairo_int_status_t _cairo_compositor_fill (const cairo_compositor_t *compositor, cairo_surface_t *surface, diff --git a/src/cairo-default-context.c b/src/cairo-default-context.c index d2c9cae10..567c5d4d5 100644 --- a/src/cairo-default-context.c +++ b/src/cairo-default-context.c @@ -403,6 +403,14 @@ _cairo_default_context_set_line_width (void *abstract_cr, return _cairo_gstate_set_line_width (cr->gstate, line_width); } +static cairo_status_t +_cairo_default_context_set_hairline (void *abstract_cr, cairo_bool_t set_hairline) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_set_hairline (cr->gstate, set_hairline); +} + static cairo_status_t _cairo_default_context_set_line_cap (void *abstract_cr, cairo_line_cap_t line_cap) @@ -477,6 +485,14 @@ _cairo_default_context_get_line_width (void *abstract_cr) return _cairo_gstate_get_line_width (cr->gstate); } +static cairo_bool_t +_cairo_default_context_get_hairline (void *abstract_cr) +{ + cairo_default_context_t *cr = abstract_cr; + + return _cairo_gstate_get_hairline (cr->gstate); +} + static cairo_line_cap_t _cairo_default_context_get_line_cap (void *abstract_cr) { @@ -1365,6 +1381,7 @@ static const cairo_backend_t _cairo_default_context_backend = { _cairo_default_context_set_line_cap, _cairo_default_context_set_line_join, _cairo_default_context_set_line_width, + _cairo_default_context_set_hairline, _cairo_default_context_set_miter_limit, _cairo_default_context_set_opacity, _cairo_default_context_set_operator, @@ -1375,6 +1392,7 @@ static const cairo_backend_t _cairo_default_context_backend = { _cairo_default_context_get_line_cap, _cairo_default_context_get_line_join, _cairo_default_context_get_line_width, + _cairo_default_context_get_hairline, _cairo_default_context_get_miter_limit, _cairo_default_context_get_opacity, _cairo_default_context_get_operator, diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index 198c66998..fe1556b03 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -139,6 +139,12 @@ _cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width); cairo_private double _cairo_gstate_get_line_width (cairo_gstate_t *gstate); +cairo_private cairo_status_t +_cairo_gstate_set_hairline (cairo_gstate_t *gstate, cairo_bool_t set_hairline); + +cairo_private cairo_bool_t +_cairo_gstate_get_hairline (cairo_gstate_t *gstate); + cairo_private cairo_status_t _cairo_gstate_set_line_cap (cairo_gstate_t *gstate, cairo_line_cap_t line_cap); diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 64060c4fc..a8c67e718 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -470,7 +470,10 @@ _cairo_gstate_get_fill_rule (cairo_gstate_t *gstate) cairo_status_t _cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width) { - gstate->stroke_style.line_width = width; + if (gstate->stroke_style.is_hairline) + gstate->stroke_style.pre_hairline_line_width = width; + else + gstate->stroke_style.line_width = width; return CAIRO_STATUS_SUCCESS; } @@ -481,6 +484,29 @@ _cairo_gstate_get_line_width (cairo_gstate_t *gstate) return gstate->stroke_style.line_width; } +cairo_status_t +_cairo_gstate_set_hairline (cairo_gstate_t *gstate, cairo_bool_t set_hairline) +{ + if (gstate->stroke_style.is_hairline != set_hairline) { + gstate->stroke_style.is_hairline = set_hairline; + + if (set_hairline) { + gstate->stroke_style.pre_hairline_line_width = gstate->stroke_style.line_width; + gstate->stroke_style.line_width = 0.0; + } else { + gstate->stroke_style.line_width = gstate->stroke_style.pre_hairline_line_width; + } + } + + return CAIRO_STATUS_SUCCESS; +} + +cairo_bool_t +_cairo_gstate_get_hairline (cairo_gstate_t *gstate) +{ + return gstate->stroke_style.is_hairline; +} + cairo_status_t _cairo_gstate_set_line_cap (cairo_gstate_t *gstate, cairo_line_cap_t line_cap) { @@ -1172,7 +1198,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) if (gstate->op == CAIRO_OPERATOR_DEST) return CAIRO_STATUS_SUCCESS; - if (gstate->stroke_style.line_width <= 0.0) + if (gstate->stroke_style.line_width <= 0.0 && !gstate->stroke_style.is_hairline) return CAIRO_STATUS_SUCCESS; if (_cairo_clip_is_all_clipped (gstate->clip)) diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c index 800db0780..9d6b954c1 100644 --- a/src/cairo-script-surface.c +++ b/src/cairo-script-surface.c @@ -708,6 +708,24 @@ _emit_line_width (cairo_script_surface_t *surface, return CAIRO_STATUS_SUCCESS; } +static cairo_status_t +_emit_hairline (cairo_script_surface_t *surface, cairo_bool_t set_hairline) +{ + assert (target_is_active (surface)); + + if (surface->cr.current_style.is_hairline == set_hairline) + { + return CAIRO_STATUS_SUCCESS; + } + + surface->cr.current_style.is_hairline = set_hairline; + + _cairo_output_stream_printf (to_context (surface)->stream, + "%d set-hairline\n", + set_hairline); + return CAIRO_STATUS_SUCCESS; +} + static cairo_status_t _emit_line_cap (cairo_script_surface_t *surface, cairo_line_cap_t line_cap) @@ -858,6 +876,10 @@ _emit_stroke_style (cairo_script_surface_t *surface, if (unlikely (status)) return status; + status = _emit_hairline (surface, style->is_hairline); + if (unlikely (status)) + return status; + status = _emit_dash (surface, style->dash, style->num_dashes, style->dash_offset, force); diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c index 9c373c333..856cb341b 100644 --- a/src/cairo-stroke-style.c +++ b/src/cairo-stroke-style.c @@ -49,6 +49,8 @@ _cairo_stroke_style_init (cairo_stroke_style_t *style) style->dash = NULL; style->num_dashes = 0; style->dash_offset = 0.0; + + style->is_hairline = FALSE; } cairo_status_t @@ -80,6 +82,8 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style, style->dash_offset = other->dash_offset; + style->is_hairline = other->is_hairline; + return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index 412b32aff..fb6081c48 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -2992,13 +2992,23 @@ _cairo_svg_surface_emit_stroke_style (cairo_svg_stream_t *output, ASSERT_NOT_REACHED; } - _cairo_svg_stream_printf (output, - " stroke-width=\"%f\"" - " stroke-linecap=\"%s\"" - " stroke-linejoin=\"%s\"", - stroke_style->line_width, - line_cap, - line_join); + if (stroke_style->is_hairline) { + _cairo_svg_stream_printf (output, + " stroke-width=\"1px\"" + " stroke-linecap=\"%s\"" + " stroke-linejoin=\"%s\"" + " style=\"vector-effect: non-scaling-stroke\"", + line_cap, + line_join); + } else { + _cairo_svg_stream_printf (output, + " stroke-width=\"%f\"" + " stroke-linecap=\"%s\"" + " stroke-linejoin=\"%s\"", + stroke_style->line_width, + line_cap, + line_join); + } status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE, parent_matrix); if (unlikely (status)) { diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index 0f46214ed..2ec2ce67b 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -376,6 +376,8 @@ typedef struct _cairo_stroke_style { double *dash; unsigned int num_dashes; double dash_offset; + cairo_bool_t is_hairline; + double pre_hairline_line_width; } cairo_stroke_style_t; typedef struct _cairo_format_masks { diff --git a/src/cairo.c b/src/cairo.c index b2bda657d..d141b56d2 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1184,6 +1184,47 @@ cairo_set_line_width (cairo_t *cr, double width) } slim_hidden_def (cairo_set_line_width); +/** + * cairo_set_hairline: + * @cr: a #cairo_t + * @set_hairline: whether or not to set hairline mode + * + * Sets lines within the cairo context to be hairlines. + * Hairlines are logically zero-width lines that are drawn at the + * thinnest renderable width possible in the current context. + * + * On surfaces with native hairline support, the native hairline + * functionality will be used. Surfaces that support hairlines include: + * - pdf/ps: Encoded as 0-width line. + * - win32_printing: Rendered with PS_COSMETIC pen. + * - svg: Encoded as 1px non-scaling-stroke. + * - script: Encoded with set-hairline function. + * + * Cairo will always render hairlines at 1 device unit wide, even if + * an anisotropic scaling was applied to the stroke width. In the wild, + * handling of this situation is not well-defined. Some PDF, PS, and SVG + * renderers match Cairo's output, but some very popular implementations + * (Acrobat, Chrome, rsvg) will scale the hairline unevenly. + * As such, best practice is to reset any anisotropic scaling before calling + * cairo_stroke(). See https://cairographics.org/cookbook/ellipses/ + * for an example. + * + * Since: 1.18 + **/ +void +cairo_set_hairline (cairo_t *cr, cairo_bool_t set_hairline) +{ + cairo_status_t status; + + if (unlikely (cr->status)) + return; + + status = cr->backend->set_hairline (cr, set_hairline); + if (unlikely (status)) + _cairo_set_error (cr, status); +} +slim_hidden_def (cairo_set_hairline); + /** * cairo_set_line_cap: * @cr: a cairo context @@ -4057,6 +4098,26 @@ cairo_get_line_width (cairo_t *cr) } slim_hidden_def (cairo_get_line_width); +/** + * cairo_get_hairline: + * @cr: a cairo context + * + * Returns whether or not hairline mode is set, as set by cairo_set_hairline(). + * + * Return value: whether hairline mode is set. + * + * Since: 1.18 + **/ +cairo_bool_t +cairo_get_hairline (cairo_t *cr) +{ + if (unlikely (cr->status)) + return FALSE; + + return cr->backend->get_hairline (cr); +} +slim_hidden_def (cairo_get_hairline); + /** * cairo_get_line_cap: * @cr: a cairo context diff --git a/src/cairo.h b/src/cairo.h index 96427b425..5ab47c112 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -765,6 +765,9 @@ cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule); cairo_public void cairo_set_line_width (cairo_t *cr, double width); +cairo_public void +cairo_set_hairline (cairo_t *cr, cairo_bool_t set_hairline); + /** * cairo_line_cap_t: * @CAIRO_LINE_CAP_BUTT: start(stop) the line exactly at the start(end) point (Since 1.0) @@ -1957,6 +1960,9 @@ cairo_get_fill_rule (cairo_t *cr); cairo_public double cairo_get_line_width (cairo_t *cr); +cairo_public cairo_bool_t +cairo_get_hairline (cairo_t *cr); + cairo_public cairo_line_cap_t cairo_get_line_cap (cairo_t *cr); diff --git a/src/cairoint.h b/src/cairoint.h index 64ed2aa4d..6affe5601 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1959,6 +1959,7 @@ slim_hidden_proto (cairo_font_options_status); slim_hidden_proto (cairo_format_stride_for_width); slim_hidden_proto (cairo_get_current_point); slim_hidden_proto (cairo_get_line_width); +slim_hidden_proto (cairo_get_hairline); slim_hidden_proto (cairo_get_matrix); slim_hidden_proto (cairo_get_scaled_font); slim_hidden_proto (cairo_get_target); @@ -2031,6 +2032,7 @@ slim_hidden_proto (cairo_set_font_size); slim_hidden_proto (cairo_set_line_cap); slim_hidden_proto (cairo_set_line_join); slim_hidden_proto (cairo_set_line_width); +slim_hidden_proto (cairo_set_hairline); slim_hidden_proto (cairo_set_matrix); slim_hidden_proto (cairo_set_operator); slim_hidden_proto (cairo_set_source); diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c index 094068c15..6e3636104 100644 --- a/src/win32/cairo-win32-printing-surface.c +++ b/src/win32/cairo-win32-printing-surface.c @@ -1520,7 +1520,7 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, cairo_matrix_multiply (&mat, stroke_ctm, &surface->ctm); _cairo_matrix_factor_out_scale (&mat, &scale); - pen_style = PS_GEOMETRIC; + pen_style = style->is_hairline ? PS_COSMETIC : PS_GEOMETRIC; dash_array = NULL; if (style->num_dashes) { pen_style |= PS_USERSTYLE; @@ -1546,10 +1546,12 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface, brush.lbStyle = BS_SOLID; brush.lbColor = color; brush.lbHatch = 0; - pen_style |= _cairo_win32_line_cap (style->line_cap); - pen_style |= _cairo_win32_line_join (style->line_join); + if (!style->is_hairline) { + pen_style |= _cairo_win32_line_cap (style->line_cap); + pen_style |= _cairo_win32_line_join (style->line_join); + } pen = ExtCreatePen(pen_style, - scale * style->line_width, + style->is_hairline ? 1 : scale * style->line_width, &brush, style->num_dashes, dash_array); diff --git a/test/Makefile.sources b/test/Makefile.sources index b887b054d..12b9790b1 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -162,6 +162,7 @@ test_sources = \ group-paint.c \ group-state.c \ group-unaligned.c \ + hairline.c \ half-coverage.c \ halo.c \ hatchings.c \ diff --git a/test/hairline.c b/test/hairline.c new file mode 100644 index 000000000..a14b944e3 --- /dev/null +++ b/test/hairline.c @@ -0,0 +1,175 @@ +#include "cairo-test.h" + +/** + * draw: + * @cr: a #cairo_t + * @width: Width of the test image + * @height: Height of the test image + * @scale_width: Percentage to scale the width + * @scale_height: Percentage to scale the height + * @fit_to_scale: Whether or not to adjust the image to fit in the scale parameters + * regardless of the scale parameters + * @correct_scale: Tests if the hairlines render correctly regardless of + * whether or not the scale is set "correctly", as per + * https://cairographics.org/cookbook/ellipses/ + */ +static cairo_test_status_t +draw (cairo_t *cr, int width, int height, double scale_width, double scale_height, cairo_bool_t fit_to_scale, cairo_bool_t correct_scale) +{ + cairo_matrix_t save_matrix; + double fit_width = fit_to_scale ? scale_width : 1.0; + double fit_height = fit_to_scale ? scale_height : 1.0; + double fit_max = MAX(fit_width, fit_height); + double dash[] = {3.0}; + + if (cairo_get_hairline (cr) == TRUE) { + return CAIRO_TEST_ERROR; + } + + /* Clear background */ + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_line_width (cr, 100.0); /* If everything is working right, this value should never get used */ + + /* Hairline sample */ + if (correct_scale) { + cairo_get_matrix (cr, &save_matrix); + } + cairo_scale (cr, scale_width, scale_height); + + cairo_set_hairline (cr, TRUE); + if (cairo_get_hairline (cr) == FALSE) { + return CAIRO_TEST_ERROR; + } + + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_move_to (cr, width/fit_width/2, 0); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_move_to (cr, 0, height/fit_height/2); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_move_to (cr, width/fit_width/4, 0); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_arc (cr, width/fit_width/2, height/fit_height/2, width/fit_max/4, M_PI*0.5, M_PI*1.0); + + if (correct_scale) { + cairo_set_matrix (cr, &save_matrix); + } + cairo_stroke (cr); + + /* Dashed sample */ + if (correct_scale) { + cairo_get_matrix (cr, &save_matrix); + cairo_scale (cr, scale_width, scale_height); + } + cairo_set_dash (cr, dash, 1, 0); + cairo_arc (cr, width/fit_width/2, height/fit_height/2, width/fit_max/4, M_PI*1.0, M_PI*1.5); + if (correct_scale) { + cairo_set_matrix (cr, &save_matrix); + } + cairo_stroke (cr); + + /* Control sample */ + if (correct_scale) { + cairo_get_matrix (cr, &save_matrix); + cairo_scale (cr, scale_width, scale_height); + } + + cairo_set_line_width (cr, 3.0); + cairo_set_hairline (cr, FALSE); + if (cairo_get_hairline (cr) == TRUE) { + return CAIRO_TEST_ERROR; + } + + cairo_set_dash (cr, 0, 0, 0); + + cairo_move_to (cr, width/fit_width, height/fit_height); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_move_to (cr, width/fit_width/2, height/fit_height); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_move_to (cr, width/fit_width, height/fit_height/2); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_move_to (cr, width/fit_width*0.75, height/fit_height); + cairo_line_to (cr, width/fit_width/2, height/fit_height/2); + cairo_arc (cr, width/fit_width/2, height/fit_height/2, width/fit_max/4, M_PI*1.5, M_PI*2.0); + + if (correct_scale) { + cairo_set_matrix (cr, &save_matrix); + } + cairo_stroke (cr); + + /* Dashed sample */ + if (correct_scale) { + cairo_get_matrix (cr, &save_matrix); + cairo_scale (cr, scale_width, scale_height); + } + cairo_set_dash (cr, dash, 1, 0); + cairo_arc (cr, width/fit_width/2, height/fit_height/2, width/fit_max/4, 0, M_PI*0.5); + if (correct_scale) { + cairo_set_matrix (cr, &save_matrix); + } + cairo_stroke (cr); + + return CAIRO_TEST_SUCCESS; +} + +static cairo_test_status_t +draw_typical (cairo_t *cr, int width, int height) +{ + return draw (cr, width, height, 1.0, 1.0, TRUE, TRUE); +} + +static cairo_test_status_t +draw_scaled (cairo_t *cr, int width, int height) +{ + return draw (cr, width, height, 0.5, 0.5, FALSE, TRUE); +} + +static cairo_test_status_t +draw_anisotropic (cairo_t *cr, int width, int height) +{ + return draw (cr, width, height, 2.0, 5.0, TRUE, TRUE); +} + +static cairo_test_status_t +draw_anisotropic_incorrect (cairo_t *cr, int width, int height) +{ + return draw (cr, width, height, 2.0, 5.0, TRUE, FALSE); +} + +CAIRO_TEST (hairline, + "Tests hairlines are drawn at a single pixel width", + "path, stroke, hairline", /* keywords */ + NULL, /* requirements */ + 49, 49, + NULL, draw_typical) + +CAIRO_TEST (hairline_big, + "Tests hairlines are drawn at a single pixel width", + "path, stroke, hairline", /* keywords */ + NULL, /* requirements */ + 99, 99, + NULL, draw_typical) + +CAIRO_TEST (hairline_scaled, + "Tests hairlines are drawn at a single pixel width", + "path, stroke, hairline", /* keywords */ + NULL, /* requirements */ + 99, 99, + NULL, draw_scaled) + +CAIRO_TEST (hairline_anisotropic, + "Tests hairlines with a really lopsided scale parameter", + "path, stroke, hairline", /* keywords */ + NULL, /* requirements */ + 99, 99, + NULL, draw_anisotropic) + +CAIRO_TEST (hairline_anisotropic_incorrect, + "Tests hairlines with a really lopsided scale parameter", + "path, stroke, hairline", /* keywords */ + NULL, /* requirements */ + 99, 99, + NULL, draw_anisotropic_incorrect) \ No newline at end of file diff --git a/test/meson.build b/test/meson.build index 9d84d048d..ed8ec2cfd 100644 --- a/test/meson.build +++ b/test/meson.build @@ -162,6 +162,7 @@ test_sources = [ 'group-paint.c', 'group-state.c', 'group-unaligned.c', + 'hairline.c', 'half-coverage.c', 'halo.c', 'hatchings.c', diff --git a/test/reference/hairline-anisotropic-incorrect.image16.ref.png b/test/reference/hairline-anisotropic-incorrect.image16.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..c69a90d3750f652cabc33a50d804a3a5785873f1 GIT binary patch literal 1773 zcmV>A+^Ur4%JSzyL;xT;4{f0S zxK0AgwryS4ZQCZODVd}YkqTCMu1um;a!DZ(EGn%MO$v!%k!Y24Qb+-dM5`2#LJC;& zTBU;&O2d-ZDmA1~8kVG1X(EMkuq3rg87Y*5C8JgPNTCEQ8Ld)D3MF8L)+()}Ff6Rl zTBVp2hJ_VQt8|mXP_V*jm3mSb3RVcMhJh4{!{XQK{tx$a6S=}n0RUz{ovp4`@o&-U zB21W1PZSoXRtq;4;O%5iWVZj<4pCtg3F)~IEKaT5qyRu0(MT4r{l_x0& zRuasT>O1*i@o42o3IH<4Go4OHrd0X7=T{t0vM00aKdw)oo38yUcY%g+_7Ylhs|kLpjHg0000gE$%UWLk#fojr&*F(!9NiGSdvg7=P`?+Rp)ib zJZ7>>)iiDI)gD#BqM@7(^T6^O1S?-vtT8L_b6vQxKv=L)h`%=k!eVF@&`$vXfN{j2 zEto$9{ZxMf`z*=cYWL-C*2K43qSzTErD^w`aeFzM*dRi6F7uVL;oQ<4L0l-#cE4s4%675P51D1Ob z$Cj~yRnopZsjjiSHmv?t}{SGvbndNI`_x9F{R=eGfq*njLK?=NJ)gIR-Cnf{u zR`Z|FYa*r6zZRtNP!F1VdHRNrZE4-JXVf^&#To?Zxt3xxX2f z=gQd+vvL3PLQz6$o!Pe(Eiw`r=>Sm5drv<`L6=X)Af_&{0In zG!-mb%0&^WqbA`3Q|aSU3^N;bPW?qjYWch6%b#4PI-6hAkjfm-&|X}L0hY3{&pcu_ zpAy5m^4S%_6Anb(I(l}T{OabNZ|+2AmNHV-2UZlf7ev<#m66Jw$_3uGcNNNRCX34{rOm(&DJm~289I~^IyjCD>mU>c%SUg`WT`IXr z8OEEZWY!+7$&-?Vl?YOuPRAOv+~R1O*4u|fD;ZdcAccsX*PYDqjQbzk+k5jsAC*?2 zVI_qW`dsg;Z`OM|P-ztomg2E5FsnqL7|KFA!hJNC$;^2yZ1VOHqX#X*Y(+} zv;1ckoxvxaRO`iCi^vSE8c!PeiM$Xjv3VA0S0feAe##oP26kg;V~VWqzH zfwOMqua)1AHi|aGVITznm0P~ORr6WX?|BL#SVKaJu^gH|lV?0R$Pa5sNP+(#I6XDZ zK9CdE@R0J>>Hy@=<^zxAfi*m&z)P##>71_XJjVvY8Y)t5t%RNeXT$mzbXNxtDs~h^ P00000NkvXXu0mjfO7BgF literal 0 HcmV?d00001 diff --git a/test/reference/hairline-anisotropic-incorrect.pdf.ref.png b/test/reference/hairline-anisotropic-incorrect.pdf.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..37acfaa5599b88271811a773d4e178b49040a56a GIT binary patch literal 1856 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 VVLIT;hjst}002ovPDHLkV1iH`$iV;r literal 0 HcmV?d00001 diff --git a/test/reference/hairline-anisotropic-incorrect.ref.png b/test/reference/hairline-anisotropic-incorrect.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..54929db44ed0bbc8279fc72a8efe46f8ad6806ac GIT binary patch literal 1942 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 P00000NkvXXu0mjf5ar#> literal 0 HcmV?d00001 diff --git a/test/reference/hairline-anisotropic-incorrect.svg11.rgb24.ref.png b/test/reference/hairline-anisotropic-incorrect.svg11.rgb24.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..d0f0f2e255fb61ae054685699ca33c8ca0dba0c5 GIT binary patch literal 2007 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 Ber5mw literal 0 HcmV?d00001 diff --git a/test/reference/hairline-anisotropic-incorrect.xlib.ref.png b/test/reference/hairline-anisotropic-incorrect.xlib.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..042715325b861b42d168bbd67131eb5b1b0348f5 GIT binary patch literal 1863 zcmV-N2e|l&P)#NGgrLlW8!|I9g90lWjfO&@Xf%pY zlQ&5L02VAw(@?bXE-65Qg{76JNdXcp6s^2Y3NT=yXypS^fB{QfD}RszVOZi?`Gyn- z!xGfWPozK$mY`NXBL!lxM6~iBDG-1qqLnX6fdDLSt^7&~cwupC{^YFk2f|pHa0dALM~mpG%+#p=g%Lv<;e@rr{@+HqgHqB z+#&y_s;cVEn>QR4$_S_Du3#~0WhO-k$;-<_S-chxe@Acyi$yC-QiPCTF!=7>JMKEM zBGfzCVX4Goi%lNT;rn4O)aY*tuU*w@!LIy%btF0okb-o1N#`{D!(Ig42o zt+uzf%gf8@rRL`5e*5+ft6;amyc%YKW!J4nMn-CCY8*e;Teof@7VIj>_YID)?6lH# zo!+O66c-okx{g~jV-WgOavXb>xmy7MAtVq8u*|=?xw){gfKjRY$iPoGD_N^}JRXTe z*4Nj;>D-sdwQJX8)a)2!r;O0eO4e#>YHI)f{bglk?2|u!{1~fFcairYP|Qkb)!p6w z^yyP$kkKhZ$m`dy<&|w0xhp{wSjI_E*Y!k)W+(OF!2_vfTSoetnH?+9?9-n~oN_tdFVmg9?yi-;AnCOsdB*{tQ|<)WgZWUb6j-Mo48 z_U+r|ngfBr_wV1+Q+XoNoibuJYkq$I^y$-%cY>OxnFj&j)vH%B>ZBx1q=*StK|#T} zbLR#J2Om9pw6(Qmw^x3C{^iS;&EqR8EAmRUO!`QXe_^$^x1Tw4hGl`_;>C;R!B3w) zNh{MPX+GM))Uy&NLCZb`0P%R-Ty|?~YnsbWt5ZfA8XCsN#@gE2jKk1TtE{Z7o}QkR z!H*w5%B<0(l+uyNVK0FJ8Quot=fGo)wKob8>Q2!=Oe9spKSJ{ddYa2CUA`PSr4|QG({-!-rqK zd`W?oo13c|1~p1ZRaREMefu_Lu)n`wH4IwRTqW%8?wb3ztCi3H@oA5MMXuQKYvacWcQw;1n$R+8NQJ}U)zwwY1#-Tm0hY3JUr9;H`}gk==adag z4Jks%i4!N#zulAyOBt!!+FBV;*U5vWj8t7+-OHCRWy~xImNHTm6%~8;?p<11k}1xca6Qvc29lP6EY;czS#Gm|PVE(QP;t;AueCj|gqU0uDsy=GFOP{`N- zMJqvAo*=cevvd6Tar1Anva_>|4Y0Hlf#nHO0PyqYPs^*P#52NJT5-ej3MsI8a(`}a z&iE^$R(!BjUQe-PZEekX5eNk6*H)#arR>vkTxWTm)Q1lr60ciYS}0nDLZK^HuCUMS z7M9mZt*@^qUemQ&T3TvqY8n_AV4vI_EbMN>AIm-!iA0jOp?9lDBodFuUBM#EJ$(hBo+edLP_VqboU)mtR>p4z(P4R-)b;DvEw^;k3INbyd76~* zYY=l-v;u5cz9a=~S^+97zmj6q3h-e0l@u^*1xT=bOp0AAz<}jrQs71_5QgP%Qm(WD zFg5~v97nac1t%iq(!L+Ut2n6omzwZiGCXk}9 zTdl0D#9}eaygR_2f*R$9>yz2rE;`U|o>$q*Q8XlMWc002ovPDHLkV1g`< Ber5mw literal 0 HcmV?d00001 diff --git a/test/reference/hairline-anisotropic.image16.ref.png b/test/reference/hairline-anisotropic.image16.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..a5a7217ca86daa2a2183e78b153270cc7ca3c3c4 GIT binary patch literal 1814 zcmV+x2kH2UP)5hIU`6Np}fAqQEdw1^+OUkU$?zF+2`osFxy)E|l0U${dm-pctsr$Oi z1=eslR1{@69CD~>I!OWG1#9cx78k9imlQa`;-%G8lL9ALT(p{YQs4oLi&hyR1s<^2 zwaNx5FvDWkDl??O42w~#ERg~mEJm#|Mha}OShUI>DKNld(JGUqzyK?@R#_#5xUgbt zm0?nd3oD*h*(QZpu;OWzc~Xc4D~48iAcg3#VrZ2UQiu*Ks#f_Sg@~}CYLzQehzKi^ zR(T_ZD6k@Fl|xd90xP^$`6PwVutI9Jw!S7wQuX`l-fw$2XRnT1_ar@lXYn6pCc+BtR+JO~{hcn)$mWlY z#|`eKMoJ>%aWE{0R>hTKf6%`u$VLi4^GVa%8D|y4Fp{V?WRjY>1jC|QY5Q8~%hFgu zeOcI>q1;C})symS4AWlfpTa zS!*2Zz7{sUO8mIN50>8`=s^mo-L07$Yd_SIE!RJ39AWvvD&Hu(weloI=kA4qupKa^ zV^KFO{X{R!7u;HTk^(Mvz}|5$jf!3QOiCrCYo((XN4LJY)p^x1w{%{2uCHIOZdMzQ z8)4p|yk0gRbl-H7sxmlfel2#hv;*z%=+ND*{0gHJtBr3r(yaNSu#`W~y&F0PK|fNx zw>@(^StKddIvxS%%p9;BTKUR;4(W62snKYZX2Dir>3<{uZC{gTWD3i!RX|%%m#uR$ zy|)6IdP*JLoz<09+TgeEZ?|?^A3l5t{uM&3!g#2y#P{T_P+MZws~Aadlv0h0fjYwvQP?{sf%9)p|H$u6+lWm(9EaGH_GYPDXdS? z&`Ig#tCw55t$_3zTPlD4naeyq_>C07-P;}Oeg7w$Nna@VI|bVu zecB?XqsudL$nmSXS)~wr$JRlzkUsT!aG?oBmgUobPs6;@oHsoG^|>TTbA`FaQ{ym)h zI$K)1t-CoK$XB99ufCI!}Lox_y7U^G7GK(tIO` z)B>4!=A{0xP9HlA3O?vbDB_&@YXT{CS*2PLLg?bCBuRU}?bW92QLm* zORLJPQu*3qm-f^l&9B9t=Ch`!6z;+tgJAPnQ;1o@Na-g!S@2lnbd$1oE9uj93F*TU zc^;iC68Gg8p0ZyIg7X(}Q-&py)XsyQod-LPjh>|JTG_{eG+~J()jRIFFEVhGG7RJJ z=+H3;(xe7U@G4eur5N%$Py6i;j_E}@umqFR_O;@bqJ4{#lA;E2IKT{K}}h zq_$sPoU3w>GR};xdt0(BE3*nc=jql8$-@#)N;}ZhC6!*4@7d8u|BTGldB1LDCQ(@8 zNdefny+Qvl`lt2>efP-dHwe-s2Wu)w8HQ23QgqylW!^DU-K;w9Eeh5OiNTr*QUHuI zqjIz2d4HedX2^+JAsJZHLduMN4Vf$ubxHNS{BELFNC4J!k%FyH>F;#Ed-}p?1>Ufx zmsIe}!e|Aqu(C=jq*mYuE32dsS}SmZm0?ohwE_=V8774&T7el>wn;_O3T&{lO$rgU z0t2kflZvVp;=;;2DMZ%_v0&waR1B>U9abJlA(mE%2rDO~;%S8_uyR5QakWBdSot9p zTPuWvl^;@I&h($ literal 0 HcmV?d00001 diff --git a/test/reference/hairline-anisotropic.pdf.ref.png b/test/reference/hairline-anisotropic.pdf.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..acb2ffbcfd730a6e4d684646ab12109054967714 GIT binary patch literal 2056 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 ktZHj(jb3H4A|OF)S*b|R8kUA6fBmP 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 literal 0 HcmV?d00001 diff --git a/test/reference/hairline-big.xcb-window.ref.png b/test/reference/hairline-big.xcb-window.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..a662668db96fde536c5fd265bf9671dcfd1bf3b2 GIT binary patch literal 2309 zcmV+g3HtVlP)P3l2VAxhS=lt@#zNfw1NbAEmgj=o&m-RF9a4sIBa$AbcEWMm{c zIeBDc1fi$7NeTe4VAa;vqG&aDNdXcpEUo4=DL{gSqSag{1sJeUw9)`6z<@=sl{QEL zH7t6qG(!rgVNq(OB~m~Ki&86%kpencG+Jqo6i~pT(Mpq~fC83ct+YxCl)_T1m4-=y zQdr8g(l#kj1WTD#nkNN{U@6c_52QdoECpKWgcQh!C08r`kOG;ojbHZwDW)w#rA zjtEj<5v>LW1{@B@FVn0HEY()n>Q~4*~*nGA3S(~*nG?& zkDcPMd_G@MQBh)IqR2&%cUbuL?c43!w@XV)YGV zv)SCx&~V_u0g=&4d;lFC9X)jD5O;J>NlAJ5@F8OVf{m$Blo!_9w{M4shauM7O3I}s z7z|cdR~rllGI*UhaRRS>{-`x`A+UOTdqbg6#8#1up!AEf*XvD9O(px+)YOE-VT9HN zqT(FSeI-Snx^t zd_LZ9l^0gDR*FdhfY<9KQwQ|lAU>&zii(DY2Hs84u%fl1Aq4=Hm6hz_t5&VTy*I=s z6$*u>rly3pM#GBGijq_y5J*T!U@P3cdskTz-ps-?vj|ubT2Yb$fV#RmwnBb>K7F?& zn4|)Mz>60zr0f|1i>nnqso~*a_D0%ZF!cBLE3Oj}Oj0hFtFp3E;?7)HT&?Iy0l=0m zTi7DUjvb?^!wn{>f`S5BR~#-Zq7@3M*49?G$olo`Y3gu;Nvf`{F5aD-=>= zV`Fh~aSX%6$H)Kt`IDv;$?U%cA+T7jP)Gs5>eZ{+I?tXxL+LY)neAAuR=3-2x7*jQ zU3>NFRjjgESy}9d41<^>k z-R|DrUd4yAuzWrrRzGQJY3v8T-;YxfI@872^;_-NJ&g%cnW>ACzB&UG- z)xUZ{8>dVr(~loNu&R+%RaGf_k8thUHMT-|c{%;}2LSW2PRU}i3=a=uRU>I`Ze|$f z^5x6yOj3IC^75LRn)>?sGBPr7T0!9r08LFzd-v|8ufyAXDeH*el#_eXq|fO+3nT3SjTchKj^kt0N_?CfmzgT$XRx5+S(ACu?3l@5iNxgdYYVqR5(TiK8Cqj0jmCa@ghr=;p`ThPYSFX@B zAlMjs#p2>(m&>L2@CZ^|t-8CrW5U|CYZt>XX=!P};*BUhL`VNl8h0^5luEqj*UHpH=`64u>5M2RS4oBV&4c8liRG##E}yrn9p% zB_+k}c1u4*h!n3@05CN*m7bn1K6OBe>hJryy1G(RQ%{~eDe(k^NI{fVWYNduXyHiHQldXYl{%9rEwrznxB} z*=#<0_N@2>T7(pEv|^KD%^?A3v6ql%%DlH8wU1Ef?S=6$}Pj zT3QYtK1{S?W4GG_fdJV}RampIF5&g-*EX9iDJiL zO(qk=FmZ8lU%q@HTJbIEzc{f&){g@uJiqcJBZXZP;iXU?1|g5Z>xC|YBr3t0{k1NWlatS%KfiS8(!qlV$pU;f7cX99_c?d&TyAde@#Duo zfBp;tb1QDtfHnK1B0^5Dyu4g!iXT%ePyyE5B_+OFOsxPLmR3ng(F#yuX_XX6(+col zX_%BmtpEv@hDm{BtpEd-wn<6X3aDXen-s{=3g}>Io|G)DfC850Nr6nQKq)Lekdmtv zD1xO2QXpR|kPk~Iq!efcGGXb26e!XPxLWLWwk1xmF7X|QxfO0iZT0hX>v z0fkl&3zptU(P#ytu=GX>=(GZ1SUMy{sTByo(jh6J)(ZGw>5~+_RuBbCpQPZAR!f&I frTO1>F0B6mn6T|m`xo#I00000NkvXXu0mjfl6_++ literal 0 HcmV?d00001 diff --git a/test/reference/hairline-big.xcb.ref.png b/test/reference/hairline-big.xcb.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..a662668db96fde536c5fd265bf9671dcfd1bf3b2 GIT binary patch literal 2309 zcmV+g3HtVlP)P3l2VAxhS=lt@#zNfw1NbAEmgj=o&m-RF9a4sIBa$AbcEWMm{c zIeBDc1fi$7NeTe4VAa;vqG&aDNdXcpEUo4=DL{gSqSag{1sJeUw9)`6z<@=sl{QEL zH7t6qG(!rgVNq(OB~m~Ki&86%kpencG+Jqo6i~pT(Mpq~fC83ct+YxCl)_T1m4-=y zQdr8g(l#kj1WTD#nkNN{U@6c_52QdoECpKWgcQh!C08r`kOG;ojbHZwDW)w#rA zjtEj<5v>LW1{@B@FVn0HEY()n>Q~4*~*nGA3S(~*nG?& zkDcPMd_G@MQBh)IqR2&%cUbuL?c43!w@XV)YGV zv)SCx&~V_u0g=&4d;lFC9X)jD5O;J>NlAJ5@F8OVf{m$Blo!_9w{M4shauM7O3I}s z7z|cdR~rllGI*UhaRRS>{-`x`A+UOTdqbg6#8#1up!AEf*XvD9O(px+)YOE-VT9HN zqT(FSeI-Snx^t zd_LZ9l^0gDR*FdhfY<9KQwQ|lAU>&zii(DY2Hs84u%fl1Aq4=Hm6hz_t5&VTy*I=s z6$*u>rly3pM#GBGijq_y5J*T!U@P3cdskTz-ps-?vj|ubT2Yb$fV#RmwnBb>K7F?& zn4|)Mz>60zr0f|1i>nnqso~*a_D0%ZF!cBLE3Oj}Oj0hFtFp3E;?7)HT&?Iy0l=0m zTi7DUjvb?^!wn{>f`S5BR~#-Zq7@3M*49?G$olo`Y3gu;Nvf`{F5aD-=>= zV`Fh~aSX%6$H)Kt`IDv;$?U%cA+T7jP)Gs5>eZ{+I?tXxL+LY)neAAuR=3-2x7*jQ zU3>NFRjjgESy}9d41<^>k z-R|DrUd4yAuzWrrRzGQJY3v8T-;YxfI@872^;_-NJ&g%cnW>ACzB&UG- z)xUZ{8>dVr(~loNu&R+%RaGf_k8thUHMT-|c{%;}2LSW2PRU}i3=a=uRU>I`Ze|$f z^5x6yOj3IC^75LRn)>?sGBPr7T0!9r08LFzd-v|8ufyAXDeH*el#_eXq|fO+3nT3SjTchKj^kt0N_?CfmzgT$XRx5+S(ACu?3l@5iNxgdYYVqR5(TiK8Cqj0jmCa@ghr=;p`ThPYSFX@B zAlMjs#p2>(m&>L2@CZ^|t-8CrW5U|CYZt>XX=!P};*BUhL`VNl8h0^5luEqj*UHpH=`64u>5M2RS4oBV&4c8liRG##E}yrn9p% zB_+k}c1u4*h!n3@05CN*m7bn1K6OBe>hJryy1G(RQ%{~eDe(k^NI{fVWYNduXyHiHQldXYl{%9rEwrznxB} z*=#<0_N@2>T7(pEv|^KD%^?A3v6ql%%DlH8wU1Ef?S=6$}Pj zT3QYtK1{S?W4GG_fdJV}RampIF5&g-*EX9iDJiL zO(qk=FmZ8lU%q@HTJbIEzc{f&){g@uJiqcJBZXZP;iXU?1|g5Z>xC|YBr3t0{k1NWlatS%KfiS8(!qlV$pU;f7cX99_c?d&TyAde@#Duo zfBp;tb1QDtfHnK1B0^5Dyu4g!iXT%ePyyE5B_+OFOsxPLmR3ng(F#yuX_XX6(+col zX_%BmtpEv@hDm{BtpEd-wn<6X3aDXen-s{=3g}>Io|G)DfC850Nr6nQKq)Lekdmtv zD1xO2QXpR|kPk~Iq!efcGGXb26e!XPxLWLWwk1xmF7X|QxfO0iZT0hX>v z0fkl&3zptU(P#ytu=GX>=(GZ1SUMy{sTByo(jh6J)(ZGw>5~+_RuBbCpQPZAR!f&I frTO1>F0B6mn6T|m`xo#I00000NkvXXu0mjfl6_++ literal 0 HcmV?d00001 diff --git a/test/reference/hairline-big.xlib-window.ref.png b/test/reference/hairline-big.xlib-window.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6aaaeed39e57e5683b32c9d234a63ee2d1bbac GIT binary patch literal 2287 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 JPDHLkV1o0AM56!z literal 0 HcmV?d00001 diff --git a/test/reference/hairline-big.xlib.ref.png b/test/reference/hairline-big.xlib.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6aaaeed39e57e5683b32c9d234a63ee2d1bbac GIT binary patch literal 2287 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 JPDHLkV1o0AM56!z literal 0 HcmV?d00001 diff --git a/test/reference/hairline-scaled.image16.ref.png b/test/reference/hairline-scaled.image16.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..5b82d0dc8a69ef1179299978e32976ca7fc35d13 GIT binary patch literal 1532 zcmchX`9Bj39LJYuq%CK2K9OUwgY+OYp*eDmS(|Ag_w$61W3A<=#>|=HaXifEDUFb3 ztthD;=EzY@L?ay@w-(Bk@#vp;UfF(DjFFcYq zP3ZEcI|-M#Ky+GyT6%&;!M%EPjV)E{RTgBoox?;|O z$~#4H6CSvj7OsmC~`oD@ENWUIRryhb66$WX)k@g3;Lf0pY$kge_dz`*4DCwo)5p z!#BoL9yt9z*>EiJ`~9PcOnycLD5x%}I-mA|^&y&(V9WELleZ@#SoxcWMN}gpVTzgx zaS{vi;!luHvST(5zBdWg=XPaXj{v>xb7yLvi_@P%PTH*>+3fx|Ca4+3)~kR%2p{eC zQ|e;8!L;g#;D~das`=Lq?AElc30De%5`%MOrC&! zz`Z`qP!xh0?S^sZAhQzfAnke~M^aW5Y+*Zy30}`)qfi*ts3!SsX~MIqbtT}E1Nk}X zm{t1`WT8uYU!eEiVR91>T$JgZp(TBL4#tWw7f>GEPm{&Krwc|X4R*&eZ4BzIeI2AF zqk!UyO||itc6IS9l^2g0p`FwS%S`IJ8*a>?e(R~Nei;vmmKQu{Kg?90oS#K$8FhUX zUp#NkhaDX!@9UMqxU6wzQ*Qsb{;FznPsx(X*+ndl)L|og?$-k+SKy*FFI++UAr)_# zg=K6{?Az&X%MeP%kJWKuZm8Fqgz4GKzPZr51Y^Gm0fy@MG~2g-^s!m}Ly_eprt)y& zz+POfm0lQP0}7XZ=v4`IW)vLXRF#NZQ)pdl&A5ee!+Ii$%=2axk{fB0e>Bd>j!E~s z&QU!z<~!hrbCogLDZ78z%`vXIVLbII@4im(7u;40tO zF(2CJ!}_~fg0Wild%b4eyBMQbf-<)hWpQ2i3sx;vAyK|?Z^&IgP_I;*L1@`ItyO=fL#|z*MRMsL$2ct29w7iy2KG2 z7ZnLI38J%fdt~toX95^q+%`z0GI9Y(GApUcDfD#nU-i#qgLly1#_4p)xC^U0BW z)y3!IVqye_rDfV+5xDRU4W%xBb{>=~*$%!kox|FyO;}G_pPDw$v8h>=Kt)7> zhr$XwGSHjFJW>AZ)Foa5zJifeTzqurxNo#dOe`Mdhi1%oM!^R+xND%0Mjd%9w W*!XeNClT16t?umLZeMTfPx}wGXUrx5 literal 0 HcmV?d00001 diff --git a/test/reference/hairline-scaled.pdf.ref.png b/test/reference/hairline-scaled.pdf.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..ef0973242f1b510211f7b43f5f62de811e0b60e7 GIT binary patch literal 1747 zcmcgtiC5BT7q({1L@gI^K^aHOiZs(SmvKq`NJ0Y_%0$#++|mrwn5M-GaK`TxrHqiDIwfXS^#E-tINnS|2q?KCS* zK_d!5F3>$#X++(=6@6X4Vn47lz9FAClO* zdU`w_kE=^bhim5lw7NKE7xR0j1xN=gp;=Xn*s02utSt3zM0o^ASvV|_1P2D1mmaD( zO$fkYszn!UI&Xa$Co}x*C?})F*jKBYn}^5@ZF>qOYHNLocfsZ~8hrx=eptm~)sD6$ z&|gO%&GHh1_48ZW+xa&Aygbt}HP{~HDf)|@jZi4GPaqgW?lEz?tqt0{cSN=v8ykDB zJ{)Ff7>vgkamL?Ibm+K7ZEY-Dnwb&e3$YMrKJqA)U1zXm;o` zH}Z;$z(RL;8cZB=#M~r>r9?{sfEg+L27;xi^WsCyrPKklAa0SEJ?~q z)w8A85@Tb{Vp>8L`unM8Dg~NDU_qmXhQ=l`T)ZqBIU3sjJu!Q#eSSV(*B_6!M2&rJ zQm9=rmno)rKuO9~xdD(OZT+)_x`ci8ATQCFb5VQ81E`S^4u?~i$mQ}F!vmI@qhbhddy+yyskK+CFG9VaA(=G`g()BwJl{biPU_Z%KugV*sMS1+reql z4^J43+bAH%We0l5Ru}yO7Aq<`=%?)k(0C$sqnV#)e9!wmWxBTwe%C)K>2q%{0)yFO zGrP8SolGYC`sQ?475h{U#{n1g0W5(q;hn8zoez&|2<|m7505z?6=fl4l$oD9cka3S zmH1STDsLq6p7)fr>lS6_-9;<}0zrr;CmE3zYU;wJGv40bfq{XSE-|~bM#bWwvuBsL zl&fJK*TOg{H;BaFrJDHNWrGC;1u&OupGLc7@5zVl>_khto8yY^J8G3mW5GRBnR^bm zkVczXw(g zGBTJ?pE~7^MshuSqz9&*7R7aV%^pd7D?r*Y{(yUpT zi9OFralY}n0#nVbsrfiJ_qHv;RA+E_m}1*Hx^TESn<|NS$er5Wfur9%No*UH19(mL zs;8BU-n~1Gfq=pJ1yri$KLKwx?RK0{e&==*;hna<`RbOsJ9$MjqLzfyr6)<3I+H$R zlko(K08|DaXno;R0`b5~@OT2Z4^#`Uzf38HTe7NH9(aOkAE+H(4n!0|u3&@P>sXA) zR|KDmI#v>3K{>6EpiHX=r`c`8vXOeXZ-PteYHO#Xeo9XE4J^HTaZV;1til0spwX`d z0vFQ9{E=jSKtKTSp{!{#fEr}pcOOOuTn`sN1zrnGsst&gC8TcgNbAW@TdiS-OK7xx z=H{+2c28ocpPyf1VuP#2Iwhs*ey%C`k=dT(s+5Q6UTDwqsxp79e+~T55EvW>0{yG* aFFS7A7F~0GjM@8jS)op15YN0Wr2h?ZG*%=4 literal 0 HcmV?d00001 diff --git a/test/reference/hairline-scaled.quartz.ref.png b/test/reference/hairline-scaled.quartz.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..c0653a12c07f30fe970fbc5f255e54b0cd0bce7e GIT binary patch literal 1683 zcmcgt`#aMM82?s=c&Hem7Av>8%tEawOq1J88gr-FVxj4xxg?65nCKDOVHT$jPRD&y zj>{%`nj{*T6qA}+O^Z5|xt{qa&ig*^<#~VmT%PC6J%x4GP%}^i06@dj1ASUCiJPUm zRndW9SdXGBM|r!WfsM_qN`P(tX`fs+Bc$kBZodB$U?zTg-`Z`g!`Wc-~7uS0Xtk9?r$%V zLnc2Y{7y}pyhhDni?G~^H%o)h2H6#IuA|+Y$L*7%e!30nK9k9uo}QM=Q%-6CLG`1L z9>J*j)w!t)pN9q*NQkCNVfPut1m|jNRh3)AR1*MTYl@gwn7Z|K%q~|iFR!t_PtE&p z?i|v04BkS#Vs7h3Fw5(uC6^M7^B}b+ieYL8f|axWXlrYG{5XJ#)4RB|XhyG-$dA)>AF^4j*toa~=L~LFS7Tb2iaUUt^3}~3yn6MD zflT=9;pIh32(h!Z-RG31*T4%fYl6)enyB`O`{~4}sIOE<2+Z2LgdwEE!$Tq?cLc6j zWZHr`E1a$^N&|>QQLeTbIyjo0LLflHKDbynRlDqui;GiV zUwy3QlZ(`a(`SFm#{K*@B0{ybwFB|^VoF3nCSq}MHjpu(YiQ_OWWrHhE_;B%VD>tv zmw$7(`m?TA+kPpFc@5sKRz^+F+?UYwq9>(u@AAcv(vuRp^~#< zMzVoNbbkJxoYw2@?cK}cwRdzNk;sFFuE^+^n1d?$_KCpLh9w2O*jVWuL+5F=a%_zt zwrX7Rx`IA=*-O6g<&9Ko0X05!Xi>4=K7bF{jOLEh6=YtP>T?;jLr9?phlNdyj_N|E zg&j#-cCO`<)VM-g4UO)-8(tTvZ#7Y)tTth3P4XfJPjvhbGgumz$7@L>~+ppwN_T-;r448g<+1Cey z!MY9M!>T=CC@DF4X?by0E|)75zH}(*+r-h-1#>8gK_O{Mpt2I3 z2wXZ5^uAazjkGQKm32*wyLmcfAN-iljkG!!9BTyeJV%G@e$Sx#y1pep$EpN#K0clg zQg(fjx7#L7y_0l2eKn|%2SzuJIMZWdVnXZjwF2oc$d6`XFE?X@%i*j|b#J>^g`#0= zENyHyR^|V$uBIv6e*S#@{&1MbRIALZnaw65^g1K9rfva5B9T}umbQSw($Zmv?)sE{ z(f`1#CcwHBHFacmHlwGjh3e?7}pBvbKGM_4HK=Ckp1!=f8p&t(1wX}m5C literal 0 HcmV?d00001 diff --git a/test/reference/hairline-scaled.ref.png b/test/reference/hairline-scaled.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..f059b4288f7ec7466cf22260a3802ea31bd699cc GIT binary patch literal 1720 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

    5kr69DjK`IF+Npf<(x zn6@dhAe@BO|6j_SlE(zk2_$>4K@;9jl_u}RE3av?p8$ZiY5WlDn<`n+EV_7ivHxmc z`F2_+|I8m;4r-ZXY3Y=fDVjxeiz0KatT7lXTV#05%a{P*;Pt`qYFO9ASnjdQ4$|*h zQ&jD_05|mxdx)>$xc~ry+kkG-Y>^?R_#x)U;+|vGnV+5^AFELAk?Xzjc3c)6Hkk@$nff~U0Hm!c>X7<;3g1Rnpfg7vr6)q^bUK@rZc!4 zunVg232B?MhonUSpe}3q`6-%3{<%-vv^*CCw*f!H(6v|%{K(Jqyxa+UFZbA)-eHfO z(PuUD$3xj9b``&2YO+k30DxbBJSt6=K~rT^IxK@GkVK_qnKj9x!dYfbAdd=R88;zO z$ymlsfJRlxT7^j*7Al83@n0eD#9M_4R8bXJD>D6xY7M)6bJkCWEuu?dmDdOW0000< KMNUMnLSTZ>BALYi literal 0 HcmV?d00001 diff --git a/test/reference/hairline.pdf.ref.png b/test/reference/hairline.pdf.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..0a0ecb33ee175d942bd919c970206bbffc9139ad GIT binary patch literal 1014 zcmV_<6}&u$gCiu(T~c#>Q`&pve*JU3 zTq{VDq^c^|SEW*EYilc&N|YV|SY2JEH#jfh{QO*&<wnkXzvRNPGzmR(f! zFxj!HMwQKG1wqg>?dRu*ugQ*OjY=?7dwY8_napG|2q7+}sw^DU(b3V<)05Ris<*c{ zlgV%~Sy{zmvAerF5D1)|otaFnt*s_mEEfCv`tsgnVr8@0<>h7Lsv-h}(Bo?Tu+|ZLR7++R4TQyvf|1l2!f(0wH@mmnXay`Iy*bRzrS6XNLrev<#IWX zO#m=5GP1tD&NPXlXiX~~kNbSSiHV7qmlrQh4-XHrEZeOrB8Wz#l<$+1hn))(0POGY zcXf4DJu#A5bGaOes;{rl2#UpG4kz+aK9;G*#>Qr5W(EcZZf{rvR&{JgcbH9R~V3WZFjbUKY+ilTUXd+V0v z&5wMO2_ZB%IEdegMxy}Wip9kQ0Qr30=kt-MT(NkW0D$aOI4b8XjwWkV4p|&cP%SDa zEWW0yQ88J3O<)rhoyFZ`7ZruY-30bg*|F+jB8LT06s?Clgb?{dK@bE*QR-m=YE)KM kolH2Y#>PgwebUJK0}=JAXFfU?lmGw#07*qoM6N<$f;(i}6951J literal 0 HcmV?d00001 diff --git a/test/reference/hairline.quartz.ref.png b/test/reference/hairline.quartz.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..e51ea63c9a7d53f57c6272b3757650462e584203 GIT binary patch literal 968 zcmV;(12_DMP)+7qksxL1uoIU`cCiNoSVmAZ+t78Vv9#|gAYMKul+06315 z&*uZIp;7gEJw;LO?(SUIP1h8~3P+{*s!%8xhGALO@9%FarlBkvm2KO$ZHG;)%H{I; z`FSd)Fzf58<1^nZGC=zCT|L`27|%T(b4?;JR4O^KnOtywcG94 z*;&?DsZ@l^icw5{*3Zum{5`7J=~-vjbxqUsv*go?VX`c1eSMux5dH@+Y@&5~dOA5d z$!=o8CXDgo;^Oo3v;QWtsG>}i#g0l2d0ErJ!NKL_CEaE$78ShuC7#7<(mMY-EPwkhG8UQIypJ{`1puo)$4Vk2_Zx~6bgj| zOmA;*s;WjEbsT4IZcb<-gs|yU_)Zj?5JJn#%bX65<0$|C66SP!d%L>2DoA_GCeQP7 zxm+w$qtPIQ_&X3n*mRJ{h{`ta~@V`D>jIw@1L+3a*Wu}nkL zk}N4xzuzyFN}Sh1)WD#u_xJawr>BHX08p(~yWOtPl*wcQEYmc%x3{OJrdq9*=Xpt* z5JH-!Jw872O|@E$^E_Q#TqJ1%fU~o+VzC(YaYqYd%%WOZS@DD9*H8a(E-O%mVeIek z7mLM*hli*>l}crEbCYgQPfs@*4R&Z|W(Fi@GWncXTAHSHyIuc~_x~EknC;rO?Pp0o ziKDDl5JJ^zwNxr~IvqN11+H*uX^HM?nnnnT%Nl+C)bID3&8DvFxm+$_IzB#TEg0jt ztOP#tJWahQM` qRhTs<6OC$OVxnHJ4_!n1S$_bb;Gu1HFaCJ|0000C)I;OZ>e%}~@hsH3%` zLva)ladL4{^Ct*Z&m7fBBl+Sk9=Btwu*jH#Rnk#UjR-i>V`vM0I(2`SSAOG|`%xnkp8HTue?@ zyLV>jPb+6Lq4C6Mx*rN%*>4E zv7#FjIMTAODmp!Fet&;oUthPg{HGPbbar;Oyu3_V_8*|rMC#<^WME)`3}v&~kWGeR zh@xm1hCMABm756wPESwi==Jq=n5N_7`UGXwema3}pc${qlfSsKk(y+C)6^?0tf4}2RL(?=-6w~Rnr|JIwo-~Y& zjfG%pHk;9C)NNGLw86naPZP#?XlRJ^v|6qIYO2+0sZ@&5plKTV|CeV@^?IG16S&-i zIhsB{KVz|2Ak*5~TH8MK_xDGaU9;Kr_%u%w03?&ir>7_XCMV0Xta7=$ySqC-Kkqr6 zFHblarH6OH1T60Bmk<(xJY-KFhLv&E!8PQmU#- zl5}uzU|;g~Pt$dsMs^fpd2w-Ze0;o6C{!vHaGWz!sT6rDilSv% zL0R3OpUUNOKA%q}lk|p9O{%Jrw}K#4DwUwD5dP$UeSNi=FvfFpbL2`UlL3H0tZ*JY zI9I2x>yb!=Miq#~%LD*)uOdk(Xo5~r`C;)jb&SfB#n%KbQL$OvO>R*! zSlmtE9+exb7bbdG5Cp+_xWgFJ2MP!wMNxWT0%lZBR*y_1s{a0dw|&yi`Uk^crw0z9 R)5-t<002ovPDHLkV1mM3;w}IH literal 0 HcmV?d00001 diff --git a/test/reference/hairline.svg11.ref.png b/test/reference/hairline.svg11.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..834f3a43a1a86a1edb2a7e9a164c54549bae512e GIT binary patch literal 988 zcmV<210(#2P)C)I;OZ>e%}~@hsH3%` zLva)ladL4{^AUt9Xa*6BU0O+~U0g&O-D(FFygUvEM`)T$(l^)PeWo<`ko@}Ra=8|X zqNr&axL2#y8W|aBG#ZQ^06++_8~hi#yStMl>E`B!(X_q2oy+BVX956ER-@5~$K!8r zZ@n}5VR=RszR8p285I|kCyN~wFB6-^j*6p+&0<8w*Ti5kqT+61u-u~Rg~^T8F{)Cj zgb*@K^XKP>ugQ(&j0)LmbaZrMW20CsVvM<%IFE36Lt*NQ0VzJ1@9$r%y@1q zx-o$xE&HsZx2MhT@9*pD>vop^v;vsU&d!#XmnqBs06I;iPEJk+1_sDbHk%FEWEh4h ziiTm>)1pzinE>GQ^puWXUtfo5IzB!=Iyxf9ltrUrm;gXg6f&Alr~NDtT`s)8pgg#Kgq+_je!@P0KXRYPA}&2>=!r77h;&JxzijIMd2z zvyn(-b#?Xi^)*aWtyYsHN!N9@DU-=Co+m#qy8tEtxVX4TBoZGV9}H8qTBT7)ovV7gie@>)SRh1;^ z;NZYM=iK@T9-))_=v;F{glcyqU&W7Xw0000< KMNUMnLSTaV@YbjR literal 0 HcmV?d00001 diff --git a/test/reference/hairline.xcb-window&.ref.png b/test/reference/hairline.xcb-window&.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..1175b14a97447e081b8413867461ee2f2dc68035 GIT binary patch literal 950 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 RD|!F`002ovPDHLkV1imj(Zv7& literal 0 HcmV?d00001 diff --git a/test/reference/hairline.xlib.ref.png b/test/reference/hairline.xlib.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..ed55291f30c6619bab5fe7df61ae35f5422c9fdf GIT binary patch literal 943 zcmV;g15o^lP)METPu}Hgb*brR~C)x;^N}v<;7{jnw*?0l}buXPL^d^kw|1{Xb4AK zO|&wZ%-7eK_og=1&CSjB_O|`5LIEM9TrMvzE)EY5<6t6@5N<2FF@Ym3`(1^X$L9C< z_xbsG9G{t)kx#1wQ?Xb~r_;!?KY&gXt>fckoLXI7_1N_M{2UAhE0u~pEsTm~0)Uf~ z6P&%ey7JO=baZrhcu0?tg;8-#05Cf{i%+7=0@3B-i!2%y-&C*H`}_Olqw4;JKw0PK z=en-*O#qNerD((Y`nor!y}iBf?{5}sYHCVoDwoT&Ash~SU}`iP0|NuBS;H{wDAlxbsQV|RDABa>@dk|kxjy}cbDA9r1%I3{G( z>vhvKJvITr($dnw!GX}^^ZA^tL?S^CUSD6mG*zorUDqp>3g3k95ZAiAy!6rp0B2`s zu~_Ww?TuqHO%tPCcOmgJMz&0fW_tmWn9P$;ysv-9xq z0FHfTEEc1uqobp3Y00p<-#^{o-*0YiMx#;Ouc4_}EYee-&u5xurz{VC^zvPJ94qR2{KYnZUN+rBTVV6q=k-NwO50z%42nmRgf*R6>?o z6ELFUvy_`yQE^zxO~8(d#p;EL6O}8g7bf6F&xYGuIr?o^#=u-p<87^ RD|!F`002ovPDHLkV1imj(Zv7& literal 0 HcmV?d00001 diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index df8886ef6..d0452d338 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -5161,6 +5161,27 @@ _set_line_width (csi_t *ctx) return CSI_STATUS_SUCCESS; } +static csi_status_t +_set_hairline (csi_t *ctx) +{ + csi_status_t status; + cairo_t *cr; + cairo_bool_t set_hairline = FALSE; /* silence the compiler */ + + check (2); + + status = _csi_ostack_get_boolean (ctx, 0, &set_hairline); + if (_csi_unlikely (status)) + return status; + status = _csi_ostack_get_context (ctx, 1, &cr); + if (_csi_unlikely (status)) + return status; + + cairo_set_hairline (cr, set_hairline); + pop (1); + return CSI_STATUS_SUCCESS; +} + static csi_status_t _set_matrix (csi_t *ctx) { @@ -6625,6 +6646,7 @@ _defs[] = { { "set-line-cap", _set_line_cap }, { "set-line-join", _set_line_join }, { "set-line-width", _set_line_width }, + { "set-hairline", _set_hairline }, { "set-matrix", _set_matrix }, { "set-miter-limit", _set_miter_limit }, { "set-mime-data", _set_mime_data },