From 53444c286ef45fa0054ba6ab94dac11016e9600c Mon Sep 17 00:00:00 2001 From: Billy Biggs Date: Mon, 8 Aug 2005 18:35:22 +0000 Subject: [PATCH] Add a new API for disabling antialiasing of shapes drawn by cairo. This is a hint and is not supported by all backends. Store the antialiasing mode in the gstate and pass it to the backend for trapezoid rendering and for clipping. Pass the antialiasing parameter down to the backend where appropriate. Pass the antialiasing parameter down to the backend where appropriate. Add support for A1 format trapezoid rendering, and remove the _create_mask_image function, creating a temporary image from memory we allocate and clear. Support A1 masks to disable antialiasing using the RENDER extension when requested. Support A1 masks to disable antialiasing using the RENDER extension when requested. Blindly pass through the antialising parameter. Add the antialiasing parameter but don't support it. Add a test case and a reference image from the latest libpixman. Add the new antialiasing disabling API to the docs. Update progress on a parameter to disable antialiasing. reviewed by: cworth, otaylor --- ChangeLog | 74 +++++++++++++++++++++ TODO | 2 +- doc/public/cairo-sections.txt | 4 +- doc/public/tmpl/cairo-font.sgml | 10 --- doc/public/tmpl/cairo.sgml | 28 ++++++++ src/cairo-clip-private.h | 2 + src/cairo-clip.c | 15 +++-- src/cairo-glitz-surface.c | 1 + src/cairo-gstate-private.h | 1 + src/cairo-gstate.c | 49 ++++++++++---- src/cairo-image-surface.c | 71 ++++++++++---------- src/cairo-meta-surface-private.h | 3 + src/cairo-meta-surface.c | 11 +++- src/cairo-pdf-surface.c | 4 +- src/cairo-ps-surface.c | 12 +++- src/cairo-surface.c | 20 ++++-- src/cairo-xcb-surface.c | 11 +++- src/cairo-xlib-surface.c | 22 +++++-- src/cairo.c | 40 ++++++++++++ src/cairo.h | 46 +++++++------ src/cairoint.h | 18 +++++- test/Makefile.am | 3 + test/unantialiased-shapes-ref.png | Bin 0 -> 4450 bytes test/unantialiased-shapes.c | 103 ++++++++++++++++++++++++++++++ 24 files changed, 450 insertions(+), 100 deletions(-) create mode 100644 test/unantialiased-shapes-ref.png create mode 100644 test/unantialiased-shapes.c diff --git a/ChangeLog b/ChangeLog index 6e685b535..cff7534a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,77 @@ +2005-08-08 Billy Biggs + + reviewed by: cworth, otaylor + + * src/cairo.c: (cairo_set_antialias), (cairo_get_antialias): + * src/cairo.h: Add a new API for disabling antialiasing of shapes + drawn by cairo. This is a hint and is not supported by all backends. + + * src/cairoint.h: + * src/cairo-gstate-private.h: + * src/cairo-gstate.c: (_cairo_gstate_init), + (_composite_traps_draw_func), + (_cairo_surface_clip_and_composite_trapezoids), + (_cairo_gstate_clip_and_composite_trapezoids), + (_cairo_gstate_clip), (_cairo_gstate_set_antialias), + (_cairo_gstate_get_antialias): Store the antialiasing mode in the + gstate and pass it to the backend for trapezoid rendering and for + clipping. + + * src/cairo-clip-private.h: + * src/cairo-clip.c: (_cairo_clip_intersect_path), + (_cairo_clip_intersect_mask), (_cairo_clip_clip): Pass the + antialiasing parameter down to the backend where appropriate. + + * src/cairo-surface.c: (_fallback_composite_trapezoids), + (_cairo_surface_composite_trapezoids), (_cairo_surface_reset_clip), + (_cairo_surface_intersect_clip_path), + (_cairo_surface_set_clip_path_recursive), + (_cairo_surface_set_clip_path): Pass the antialiasing parameter down + to the backend where appropriate. + + * src/cairo-image-surface.c: + (_cairo_image_surface_composite_trapezoids): Add support for A1 format + trapezoid rendering, and remove the _create_mask_image function, + creating a temporary image from memory we allocate and clear. + + * src/cairo-xcb-surface.c: + (_cairo_xcb_surface_composite_trapezoids): Support A1 masks to disable + antialiasing using the RENDER extension when requested. + + * src/cairo-xlib-surface.c: (_create_trapezoid_mask), + (_cairo_xlib_surface_composite_trapezoids): Support A1 masks to disable + antialiasing using the RENDER extension when requested. + + * src/cairo-meta-surface-private.h: + * src/cairo-meta-surface.c: + (_cairo_meta_surface_composite_trapezoids), + (_cairo_meta_surface_intersect_clip_path), + (_cairo_meta_surface_replay): Blindly pass through the antialising + parameter. + + * src/cairo-glitz-surface.c: + (_cairo_glitz_surface_composite_trapezoids): + * src/cairo-pdf-surface.c: + (_cairo_pdf_surface_composite_trapezoids), + (_cairo_pdf_surface_intersect_clip_path): + * src/cairo-ps-surface.c: (_cairo_ps_surface_composite_trapezoids), + (_cairo_ps_surface_intersect_clip_path), + (_ps_output_composite_trapezoids), + (_ps_output_intersect_clip_path): Add the antialiasing parameter but + don't support it. + + * test/Makefile.am: + * test/unantialiased-shapes-ref.png: + * test/unantialiased-shapes.c: (big_star_path), (draw), (main): + Add a test case and a reference image from the latest libpixman. + + * doc/public/tmpl/cairo-font.sgml: + * doc/public/tmpl/cairo.sgml: + * doc/public/cairo-sections.txt: Add the new antialiasing disabling API to + the docs. + + * TODO: Update progress on a parameter to disable antialiasing. + 2005-08-08 Carl Worth * test/.cvsignore: Ignore clip-operator and unbounded-operator. diff --git a/TODO b/TODO index bb04c887f..7a8e1641d 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ Backwards compatible (API additions only) ----------------------------------------- cairo_begin_group, cairo_end_group, cairo_get_group PDR C cairo_surface_mark_dirty (see below for details) -PDR Add support for non-antialiased rendering. API ? +PDRTC Add support for non-antialiased rendering + API Add CAIRO_FILL_RULE_INVERSE_WINDING and CAIRO_FILL_RULE_INVERSE_EVEN_ODD Add cairo_text_glyphs (see below for details) Add support for programmatic patterns, (ie. arbitrary gradients) diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index 1c0edccbc..a27a2945b 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -169,7 +169,6 @@ cairo_font_options_status cairo_font_options_merge cairo_font_options_hash cairo_font_options_equal -cairo_antialias_t cairo_font_options_set_antialias cairo_font_options_get_antialias cairo_subpixel_order_t @@ -203,6 +202,8 @@ cairo_set_source_rgba cairo_set_source cairo_set_source_surface cairo_set_tolerance +cairo_antialias_t +cairo_set_antialias cairo_fill_rule_t cairo_set_fill_rule cairo_set_line_width @@ -272,6 +273,7 @@ cairo_glyph_path cairo_get_operator cairo_get_source cairo_get_tolerance +cairo_get_antialias cairo_get_current_point cairo_get_fill_rule cairo_get_line_width diff --git a/doc/public/tmpl/cairo-font.sgml b/doc/public/tmpl/cairo-font.sgml index 6fd8e163a..78c9d3bfd 100644 --- a/doc/public/tmpl/cairo-font.sgml +++ b/doc/public/tmpl/cairo-font.sgml @@ -228,16 +228,6 @@ Font Handling @Returns: - - - - - -@CAIRO_ANTIALIAS_DEFAULT: -@CAIRO_ANTIALIAS_NONE: -@CAIRO_ANTIALIAS_GRAY: -@CAIRO_ANTIALIAS_SUBPIXEL: - diff --git a/doc/public/tmpl/cairo.sgml b/doc/public/tmpl/cairo.sgml index 8b29acc74..3f2ec8d6c 100644 --- a/doc/public/tmpl/cairo.sgml +++ b/doc/public/tmpl/cairo.sgml @@ -191,6 +191,25 @@ Drawing contexts. @tolerance: + + + + + +@CAIRO_ANTIALIAS_DEFAULT: +@CAIRO_ANTIALIAS_NONE: +@CAIRO_ANTIALIAS_GRAY: +@CAIRO_ANTIALIAS_SUBPIXEL: + + + + + + +@cr: +@antialias: + + @@ -846,6 +865,15 @@ Drawing contexts. @Returns: + + + + + +@cr: +@Returns: + + diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h index a56f57983..23eb78c90 100644 --- a/src/cairo-clip-private.h +++ b/src/cairo-clip-private.h @@ -49,6 +49,7 @@ struct _cairo_clip_path { cairo_path_fixed_t path; cairo_fill_rule_t fill_rule; double tolerance; + cairo_antialias_t antialias; cairo_clip_path_t *prev; }; @@ -100,6 +101,7 @@ _cairo_clip_clip (cairo_clip_t *clip, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, + cairo_antialias_t antialias, cairo_surface_t *target); cairo_private cairo_status_t diff --git a/src/cairo-clip.c b/src/cairo-clip.c index a4b8d5332..d479da8fc 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -246,6 +246,7 @@ _cairo_clip_intersect_path (cairo_clip_t *clip, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, + cairo_antialias_t antialias, cairo_surface_t *target) { cairo_clip_path_t *clip_path; @@ -265,6 +266,7 @@ _cairo_clip_intersect_path (cairo_clip_t *clip, clip_path->ref_count = 1; clip_path->fill_rule = fill_rule; clip_path->tolerance = tolerance; + clip_path->antialias = antialias; clip_path->prev = clip->path; clip->path = clip_path; clip->serial = _cairo_surface_allocate_clip_serial (target); @@ -339,9 +341,10 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, } static cairo_status_t -_cairo_clip_intersect_mask (cairo_clip_t *clip, - cairo_traps_t *traps, - cairo_surface_t *target) +_cairo_clip_intersect_mask (cairo_clip_t *clip, + cairo_traps_t *traps, + cairo_antialias_t antialias, + cairo_surface_t *target) { cairo_pattern_union_t pattern; cairo_box_t extents; @@ -375,6 +378,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip, status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN, &pattern.base, surface, + antialias, 0, 0, 0, 0, surface_rect.width, @@ -429,6 +433,7 @@ _cairo_clip_clip (cairo_clip_t *clip, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, + cairo_antialias_t antialias, cairo_surface_t *target) { cairo_status_t status; @@ -436,7 +441,7 @@ _cairo_clip_clip (cairo_clip_t *clip, status = _cairo_clip_intersect_path (clip, path, fill_rule, tolerance, - target); + antialias, target); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; @@ -452,7 +457,7 @@ _cairo_clip_clip (cairo_clip_t *clip, if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto bail; - status = _cairo_clip_intersect_mask (clip, &traps, target); + status = _cairo_clip_intersect_mask (clip, &traps, antialias, target); bail: _cairo_traps_fini (&traps); diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 402b34f15..7e0f33876 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -936,6 +936,7 @@ static cairo_int_status_t _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, cairo_pattern_t *pattern, void *abstract_dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index 7e82883d3..489afdba4 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -42,6 +42,7 @@ struct _cairo_gstate { cairo_operator_t operator; double tolerance; + cairo_antialias_t antialias; /* stroke style */ double line_width; diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index e63f29f6f..a657f15e5 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -92,6 +92,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate, gstate->operator = CAIRO_GSTATE_OPERATOR_DEFAULT; gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT; + gstate->antialias = CAIRO_ANTIALIAS_DEFAULT; gstate->line_width = CAIRO_GSTATE_LINE_WIDTH_DEFAULT; gstate->line_cap = CAIRO_GSTATE_LINE_CAP_DEFAULT; @@ -1234,6 +1235,11 @@ _composite_trap_region_solid (cairo_clip_t *clip, return status; } +typedef struct { + cairo_traps_t *traps; + cairo_antialias_t antialias; +} cairo_composite_traps_info_t; + static cairo_status_t _composite_traps_draw_func (void *closure, cairo_operator_t operator, @@ -1243,24 +1249,24 @@ _composite_traps_draw_func (void *closure, int dst_y, const cairo_rectangle_t *extents) { - cairo_traps_t *traps = closure; + cairo_composite_traps_info_t *info = closure; cairo_pattern_union_t pattern; cairo_status_t status; if (dst_x != 0 || dst_y != 0) - _cairo_traps_translate (traps, - dst_x, - dst_y); + _cairo_traps_translate (info->traps, - dst_x, - dst_y); _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); if (!src) src = &pattern.base; status = _cairo_surface_composite_trapezoids (operator, - src, dst, + src, dst, info->antialias, extents->x, extents->y, extents->x - dst_x, extents->y - dst_y, extents->width, extents->height, - traps->traps, - traps->num_traps); + info->traps->traps, + info->traps->num_traps); _cairo_pattern_fini (&pattern.base); return status; @@ -1285,11 +1291,13 @@ _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src, cairo_operator_t operator, cairo_surface_t *dst, cairo_traps_t *traps, - cairo_clip_t *clip) + cairo_clip_t *clip, + cairo_antialias_t antialias) { cairo_status_t status; pixman_region16_t *trap_region; cairo_rectangle_t extents; + cairo_composite_traps_info_t traps_info; if (traps->num_traps == 0) return CAIRO_STATUS_SUCCESS; @@ -1350,10 +1358,12 @@ _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src, goto out; } + traps_info.traps = traps; + traps_info.antialias = antialias; + status = _cairo_gstate_clip_and_composite (clip, operator, src, - _composite_traps_draw_func, traps, - dst, - &extents); + _composite_traps_draw_func, &traps_info, + dst, &extents); out: if (trap_region) @@ -1376,7 +1386,8 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, gstate->operator, gstate->target, traps, - &gstate->clip); + &gstate->clip, + gstate->antialias); _cairo_pattern_fini (&pattern.base); @@ -1545,7 +1556,7 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { return _cairo_clip_clip (&gstate->clip, path, gstate->fill_rule, gstate->tolerance, - gstate->target); + gstate->antialias, gstate->target); } static void @@ -2005,3 +2016,19 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, free (transformed_glyphs); return status; } + +cairo_private cairo_status_t +_cairo_gstate_set_antialias (cairo_gstate_t *gstate, + cairo_antialias_t antialias) +{ + gstate->antialias = antialias; + + return CAIRO_STATUS_SUCCESS; +} + +cairo_private cairo_antialias_t +_cairo_gstate_get_antialias (cairo_gstate_t *gstate) +{ + return gstate->antialias; +} + diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 7c284b467..f7dbc8cfe 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -655,34 +655,6 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } -static pixman_image_t * -_create_mask_image (int width, - int height) -{ - pixman_image_t *image; - pixman_color_t pixman_color = { 0, 0, 0, 0 }; /* transparent */ - pixman_rectangle_t rect; - pixman_format_t *format; - - format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); - if (!format) - return NULL; - - image = pixman_image_create (format, width, height); - if (!image) - return NULL; - - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - - pixman_fill_rectangles (PIXMAN_OPERATOR_SRC, image, - &pixman_color, &rect, 1); - - return image; -} - static cairo_bool_t _cairo_image_surface_is_alpha_only (cairo_image_surface_t *surface) { @@ -701,6 +673,7 @@ static cairo_int_status_t _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, @@ -715,6 +688,10 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, cairo_image_surface_t *src; cairo_int_status_t status; pixman_image_t *mask; + pixman_format_t *format; + pixman_bits_t *mask_data; + int mask_stride; + int mask_bpp; /* Special case adding trapezoids onto a mask surface; we want to avoid * creating an intermediate temporary mask unecessarily. @@ -732,7 +709,8 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, if (operator == CAIRO_OPERATOR_ADD && _cairo_pattern_is_opaque_solid (pattern) && _cairo_image_surface_is_alpha_only (dst) && - !dst->has_clip) + !dst->has_clip && + antialias != CAIRO_ANTIALIAS_NONE) { pixman_add_trapezoids (dst->pixman_image, 0, 0, (pixman_trapezoid_t *) traps, num_traps); @@ -750,10 +728,37 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, if (status) goto CLEANUP_SOURCE; - mask = _create_mask_image (width, height); + switch (antialias) { + case CAIRO_ANTIALIAS_NONE: + format = pixman_format_create (PIXMAN_FORMAT_NAME_A1); + mask_stride = (width + 31)/8; + mask_bpp = 1; + break; + default: + format = pixman_format_create (PIXMAN_FORMAT_NAME_A8); + mask_stride = (width + 3) & ~3; + mask_bpp = 8; + break; + } + if (!format) { + status = CAIRO_STATUS_NO_MEMORY; + goto CLEANUP_SOURCE; + } + + /* The image must be initially transparent */ + mask_data = calloc (1, mask_stride * height); + if (!mask_data) { + status = CAIRO_STATUS_NO_MEMORY; + pixman_format_destroy (format); + goto CLEANUP_SOURCE; + } + + mask = pixman_image_create_for_data (mask_data, format, width, height, + mask_bpp, mask_stride); + pixman_format_destroy (format); if (!mask) { status = CAIRO_STATUS_NO_MEMORY; - goto CLEANUP_MASK; + goto CLEANUP_IMAGE_DATA; } /* XXX: The pixman_trapezoid_t cast is evil and needs to go away @@ -771,9 +776,11 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, dst_x, dst_y, width, height); - CLEANUP_MASK: pixman_image_destroy (mask); + CLEANUP_IMAGE_DATA: + free (mask_data); + CLEANUP_SOURCE: _cairo_pattern_release_surface (pattern, &src->base, &attributes); diff --git a/src/cairo-meta-surface-private.h b/src/cairo-meta-surface-private.h index 234c6ccfc..f37a89164 100644 --- a/src/cairo-meta-surface-private.h +++ b/src/cairo-meta-surface-private.h @@ -77,6 +77,7 @@ typedef struct _cairo_command_composite_trapezoids { cairo_command_type_t type; cairo_operator_t operator; cairo_pattern_union_t pattern; + cairo_antialias_t antialias; int x_src; int y_src; int x_dst; @@ -99,6 +100,7 @@ typedef struct _cairo_command_intersect_clip_path { cairo_path_fixed_t path; cairo_fill_rule_t fill_rule; double tolerance; + cairo_antialias_t antialias; } cairo_command_intersect_clip_path_t; typedef struct _cairo_command_show_glyphs { @@ -123,6 +125,7 @@ typedef struct _cairo_command_fill_path { cairo_path_fixed_t path; cairo_fill_rule_t fill_rule; double tolerance; + cairo_antialias_t antialias; } cairo_command_fill_path_t; typedef union _cairo_command { diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index 3781fabc3..f218ae240 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -217,6 +217,7 @@ static cairo_int_status_t _cairo_meta_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_surface, + cairo_antialias_t antialias, int x_src, int y_src, int x_dst, @@ -236,6 +237,7 @@ _cairo_meta_surface_composite_trapezoids (cairo_operator_t operator, command->type = CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS; command->operator = operator; _cairo_pattern_init_copy (&command->pattern.base, pattern); + command->antialias = antialias; command->x_src = x_src; command->y_src = y_src; command->x_dst = x_dst; @@ -267,7 +269,8 @@ static cairo_int_status_t _cairo_meta_surface_intersect_clip_path (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance) + double tolerance, + cairo_antialias_t antialias) { cairo_meta_surface_t *meta = dst; cairo_command_intersect_clip_path_t *command; @@ -291,6 +294,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst, } command->fill_rule = fill_rule; command->tolerance = tolerance; + command->antialias = antialias; if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { if (path) @@ -494,6 +498,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, (command->composite_trapezoids.operator, &command->composite_trapezoids.pattern.base, target, + command->composite_trapezoids.antialias, command->composite_trapezoids.x_src, command->composite_trapezoids.y_src, command->composite_trapezoids.x_dst, @@ -514,6 +519,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, command->intersect_clip_path.path_pointer, command->intersect_clip_path.fill_rule, command->intersect_clip_path.tolerance, + command->intersect_clip_path.antialias, target); break; @@ -566,7 +572,8 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, command->fill_path.operator, target, &traps, - &clip); + &clip, + command->fill_path.antialias); _cairo_traps_fini (&traps); break; diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index c068c8aaf..6b863721e 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1151,6 +1151,7 @@ static cairo_int_status_t _cairo_pdf_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, + cairo_antialias_t antialias, int x_src, int y_src, int x_dst, @@ -1334,7 +1335,8 @@ static cairo_int_status_t _cairo_pdf_surface_intersect_clip_path (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance) + double tolerance, + cairo_antialias_t antialias) { cairo_pdf_surface_t *surface = dst; cairo_pdf_document_t *document = surface->document; diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 0b2962c28..a897ed0ef 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -272,6 +272,7 @@ static cairo_int_status_t _cairo_ps_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, + cairo_antialias_t antialias, int x_src, int y_src, int x_dst, @@ -286,6 +287,7 @@ _cairo_ps_surface_composite_trapezoids (cairo_operator_t operator, return _cairo_surface_composite_trapezoids (operator, pattern, surface->current_page, + antialias, x_src, y_src, x_dst, @@ -324,14 +326,16 @@ static cairo_int_status_t _cairo_ps_surface_intersect_clip_path (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance) + double tolerance, + cairo_antialias_t antialias) { cairo_ps_surface_t *surface = dst; return _cairo_surface_intersect_clip_path (surface->current_page, path, fill_rule, - tolerance); + tolerance, + antialias); } static cairo_int_status_t @@ -929,6 +933,7 @@ static cairo_int_status_t _ps_output_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, + cairo_antialias_t antialias, int x_src, int y_src, int x_dst, @@ -1054,7 +1059,8 @@ static cairo_int_status_t _ps_output_intersect_clip_path (void *abstract_surface, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance) + double tolerance, + cairo_antialias_t antialias) { ps_output_surface_t *surface = abstract_surface; cairo_output_stream_t *stream = surface->parent->stream; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 6c0c76919..8353d329a 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -991,6 +991,7 @@ static cairo_status_t _fallback_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, cairo_surface_t *dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, @@ -1043,6 +1044,7 @@ _fallback_composite_trapezoids (cairo_operator_t operator, state.image->base.backend->composite_trapezoids (operator, pattern, &state.image->base, + antialias, src_x, src_y, dst_x - state.image_rect.x, dst_y - state.image_rect.y, @@ -1060,6 +1062,7 @@ cairo_status_t _cairo_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, cairo_surface_t *dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, @@ -1080,6 +1083,7 @@ _cairo_surface_composite_trapezoids (cairo_operator_t operator, if (dst->backend->composite_trapezoids) { status = dst->backend->composite_trapezoids (operator, pattern, dst, + antialias, src_x, src_y, dst_x, dst_y, width, height, @@ -1089,6 +1093,7 @@ _cairo_surface_composite_trapezoids (cairo_operator_t operator, } return _fallback_composite_trapezoids (operator, pattern, dst, + antialias, src_x, src_y, dst_x, dst_y, width, height, @@ -1191,7 +1196,8 @@ _cairo_surface_reset_clip (cairo_surface_t *surface) status = surface->backend->intersect_clip_path (surface, NULL, CAIRO_FILL_RULE_WINDING, - 0); + 0, + CAIRO_ANTIALIAS_DEFAULT); if (status) return status; } @@ -1237,7 +1243,8 @@ cairo_int_status_t _cairo_surface_intersect_clip_path (cairo_surface_t *surface, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance) + double tolerance, + cairo_antialias_t antialias) { if (surface->status) return surface->status; @@ -1250,7 +1257,8 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface, return surface->backend->intersect_clip_path (surface, path, fill_rule, - tolerance); + tolerance, + antialias); } static cairo_status_t @@ -1269,7 +1277,8 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface, return surface->backend->intersect_clip_path (surface, &clip_path->path, clip_path->fill_rule, - clip_path->tolerance); + clip_path->tolerance, + clip_path->antialias); } /** @@ -1299,7 +1308,8 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface, status = surface->backend->intersect_clip_path (surface, NULL, CAIRO_FILL_RULE_WINDING, - 0); + 0, + CAIRO_ANTIALIAS_DEFAULT); if (status) return status; diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index 05e39b55e..2a7395f6e 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -942,6 +942,7 @@ static cairo_int_status_t _cairo_xcb_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, @@ -980,9 +981,17 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t operator, render_src_x = src_x + render_reference_x - dst_x; render_src_y = src_y + render_reference_y - dst_y; + switch (antialias) { + case CAIRO_ANTIALIAS_NONE: + render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1), + break; + default: + render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8), + break; + } + /* XXX: The XTrapezoid cast is evil and needs to go away somehow. */ /* XXX: _format_from_cairo is slow. should cache something. */ - render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8), status = _cairo_xcb_surface_set_attributes (src, &attributes); if (status == CAIRO_STATUS_SUCCESS) XCBRenderTrapezoids (dst->dpy, diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 9c87cc95d..7f4b84893 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -1266,8 +1266,8 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst, int dst_x, int dst_y, int width, - int height) - + int height, + XRenderPictFormat *pict_format) { XRenderColor transparent = { 0, 0, 0, 0 }; XRenderColor solid = { 0xffff, 0xffff, 0xffff, 0xffff }; @@ -1304,7 +1304,7 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst, XRenderCompositeTrapezoids (dst->dpy, PictOpAdd, solid_picture, mask_picture, - XRenderFindStandardFormat (dst->dpy, PictStandardA8), + pict_format, 0, 0, offset_traps, num_traps); @@ -1318,6 +1318,7 @@ static cairo_int_status_t _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, void *abstract_dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, @@ -1334,6 +1335,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, composite_operation_t operation; int render_reference_x, render_reference_y; int render_src_x, render_src_y; + XRenderPictFormat *pict_format; if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1354,6 +1356,15 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, status = CAIRO_INT_STATUS_UNSUPPORTED; goto FAIL; } + + switch (antialias) { + case CAIRO_ANTIALIAS_NONE: + pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA1); + break; + default: + pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA8); + break; + } if (traps[0].left.p1.y < traps[0].left.p2.y) { render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x); @@ -1382,7 +1393,8 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, * the mask somewhat cheaper.) */ Picture mask_picture = _create_trapezoid_mask (dst, traps, num_traps, - dst_x, dst_y, width, height); + dst_x, dst_y, width, height, + pict_format); if (!mask_picture) { status = CAIRO_STATUS_NO_MEMORY; goto FAIL; @@ -1406,7 +1418,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, XRenderCompositeTrapezoids (dst->dpy, _render_operator (operator), src->src_picture, dst->dst_picture, - XRenderFindStandardFormat (dst->dpy, PictStandardA8), + pict_format, render_src_x + attributes.x_offset, render_src_y + attributes.y_offset, (XTrapezoid *) traps, num_traps); diff --git a/src/cairo.c b/src/cairo.c index 05c87a423..4c4b03ebe 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -535,6 +535,32 @@ cairo_set_tolerance (cairo_t *cr, double tolerance) _cairo_set_error (cr, cr->status); } +/** + * cairo_set_antialias: + * @cr: a #cairo_t + * @antialias: the new antialiasing mode + * + * Set the antialiasing mode of the rasterizer used for drawing shapes. + * This value is a hint, and a particular backend may or may not support + * a particular value. At the current time, no backend supports + * %CAIRO_ANTIALIAS_SUBPIXEL when drawing shapes. + * + * Note that this option does not affect text rendering, instead see + * cairo_font_options_set_antialias(). + **/ +void +cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) +{ + if (cr->status) { + _cairo_set_error (cr, cr->status); + return; + } + + cr->status = _cairo_gstate_set_antialias (cr->gstate, antialias); + if (cr->status) + _cairo_set_error (cr, cr->status); +} + /** * cairo_set_fill_rule: * @cr: a #cairo_t @@ -2081,6 +2107,20 @@ cairo_get_tolerance (cairo_t *cr) return _cairo_gstate_get_tolerance (cr->gstate); } +/** + * cairo_get_antialias: + * @cr: a cairo context + * + * Gets the current shape antialiasing mode, as set by cairo_set_shape_antialias(). + * + * Return value: the current shape antialiasing mode. + **/ +cairo_antialias_t +cairo_get_antialias (cairo_t *cr) +{ + return _cairo_gstate_get_antialias (cr->gstate); +} + /** * cairo_get_current_point: * @cr: a cairo context diff --git a/src/cairo.h b/src/cairo.h index 41310be32..1d871c812 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -287,6 +287,29 @@ cairo_set_source_surface (cairo_t *cr, void cairo_set_tolerance (cairo_t *cr, double tolerance); +/** + * cairo_antialias_t: + * @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for + * the subsystem and target device + * @CAIRO_ANTIALIAS_NONE: Use a bilevel alpha mask + * @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using + * shades of gray for black text on a white background, for example). + * @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking + * advantage of the order of subpixel elements on devices + * such as LCD panels + * + * Specifies the type of antialiasing to do when rendering text or shapes. + **/ +typedef enum _cairo_antialias { + CAIRO_ANTIALIAS_DEFAULT, + CAIRO_ANTIALIAS_NONE, + CAIRO_ANTIALIAS_GRAY, + CAIRO_ANTIALIAS_SUBPIXEL +} cairo_antialias_t; + +void +cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias); + /** * cairo_fill_rule_t * @CAIRO_FILL_RULE_WINDING: If the path crosses the ray from @@ -659,26 +682,6 @@ typedef enum _cairo_font_weight { CAIRO_FONT_WEIGHT_BOLD } cairo_font_weight_t; -/** - * cairo_antialias_t: - * @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for - * the font subsystem and target device - * @CAIRO_ANTIALIAS_NONE: Do no antialiasing of fonts; use bilevel text - * @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using - * shades of gray for black text on a white background, for example). - * @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking - * advantage of the order of subpixel elements on devices - * such as LCD panels - * - * Specifies the type of antialiasing to do when rendering text. - **/ -typedef enum _cairo_antialias { - CAIRO_ANTIALIAS_DEFAULT, - CAIRO_ANTIALIAS_NONE, - CAIRO_ANTIALIAS_GRAY, - CAIRO_ANTIALIAS_SUBPIXEL -} cairo_antialias_t; - /** * cairo_subpixel_order_t: * @CAIRO_SUBPIXEL_ORDER_DEFAULT: Use the default subpixel order for @@ -920,6 +923,9 @@ cairo_get_source (cairo_t *cr); double cairo_get_tolerance (cairo_t *cr); +cairo_antialias_t +cairo_get_antialias (cairo_t *cr); + void cairo_get_current_point (cairo_t *cr, double *x, double *y); diff --git a/src/cairoint.h b/src/cairoint.h index b0a78784c..2a5f45e35 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -728,6 +728,7 @@ typedef struct _cairo_surface_backend { (*composite_trapezoids) (cairo_operator_t operator, cairo_pattern_t *pattern, void *dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, @@ -778,7 +779,8 @@ typedef struct _cairo_surface_backend { (*intersect_clip_path) (void *dst, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance); + double tolerance, + cairo_antialias_t antialias); /* Get the extents of the current surface. For many surface types * this will be as simple as { x=0, y=0, width=surface->width, @@ -1607,6 +1609,7 @@ cairo_private cairo_status_t _cairo_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, cairo_surface_t *dst, + cairo_antialias_t antialias, int src_x, int src_y, int dst_x, @@ -1621,7 +1624,8 @@ _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src, cairo_operator_t operator, cairo_surface_t *dst, cairo_traps_t *traps, - cairo_clip_t *clip); + cairo_clip_t *clip, + cairo_antialias_t antialias); cairo_private cairo_status_t _cairo_surface_copy_page (cairo_surface_t *surface); @@ -1676,7 +1680,8 @@ cairo_private cairo_int_status_t _cairo_surface_intersect_clip_path (cairo_surface_t *surface, cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, - double tolerance); + double tolerance, + cairo_antialias_t antialias); cairo_private cairo_status_t _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip); @@ -1954,6 +1959,13 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src, cairo_surface_attributes_t *src_attributes, cairo_surface_attributes_t *mask_attributes); +cairo_private cairo_status_t +_cairo_gstate_set_antialias (cairo_gstate_t *gstate, + cairo_antialias_t antialias); + +cairo_private cairo_antialias_t +_cairo_gstate_get_antialias (cairo_gstate_t *gstate); + /* cairo_unicode.c */ diff --git a/test/Makefile.am b/test/Makefile.am index 29ccb8ecc..e30af427b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -42,6 +42,7 @@ text-rotate \ transforms \ translate-show-surface \ trap-clip \ +unantialiased-shapes \ unbounded-operator \ user-data \ rel-path @@ -99,6 +100,7 @@ text-antialias-none-ref.png \ transforms-ref.png \ translate-show-surface-ref.png \ trap-clip-ref.png \ +unantialiased-shapes-ref.png \ unbounded-operator-ref.png \ rel-path-ref.png @@ -200,6 +202,7 @@ text_rotate_LDADD = $(LDADDS) transforms_LDADD = $(LDADDS) translate_show_surface_LDADD = $(LDADDS) trap_clip_LDADD = $(LDADDS) +unantialiased_shapes_LDADD = $(LDADDS) unbounded_operator_LDADD = $(LDADDS) user_data_LDADD = $(LDADDS) rel_path_LDADD = $(LDADDS) diff --git a/test/unantialiased-shapes-ref.png b/test/unantialiased-shapes-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..b948592247ce1b1fb0052e4c9eecd1519943de1c GIT binary patch literal 4450 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 oPIE#+NB{r; literal 0 HcmV?d00001 diff --git a/test/unantialiased-shapes.c b/test/unantialiased-shapes.c new file mode 100644 index 000000000..eaadf417a --- /dev/null +++ b/test/unantialiased-shapes.c @@ -0,0 +1,103 @@ +/* + * Copyright © 2005 Billy Biggs + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Billy Biggs not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Billy Biggs makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * BILLY BIGGS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL BILLY BIGGS BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Billy Biggs + */ + +#include "cairo-test.h" + +cairo_test_t test = { + "unantialiased-shapes", + "Test shape drawing without antialiasing", + 320, 240 +}; + +/* The star shape from the SVG test suite, from the fill rule test */ +static void +big_star_path (cairo_t *cr) +{ + cairo_move_to (cr, 40, 0); + cairo_rel_line_to (cr, 25, 80); + cairo_rel_line_to (cr, -65, -50); + cairo_rel_line_to (cr, 80, 0); + cairo_rel_line_to (cr, -65, 50); + cairo_close_path (cr); +} + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + int i; + + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_paint (cr); + + cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE); + + /* Try a circle */ + cairo_arc (cr, 40, 40, 20, 0, 2 * M_PI); + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_fill (cr); + + /* Try using clipping to draw a circle */ + cairo_arc (cr, 100, 40, 20, 0, 2 * M_PI); + cairo_clip (cr); + cairo_rectangle (cr, 80, 20, 40, 40); + cairo_set_source_rgb (cr, 0, 0, 1); + cairo_fill (cr); + + /* Reset the clipping */ + cairo_reset_clip (cr); + + /* Draw a bunch of lines */ + cairo_set_line_width (cr, 1.0); + cairo_set_source_rgb (cr, 0, 1, 0); + for (i = 0; i < 10; i++) { + cairo_move_to (cr, 10, 70 + (i * 4)); + cairo_line_to (cr, 120, 70 + (i * 18)); + cairo_stroke (cr); + } + + /* Try filling a poly */ + cairo_translate (cr, 160, 120); + cairo_set_source_rgb (cr, 1, 1, 0); + big_star_path (cr); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + cairo_fill (cr); + cairo_translate (cr, -160, -120); + + /* How about some curves? */ + cairo_set_source_rgb (cr, 1, 0, 1); + for (i = 0; i < 10; i++) { + cairo_move_to (cr, 150, 50 + (i * 5)); + cairo_curve_to (cr, 250, 50, 200, (i * 10), 300, 50 + (i * 10)); + cairo_stroke (cr); + } + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +}