From 61e28ec71f5492671d633ccf9459b6654f33edd6 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 28 Jul 2005 12:45:26 +0000 Subject: Add -head to CAIRO_VERSION after tagging with SNAPSHOT_0_6_0. --- ChangeLog | 5 +++++ configure.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 25f8a8f7..66bf7cbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-07-28 Carl Worth + + * configure.in: Add -head to CAIRO_VERSION after tagging with + SNAPSHOT_0_6_0. + 2005-07-28 Carl Worth * NEWS: Added notes for snapshot 0.6.0 diff --git a/configure.in b/configure.in index 27fe96fa..f1b503e2 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(src/cairo.h) dnl =========================================================================== # Package version number, (as distinct from shared library version) -CAIRO_VERSION=0.6.0 +CAIRO_VERSION=0.6.0-head # libtool shared library version -- cgit v1.2.3 From 6d8d18e2dcdb2c829ec25659c1397f258c6b5a6b Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 28 Jul 2005 14:41:36 +0000 Subject: Add notes for snapshot 0.1.6. Increment version to 0.1.6. --- pixman/ChangeLog | 6 ++++++ pixman/NEWS | 24 ++++++++++++++++++++++++ pixman/configure.in | 2 +- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 505188de..4f481fe9 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,9 @@ +2005-07-28 Carl Worth + + * NEWS: Add notes for snapshot 0.1.6. + + * configure.in: Increment version to 0.1.6. + 2005-07-27 Owen Taylor * src/icint.h (FbGetStipPixels): Fix units for stride return diff --git a/pixman/NEWS b/pixman/NEWS index f800d0e2..a52095c6 100644 --- a/pixman/NEWS +++ b/pixman/NEWS @@ -1,3 +1,27 @@ +Snapshot 0.1.6 (2005-07-28 Carl Worth ) +========================================================== +Behavioral changes +------------------ +Clips are changed to only affect destination operands, not +sources. This gives the desired behavior for cairo. If the X server's +Render implementation wants to use pixman it will have to select +source clipping, (presumably through a new API call that we can add at +that poin). + +Bug fixes +--------- +Fix leak of the clip region associated with an image in +pixman_image_destroy. + +Fix units for stride return to be FbStip-sized, (this bug was causing +non antialiased text in cairo to appear as garbage). + +Other changes +------------- +The implementation has been merged considerably with xserver/fb. Most +of the merge was just name changes, but there were likely some bug +fixes or performance improvements in there as well. + Snapshot 0.1.5 (2005-05-18 Carl Worth ) ========================================================== Bug fixes diff --git a/pixman/configure.in b/pixman/configure.in index e65a130e..57757afb 100644 --- a/pixman/configure.in +++ b/pixman/configure.in @@ -7,7 +7,7 @@ AC_INIT(src/pixman.h) dnl =========================================================================== # Package version number, (as distinct from shared library version) -LIBPIXMAN_VERSION=0.1.5-head +LIBPIXMAN_VERSION=0.1.6 # libtool shared library version -- cgit v1.2.3 From 3dd93a930f618df42f71c5961764753d0d53306b Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 28 Jul 2005 14:58:25 +0000 Subject: Add -head to LIBPIXMAN_VERSION after tagging with SNAPSHOT_0_1_6. --- pixman/ChangeLog | 5 +++++ pixman/RELEASING | 2 +- pixman/configure.in | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 4f481fe9..43616925 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,8 @@ +2005-07-28 Carl Worth + + * configure.in: Add -head to LIBPIXMAN_VERSION after tagging with + SNAPSHOT_0_1_6. + 2005-07-28 Carl Worth * NEWS: Add notes for snapshot 0.1.6. diff --git a/pixman/RELEASING b/pixman/RELEASING index 84349a99..bb7ad05a 100644 --- a/pixman/RELEASING +++ b/pixman/RELEASING @@ -75,7 +75,7 @@ fixes are committed. Here are the steps to follow: cvs tag SNAPSHOT_X_Y_Z -8) Add a "-head" to CAIRO_VERSION in configure, and commit. +8) Add a "-head" to LIBPIXMAN_VERSION in configure, and commit. 9) Send a message to cairo-announce@cairographics.org to announce the new snapshot using the text provided from "make release-publish". diff --git a/pixman/configure.in b/pixman/configure.in index 57757afb..1ee59697 100644 --- a/pixman/configure.in +++ b/pixman/configure.in @@ -7,7 +7,7 @@ AC_INIT(src/pixman.h) dnl =========================================================================== # Package version number, (as distinct from shared library version) -LIBPIXMAN_VERSION=0.1.6 +LIBPIXMAN_VERSION=0.1.6-head # libtool shared library version -- cgit v1.2.3 From 5f6c5026e66c6325f2decf25300abede587fa4dc Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 28 Jul 2005 15:38:50 +0000 Subject: CC gnome-announce-list@gnome.org on cairo release announcements. --- ChangeLog | 5 +++++ RELEASING | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 66bf7cbf..3a3d8fc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-07-28 Carl Worth + + * RELEASING: CC gnome-announce-list@gnome.org on cairo release + announcements. + 2005-07-28 Carl Worth * configure.in: Add -head to CAIRO_VERSION after tagging with diff --git a/RELEASING b/RELEASING index c6513f45..b25d127e 100644 --- a/RELEASING +++ b/RELEASING @@ -81,6 +81,7 @@ fixes are committed. Here are the steps to follow: 8) Add a "-head" to CAIRO_VERSION in configure, and commit. -9) Send a message to cairo-announce@cairographics.org to announce the +9) Send a message to cairo-announce@cairographics.org and CC + gnome-announce-list to announce the new snapshot using the text provided from "make release-publish". -- cgit v1.2.3 From 26289b366434103eda1dd619d8bad0e9394724d6 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 28 Jul 2005 15:55:00 +0000 Subject: Add two new tests: mask-ctm mask-surface-ctm demonstrating that masks are not currently being modified by the CTM. --- ChangeLog | 13 +++++++ test/.cvsignore | 2 ++ test/Makefile.am | 6 ++++ test/mask-ctm-ref.png | Bin 0 -> 129 bytes test/mask-ctm.c | 82 ++++++++++++++++++++++++++++++++++++++++++ test/mask-surface-ctm-ref.png | Bin 0 -> 129 bytes test/mask-surface-ctm.c | 75 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 178 insertions(+) create mode 100644 test/mask-ctm-ref.png create mode 100644 test/mask-ctm.c create mode 100644 test/mask-surface-ctm-ref.png create mode 100644 test/mask-surface-ctm.c diff --git a/ChangeLog b/ChangeLog index 3a3d8fc0..4eda2b5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-07-28 Carl Worth + + * test/.cvsignore: + * test/Makefile.am: + * test/mask-ctm-ref.png: + * test/mask-ctm.c: (draw), (main): + * test/mask-surface-ctm-ref.png: + * test/mask-surface-ctm.c: (draw), (main): Add two new tests: + mask-ctm + mask-surface-ctm + demonstrating that masks are not currently being modified by the + CTM. + 2005-07-28 Carl Worth * RELEASING: CC gnome-announce-list@gnome.org on cairo release diff --git a/test/.cvsignore b/test/.cvsignore index 1d037fa0..557831c0 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -20,6 +20,8 @@ leaky-polygon line-width linear-gradient mask +mask-ctm +mask-surface-ctm move-to-show-surface paint paint-with-alpha diff --git a/test/Makefile.am b/test/Makefile.am index 649c4012..0f3a23ea 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -16,6 +16,8 @@ leaky-polygon \ line-width \ linear-gradient \ mask \ +mask-ctm \ +mask-surface-ctm \ move-to-show-surface \ paint \ paint-with-alpha \ @@ -72,6 +74,8 @@ leaky-polygon-ref.png \ line-width-ref.png \ linear-gradient-ref.png \ mask-ref.png \ +mask-ctm-ref.png \ +mask-surface-ctm-ref.png \ move-to-show-surface-ref.png \ paint-ref.png \ paint-with-alpha-ref.png \ @@ -161,6 +165,8 @@ leaky_polygon_LDADD = $(LDADDS) line_width_LDADD = $(LDADDS) linear_gradient_LDADD = $(LDADDS) mask_LDADD = $(LDADDS) +mask_ctm_LDADD = $(LDADDS) +mask_surface_ctm_LDADD = $(LDADDS) move_to_show_surface_LDADD = $(LDADDS) paint_LDADD = $(LDADDS) paint_with_alpha_LDADD = $(LDADDS) diff --git a/test/mask-ctm-ref.png b/test/mask-ctm-ref.png new file mode 100644 index 00000000..88a0402c Binary files /dev/null and b/test/mask-ctm-ref.png differ diff --git a/test/mask-ctm.c b/test/mask-ctm.c new file mode 100644 index 00000000..1fd48285 --- /dev/null +++ b/test/mask-ctm.c @@ -0,0 +1,82 @@ +/* + * Copyright © 2005 Red Hat, Inc. + * + * 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 + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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: Carl D. Worth + */ + +#include "cairo-test.h" + +cairo_test_t test = { + "mask-ctm", + "Test that cairo_mask is affected properly by the CTM", + 10, 10 +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *mask_surface; + cairo_pattern_t *mask; + unsigned long data[] = { + 0x80000000, 0x80000000, + 0x80000000, 0x80000000, + }; + cairo_matrix_t matrix; + + mask_surface = cairo_image_surface_create_for_data ((unsigned char *) data, + CAIRO_FORMAT_ARGB32, 2, 2, 8); + mask = cairo_pattern_create_for_surface (mask_surface); + cairo_surface_destroy (mask_surface); + + cairo_set_source_rgb (cr, 1.0, 0, 0); + + /* We can translate with the CTM, with the pattern matrix, or with + * both. */ + + /* 1. CTM alone. */ + cairo_save (cr); + { + cairo_translate (cr, 2, 2); + cairo_mask (cr, mask); + } + cairo_restore (cr); + + /* 2. Pattern matrix alone. */ + cairo_matrix_init_translate (&matrix, -4, -4); + cairo_pattern_set_matrix (mask, &matrix); + + cairo_mask (cr, mask); + + /* 3. CTM + pattern matrix */ + cairo_translate (cr, 2, 2); + cairo_mask (cr, mask); + + cairo_pattern_destroy (mask); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/mask-surface-ctm-ref.png b/test/mask-surface-ctm-ref.png new file mode 100644 index 00000000..744b1dd3 Binary files /dev/null and b/test/mask-surface-ctm-ref.png differ diff --git a/test/mask-surface-ctm.c b/test/mask-surface-ctm.c new file mode 100644 index 00000000..6eb2bf26 --- /dev/null +++ b/test/mask-surface-ctm.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2005 Red Hat, Inc. + * + * 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 + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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: Carl D. Worth + */ + +#include "cairo-test.h" + +cairo_test_t test = { + "mask-surface-ctm", + "Test that cairo_mask_surface is affected properly by the CTM", + 10, 10 +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *mask; + unsigned long data[] = { + 0x80000000, 0x80000000, + 0x80000000, 0x80000000, + }; + + mask = cairo_image_surface_create_for_data ((unsigned char *) data, + CAIRO_FORMAT_ARGB32, 2, 2, 8); + + cairo_set_source_rgb (cr, 1.0, 0, 0); + + /* We can translate with the CTM, with the mask_surface offset, or + * with both. */ + + /* 1. CTM alone. */ + cairo_save (cr); + { + cairo_translate (cr, 2, 2); + cairo_mask_surface (cr, mask, 0, 0); + } + cairo_restore (cr); + + /* 2. Offset alone. */ + cairo_mask_surface (cr, mask, 4, 4); + + /* 3. CTM + offset */ + cairo_translate (cr, 2, 2); + cairo_mask_surface (cr, mask, 4, 4); + + cairo_surface_destroy (mask); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +} -- cgit v1.2.3 From a0ca6026ad0ea049198e17dbda379d4737078053 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 28 Jul 2005 15:58:09 +0000 Subject: Run the mask pattern through the CTM in the same way as the source pattern. This fixes the bug demonstrated by the mask-ctm and mask-surface-ctm tests so they should no longer fail. --- ChangeLog | 7 +++++++ src/cairo-gstate.c | 16 ++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4eda2b5a..874bea6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-07-28 Carl Worth + + * src/cairo-gstate.c: (_cairo_gstate_mask): Run the mask pattern + through the CTM in the same way as the source pattern. This fixes + the bug demonstrated by the mask-ctm and mask-surface-ctm tests so + they should no longer fail. + 2005-07-28 Carl Worth * test/.cvsignore: diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index ed3359b9..50a6f2d2 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -877,7 +877,7 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, cairo_pattern_t *mask) { cairo_rectangle_t extents; - cairo_pattern_union_t pattern; + cairo_pattern_union_t source_pattern, mask_pattern; cairo_surface_pattern_t intermediate_pattern; cairo_pattern_t *effective_mask; cairo_status_t status; @@ -937,12 +937,15 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, mask_x = mask_y = 0; } - _cairo_pattern_init_copy (&pattern.base, gstate->source); - _cairo_gstate_pattern_transform (gstate, &pattern.base); + _cairo_pattern_init_copy (&source_pattern.base, gstate->source); + _cairo_gstate_pattern_transform (gstate, &source_pattern.base); + + _cairo_pattern_init_copy (&mask_pattern.base, effective_mask); + _cairo_gstate_pattern_transform (gstate, &mask_pattern.base); status = _cairo_surface_composite (gstate->operator, - &pattern.base, - effective_mask, + &source_pattern.base, + &mask_pattern.base, gstate->target, extents.x, extents.y, extents.x - mask_x, extents.y - mask_y, @@ -951,7 +954,8 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, if (gstate->clip.surface) _cairo_pattern_fini (&intermediate_pattern.base); - _cairo_pattern_fini (&pattern.base); + _cairo_pattern_fini (&source_pattern.base); + _cairo_pattern_fini (&mask_pattern.base); return status; } -- cgit v1.2.3 From 449087745b520c64113102f5c62bc5a8beba6c98 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Fri, 29 Jul 2005 12:45:01 +0000 Subject: src/cairo-font.c src/cairo-ft-font.c src/cairo-win32-font.c src/cairoint.h: Move the font options into the base cairo_scaled_font_t object so that we have them available to use when we are removing a scaled font from the cache. (http://bugzilla.gnome.org/show_bug.cgi?id=#311299, Ali Akcaagac, Behdad Esfahbod) --- ChangeLog | 9 +++++++++ src/cairo-font.c | 8 ++++++++ src/cairo-ft-font.c | 7 ++----- src/cairo-win32-font.c | 4 +--- src/cairoint.h | 17 ++++++++++------- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 874bea6a..ecb773fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-07-29 Owen Taylor + + * src/cairo-font.c src/cairo-ft-font.c src/cairo-win32-font.c + src/cairoint.h: Move the font options into the base + cairo_scaled_font_t object so that we have them available + to use when we are removing a scaled font from the cache. + (http://bugzilla.gnome.org/show_bug.cgi?id=#311299, + Ali Akcaagac, Behdad Esfahbod) + 2005-07-28 Carl Worth * src/cairo-gstate.c: (_cairo_gstate_mask): Run the mask pattern diff --git a/src/cairo-font.c b/src/cairo-font.c index 9645f3df..022be7da 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -466,6 +466,10 @@ static const cairo_scaled_font_t _cairo_scaled_font_nil = { { 1., 0., 0., 1., 0, 0}, /* font_matrix */ { 1., 0., 0., 1., 0, 0}, /* ctm */ { 1., 0., 0., 1., 0, 0}, /* scale */ + { CAIRO_ANTIALIAS_DEFAULT, /* options */ + CAIRO_SUBPIXEL_ORDER_DEFAULT, + CAIRO_HINT_STYLE_DEFAULT, + CAIRO_HINT_METRICS_DEFAULT} , NULL, /* font_face */ CAIRO_SCALED_FONT_BACKEND_DEFAULT, }; @@ -864,6 +868,7 @@ void _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, + const cairo_font_options_t *options, const cairo_scaled_font_backend_t *backend) { scaled_font->status = CAIRO_STATUS_SUCCESS; @@ -871,6 +876,8 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, scaled_font->font_matrix = *font_matrix; scaled_font->ctm = *ctm; cairo_matrix_multiply (&scaled_font->scale, &scaled_font->font_matrix, &scaled_font->ctm); + + scaled_font->options = *options; scaled_font->ref_count = 1; scaled_font->backend = backend; @@ -1071,6 +1078,7 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font) key.font_face = scaled_font->font_face; key.font_matrix = &scaled_font->font_matrix; key.ctm = &scaled_font->ctm; + key.options = scaled_font->options; _cairo_cache_remove (cache, &key); _unlock_global_font_cache (); diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index afe80dff..f6b0e9c0 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -1218,7 +1218,6 @@ const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = { typedef struct { cairo_scaled_font_t base; int load_flags; - cairo_font_options_t options; ft_unscaled_font_t *unscaled; } cairo_ft_scaled_font_t; @@ -1385,14 +1384,12 @@ _ft_scaled_font_create (ft_unscaled_font_t *unscaled, f->unscaled = unscaled; _cairo_unscaled_font_reference (&unscaled->base); - f->options = *options; - if (options->hint_metrics != CAIRO_HINT_METRICS_OFF) load_flags |= PRIVATE_FLAG_HINT_METRICS; f->load_flags = load_flags; - _cairo_scaled_font_init (&f->base, font_matrix, ctm, &cairo_ft_scaled_font_backend); + _cairo_scaled_font_init (&f->base, font_matrix, ctm, options, &cairo_ft_scaled_font_backend); return (cairo_scaled_font_t *)f; } @@ -1611,7 +1608,7 @@ _cairo_ft_scaled_font_font_extents (void *abstract_font, * Get to unscaled metrics so that the upper level can get back to * user space */ - if (scaled_font->options.hint_metrics != CAIRO_HINT_METRICS_OFF) { + if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) { double x_factor, y_factor; if (scaled_font->unscaled->x_scale == 0) diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index 15dd96b3..2867ab15 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -58,7 +58,6 @@ typedef struct { cairo_scaled_font_t base; LOGFONTW logfont; - cairo_font_options_t options; BYTE quality; @@ -227,7 +226,6 @@ _win32_scaled_font_create (LOGFONTW *logfont, return NULL; f->logfont = *logfont; - f->options = *options; /* We don't have any control over the hinting style or subpixel * order in the Win32 font API, so we ignore those parts of @@ -263,7 +261,7 @@ _win32_scaled_font_create (LOGFONTW *logfont, cairo_matrix_multiply (&scale, font_matrix, ctm); _compute_transform (f, &scale); - _cairo_scaled_font_init (&f->base, font_matrix, ctm, &cairo_win32_scaled_font_backend); + _cairo_scaled_font_init (&f->base, font_matrix, ctm, options, &cairo_win32_scaled_font_backend); return &f->base; } diff --git a/src/cairoint.h b/src/cairoint.h index 45747838..0e0cb713 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -458,13 +458,22 @@ struct _cairo_unscaled_font { const cairo_unscaled_font_backend_t *backend; }; +struct _cairo_font_options { + cairo_antialias_t antialias; + cairo_subpixel_order_t subpixel_order; + cairo_hint_style_t hint_style; + cairo_hint_metrics_t hint_metrics; +}; + struct _cairo_scaled_font { cairo_status_t status; int ref_count; cairo_matrix_t font_matrix; /* font space => user space */ cairo_matrix_t ctm; /* user space => device space */ cairo_matrix_t scale; /* font space => device space */ + cairo_font_options_t options; cairo_font_face_t *font_face; /* may be NULL */ + const cairo_scaled_font_backend_t *backend; }; @@ -475,13 +484,6 @@ struct _cairo_font_face { const cairo_font_face_backend_t *backend; }; -struct _cairo_font_options { - cairo_antialias_t antialias; - cairo_subpixel_order_t subpixel_order; - cairo_hint_style_t hint_style; - cairo_hint_metrics_t hint_metrics; -}; - /* cairo_font.c is responsible for a global glyph cache: * * - glyph entries: [[[base], cairo_unscaled_font_t, scale, flags, index], @@ -1320,6 +1322,7 @@ cairo_private void _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, + const cairo_font_options_t *options, const cairo_scaled_font_backend_t *backend); cairo_private void -- cgit v1.2.3 From ef4209a8a1fdcf7226bec2c6481a4f8239d63ec3 Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Fri, 29 Jul 2005 15:31:48 +0000 Subject: src/cairo-quartz-surface.c (_cairo_quartz_surface_acquire_dest_image): Minor updates to keep quartz backend limping along. --- ChangeLog | 6 ++++++ src/cairo-atsui-font.c | 1 + src/cairo-quartz-surface.c | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ecb773fd..b5d37120 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-07-29 T Rowley + + * src/cairo-atsui-font.c ( _cairo_atsui_font_create): + src/cairo-quartz-surface.c (_cairo_quartz_surface_acquire_dest_image): + Minor updates to keep quartz backend limping along. + 2005-07-29 Owen Taylor * src/cairo-font.c src/cairo-ft-font.c src/cairo-win32-font.c diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c index 990a2311..bf5ecb28 100644 --- a/src/cairo-atsui-font.c +++ b/src/cairo-atsui-font.c @@ -110,6 +110,7 @@ _cairo_atsui_font_create(const char *family, cairo_font_weight_t weight, const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, + const cairo_font_options_t *options, cairo_scaled_font_t **font_out) { cairo_atsui_font_t *font = NULL; diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index af92c010..0d847391 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -152,7 +152,8 @@ _cairo_quartz_surface_acquire_dest_image(void *abstract_surface, image_rect->height = surface->image->height; *image_out = surface->image; - *image_extra = NULL; + if (image_extra) + *image_extra = NULL; return CAIRO_STATUS_SUCCESS; } -- cgit v1.2.3 From 172e535ee05ab725ed1a951b31077843d112e7ca Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 29 Jul 2005 15:35:19 +0000 Subject: Remove completed 0.6 tasks. Add cairo_surface_flush to the cairo_surface_mark_dirty task. --- ChangeLog | 5 +++++ ROADMAP | 25 ++++--------------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5d37120..0192af0a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-07-29 Carl Worth + + * ROADMAP: Remove completed 0.6 tasks. Add cairo_surface_flush to + the cairo_surface_mark_dirty task. + 2005-07-29 T Rowley * src/cairo-atsui-font.c ( _cairo_atsui_font_create): diff --git a/ROADMAP b/ROADMAP index 7c2d049b..2f449127 100644 --- a/ROADMAP +++ b/ROADMAP @@ -1,22 +1,3 @@ -cairo 0.6 release requirements -============================== -The cairo 0.6 snapshot is intended to intended to have the last of the -API _changes_ prior to cairo 1.0. Here they are: - -API changes ------------ -✓ A9. consistent error handling for all objects - Difficulty: Easy to implement to get the API right. Hard to test. - Status: Done. - -✓ A10. cairo_font_options_t - Difficulty: Moderate - Status: Done. - -✓ A11. cairo_xlib_surface_create needs to be screen-aware - Difficulty: Easy - Status: Done. - cairo 1.0 release requirements ============================== Implementation work @@ -60,10 +41,12 @@ API additions (more detail in TODO file) krh, and otaylor answered all the tough questions it raised. There's not much work left to finish this one. - A7. cairo_surface_mark_dirty + A7. cairo_surface_mark_dirty and cairo_surface_flush Difficulty: trivial to add API, moderate to actually optimize based on it - Status: cworth has sent API proposal to list + Status: cworth has sent an API proposal to the list for + cairo_surface_mark_dirty. Recent discussions suggest + that cairo_surface_flush will need to reset the clip. ✓A12. cairo_xlib_surface_set_drawable Difficulty: Easy -- cgit v1.2.3 From 5ebf2c5d967fb84a2e102254421057af9bcd307a Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Sat, 30 Jul 2005 08:48:25 +0000 Subject: Add some optimizations from jaymz. Also adds some compile warnings that will hopefully go away as we continue merging. --- pixman/ChangeLog | 9 + pixman/src/ic.c | 595 +++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 504 insertions(+), 100 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 43616925..9b395b6c 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,12 @@ +2005-07-30 Jeff Muizelaar + + * src/ic.c: (fbCompositeSolidMask_nx8x0888), + (fbCompositeSolidMask_nx8x0565), (fbCompositeTrans_0565xnx0565), + (fbCompositeTrans_0888xnx0888), (fbCompositeSrcSrc_nxn), + (pixman_composite): + Add some optimizations from jaymz. Also adds some compile warnings + that will hopefully go away as we continue merging. + 2005-07-28 Carl Worth * configure.in: Add -head to LIBPIXMAN_VERSION after tagging with diff --git a/pixman/src/ic.c b/pixman/src/ic.c index 381afcd4..5d56ac3d 100644 --- a/pixman/src/ic.c +++ b/pixman/src/ic.c @@ -150,6 +150,51 @@ fbIn24 (CARD32 x, CARD8 y) (line) = ((type *) __bits__) + (stride) * ((y) + __yoff__) + (mul) * ((x) + __xoff__); \ } +#define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d))) + +#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \ + dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \ + drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ + *destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ + +#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \ + dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \ + drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ + *destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ + +// Note: this macro expects 6 bits of alpha, not 8! +#define fastCombine0565(alpha, source, destval, destptr) { \ + CARD16 dstrb = destval & 0xf81f; CARD16 dstg = destval & 0x7e0; \ + CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \ + destptr= ((((drb>>6) + dstrb)&0xf81f) | (((dg>>6) + dstg) & 0x7e0)); \ + } + +#if IMAGE_BYTE_ORDER == LSBFirst + #define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \ + temp=count&3; \ + where-=temp; \ + workingWhere=(CARD32 *)where; \ + workingVal=*workingWhere++; \ + count=4-temp; \ + workingVal>>=(8*temp) + #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)&0xff; (y)>>=8; (x)--;} + #define readPackedSource(where) readPacked(where,ws,workingSource,wsrc) + #define readPackedDest(where) readPacked(where,wd,workingiDest,widst) + #define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; *wodst++=workingoDest; } +#else + #warning "I havn't tested fbCompositeTrans_0888xnx0888() on big endian yet!" + #define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(int)where; \ + temp=count&3; \ + where-=temp; \ + workingWhere=(CARD32 *)where; \ + workingVal=*workingWhere++; \ + count=4-temp; \ + workingVal<<=(8*temp) + #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y=*z++; } where=(y)>>24; (y)<<=8; (x)--;} + #define readPackedSource(where) readPacked(where,ws,workingSource,wsrc) + #define readPackedDest(where) readPacked(where,wd,workingiDest,widst) + #define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; *wodst++=workingoDest; } +#endif /* * Naming convention: * @@ -287,6 +332,7 @@ fbCompositeSolidMask_nx8888x8888C (pixman_operator_t op, } } +#define srcAlphaCombine24(a,b) genericCombine24(a,b,srca,srcia) static void fbCompositeSolidMask_nx8x0888 (pixman_operator_t op, PicturePtr pSrc, @@ -301,52 +347,86 @@ fbCompositeSolidMask_nx8x0888 (pixman_operator_t op, CARD16 width, CARD16 height) { - CARD32 src, srca; - CARD8 *dstLine, *dst; + CARD32 src, srca, srcia; + CARD8 *dstLine, *dst, *edst; CARD32 d; CARD8 *maskLine, *mask, m; FbStride dstStride, maskStride; CARD16 w; + CARD32 rs,gs,bs,rd,gd,bd; fbComposeGetSolid(pSrc, src); srca = src >> 24; + srcia = 255-srca; if (src == 0) return; + + rs=src&0xff; + gs=(src>>8)&0xff; + bs=(src>>16)&0xff; fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - - while (height--) - { - dst = dstLine; - dstLine += dstStride; - mask = maskLine; - maskLine += maskStride; - w = width; - while (w--) + while (height--) { - m = *mask++; - if (m == 0xff) - { - if (srca == 0xff) - d = src; - else + // fixme: cleanup unused + unsigned int wt,wd; + CARD32 workingiDest; + CARD32 *widst; + + edst=dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + +#ifndef NO_MASKED_PACKED_READ + setupPackedReader(wd,wt,edst,widst,workingiDest); +#endif + + while (w--) { - d = Fetch24(dst); - d = fbOver24 (src, d); +#ifndef NO_MASKED_PACKED_READ + readPackedDest(rd); + readPackedDest(gd); + readPackedDest(bd); +#else + rd= *edst++; + gd= *edst++; + bd= *edst++; +#endif + m = *mask++; + if (m == 0xff) + { + if (srca == 0xff) + { + *dst++=rs; + *dst++=gs; + *dst++=bs; + } + else + { + *dst++=(srcAlphaCombine24(rs, rd)>>8); + *dst++=(srcAlphaCombine24(gs, gd)>>8); + *dst++=(srcAlphaCombine24(bs, bd)>>8); + } + } + else if (m) + { + int na=(srca*(int)m)>>8; + int nia=255-na; + *dst++=(genericCombine24(rs, rd, na, nia)>>8); + *dst++=(genericCombine24(gs, gd, na, nia)>>8); + *dst++=(genericCombine24(bs, bd, na, nia)>>8); + } + else + { + dst+=3; + } } - Store24(dst,d); - } - else if (m) - { - d = fbOver24 (fbIn(src,m), Fetch24(dst)); - Store24(dst,d); - } - dst += 3; } - } } static void @@ -363,55 +443,60 @@ fbCompositeSolidMask_nx8x0565 (pixman_operator_t op, CARD16 width, CARD16 height) { - CARD32 src, srca; + CARD32 src, srca,na, rsrca; CARD16 *dstLine, *dst; - CARD32 d; + CARD16 d; CARD8 *maskLine, *mask, m; FbStride dstStride, maskStride; - CARD16 w; + CARD16 w,src16; fbComposeGetSolid(pSrc, src); + src16 = cvt8888to0565(src); - srca = src >> 24; + rsrca = src >> 24; + srca=rsrca>>2; if (src == 0) - return; + return; fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - - while (height--) - { - dst = dstLine; - dstLine += dstStride; - mask = maskLine; - maskLine += maskStride; - w = width; - - while (w--) + + while (height--) { - m = *mask++; - if (m == 0xff) - { - if (srca == 0xff) - d = src; - else + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) { - d = *dst; - d = fbOver24 (src, cvt0565to8888(d)); + m = *mask++; + if (m == 0xff) + { + if (srca == 0xff) + { + *dst=src16; + } + else + { + d = *dst; + fastCombine0565(srca, src16, d, *dst++); + } + } + else if (m) + { + na=(rsrca*(int)m)>>10; + d = *dst; + fastCombine0565(na, src16, d, *dst++); + } + else + dst++; } - *dst = cvt8888to0565(d); - } - else if (m) - { - d = *dst; - d = fbOver24 (fbIn(src,m), cvt0565to8888(d)); - *dst = cvt8888to0565(d); - } - dst++; } - } } + static void fbCompositeSolidMask_nx8888x0565C (pixman_operator_t op, PicturePtr pSrc, @@ -910,7 +995,7 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, CARD32 s_32, d_32, i_32, r_32; fbComposeGetSolid (pMask, mask); - maskAlpha = mask >> 24; + maskAlpha = mask >> 26; if (!maskAlpha) return; @@ -926,26 +1011,272 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); while (height--) - { - dst = dstLine; - dstLine += dstStride; - src = srcLine; - srcLine += srcStride; - w = width; + { + CARD32 *isrc; + dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width; + + if(((int)src&1)==1) + { + s_16 = *src++; + d_16 = *dst; + fastCombine0565(maskAlpha, s_16, d_16, *dst++); + w--; + } + isrc=(CARD32 *)src; + while (w>1) + { + s_32=*isrc++; +#if IMAGE_BYTE_ORDER == LSBFirst + s_16=s_32&0xffff; +#else + s_16=s_32>>16; +#endif + d_16 = *dst; + fastCombine0565(maskAlpha, s_16, d_16, *dst++); +#if IMAGE_BYTE_ORDER == LSBFirst + s_16=s_32>>16; +#else + s_16=s_32&0xffff; +#endif + d_16 = *dst; + fastCombine0565(maskAlpha, s_16, d_16, *dst++); + w-=2; + } + src=(CARD16 *)isrc; + if(w!=0) + { + s_16 = *src; + d_16 = *dst; + fastCombine0565(maskAlpha, s_16, d_16, *dst); + } + } +} + + + +// macros for "i can't believe it's not fast" packed pixel handling +#define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha) +static void +fbCompositeTrans_0888xnx0888(pixman_operator_t op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD8 *dstLine, *dst,*idst; + CARD8 *srcLine, *src; + FbStride dstStride, srcStride; + CARD16 w; + FbBits mask; + CARD16 maskAlpha,maskiAlpha; + + fbComposeGetSolid (pMask, mask); + maskAlpha = mask >> 24; + maskiAlpha= 255-maskAlpha; + + if (!maskAlpha) + return; + //if (maskAlpha == 0xff) + //{ + //fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst, + // xSrc, ySrc, xMask, yMask, xDst, yDst, + // width, height); + //return; + //} + + fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3); + fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); - while (w--) { - s_16 = *src++; - s_32 = cvt0565to8888(s_16); - d_16 = *dst; - d_32 = cvt0565to8888(d_16); - - i_32 = fbIn24 (s_32, maskAlpha); - r_32 = fbOver24 (i_32, d_32); - r_16 = cvt8888to0565(r_32); - *dst++ = r_16; + unsigned int ws,wt,wd,ww; + CARD32 workingSource; + CARD32 *wsrc; + CARD32 rs,gs,bs; + CARD32 rd,gd,bd; + + CARD32 workingiDest,workingoDest; + CARD32 *widst,*wodst; + + + // are xSrc and xDst at the same alignment? if not, we need to be complicated :) + //if(0==0) + if( (((xSrc*3)&3)!=((xDst*3)&3)) || (srcStride&3)!=0 || (dstStride&3)!=0) + { + while (height--) + { + idst=dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width*3; + + setupPackedReader(wd,wt,idst,widst,workingiDest); + ww=(int)dst; + wt=ww&3; + dst-=wt; + wodst=(CARD32 *)dst; + workingoDest=*wodst; + ww=4-wt; +#if IMAGE_BYTE_ORDER == LSBFirst + workingoDest<<=(8*(ww+1)); +#else + workingoDest>>=(8*(ww+1)); +#endif + + // get to word aligned + switch(!(int)src&3) + { + case 1: + readPackedDest(rd); + rd=alphamaskCombine24(*src++, rd)>>8; + writePacked(rd); + w--; if(w==0) break; + case 2: + readPackedDest(rd); + rd=alphamaskCombine24(*src++, rd)>>8; + writePacked(rd); + w--; if(w==0) break; + case 3: + readPackedDest(rd); + rd=alphamaskCombine24(*src++, rd)>>8; + writePacked(rd); + w--; if(w==0) break; + } + wsrc=(CARD32 *)src; + while (w>3) + { + rs=*wsrc++; + // FIXME: write a version of readPackedDest() which + // can collect 4 bytes at once if we're on a boundry (which we're + // actually guarenteed not to be in this version, but do it anyhow), and can + // collect as 2 16bit words on a 2byte boundry, and then use the 32bit combine here +#if IMAGE_BYTE_ORDER == LSBFirst + readPackedDest(rd); + rd=alphamaskCombine24(rs&0xff, rd)>>8; + writePacked(rd); + + readPackedDest(rd); + rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8; + writePacked(rd); + + readPackedDest(rd); + rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8; + writePacked(rd); + + readPackedDest(rd); + rd=alphamaskCombine24(rs>>24, rd)>>8; + writePacked(rd); +#else + readPackedDest(rd); + rd=alphamaskCombine24(rs>>24, rd)>>8; + writePacked(rd); + + readPackedDest(rd); + rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8; + writePacked(rd); + + readPackedDest(rd); + rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8; + writePacked(rd); + + readPackedDest(rd); + rd=alphamaskCombine24(rs&0xff, rd)>>8; + writePacked(rd); +#endif + w-=4; + } + src=(CARD8 *)wsrc; + switch(w) + { + case 3: + readPackedDest(rd); + rd=alphamaskCombine24(*src++, rd)>>8; + writePacked(rd); + case 2: + readPackedDest(rd); + rd=alphamaskCombine24(*src++, rd)>>8; + writePacked(rd); + case 1: + readPackedDest(rd); + rd=alphamaskCombine24(*src++, rd)>>8; + writePacked(rd); + } + dst=(CARD8 *)wodst; + switch(ww) + { + case 1: + dst[2]=(workingoDest>>8)&0xff; + case 2: + dst[1]=(workingoDest>>16)&0xff; + case 3: + dst[0]=workingoDest>>24; + } + } + } + else + { + while (height--) + { + idst=dst = dstLine; + dstLine += dstStride; + src = srcLine; + srcLine += srcStride; + w = width*3; + // get to word aligned + switch(!(int)src&3) + { + case 1: + rd=alphamaskCombine24(*src++, *dst)>>8; + *dst++=rd; + w--; if(w==0) break; + case 2: + rd=alphamaskCombine24(*src++, *dst)>>8; + *dst++=rd; + w--; if(w==0) break; + case 3: + rd=alphamaskCombine24(*src++, *dst)>>8; + *dst++=rd; + w--; if(w==0) break; + } + wsrc=(CARD32 *)src; + widst=(CARD32 *)dst; + + register CARD32 t1, t2, t3, t4; + while(w>3) + { + rs = *wsrc++; + rd = *widst; + fastcombine32(maskAlpha, rs, rd, widst, t1, t2, t3, t4); + w-=4; + } + src=(CARD8 *)wsrc; + dst=(CARD8 *)widst; + switch(w) + { + case 3: + rd=alphamaskCombine24(*src++, *dst)>>8; + *dst++=rd; + case 2: + rd=alphamaskCombine24(*src++, *dst)>>8; + *dst++=rd; + case 1: + rd=alphamaskCombine24(*src++, *dst)>>8; + *dst++=rd; + } + } + } } - } } /* @@ -973,29 +1304,80 @@ fbCompositeSrcSrc_nxn (pixman_operator_t op, int dstXoff, dstYoff; int srcBpp; int dstBpp; + // these need to be signed now! + int iwidth=width; + int iheight=height; Bool reverse = FALSE; Bool upsidedown = FALSE; - - FbGetPixels(pSrc->pixels,src,srcStride,srcBpp,srcXoff,srcYoff); - FbGetPixels(pDst->pixels,dst,dstStride,dstBpp,dstXoff,dstYoff); - - fbBlt (src + (ySrc + srcYoff) * srcStride, - srcStride, - (xSrc + srcXoff) * srcBpp, - - dst + (yDst + dstYoff) * dstStride, - dstStride, - (xDst + dstXoff) * dstBpp, - - (width) * dstBpp, - (height), - - GXcopy, - FB_ALLONES, - dstBpp, - - reverse, - upsidedown); + int initialWidth=width; + int initialX=xDst; + + // FIXME: this is possibly the worst piece of code I've ever written. + // My main objection to it, is that it is incrfedibly slow in a few cases, due to the + // call-per-repeat structure of it - the *correct* solution is to implement + // repeat into fbBlt(), but that's a nontrivial job, and it's far more + // important to get the "requireRepeat" stuff implented functionally + // first, *then* make it fast. + // -- jj + Bool srcRepeat=pSrc->repeat; + CARD32 srcHeight=pSrc->pDrawable->height; + CARD32 srcWidth=pSrc->pDrawable->width; + + FbGetPixels(pSrc->pixels,src,srcStride,srcBpp,srcXoff,srcYoff); + FbGetPixels(pDst->pixels,dst,dstStride,dstBpp,dstXoff,dstYoff); + + if(srcRepeat) + { + xSrc%=srcWidth; + ySrc%=srcHeight; + } + + while(iheight>0) + { + int wheight=iheight; + if(wheight>(srcHeight-ySrc)) + wheight=(srcHeight-ySrc); + iwidth=initialWidth; + xDst=initialX; + while(iwidth>0) + { + int wwidth=iwidth; + if(wwidth>(srcWidth-xSrc)) + wwidth=(srcWidth-xSrc); + + fbBlt (src + (ySrc + srcYoff) * srcStride, + srcStride, + (xSrc + srcXoff) * srcBpp, + + dst + (yDst + dstYoff) * dstStride, + dstStride, + (xDst + dstXoff) * dstBpp, + + (wwidth) * dstBpp, + (wheight), + + GXcopy, + FB_ALLONES, + dstBpp, + + reverse, + upsidedown); + if(!srcRepeat) + iwidth=0; + else + { + xDst+=wwidth; + iwidth-=wwidth; + } + } + if(!srcRepeat) + iheight=0; + else + { + yDst+=wheight; + iheight-=wheight; + } + } } /* @@ -1164,7 +1546,13 @@ pixman_composite (pixman_operator_t op, if (pDst->format_code == pSrc->format_code) func = fbCompositeTrans_0565xnx0565; break; + case PICT_r8g8b8: + case PICT_b8g8r8: + if (pDst->format_code == pSrc->format_code) + func = fbCompositeTrans_0888xnx0888; + break; } + if (func != pixman_compositeGeneral) maskRepeat = FALSE; } @@ -1272,6 +1660,13 @@ pixman_composite (pixman_operator_t op, n = pixman_region_num_rects (region); pbox = pixman_region_rects (region); + // FIXME: this is bascially a "white list" of composites that work + // with repeat until they are all implented. Once that's done, we + // remove the checks below entirely + if(func==fbCompositeSrcSrc_nxn) + { + srcRepeat=maskRepeat=FALSE; + } while (n--) { h = pbox->y2 - pbox->y1; -- cgit v1.2.3 From bdfb7f4db0b48cf3882241b4b547082f68410567 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Sat, 30 Jul 2005 09:43:51 +0000 Subject: s/uint(8|16|32)_t/CARD(8|16|32)/ --- pixman/ChangeLog | 17 +++ pixman/src/iccompose.c | 280 ++++++++++++++++++++++++------------------------- 2 files changed, 157 insertions(+), 140 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 9b395b6c..0d64c6a9 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,20 @@ +2005-07-30 Jeff Muizelaar + + * src/iccompose.c: (fbCombineMaskAlphaU), + (fbCombineDisjointOutPart), (fbCombineDisjointInPart), + (fbCombineConjointOutPart), (fbCombineConjointInPart), + (fbStore_a8r8g8b8), (fbStore_x8r8g8b8), (fbStore_a8b8g8r8), + (fbStore_x8b8g8r8), (fbStore_r8g8b8), (fbStore_b8g8r8), + (fbStore_r5g6b5), (fbStore_b5g6r5), (fbStore_a1r5g5b5), + (fbStore_x1r5g5b5), (fbStore_a1b5g5r5), (fbStore_x1b5g5r5), + (fbStore_a4r4g4b4), (fbStore_x4r4g4b4), (fbStore_a4b4g4r4), + (fbStore_x4b4g4r4), (fbStore_a8), (fbStore_r3g3b2), + (fbStore_b2g3r3), (fbStore_a2r2g2b2), (fbStore_a4), + (fbStore_r1g2b1), (fbStore_b1g2r1), (fbStore_a1r1g1b1), + (fbStore_a1b1g1r1), (fbStore_a1), (fbFetch_external), + (fbStore_external), (fbFetch_transform), (fbFetcha_transform): + s/uint(8|16|32)_t/CARD(8|16|32)/ + 2005-07-30 Jeff Muizelaar * src/ic.c: (fbCompositeSolidMask_nx8x0888), diff --git a/pixman/src/iccompose.c b/pixman/src/iccompose.c index bf9de02f..db22243a 100644 --- a/pixman/src/iccompose.c +++ b/pixman/src/iccompose.c @@ -35,7 +35,7 @@ * Combine src and mask using IN */ -static uint32_t +static CARD32 fbCombineMaskU (FbCompositeOperand *src, FbCompositeOperand *msk) { @@ -117,7 +117,7 @@ fbCombineMaskC (FbCompositeOperand *src, return s; } -static uint32_t +static CARD32 fbCombineMaskValueC (FbCompositeOperand *src, FbCompositeOperand *msk) { @@ -149,13 +149,13 @@ fbCombineMaskValueC (FbCompositeOperand *src, /* * Combine src and mask using IN, generating only the alpha component */ -static uint32_t +static CARD32 fbCombineMaskAlphaU (FbCompositeOperand *src, FbCompositeOperand *msk) { - uint32_t x; - uint16_t a; - uint16_t t; + CARD32 x; + CARD16 a; + CARD16 t; if (!msk) return (*src->fetch) (src); @@ -171,7 +171,7 @@ fbCombineMaskAlphaU (FbCompositeOperand *src, return FbInU(x,24,a,t); } -static uint32_t +static CARD32 fbCombineMaskAlphaC (FbCompositeOperand *src, FbCompositeOperand *msk) { @@ -792,8 +792,8 @@ fbCombineAddC (FbCompositeOperand *src, #define CombineXor (CombineAOut|CombineBOut) /* portion covered by a but not b */ -static uint8_t -fbCombineDisjointOutPart (uint8_t a, uint8_t b) +static CARD8 +fbCombineDisjointOutPart (CARD8 a, CARD8 b) { /* min (1, (1-b) / a) */ @@ -804,8 +804,8 @@ fbCombineDisjointOutPart (uint8_t a, uint8_t b) } /* portion covered by both a and b */ -static uint8_t -fbCombineDisjointInPart (uint8_t a, uint8_t b) +static CARD8 +fbCombineDisjointInPart (CARD8 a, CARD8 b) { /* max (1-(1-b)/a,0) */ /* = - min ((1-b)/a - 1, 0) */ @@ -1102,8 +1102,8 @@ fbCombineDisjointXorC (FbCompositeOperand *src, } /* portion covered by a but not b */ -static uint8_t -fbCombineConjointOutPart (uint8_t a, uint8_t b) +static CARD8 +fbCombineConjointOutPart (CARD8 a, CARD8 b) { /* max (1-b/a,0) */ /* = 1-min(b/a,1) */ @@ -1116,8 +1116,8 @@ fbCombineConjointOutPart (uint8_t a, uint8_t b) } /* portion covered by both a and b */ -static uint8_t -fbCombineConjointInPart (uint8_t a, uint8_t b) +static CARD8 +fbCombineConjointInPart (CARD8 a, CARD8 b) { /* min (1,b/a) */ @@ -1511,21 +1511,21 @@ static FbCombineFunc const fbCombineFuncC[] = { * All of the fetch functions */ -static uint32_t +static CARD32 fbFetch_a8r8g8b8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; return ((CARD32 *)line)[offset >> 5]; } -static uint32_t +static CARD32 fbFetch_x8r8g8b8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; return ((CARD32 *)line)[offset >> 5] | 0xff000000; } -static uint32_t +static CARD32 fbFetch_a8b8g8r8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1537,7 +1537,7 @@ fbFetch_a8b8g8r8 (FbCompositeOperand *op) ((pixel & 0xff) << 16)); } -static uint32_t +static CARD32 fbFetch_x8b8g8r8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1549,7 +1549,7 @@ fbFetch_x8b8g8r8 (FbCompositeOperand *op) ((pixel & 0xff) << 16)); } -static uint32_t +static CARD32 fbFetch_r8g8b8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1567,7 +1567,7 @@ fbFetch_r8g8b8 (FbCompositeOperand *op) #endif } -static uint32_t +static CARD32 fbFetch_b8g8r8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1585,7 +1585,7 @@ fbFetch_b8g8r8 (FbCompositeOperand *op) #endif } -static uint32_t +static CARD32 fbFetch_r5g6b5 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1598,7 +1598,7 @@ fbFetch_r5g6b5 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_b5g6r5 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1611,7 +1611,7 @@ fbFetch_b5g6r5 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_a1r5g5b5 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1625,7 +1625,7 @@ fbFetch_a1r5g5b5 (FbCompositeOperand *op) return (a | r | g | b); } -static uint32_t +static CARD32 fbFetch_x1r5g5b5 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1638,7 +1638,7 @@ fbFetch_x1r5g5b5 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_a1b5g5r5 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1652,7 +1652,7 @@ fbFetch_a1b5g5r5 (FbCompositeOperand *op) return (a | r | g | b); } -static uint32_t +static CARD32 fbFetch_x1b5g5r5 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1665,7 +1665,7 @@ fbFetch_x1b5g5r5 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_a4r4g4b4 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1679,7 +1679,7 @@ fbFetch_a4r4g4b4 (FbCompositeOperand *op) return (a | r | g | b); } -static uint32_t +static CARD32 fbFetch_x4r4g4b4 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1692,7 +1692,7 @@ fbFetch_x4r4g4b4 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_a4b4g4r4 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1706,7 +1706,7 @@ fbFetch_a4b4g4r4 (FbCompositeOperand *op) return (a | r | g | b); } -static uint32_t +static CARD32 fbFetch_x4b4g4r4 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1719,7 +1719,7 @@ fbFetch_x4b4g4r4 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_a8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1728,7 +1728,7 @@ fbFetch_a8 (FbCompositeOperand *op) return pixel << 24; } -static uint32_t +static CARD32 fbFetcha_a8 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1739,7 +1739,7 @@ fbFetcha_a8 (FbCompositeOperand *op) return pixel; } -static uint32_t +static CARD32 fbFetch_r3g3b2 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1755,7 +1755,7 @@ fbFetch_r3g3b2 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_b2g3r3 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1773,7 +1773,7 @@ fbFetch_b2g3r3 (FbCompositeOperand *op) return (0xff000000 | r | g | b); } -static uint32_t +static CARD32 fbFetch_a2r2g2b2 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1794,7 +1794,7 @@ fbFetch_a2r2g2b2 (FbCompositeOperand *op) #define Fetch4(l,o) ((o) & 2 ? Fetch8(l,o) >> 4 : Fetch8(l,o) & 0xf) #endif -static uint32_t +static CARD32 fbFetch_a4 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1804,7 +1804,7 @@ fbFetch_a4 (FbCompositeOperand *op) return pixel << 24; } -static uint32_t +static CARD32 fbFetcha_a4 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1816,7 +1816,7 @@ fbFetcha_a4 (FbCompositeOperand *op) return pixel; } -static uint32_t +static CARD32 fbFetch_r1g2b1 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1829,7 +1829,7 @@ fbFetch_r1g2b1 (FbCompositeOperand *op) return 0xff000000|r|g|b; } -static uint32_t +static CARD32 fbFetch_b1g2r1 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1842,7 +1842,7 @@ fbFetch_b1g2r1 (FbCompositeOperand *op) return 0xff000000|r|g|b; } -static uint32_t +static CARD32 fbFetch_a1r1g1b1 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1856,7 +1856,7 @@ fbFetch_a1r1g1b1 (FbCompositeOperand *op) return a|r|g|b; } -static uint32_t +static CARD32 fbFetch_a1b1g1r1 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1870,7 +1870,7 @@ fbFetch_a1b1g1r1 (FbCompositeOperand *op) return a|r|g|b; } -static uint32_t +static CARD32 fbFetcha_a1 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1890,7 +1890,7 @@ fbFetcha_a1 (FbCompositeOperand *op) return a; } -static uint32_t +static CARD32 fbFetch_a1 (FbCompositeOperand *op) { FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; @@ -1912,44 +1912,44 @@ fbFetch_a1 (FbCompositeOperand *op) * All the store functions */ -#define Splita(v) uint32_t a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff -#define Split(v) uint32_t r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff +#define Splita(v) CARD32 a = ((v) >> 24), r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff +#define Split(v) CARD32 r = ((v) >> 16) & 0xff, g = ((v) >> 8) & 0xff, b = (v) & 0xff static void -fbStore_a8r8g8b8 (FbCompositeOperand *op, uint32_t value) +fbStore_a8r8g8b8 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - ((uint32_t *)line)[offset >> 5] = value; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + ((CARD32 *)line)[offset >> 5] = value; } static void -fbStore_x8r8g8b8 (FbCompositeOperand *op, uint32_t value) +fbStore_x8r8g8b8 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - ((uint32_t *)line)[offset >> 5] = value & 0xffffff; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + ((CARD32 *)line)[offset >> 5] = value & 0xffffff; } static void -fbStore_a8b8g8r8 (FbCompositeOperand *op, uint32_t value) +fbStore_a8b8g8r8 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; Splita(value); - ((uint32_t *)line)[offset >> 5] = a << 24 | b << 16 | g << 8 | r; + ((CARD32 *)line)[offset >> 5] = a << 24 | b << 16 | g << 8 | r; } static void -fbStore_x8b8g8r8 (FbCompositeOperand *op, uint32_t value) +fbStore_x8b8g8r8 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; Split(value); - ((uint32_t *)line)[offset >> 5] = b << 16 | g << 8 | r; + ((CARD32 *)line)[offset >> 5] = b << 16 | g << 8 | r; } static void -fbStore_r8g8b8 (FbCompositeOperand *op, uint32_t value) +fbStore_r8g8b8 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint8_t *pixel = ((uint8_t *) line) + (offset >> 3); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD8 *pixel = ((CARD8 *) line) + (offset >> 3); Split(value); #if IMAGE_BYTE_ORDER == MSBFirst pixel[0] = r; @@ -1963,10 +1963,10 @@ fbStore_r8g8b8 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_b8g8r8 (FbCompositeOperand *op, uint32_t value) +fbStore_b8g8r8 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint8_t *pixel = ((uint8_t *) line) + (offset >> 3); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD8 *pixel = ((CARD8 *) line) + (offset >> 3); Split(value); #if IMAGE_BYTE_ORDER == MSBFirst pixel[0] = b; @@ -1980,10 +1980,10 @@ fbStore_b8g8r8 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_r5g6b5 (FbCompositeOperand *op, uint32_t value) +fbStore_r5g6b5 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Split(value); *pixel = (((r << 8) & 0xf800) | ((g << 3) & 0x07e0) | @@ -1991,10 +1991,10 @@ fbStore_r5g6b5 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_b5g6r5 (FbCompositeOperand *op, uint32_t value) +fbStore_b5g6r5 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Split(value); *pixel = (((b << 8) & 0xf800) | ((g << 3) & 0x07e0) | @@ -2002,10 +2002,10 @@ fbStore_b5g6r5 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a1r5g5b5 (FbCompositeOperand *op, uint32_t value) +fbStore_a1r5g5b5 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Splita(value); *pixel = (((a << 8) & 0x8000) | ((r << 7) & 0x7c00) | @@ -2014,10 +2014,10 @@ fbStore_a1r5g5b5 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_x1r5g5b5 (FbCompositeOperand *op, uint32_t value) +fbStore_x1r5g5b5 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Split(value); *pixel = (((r << 7) & 0x7c00) | ((g << 2) & 0x03e0) | @@ -2025,10 +2025,10 @@ fbStore_x1r5g5b5 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a1b5g5r5 (FbCompositeOperand *op, uint32_t value) +fbStore_a1b5g5r5 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Splita(value); *pixel = (((a << 8) & 0x8000) | ((b << 7) & 0x7c00) | @@ -2037,10 +2037,10 @@ fbStore_a1b5g5r5 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_x1b5g5r5 (FbCompositeOperand *op, uint32_t value) +fbStore_x1b5g5r5 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Split(value); *pixel = (((b << 7) & 0x7c00) | ((g << 2) & 0x03e0) | @@ -2048,10 +2048,10 @@ fbStore_x1b5g5r5 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a4r4g4b4 (FbCompositeOperand *op, uint32_t value) +fbStore_a4r4g4b4 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Splita(value); *pixel = (((a << 8) & 0xf000) | ((r << 4) & 0x0f00) | @@ -2060,10 +2060,10 @@ fbStore_a4r4g4b4 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_x4r4g4b4 (FbCompositeOperand *op, uint32_t value) +fbStore_x4r4g4b4 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Split(value); *pixel = (((r << 4) & 0x0f00) | ((g ) & 0x00f0) | @@ -2071,10 +2071,10 @@ fbStore_x4r4g4b4 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a4b4g4r4 (FbCompositeOperand *op, uint32_t value) +fbStore_a4b4g4r4 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Splita(value); *pixel = (((a << 8) & 0xf000) | ((b << 4) & 0x0f00) | @@ -2083,10 +2083,10 @@ fbStore_a4b4g4r4 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_x4b4g4r4 (FbCompositeOperand *op, uint32_t value) +fbStore_x4b4g4r4 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint16_t *pixel = ((uint16_t *) line) + (offset >> 4); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD16 *pixel = ((CARD16 *) line) + (offset >> 4); Split(value); *pixel = (((b << 4) & 0x0f00) | ((g ) & 0x00f0) | @@ -2094,18 +2094,18 @@ fbStore_x4b4g4r4 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a8 (FbCompositeOperand *op, uint32_t value) +fbStore_a8 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint8_t *pixel = ((uint8_t *) line) + (offset >> 3); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD8 *pixel = ((CARD8 *) line) + (offset >> 3); *pixel = value >> 24; } static void -fbStore_r3g3b2 (FbCompositeOperand *op, uint32_t value) +fbStore_r3g3b2 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint8_t *pixel = ((uint8_t *) line) + (offset >> 3); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD8 *pixel = ((CARD8 *) line) + (offset >> 3); Split(value); *pixel = (((r ) & 0xe0) | ((g >> 3) & 0x1c) | @@ -2113,10 +2113,10 @@ fbStore_r3g3b2 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_b2g3r3 (FbCompositeOperand *op, uint32_t value) +fbStore_b2g3r3 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint8_t *pixel = ((uint8_t *) line) + (offset >> 3); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD8 *pixel = ((CARD8 *) line) + (offset >> 3); Split(value); *pixel = (((b ) & 0xe0) | ((g >> 3) & 0x1c) | @@ -2124,10 +2124,10 @@ fbStore_b2g3r3 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a2r2g2b2 (FbCompositeOperand *op, uint32_t value) +fbStore_a2r2g2b2 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint8_t *pixel = ((uint8_t *) line) + (offset >> 3); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD8 *pixel = ((CARD8 *) line) + (offset >> 3); Splita(value); *pixel = (((a ) & 0xc0) | ((r >> 2) & 0x30) | @@ -2135,7 +2135,7 @@ fbStore_a2r2g2b2 (FbCompositeOperand *op, uint32_t value) ((b >> 6) )); } -#define Store8(l,o,v) (((uint8_t *) l)[(o) >> 3] = (v)) +#define Store8(l,o,v) (((CARD8 *) l)[(o) >> 3] = (v)) #if IMAGE_BYTE_ORDER == MSBFirst #define Store4(l,o,v) Store8(l,o,((o) & 4 ? \ (Fetch8(l,o) & 0xf0) | (v) : \ @@ -2147,17 +2147,17 @@ fbStore_a2r2g2b2 (FbCompositeOperand *op, uint32_t value) #endif static void -fbStore_a4 (FbCompositeOperand *op, uint32_t value) +fbStore_a4 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; Store4(line,offset,value>>28); } static void -fbStore_r1g2b1 (FbCompositeOperand *op, uint32_t value) +fbStore_r1g2b1 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint32_t pixel; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD32 pixel; Split(value); pixel = (((r >> 4) & 0x8) | @@ -2167,10 +2167,10 @@ fbStore_r1g2b1 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_b1g2r1 (FbCompositeOperand *op, uint32_t value) +fbStore_b1g2r1 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint32_t pixel; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD32 pixel; Split(value); pixel = (((b >> 4) & 0x8) | @@ -2180,10 +2180,10 @@ fbStore_b1g2r1 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a1r1g1b1 (FbCompositeOperand *op, uint32_t value) +fbStore_a1r1g1b1 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint32_t pixel; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD32 pixel; Splita(value); pixel = (((a >> 4) & 0x8) | ((r >> 5) & 0x4) | @@ -2193,10 +2193,10 @@ fbStore_a1r1g1b1 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a1b1g1r1 (FbCompositeOperand *op, uint32_t value) +fbStore_a1b1g1r1 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint32_t pixel; + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD32 pixel; Splita(value); pixel = (((a >> 4) & 0x8) | ((b >> 5) & 0x4) | @@ -2206,48 +2206,48 @@ fbStore_a1b1g1r1 (FbCompositeOperand *op, uint32_t value) } static void -fbStore_a1 (FbCompositeOperand *op, uint32_t value) +fbStore_a1 (FbCompositeOperand *op, CARD32 value) { - FbBits *line = op->u.drawable.line; uint32_t offset = op->u.drawable.offset; - uint32_t *pixel = ((uint32_t *) line) + (offset >> 5); - uint32_t mask = FbStipMask(offset & 0x1f, 1); + FbBits *line = op->u.drawable.line; CARD32 offset = op->u.drawable.offset; + CARD32 *pixel = ((CARD32 *) line) + (offset >> 5); + CARD32 mask = FbStipMask(offset & 0x1f, 1); value = value & 0x80000000 ? mask : 0; *pixel = (*pixel & ~mask) | value; } -static uint32_t +static CARD32 fbFetch_external (FbCompositeOperand *op) { - uint32_t rgb = (*op[1].fetch) (&op[1]); - uint32_t a = (*op[2].fetch) (&op[2]); + CARD32 rgb = (*op[1].fetch) (&op[1]); + CARD32 a = (*op[2].fetch) (&op[2]); return (rgb & 0xffffff) | (a & 0xff000000); } -static uint32_t +static CARD32 fbFetcha_external (FbCompositeOperand *op) { return (*op[2].fetch) (&op[2]); } static void -fbStore_external (FbCompositeOperand *op, uint32_t value) +fbStore_external (FbCompositeOperand *op, CARD32 value) { (*op[1].store) (&op[1], value | 0xff000000); (*op[2].store) (&op[2], value & 0xff000000); } -static uint32_t +static CARD32 fbFetch_transform (FbCompositeOperand *op) { pixman_vector_t v; int x, y; int minx, maxx, miny, maxy; - uint32_t rtot, gtot, btot, atot; - uint32_t xerr, yerr; - uint32_t bits; + CARD32 rtot, gtot, btot, atot; + CARD32 xerr, yerr; + CARD32 bits; pixman_box16_t box; v.vector[0] = IntToxFixed(op->u.transform.x); @@ -2286,7 +2286,7 @@ fbFetch_transform (FbCompositeOperand *op) yerr = xFixed1 - xFixedFrac (v.vector[1]); for (y = miny; y <= maxy; y++) { - uint32_t lrtot = 0, lgtot = 0, lbtot = 0, latot = 0; + CARD32 lrtot = 0, lgtot = 0, lbtot = 0, latot = 0; int tx, ty; if (op->u.transform.repeat) @@ -2338,15 +2338,15 @@ fbFetch_transform (FbCompositeOperand *op) return bits; } -static uint32_t +static CARD32 fbFetcha_transform (FbCompositeOperand *op) { pixman_vector_t v; int x, y; int minx, maxx, miny, maxy; - uint32_t rtot, gtot, btot, atot; - uint32_t xerr, yerr; - uint32_t bits; + CARD32 rtot, gtot, btot, atot; + CARD32 xerr, yerr; + CARD32 bits; pixman_box16_t box; v.vector[0] = IntToxFixed(op->u.transform.x); @@ -2386,7 +2386,7 @@ fbFetcha_transform (FbCompositeOperand *op) yerr = xFixed1 - xFixedFrac (v.vector[1]); for (y = miny; y <= maxy; y++) { - uint32_t lrtot = 0, lgtot = 0, lbtot = 0, latot = 0; + CARD32 lrtot = 0, lgtot = 0, lbtot = 0, latot = 0; int tx, ty; if (op->u.transform.repeat) -- cgit v1.2.3 From 05d84a0a1e1f4f4cb750ab6828a1e09ffa73b0f0 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Sat, 30 Jul 2005 10:23:21 +0000 Subject: Finish up merging the optimization work from jaymz. --- pixman/ChangeLog | 10 ++ pixman/src/ic.c | 316 +++++++++++++++++++++++-------------------------- pixman/src/icblt.c | 4 +- pixman/src/iccompose.c | 13 +- 4 files changed, 170 insertions(+), 173 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 0d64c6a9..7f9da47e 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,13 @@ +2005-07-30 Jeff Muizelaar + + * src/ic.c: (fbCompositeSolidMask_nx8x0888), + (fbCompositeSolidMask_nx8x0565), (fbCompositeSolidMask_nx1xn), + (fbCompositeTrans_0565xnx0565), (fbCompositeTrans_0888xnx0888), + (fbCompositeSrcSrc_nxn), (pixman_composite): + * src/icblt.c: (fbBlt): + * src/iccompose.c: (fbFetch_r8g8b8): + Finish up merging the optimization work from jaymz. + 2005-07-30 Jeff Muizelaar * src/iccompose.c: (fbCombineMaskAlphaU), diff --git a/pixman/src/ic.c b/pixman/src/ic.c index 5d56ac3d..327b39b6 100644 --- a/pixman/src/ic.c +++ b/pixman/src/ic.c @@ -152,21 +152,25 @@ fbIn24 (CARD32 x, CARD8 y) #define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d))) -#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \ - dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \ - drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ +#define fastcombine32(alpha, source, destval, destptr) { \ + CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \ + CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ *destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ + } -#define fastcombine32(alpha, source, destval, destptr, dstrb, dstag, drb, dag) \ - dstrb=destval&0xFF00FF; dstag=(destval>>8)&0xFF00FF; \ - drb=((source&0xFF00FF)-dstrb)*alpha; dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ - *destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ - -// Note: this macro expects 6 bits of alpha, not 8! +/* Note: this macro expects 5 bits of alpha, not 8! + * (single op can actually be changed to take 6 bits, but double op can't) + */ #define fastCombine0565(alpha, source, destval, destptr) { \ CARD16 dstrb = destval & 0xf81f; CARD16 dstg = destval & 0x7e0; \ CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \ - destptr= ((((drb>>6) + dstrb)&0xf81f) | (((dg>>6) + dstg) & 0x7e0)); \ + destptr= ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5) + dstg) & 0x7e0)); \ + } + +#define fastCombine2x0565(alpha, source, destval, destptr) { \ + CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg = (destval & 0xf81f07e0)>>5; \ + CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \ + destptr= ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5) + dstg)<<5) & 0xf81f07e0)); \ } #if IMAGE_BYTE_ORDER == LSBFirst @@ -371,7 +375,7 @@ fbCompositeSolidMask_nx8x0888 (pixman_operator_t op, while (height--) { - // fixme: cleanup unused + /* fixme: cleanup unused */ unsigned int wt,wd; CARD32 workingiDest; CARD32 *widst; @@ -454,7 +458,7 @@ fbCompositeSolidMask_nx8x0565 (pixman_operator_t op, src16 = cvt8888to0565(src); rsrca = src >> 24; - srca=rsrca>>2; + srca=rsrca>>3; if (src == 0) return; @@ -486,7 +490,7 @@ fbCompositeSolidMask_nx8x0565 (pixman_operator_t op, } else if (m) { - na=(rsrca*(int)m)>>10; + na=(rsrca*(int)m)>>11; d = *dst; fastCombine0565(na, src16, d, *dst++); } @@ -924,7 +928,7 @@ fbCompositeSolidMask_nx1xn (pixman_operator_t op, int dstXoff, dstYoff; int maskXoff, maskYoff; FbBits src; - + fbComposeGetSolid(pSrc, src); if ((src & 0xff000000) != 0xff000000) @@ -995,7 +999,7 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, CARD32 s_32, d_32, i_32, r_32; fbComposeGetSolid (pMask, mask); - maskAlpha = mask >> 26; + maskAlpha = mask >> 27; if (!maskAlpha) return; @@ -1012,7 +1016,7 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, while (height--) { - CARD32 *isrc; + CARD32 *isrc, *idst; dst = dstLine; dstLine += dstStride; src = srcLine; @@ -1027,24 +1031,38 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, w--; } isrc=(CARD32 *)src; - while (w>1) + if(((int)dst&1)==0) + { + idst=(CARD32 *)dst; + while (w>1) + { + s_32 = *isrc++; + d_32 = *idst; + fastCombine2x0565(maskAlpha,s_32,d_32,*idst++); + w-=2; + } + dst=(CARD16 *)idst; + } + else { - s_32=*isrc++; + if(w>1) + { #if IMAGE_BYTE_ORDER == LSBFirst - s_16=s_32&0xffff; + s_16=s_32&0xffff; #else - s_16=s_32>>16; + s_16=s_32>>16; #endif - d_16 = *dst; - fastCombine0565(maskAlpha, s_16, d_16, *dst++); + d_16 = *dst; + fastCombine0565(maskAlpha, s_16, d_16, *dst++); #if IMAGE_BYTE_ORDER == LSBFirst - s_16=s_32>>16; + s_16=s_32>>16; #else - s_16=s_32&0xffff; + s_16=s_32&0xffff; #endif - d_16 = *dst; - fastCombine0565(maskAlpha, s_16, d_16, *dst++); - w-=2; + d_16 = *dst; + fastCombine0565(maskAlpha, s_16, d_16, *dst++); + w-=2; + } } src=(CARD16 *)isrc; if(w!=0) @@ -1058,7 +1076,7 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, -// macros for "i can't believe it's not fast" packed pixel handling +/* macros for "i can't believe it's not fast" packed pixel handling */ #define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha) static void fbCompositeTrans_0888xnx0888(pixman_operator_t op, @@ -1087,140 +1105,104 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op, if (!maskAlpha) return; - //if (maskAlpha == 0xff) - //{ - //fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst, - // xSrc, ySrc, xMask, yMask, xDst, yDst, - // width, height); - //return; - //} + /* + if (maskAlpha == 0xff) + { + fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height); + return; + } + */ fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3); fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); { - unsigned int ws,wt,wd,ww; + unsigned int ws,wt,ww; CARD32 workingSource; - CARD32 *wsrc; - CARD32 rs,gs,bs; - CARD32 rd,gd,bd; - - CARD32 workingiDest,workingoDest; - CARD32 *widst,*wodst; + CARD32 *wsrc, *wdst, *widst; + CARD32 rs, rd, nd; + CARD8 *isrc; - - // are xSrc and xDst at the same alignment? if not, we need to be complicated :) - //if(0==0) - if( (((xSrc*3)&3)!=((xDst*3)&3)) || (srcStride&3)!=0 || (dstStride&3)!=0) + /* are xSrc and xDst at the same alignment? if not, we need to be complicated :)*/ + /* if(0==0) */ + if( (((xSrc*3)&3)!=((xDst*3)&3)) || ((srcStride&3)!=(dstStride&3))) { while (height--) { - idst=dst = dstLine; + dst = dstLine; dstLine += dstStride; - src = srcLine; + isrc = src = srcLine; srcLine += srcStride; w = width*3; - setupPackedReader(wd,wt,idst,widst,workingiDest); - ww=(int)dst; - wt=ww&3; - dst-=wt; - wodst=(CARD32 *)dst; - workingoDest=*wodst; - ww=4-wt; -#if IMAGE_BYTE_ORDER == LSBFirst - workingoDest<<=(8*(ww+1)); -#else - workingoDest>>=(8*(ww+1)); -#endif + setupPackedReader(ws,wt,isrc,wsrc,workingSource); - // get to word aligned - switch(!(int)src&3) + /* get to word aligned */ + switch(!(int)dst&3) { case 1: - readPackedDest(rd); - rd=alphamaskCombine24(*src++, rd)>>8; - writePacked(rd); + readPackedSource(rs); + /* *dst++=alphamaskCombine24(rs, *dst)>>8; */ + rd=*dst; /* make gcc happy. hope it doens't cost us too much performance*/ + *dst++=alphamaskCombine24(rs, rd)>>8; w--; if(w==0) break; case 2: - readPackedDest(rd); - rd=alphamaskCombine24(*src++, rd)>>8; - writePacked(rd); + readPackedSource(rs); + rd=*dst; + *dst++=alphamaskCombine24(rs, rd)>>8; w--; if(w==0) break; case 3: - readPackedDest(rd); - rd=alphamaskCombine24(*src++, rd)>>8; - writePacked(rd); + readPackedSource(rs); + rd=*dst; + *dst++=alphamaskCombine24(rs, rd)>>8; w--; if(w==0) break; } - wsrc=(CARD32 *)src; + wdst=(CARD32 *)dst; while (w>3) { - rs=*wsrc++; - // FIXME: write a version of readPackedDest() which - // can collect 4 bytes at once if we're on a boundry (which we're - // actually guarenteed not to be in this version, but do it anyhow), and can - // collect as 2 16bit words on a 2byte boundry, and then use the 32bit combine here + /* FIXME: write a special readPackedWord macro, which knows how to + * halfword combine + */ + #if IMAGE_BYTE_ORDER == LSBFirst - readPackedDest(rd); - rd=alphamaskCombine24(rs&0xff, rd)>>8; - writePacked(rd); - - readPackedDest(rd); - rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8; - writePacked(rd); - - readPackedDest(rd); - rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8; - writePacked(rd); - - readPackedDest(rd); - rd=alphamaskCombine24(rs>>24, rd)>>8; - writePacked(rd); + rd=*wdst; + readPackedSource(nd); + readPackedSource(rs); + nd|=rs<<8; + readPackedSource(rs); + nd|=rs<<16; + readPackedSource(rs); + nd|=rs<<24; #else - readPackedDest(rd); - rd=alphamaskCombine24(rs>>24, rd)>>8; - writePacked(rd); - - readPackedDest(rd); - rd=alphamaskCombine24((rs>>16)&0xff, rd)>>8; - writePacked(rd); - - readPackedDest(rd); - rd=alphamaskCombine24((rs>>8)&0xff, rd)>>8; - writePacked(rd); - - readPackedDest(rd); - rd=alphamaskCombine24(rs&0xff, rd)>>8; - writePacked(rd); + readPackedSource(nd); + nd<<=24; + readPackedSource(rs); + nd|=rs<<16; + readPackedSource(rs); + nd|=rs<<8; + readPackedSource(rs); + nd|=rs; #endif + fastcombine32(maskAlpha, nd, rd, wdst) w-=4; } - src=(CARD8 *)wsrc; + dst=(CARD8 *)wdst; switch(w) { case 3: - readPackedDest(rd); - rd=alphamaskCombine24(*src++, rd)>>8; - writePacked(rd); + readPackedSource(rs); + rd=*dst; + *dst++=alphamaskCombine24(rs, rd)>>8; case 2: - readPackedDest(rd); - rd=alphamaskCombine24(*src++, rd)>>8; - writePacked(rd); - case 1: - readPackedDest(rd); - rd=alphamaskCombine24(*src++, rd)>>8; - writePacked(rd); - } - dst=(CARD8 *)wodst; - switch(ww) - { + readPackedSource(rs); + rd=*dst; + *dst++=alphamaskCombine24(rs, rd)>>8; case 1: - dst[2]=(workingoDest>>8)&0xff; - case 2: - dst[1]=(workingoDest>>16)&0xff; - case 3: - dst[0]=workingoDest>>24; + readPackedSource(rs); + rd=*dst; + *dst++=alphamaskCombine24(rs, rd)>>8; } } } @@ -1233,7 +1215,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op, src = srcLine; srcLine += srcStride; w = width*3; - // get to word aligned + /* get to word aligned */ switch(!(int)src&3) { case 1: @@ -1252,12 +1234,11 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op, wsrc=(CARD32 *)src; widst=(CARD32 *)dst; - register CARD32 t1, t2, t3, t4; while(w>3) { rs = *wsrc++; rd = *widst; - fastcombine32(maskAlpha, rs, rd, widst, t1, t2, t3, t4); + fastcombine32(maskAlpha, rs, rd, widst); w-=4; } src=(CARD8 *)wsrc; @@ -1299,33 +1280,41 @@ fbCompositeSrcSrc_nxn (pixman_operator_t op, { FbBits *dst; FbBits *src; - FbStride dstStride, srcStride; - int srcXoff, srcYoff; - int dstXoff, dstYoff; - int srcBpp; - int dstBpp; - // these need to be signed now! - int iwidth=width; - int iheight=height; - Bool reverse = FALSE; - Bool upsidedown = FALSE; + CARD8 *isrc; + CARD8 *idst; + int dstStride, srcStride; + int srcXoff, srcYoff; + int dstXoff, dstYoff; + int srcBpp; + int dstBpp; + /* these need to be signed now! */ + int iwidth=width; + int iheight=height; + int bytesPerPixel; int initialWidth=width; int initialX=xDst; - // FIXME: this is possibly the worst piece of code I've ever written. - // My main objection to it, is that it is incrfedibly slow in a few cases, due to the - // call-per-repeat structure of it - the *correct* solution is to implement - // repeat into fbBlt(), but that's a nontrivial job, and it's far more - // important to get the "requireRepeat" stuff implented functionally - // first, *then* make it fast. - // -- jj + /* FIXME: this is possibly the second worst piece of code I've ever written. + * (the worst being the previous imlementation of this) + * -- jj + */ + Bool srcRepeat=pSrc->repeat; CARD32 srcHeight=pSrc->pDrawable->height; CARD32 srcWidth=pSrc->pDrawable->width; FbGetPixels(pSrc->pixels,src,srcStride,srcBpp,srcXoff,srcYoff); FbGetPixels(pDst->pixels,dst,dstStride,dstBpp,dstXoff,dstYoff); + + src+=(srcXoff+(srcYoff*srcStride)); + dst+=(dstXoff+(dstYoff*dstStride)); + + isrc=(CARD8 *)src; + idst=(CARD8 *)dst; + bytesPerPixel=(srcBpp>>3); + srcStride*=sizeof(FbBits); + dstStride*=sizeof(FbBits); if(srcRepeat) { xSrc%=srcWidth; @@ -1342,26 +1331,16 @@ fbCompositeSrcSrc_nxn (pixman_operator_t op, while(iwidth>0) { int wwidth=iwidth; + int j; if(wwidth>(srcWidth-xSrc)) wwidth=(srcWidth-xSrc); - fbBlt (src + (ySrc + srcYoff) * srcStride, - srcStride, - (xSrc + srcXoff) * srcBpp, - - dst + (yDst + dstYoff) * dstStride, - dstStride, - (xDst + dstXoff) * dstBpp, - - (wwidth) * dstBpp, - (wheight), - - GXcopy, - FB_ALLONES, - dstBpp, - - reverse, - upsidedown); + for(j=0;ju.drawable.line; CARD32 offset = op->u.drawable.offset; CARD8 *pixel = ((CARD8 *) line) + (offset >> 3); #if IMAGE_BYTE_ORDER == MSBFirst + /* FIXME: implent WORKING_UNALIGNED_INT for this endian :) */ return (0xff000000 | (pixel[0] << 16) | (pixel[1] << 8) | (pixel[2])); #else - return (0xff000000 | - (pixel[2] << 16) | - (pixel[1] << 8) | - (pixel[0])); + #ifdef WORKING_UNALIGNED_INT + return *(CARD32 *)pixel|0xff000000; + #else + return (0xff000000 | + (pixel[2] << 16) | + (pixel[1] << 8) | + (pixel[0])); + #endif #endif } -- cgit v1.2.3 From b47c0050f985856d0c47a43d3a1b3cc8f18dbd32 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 30 Jul 2005 12:57:54 +0000 Subject: Replace wide integer divide algorithms with trivial bit-at-a-time code. Original code was of unclear provenance, this new code is completely different. --- ChangeLog | 11 ++ src/cairo-wideint.c | 461 ++++++---------------------------------------------- src/cairo-wideint.h | 6 +- 3 files changed, 60 insertions(+), 418 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0192af0a..d953d690 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-07-30 Keith Packard + + * src/cairo-wideint.c: (_cairo_int32x32_64_mul), + (_cairo_uint64_divrem), (_cairo_uint128_divrem): + * src/cairo-wideint.h: + + Replace wide integer divide algorithms with + trivial bit-at-a-time code. Original code was + of unclear provenance, this new code is + completely different. + 2005-07-29 Carl Worth * ROADMAP: Remove completed 0.6 tasks. Add cairo_surface_flush to diff --git a/src/cairo-wideint.c b/src/cairo-wideint.c index 60946d90..9e4914e6 100644 --- a/src/cairo-wideint.c +++ b/src/cairo-wideint.c @@ -1,5 +1,5 @@ /* - * $Id: cairo-wideint.c,v 1.5 2005-06-03 21:51:57 cworth Exp $ + * $Id: cairo-wideint.c,v 1.6 2005-07-30 19:57:54 keithp Exp $ * * Copyright © 2004 Keith Packard * @@ -36,22 +36,6 @@ #include "cairoint.h" -#if !HAVE_UINT64_T || !HAVE_UINT128_T - -static const unsigned char top_bit[256] = -{ - 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, -}; - -#endif - #if HAVE_UINT64_T #define _cairo_uint32s_to_uint64(h,l) ((uint64_t) (h) << 32 | (l)) @@ -157,7 +141,8 @@ _cairo_uint32x32_64_mul (uint32_t a, uint32_t b) cairo_int64_t _cairo_int32x32_64_mul (int32_t a, int32_t b) { - s = _cairo_uint32x32_64_mul ((uint32_t) a, (uint32_t b)); + cairo_int64_t s; + s = _cairo_uint32x32_64_mul ((uint32_t) a, (uint32_t) b); if (a < 0) s.hi -= b; if (b < 0) @@ -270,200 +255,38 @@ _cairo_uint64_negate (cairo_uint64_t a) } /* - * The design of this algorithm comes from GCC, - * but the actual implementation is new + * Simple bit-at-a-time divide. */ - -static const int -_cairo_leading_zeros32 (uint32_t i) -{ - int top; - - if (i < 0x100) - top = 0; - else if (i < 0x10000) - top = 8; - else if (i < 0x1000000) - top = 16; - else - top = 24; - top = top + top_bit [i >> top]; - return 32 - top; -} - -typedef struct _cairo_uquorem32_t { - uint32_t quo; - uint32_t rem; -} cairo_uquorem32_t; - -/* - * den >= num.hi - */ -static const cairo_uquorem32_t -_cairo_uint64x32_normalized_divrem (cairo_uint64_t num, uint32_t den) -{ - cairo_uquorem32_t qr; - uint32_t q0, q1, r0, r1; - uint16_t d0, d1; - uint32_t t; - - d0 = den & 0xffff; - d1 = den >> 16; - - q1 = num.hi / d1; - r1 = num.hi % d1; - - t = q1 * d0; - r1 = (r1 << 16) | (num.lo >> 16); - if (r1 < t) - { - q1--; - r1 += den; - if (r1 >= den && r1 < t) - { - q1--; - r1 += den; - } - } - - r1 -= t; - - q0 = r1 / d1; - r0 = r1 % d1; - t = q0 * d0; - r0 = (r0 << 16) | (num.lo & 0xffff); - if (r0 < t) - { - q0--; - r0 += den; - if (r0 >= den && r0 < t) - { - q0--; - r0 += den; - } - } - r0 -= t; - qr.quo = (q1 << 16) | q0; - qr.rem = r0; - return qr; -} - cairo_uquorem64_t _cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den) { - cairo_uquorem32_t qr32; cairo_uquorem64_t qr; - int norm; - uint32_t q1, q0, r1, r0; - - if (den.hi == 0) + cairo_uint64_t bit; + cairo_uint64_t quo; + + bit = _cairo_uint32_to_uint64 (1); + + /* normalize to make den >= num, but not overflow */ + while (_cairo_uint64_lt (den, num) && (den.hi & 0x80000000) == 0) { - if (den.lo > num.hi) - { - /* 0q = nn / 0d */ - - norm = _cairo_leading_zeros32 (den.lo); - if (norm) - { - den.lo <<= norm; - num = _cairo_uint64_lsl (num, norm); - } - q1 = 0; - } - else - { - /* qq = NN / 0d */ - - if (den.lo == 0) - den.lo = 1 / den.lo; - - norm = _cairo_leading_zeros32 (den.lo); - if (norm) - { - cairo_uint64_t num1; - den.lo <<= norm; - num1 = _cairo_uint64_rsl (num, 32 - norm); - qr32 = _cairo_uint64x32_normalized_divrem (num1, den.lo); - q1 = qr32.quo; - num.hi = qr32.rem; - num.lo <<= norm; - } - else - { - num.hi -= den.lo; - q1 = 1; - } - } - qr32 = _cairo_uint64x32_normalized_divrem (num, den.lo); - q0 = qr32.quo; - r1 = 0; - r0 = qr32.rem >> norm; + bit = _cairo_uint64_lsl (bit, 1); + den = _cairo_uint64_lsl (den, 1); } - else + quo = _cairo_uint32_to_uint64 (0); + + /* generate quotient, one bit at a time */ + while (bit.hi | bit.lo) { - if (den.hi > num.hi) - { - /* 00 = nn / DD */ - q0 = q1 = 0; - r0 = num.lo; - r1 = num.hi; - } - else + if (_cairo_uint64_le (den, num)) { - /* 0q = NN / dd */ - - norm = _cairo_leading_zeros32 (den.hi); - if (norm == 0) - { - if (num.hi > den.hi || num.lo >= den.lo) - { - q0 = 1; - num = _cairo_uint64_sub (num, den); - } - else - { - q0 = 0; - } - - q1 = 0; - r0 = num.lo; - r1 = num.hi; - } - else - { - cairo_uint64_t num1; - cairo_uint64_t part; - - num1 = _cairo_uint64_rsl (num, 32 - norm); - den = _cairo_uint64_lsl (den, norm); - - qr32 = _cairo_uint64x32_normalized_divrem (num1, den.hi); - part = _cairo_uint32x32_64_mul (qr32.quo, den.lo); - - q0 = qr32.quo; - - num.lo <<= norm; - num.hi = qr32.rem; - - if (_cairo_uint64_gt (part, num)) - { - q0--; - part = _cairo_uint64_sub (part, den); - } - - q1 = 0; - - num = _cairo_uint64_sub (num, part); - num = _cairo_uint64_rsl (num, norm); - r0 = num.lo; - r1 = num.hi; - } + num = _cairo_uint64_sub (num, den); + quo = _cairo_uint64_add (quo, bit); } + bit = _cairo_uint64_rsl (bit, 1); + den = _cairo_uint64_rsl (den, 1); } - qr.quo.lo = q0; - qr.quo.hi = q1; - qr.rem.lo = r0; - qr.rem.hi = r1; + qr.quo = quo; + qr.rem = num; return qr; } @@ -754,234 +577,42 @@ _cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b) _cairo_uint64_eq (a.lo, b.lo)); } -/* - * The design of this algorithm comes from GCC, - * but the actual implementation is new - */ - -/* - * den >= num.hi - */ -static cairo_uquorem64_t -_cairo_uint128x64_normalized_divrem (cairo_uint128_t num, cairo_uint64_t den) -{ - cairo_uquorem64_t qr64; - cairo_uquorem64_t qr; - uint32_t q0, q1; - cairo_uint64_t r0, r1; - uint32_t d0, d1; - cairo_uint64_t t; - - d0 = uint64_lo32 (den); - d1 = uint64_hi32 (den); - - qr64 = _cairo_uint64_divrem (num.hi, _cairo_uint32_to_uint64 (d1)); - q1 = _cairo_uint64_to_uint32 (qr64.quo); - r1 = qr64.rem; - - t = _cairo_uint32x32_64_mul (q1, d0); - - r1 = _cairo_uint64_add (_cairo_uint64_lsl (r1, 32), - _cairo_uint64_rsl (num.lo, 32)); - - if (_cairo_uint64_lt (r1, t)) - { - q1--; - r1 = _cairo_uint64_add (r1, den); - if (_cairo_uint64_ge (r1, den) && _cairo_uint64_lt (r1, t)) - { - q1--; - r1 = _cairo_uint64_add (r1, den); - } - } - - r1 = _cairo_uint64_sub (r1, t); - - qr64 = _cairo_uint64_divrem (r1, _cairo_uint32_to_uint64 (d1)); - - q0 = _cairo_uint64_to_uint32 (qr64.quo); - r0 = qr64.rem; - - t = _cairo_uint32x32_64_mul (q0, d0); - - r0 = _cairo_uint64_add (_cairo_uint64_lsl (r0, 32), - _cairo_uint32_to_uint64 (_cairo_uint64_to_uint32 (num.lo))); - if (_cairo_uint64_lt (r0, t)) - { - q0--; - r0 = _cairo_uint64_add (r0, den); - if (_cairo_uint64_ge (r0, den) && _cairo_uint64_lt (r0, t)) - { - q0--; - r0 = _cairo_uint64_add (r0, den); - } - } - - r0 = _cairo_uint64_sub (r0, t); - - qr.quo = _cairo_uint32s_to_uint64 (q1, q0); - qr.rem = r0; - return qr; -} - #if HAVE_UINT64_T - -static int -_cairo_leading_zeros64 (cairo_uint64_t q) -{ - int top = 0; - - if (q >= (uint64_t) 0x10000 << 16) - { - top += 32; - q >>= 32; - } - if (q >= (uint64_t) 0x10000) - { - top += 16; - q >>= 16; - } - if (q >= (uint64_t) 0x100) - { - top += 8; - q >>= 8; - } - top += top_bit [q]; - return 64 - top; -} - +#define _cairo_msbset64(q) (q & ((uint64_t) 1 << 63)) #else - -static const int -_cairo_leading_zeros64 (cairo_uint64_t d) -{ - if (d.hi) - return _cairo_leading_zeros32 (d.hi); - else - return 32 + _cairo_leading_zeros32 (d.lo); -} - +#define _cairo_msbset64(q) (q.hi & ((uint32_t) 1 << 31)) #endif cairo_uquorem128_t _cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den) { - cairo_uquorem64_t qr64; cairo_uquorem128_t qr; - int norm; - cairo_uint64_t q1, q0, r1, r0; - - if (_cairo_uint64_eq (den.hi, _cairo_uint32_to_uint64 (0))) + cairo_uint128_t bit; + cairo_uint128_t quo; + + bit = _cairo_uint32_to_uint128 (1); + + /* normalize to make den >= num, but not overflow */ + while (_cairo_uint128_lt (den, num) && !_cairo_msbset64(den.hi)) { - if (_cairo_uint64_gt (den.lo, num.hi)) - { - /* 0q = nn / 0d */ - - norm = _cairo_leading_zeros64 (den.lo); - if (norm) - { - den.lo = _cairo_uint64_lsl (den.lo, norm); - num = _cairo_uint128_lsl (num, norm); - } - q1 = _cairo_uint32_to_uint64 (0); - } - else - { - /* qq = NN / 0d */ - - if (_cairo_uint64_eq (den.lo, _cairo_uint32_to_uint64 (0))) - den.lo = _cairo_uint64_divrem (_cairo_uint32_to_uint64 (1), - den.lo).quo; - - norm = _cairo_leading_zeros64 (den.lo); - if (norm) - { - cairo_uint128_t num1; - - den.lo = _cairo_uint64_lsl (den.lo, norm); - num1 = _cairo_uint128_rsl (num, 64 - norm); - qr64 = _cairo_uint128x64_normalized_divrem (num1, den.lo); - q1 = qr64.quo; - num.hi = qr64.rem; - num.lo = _cairo_uint64_lsl (num.lo, norm); - } - else - { - num.hi = _cairo_uint64_sub (num.hi, den.lo); - q1 = _cairo_uint32_to_uint64 (1); - } - } - qr64 = _cairo_uint128x64_normalized_divrem (num, den.lo); - q0 = qr64.quo; - r1 = _cairo_uint32_to_uint64 (0); - r0 = _cairo_uint64_rsl (qr64.rem, norm); + bit = _cairo_uint128_lsl (bit, 1); + den = _cairo_uint128_lsl (den, 1); } - else + quo = _cairo_uint32_to_uint128 (0); + + /* generate quotient, one bit at a time */ + while (_cairo_uint128_ne (bit, _cairo_uint32_to_uint128(0))) { - if (_cairo_uint64_gt (den.hi, num.hi)) - { - /* 00 = nn / DD */ - q0 = q1 = _cairo_uint32_to_uint64 (0); - r0 = num.lo; - r1 = num.hi; - } - else + if (_cairo_uint128_le (den, num)) { - /* 0q = NN / dd */ - - norm = _cairo_leading_zeros64 (den.hi); - if (norm == 0) - { - if (_cairo_uint64_gt (num.hi, den.hi) || - _cairo_uint64_ge (num.lo, den.lo)) - { - q0 = _cairo_uint32_to_uint64 (1); - num = _cairo_uint128_sub (num, den); - } - else - { - q0 = _cairo_uint32_to_uint64 (0); - } - - q1 = _cairo_uint32_to_uint64 (0); - r0 = num.lo; - r1 = num.hi; - } - else - { - cairo_uint128_t num1; - cairo_uint128_t part; - - num1 = _cairo_uint128_rsl (num, 64 - norm); - den = _cairo_uint128_lsl (den, norm); - - qr64 = _cairo_uint128x64_normalized_divrem (num1, den.hi); - part = _cairo_uint64x64_128_mul (qr64.quo, den.lo); - - q0 = qr64.quo; - - num.lo = _cairo_uint64_lsl (num.lo, norm); - num.hi = qr64.rem; - - if (_cairo_uint128_gt (part, num)) - { - q0 = _cairo_uint64_sub (q0, _cairo_uint32_to_uint64 (1)); - part = _cairo_uint128_sub (part, den); - } - - q1 = _cairo_uint32_to_uint64 (0); - - num = _cairo_uint128_sub (num, part); - num = _cairo_uint128_rsl (num, norm); - r0 = num.lo; - r1 = num.hi; - } + num = _cairo_uint128_sub (num, den); + quo = _cairo_uint128_add (quo, bit); } + bit = _cairo_uint128_rsl (bit, 1); + den = _cairo_uint128_rsl (den, 1); } - qr.quo.lo = q0; - qr.quo.hi = q1; - qr.rem.lo = r0; - qr.rem.hi = r1; + qr.quo = quo; + qr.rem = num; return qr; } diff --git a/src/cairo-wideint.h b/src/cairo-wideint.h index 3afea5a6..8870df7b 100644 --- a/src/cairo-wideint.h +++ b/src/cairo-wideint.h @@ -1,5 +1,5 @@ /* - * $Id: cairo-wideint.h,v 1.10 2005-05-10 19:42:32 cworth Exp $ + * $Id: cairo-wideint.h,v 1.11 2005-07-30 19:57:54 keithp Exp $ * * Copyright © 2004 Keith Packard * @@ -85,7 +85,7 @@ cairo_int64_t I _cairo_int32_to_int64(int32_t i); #define _cairo_int64_add(a,b) _cairo_uint64_add (a,b) #define _cairo_int64_sub(a,b) _cairo_uint64_sub (a,b) #define _cairo_int64_mul(a,b) _cairo_uint64_mul (a,b) -int I _cairo_int32x32_64_mul (int32_t a, int32_t b); +cairo_int64_t I _cairo_int32x32_64_mul (int32_t a, int32_t b); int I _cairo_int64_lt (cairo_uint64_t a, cairo_uint64_t b); #define _cairo_int64_eq(a,b) _cairo_uint64_eq (a,b) #define _cairo_int64_lsl(a,b) _cairo_uint64_lsl (a,b) @@ -208,7 +208,7 @@ cairo_int128_t I _cairo_int64_to_int128 (cairo_int64_t i); #define _cairo_int128_add(a,b) _cairo_uint128_add(a,b) #define _cairo_int128_sub(a,b) _cairo_uint128_sub(a,b) #define _cairo_int128_mul(a,b) _cairo_uint128_mul(a,b) -cairo_uint128_t I _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b); +cairo_int128_t I _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b); #define _cairo_int128_lsl(a,b) _cairo_uint128_lsl(a,b) #define _cairo_int128_rsl(a,b) _cairo_uint128_rsl(a,b) #define _cairo_int128_rsa(a,b) _cairo_uint128_rsa(a,b) -- cgit v1.2.3 From 31e0d694294ef17037a0b464615916e065a81385 Mon Sep 17 00:00:00 2001 From: Billy Biggs Date: Sat, 30 Jul 2005 22:21:12 +0000 Subject: Pass the options down to the scaled font object to keep things compiling. --- ChangeLog | 5 +++++ src/cairo-atsui-font.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d953d690..33e6d89e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-07-31 Billy Biggs + + * src/cairo-atsui-font.c: (_cairo_atsui_font_create): Pass the + options down to the scaled font object to keep things compiling. + 2005-07-30 Keith Packard * src/cairo-wideint.c: (_cairo_int32x32_64_mul), diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c index bf5ecb28..8792faa4 100644 --- a/src/cairo-atsui-font.c +++ b/src/cairo-atsui-font.c @@ -189,7 +189,7 @@ _cairo_atsui_font_create(const char *family, font = malloc(sizeof(cairo_atsui_font_t)); - _cairo_scaled_font_init(&font->base, font_matrix, ctm, + _cairo_scaled_font_init(&font->base, font_matrix, ctm, options, &cairo_atsui_scaled_font_backend); cairo_matrix_multiply(&scale, font_matrix, ctm); -- cgit v1.2.3 From b4ae3371b34ca67e98df5e73147adcd6b7853e1d Mon Sep 17 00:00:00 2001 From: Billy Biggs Date: Sun, 31 Jul 2005 11:03:35 +0000 Subject: Cast away the const on the nil surface to avoid a compiler warning. --- ChangeLog | 5 +++++ src/cairo-quartz-surface.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 33e6d89e..3aeebf96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-07-31 Billy Biggs + + * src/cairo-quartz-surface.c: (cairo_quartz_surface_create): + Cast away the const on the nil surface to avoid a compiler warning. + 2005-07-31 Billy Biggs * src/cairo-atsui-font.c: (_cairo_atsui_font_create): Pass the diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index 0d847391..70f408a3 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -234,7 +234,7 @@ cairo_surface_t *cairo_quartz_surface_create(CGContextRef context, surface = malloc(sizeof(cairo_quartz_surface_t)); if (surface == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); - return &_cairo_surface_nil; + return (cairo_surface_t*) &_cairo_surface_nil; } _cairo_surface_init(&surface->base, &cairo_quartz_surface_backend); -- cgit v1.2.3 From cd78d99642bdf1171d21083a6947c77ff00b599e Mon Sep 17 00:00:00 2001 From: Billy Biggs Date: Sun, 31 Jul 2005 11:19:47 +0000 Subject: Support versions of freetype without exact FT_Bitmap_Size.x/y_ppem values by using the pixel width and height values instead. Add a check for FT_Bitmap_Size.y_ppem. reviewed by: keithp --- ChangeLog | 10 ++++++++++ configure.in | 14 ++++++++++++++ src/cairo-ft-font.c | 8 +++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3aeebf96..47adeb9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2005-07-31 Billy Biggs + + reviewed by: keithp + + * src/cairo-ft-font.c: (_ft_unscaled_font_set_scale): Support + versions of freetype without exact FT_Bitmap_Size.x/y_ppem + values by using the pixel width and height values instead. + + * configure.in: Add a check for FT_Bitmap_Size.y_ppem. + 2005-07-31 Billy Biggs * src/cairo-quartz-surface.c: (cairo_quartz_surface_create): diff --git a/configure.in b/configure.in index f1b503e2..807d7e34 100644 --- a/configure.in +++ b/configure.in @@ -273,6 +273,20 @@ if test "x$use_freetype" = "xyes"; then AC_SUBST(FREETYPE_CFLAGS) AC_SUBST(FREETYPE_LIBS) AC_SUBST(FREETYPE_REQUIRES) + + temp_save_libs="$LIBS" + temp_save_cflags="$CFLAGS" + LIBS="$LIBS $FREETYPE_LIBS" + CFLAGS="$CFLAGS $FREETYPE_CFLAGS" + AC_CHECK_MEMBER(FT_Bitmap_Size.y_ppem, + HAVE_FT_BITMAP_SIZE_Y_PPEM=1, + HAVE_FT_BITMAP_SIZE_Y_PPEM=0, + [#include + #include FT_FREETYPE_H]) + AC_DEFINE_UNQUOTED(HAVE_FT_BITMAP_SIZE_Y_PPEM,$HAVE_FT_BITMAP_SIZE_Y_PPEM, + [FT_Bitmap_Size structure includes y_ppem field]) + LIBS="$temp_save_libs" + CFLAGS="$temp_save_cflags" fi CAIRO_CFLAGS="$CAIRO_CFLAGS $FREETYPE_CFLAGS" diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index f6b0e9c0..4a142b9d 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -528,7 +528,11 @@ _ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled, pixel_width = pixel_height = 0; for (i = 0; i < unscaled->face->num_fixed_sizes; i++) { +#if HAVE_FT_BITMAP_SIZE_Y_PPEM double size = unscaled->face->available_sizes[i].y_ppem / 64.; +#else + double size = unscaled->face->available_sizes[i].height; +#endif double distance = fabs (size - sf.y_scale); if (distance <= min_distance) { @@ -536,11 +540,13 @@ _ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled, best_i = i; } } +#if HAVE_FT_BITMAP_SIZE_Y_PPEM error = FT_Set_Char_Size (unscaled->face, unscaled->face->available_sizes[best_i].x_ppem, unscaled->face->available_sizes[best_i].y_ppem, 0, 0); - if (error ) + if (error) +#endif error = FT_Set_Pixel_Sizes (unscaled->face, unscaled->face->available_sizes[best_i].width, unscaled->face->available_sizes[best_i].height); -- cgit v1.2.3 From 392a2746ef051d16be303477170511ef38dcf753 Mon Sep 17 00:00:00 2001 From: Amaury Jacquot Date: Mon, 1 Aug 2005 06:57:09 +0000 Subject: fix typo --- pixman/ChangeLog | 4 ++++ pixman/NEWS | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 7f9da47e..d9f1d935 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,7 @@ +2005-08-01 Amaury Jacquot + + * NEWS: fix typo + 2005-07-30 Jeff Muizelaar * src/ic.c: (fbCompositeSolidMask_nx8x0888), diff --git a/pixman/NEWS b/pixman/NEWS index a52095c6..cb412584 100644 --- a/pixman/NEWS +++ b/pixman/NEWS @@ -6,7 +6,7 @@ Clips are changed to only affect destination operands, not sources. This gives the desired behavior for cairo. If the X server's Render implementation wants to use pixman it will have to select source clipping, (presumably through a new API call that we can add at -that poin). +that point). Bug fixes --------- -- cgit v1.2.3 From 480951827e567db89f88e71e7ba20f4fa4633c1b Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 1 Aug 2005 11:45:42 +0000 Subject: src/cairo.h src/cairoint.h src/cairo-surface.c: Add cairo_mark_dirty[_rectangle]() and cairo_flush() for Implement a cairo_flush() that restores the original clip. Also restore the original flush when a surface is finished. Check off the item. --- ChangeLog | 11 +++++ ROADMAP | 2 +- doc/public/cairo-sections.txt | 3 ++ doc/public/tmpl/cairo-surface.sgml | 28 +++++++++++ src/cairo-surface.c | 97 +++++++++++++++++++++++++++++++++++++- src/cairo-win32-surface.c | 16 +++++-- src/cairo.h | 13 +++++ src/cairoint.h | 11 +++++ 8 files changed, 176 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 47adeb9a..d819ca9a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-08-01 Owen Taylor + + * src/cairo.h src/cairoint.h src/cairo-surface.c: + Add cairo_mark_dirty[_rectangle]() and cairo_flush() for + + * src/cairo-win32-surface.c: Implement a cairo_flush() + that restores the original clip. Also restore the original + flush when a surface is finished. + + * ROADMAP: Check off the item. + 2005-07-31 Billy Biggs reviewed by: keithp diff --git a/ROADMAP b/ROADMAP index 2f449127..b4fef0d1 100644 --- a/ROADMAP +++ b/ROADMAP @@ -41,7 +41,7 @@ API additions (more detail in TODO file) krh, and otaylor answered all the tough questions it raised. There's not much work left to finish this one. - A7. cairo_surface_mark_dirty and cairo_surface_flush +✓A7. cairo_surface_mark_dirty and cairo_surface_flush Difficulty: trivial to add API, moderate to actually optimize based on it Status: cworth has sent an API proposal to the list for diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index 2e237b02..24551ace 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -94,6 +94,9 @@ cairo_surface_finish cairo_surface_get_font_options cairo_surface_set_user_data cairo_surface_get_user_data +cairo_surface_flush +cairo_surface_mark_dirty +cairo_surface_mark_dirty_rectangle cairo_surface_set_device_offset diff --git a/doc/public/tmpl/cairo-surface.sgml b/doc/public/tmpl/cairo-surface.sgml index 5d069fc2..a33459d8 100644 --- a/doc/public/tmpl/cairo-surface.sgml +++ b/doc/public/tmpl/cairo-surface.sgml @@ -94,6 +94,34 @@ cairo_surface_t @Returns: + + + + + +@surface: + + + + + + + +@surface: + + + + + + + +@surface: +@x: +@y: +@width: +@height: + + diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 11fbc609..1920270e 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -310,7 +310,15 @@ cairo_surface_finish (cairo_surface_t *surface) surface->finished = TRUE; return; } - + + if (!surface->status && surface->backend->flush) { + status = surface->backend->flush (surface); + if (status) { + _cairo_surface_set_error (surface, status); + return; + } + } + status = surface->backend->finish (surface); if (status) { _cairo_surface_set_error (surface, status); @@ -392,6 +400,93 @@ cairo_surface_get_font_options (cairo_surface_t *surface, } } +/** + * cairo_surface_flush: + * @surface: a #cairo_surface_t + * + * Do any pending drawing for the surface and also restore any + * temporary modification's cairo has made to the surface's + * state. This function must be called before switching from + * drawing on the surface with cairo to drawing on it directly + * with native APIs. If the surface doesn't support direct access, + * then this function does nothing. + **/ +void +cairo_surface_flush (cairo_surface_t *surface) +{ + if (surface->status) { + _cairo_surface_set_error (surface, surface->status); + return; + } + + if (surface->finished) { + _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); + return; + } + + if (surface->backend->flush) { + cairo_status_t status; + + status = surface->backend->flush (surface); + + if (status) + _cairo_surface_set_error (surface, status); + } +} + +/** + * cairo_surface_mark_dirty: + * @surface: a #cairo_surface_t + * + * Tells cairo that drawing has been done to surface using means other + * than cairo, and that cairo should reread any cached areas. Note + * that you must call cairo_surface_flush() before doing such drawing. + */ +void +cairo_surface_mark_dirty (cairo_surface_t *surface) +{ + cairo_surface_mark_dirty_rectangle (surface, 0, 0, -1, -1); +} + +/** + * cairo_surface_mark_dirty_rectangle: + * @surface: a #cairo_surface_t + * @x: X coordinate of dirty rectangle + * @y: Y coordinate of dirty rectangle + * @width: width of dirty rectangle + * @height: height of dirty rectangle + * + * Like cairo_surface_mark_dirty(), but drawing has been done only to + * the specified rectangle, so that cairo can retain cached contents + * for other parts of the surface. + */ +void +cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, + int x, + int y, + int width, + int height) +{ + if (surface->status) { + _cairo_surface_set_error (surface, surface->status); + return; + } + + if (surface->finished) { + _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); + return; + } + + if (surface->backend->mark_dirty_rectangle) { + cairo_status_t status; + + status = surface->backend->mark_dirty_rectangle (surface, x, y, width, height); + + if (status) + _cairo_surface_set_error (surface, status); + } +} + /** * cairo_surface_set_device_offset: * @surface: a #cairo_surface_t diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index f9201245..95c37d99 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -340,8 +340,9 @@ _cairo_win32_surface_finish (void *abstract_surface) if (surface->image) cairo_surface_destroy (surface->image); - if (surface->saved_clip) + if (surface->saved_clip) { DeleteObject (surface->saved_clip); + } /* If we created the Bitmap and DC, destroy them */ if (surface->bitmap) { @@ -792,7 +793,6 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, surface->set_clip = 0; } - return CAIRO_STATUS_SUCCESS; } else { @@ -893,6 +893,12 @@ _cairo_win32_surface_get_extents (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } +static cairo_status_t +_cairo_win32_surface_flush (void *abstract_surface) +{ + return _cairo_surface_reset_clip (abstract_surface); +} + cairo_surface_t * cairo_win32_surface_create (HDC hdc) { @@ -964,5 +970,9 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = { _cairo_win32_surface_set_clip_region, NULL, /* intersect_clip_path */ _cairo_win32_surface_get_extents, - NULL /* show_glyphs */ + NULL, /* show_glyphs */ + NULL, /* fill_path */ + NULL, /* get_font_options */ + _cairo_win32_surface_flush, + NULL /* mark_dirty_rectangle */ }; diff --git a/src/cairo.h b/src/cairo.h index ba899981..ca4157a4 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -1148,6 +1148,19 @@ void cairo_surface_get_font_options (cairo_surface_t *surface, cairo_font_options_t *options); +void +cairo_surface_flush (cairo_surface_t *surface); + +void +cairo_surface_mark_dirty (cairo_surface_t *surface); + +void +cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, + int x, + int y, + int width, + int height); + void cairo_surface_set_device_offset (cairo_surface_t *surface, double x_offset, diff --git a/src/cairoint.h b/src/cairoint.h index 0e0cb713..74e70b94 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -779,6 +779,17 @@ typedef struct _cairo_surface_backend { void (*get_font_options) (void *surface, cairo_font_options_t *options); + + cairo_status_t + (*flush) (void *surface); + + cairo_status_t + (*mark_dirty_rectangle) (void *surface, + int x, + int y, + int width, + int height); + } cairo_surface_backend_t; typedef struct _cairo_format_masks { -- cgit v1.2.3 From c525c684ca712c5c5acd5431ec061bfab364cef5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 1 Aug 2005 13:33:47 +0000 Subject: New public header file. New function to reset all static data (eg. caches) to their initial state. Fix check-valgrind target to depend on the 'all' target. Add check for a new, proposed, XrmFinalize function. Add cairo-debug.c. Move the definition of CAIRO_BEGIN_DECLS to cairo-features.h so that it can be shared between public header files, and so that it doesn't clutter cairo.h Implement reset_static_data in all modules as required. Call cairo_debug_reset_static_data and FcFini so that we can have all tests be valgrind-clean with respect to memory leaks and still-reachable data. --- ChangeLog | 55 ++++++++++++++++++++++++++++++++++++ Makefile.am | 3 ++ configure.in | 7 +++++ src/Makefile.am | 1 + src/cairo-debug.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cairo-debug.h | 48 +++++++++++++++++++++++++++++++ src/cairo-features.h.in | 8 ++++++ src/cairo-font.c | 39 ++++++++++++++++++++------ src/cairo-ft-font.c | 13 +++++++++ src/cairo-xlib-screen.c | 53 +++++++++++++++++++++++++++++------ src/cairo-xlib-surface.c | 26 +++++++++++++++-- src/cairo.h | 8 ------ src/cairoint.h | 13 +++++++++ test/cairo-test.c | 6 ++++ test/cairo-test.h | 1 + test/xlib-surface.c | 2 ++ 16 files changed, 329 insertions(+), 27 deletions(-) create mode 100644 src/cairo-debug.c create mode 100644 src/cairo-debug.h diff --git a/ChangeLog b/ChangeLog index d819ca9a..055550a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,45 @@ +2005-08-01 Carl Worth + + * src/cairo-debug.h: New public header file. + + * src/cairo-debug.c: (cairo_debug_reset_static_data): New function + to reset all static data (eg. caches) to their initial state. + + * Makefile.am: Fix check-valgrind target to depend on the 'all' + target. + + * configure.in: Add check for a new, proposed, XrmFinalize + function. + + * src/Makefile.am: Add cairo-debug.c. + + * src/cairo.h: + * src/cairo-features.h.in: Move the definition of + CAIRO_BEGIN_DECLS to cairo-features.h so that it can be shared + between public header files, and so that it doesn't clutter + cairo.h + + * src/cairoint.h: + * src/cairo-font.c: (_get_global_simple_cache), + (_get_outer_font_cache), (_get_inner_font_cache), + (_cairo_unlock_global_image_glyph_cache), + (_cairo_font_reset_static_data): + * src/cairo-ft-font.c: (_cairo_ft_font_reset_static_data): + * src/cairo-xlib-screen.c: (_cairo_xlib_close_display), + (_cairo_xlib_screen_info_reset), + (_cairo_xlib_screen_reset_static_data): + * src/cairo-xlib-surface.c: (_unlock_xlib_glyphset_caches), + (_destroy_glyphset_cache_recurse), + (_cairo_xlib_surface_reset_static_data): Implement + reset_static_data in all modules as required. + + * test/xlib-surface.c: (main): + * test/cairo-test.h: + * test/cairo-test.c: (cairo_test_for_target), + (cairo_test_expecting): Call cairo_debug_reset_static_data and + FcFini so that we can have all tests be valgrind-clean with + respect to memory leaks and still-reachable data. + 2005-08-01 Owen Taylor * src/cairo.h src/cairoint.h src/cairo-surface.c: @@ -640,6 +682,19 @@ the .valgrind-suppresions file and to tee output into valgrind.log. +2005-07-18 Carl Worth + + * test/.valgrind-suppressions: Add valgrind suppressions for + libpng/libz use of uninitialized data. There are clearly bugs here + that are not cairo's fault as zeroing the buffer before writing + the png image actually causes more errors(!). And, notably, + setting all the data to random bytes usually makes the errors go + away. + + * test/Makefile.am: Change the check-valgrind target to include + the .valgrind-suppresions file and to tee output into + valgrind.log. + 2005-07-18 Carl Worth * configure.in: Add -head to CAIRO_VERSION after tagging with diff --git a/Makefile.am b/Makefile.am index c2a9965a..e375b1b1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,6 +15,9 @@ EXTRA_DIST = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = cairo.pc +check-valgrind: all + $(MAKE) -C test check-valgrind + DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc # Some custom targets to make it easier to release things. diff --git a/configure.in b/configure.in index 807d7e34..656db948 100644 --- a/configure.in +++ b/configure.in @@ -61,6 +61,13 @@ if test "x$use_xlib" = "xyes"; then XRENDER_LIBS="$X_LIBS -lXrender -lXext -lX11 $X_EXTRA_LIBS" use_xlib=yes], [ use_xlib="no (requires Xrender http://freedesktop.org/Software/xlibs)"])]) + save_cflags="$CFLAGS" + save_libs="$LIBS" + CFLAGS="$CFLAGS $XRENDER_CFLAGS" + LIBS="$LIBS $XRENDER_LIBS" + AC_CHECK_FUNCS(XrmFinalize) + CFLAGS="$save_cflags" + LIBS="$save_libs" fi AM_CONDITIONAL(CAIRO_HAS_XLIB_SURFACE, test "x$use_xlib" = "xyes") diff --git a/src/Makefile.am b/src/Makefile.am index 16cbb1c5..4456bdc9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,6 +86,7 @@ libcairo_la_SOURCES = \ cairo-array.c \ cairo-cache.c \ cairo-color.c \ + cairo-debug.c \ cairo-fixed.c \ cairo-font.c \ cairo-font-options.c \ diff --git a/src/cairo-debug.c b/src/cairo-debug.c new file mode 100644 index 00000000..31eefc5a --- /dev/null +++ b/src/cairo-debug.c @@ -0,0 +1,73 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl D. Worth + */ + +#include "cairoint.h" + +/** + * cairo_debug_reset_static_data: + * + * Resets all static data within cairo to its original state, + * (ie. identical to the state at the time of program invocation). For + * example, all caches within cairo will be flushed empty. + * + * This function is intended to be useful when using memory-checking + * tools such as valgrind. When valgrind's memcheck analyzes a + * cairo-using program without a call to cairo_debug_reset_static_data, + * it will report all data reachable via cairo's static objects as + * "still reachable". Calling cairo_debug_reset_static_data just prior + * to program termination will make it easier to get squeaky clean + * reports from valgrind. + * + * WARNING: It is only safe to call this function when there are no + * active cairo objects remaining, (ie. the appropriate destroy + * functions have been called as necessary). If there are active cairo + * objects, this call is likely to cause a crash, (eg. an assertion + * failure due to a hash table being destroyed when non-empty). + **/ +void +cairo_debug_reset_static_data (void) +{ +#if CAIRO_HAS_XLIB_SURFACE + _cairo_xlib_surface_reset_static_data (); + _cairo_xlib_screen_reset_static_data (); +#endif + + _cairo_font_reset_static_data (); + +#if CAIRO_HAS_FT_FONT + _cairo_ft_font_reset_static_data (); +#endif +} + diff --git a/src/cairo-debug.h b/src/cairo-debug.h new file mode 100644 index 00000000..1dab2c74 --- /dev/null +++ b/src/cairo-debug.h @@ -0,0 +1,48 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl D. Worth + */ + +#ifndef CAIRO_DEBUG_H +#define CAIRO_DEBUG_H + +#include + +CAIRO_BEGIN_DECLS + +void +cairo_debug_reset_static_data (void); + +CAIRO_END_DECLS + +#endif /* CAIRO_H */ diff --git a/src/cairo-features.h.in b/src/cairo-features.h.in index 8065be35..fdc1e37e 100644 --- a/src/cairo-features.h.in +++ b/src/cairo-features.h.in @@ -37,6 +37,14 @@ #ifndef CAIRO_FEATURES_H #define CAIRO_FEATURES_H +#ifdef __cplusplus +# define CAIRO_BEGIN_DECLS extern "C" { +# define CAIRO_END_DECLS } +#else +# define CAIRO_BEGIN_DECLS +# define CAIRO_END_DECLS +#endif + @PS_SURFACE_FEATURE@ @PDF_SURFACE_FEATURE@ diff --git a/src/cairo-font.c b/src/cairo-font.c index 022be7da..dc34ef61 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -233,11 +233,11 @@ _unlock_global_simple_cache (void) CAIRO_MUTEX_UNLOCK (_global_simple_cache_mutex); } +static cairo_cache_t *global_simple_cache = NULL; + static cairo_cache_t * _get_global_simple_cache (void) { - static cairo_cache_t *global_simple_cache = NULL; - if (global_simple_cache == NULL) { global_simple_cache = malloc (sizeof (cairo_cache_t)); @@ -564,11 +564,11 @@ _unlock_global_font_cache (void) CAIRO_MUTEX_UNLOCK (_global_font_cache_mutex); } +static cairo_cache_t *outer_font_cache = NULL; + static cairo_cache_t * _get_outer_font_cache (void) { - static cairo_cache_t *outer_font_cache = NULL; - if (outer_font_cache == NULL) { outer_font_cache = malloc (sizeof (cairo_cache_t)); @@ -589,11 +589,11 @@ _get_outer_font_cache (void) return NULL; } +static cairo_cache_t *inner_font_cache = NULL; + static cairo_cache_t * _get_inner_font_cache (void) { - static cairo_cache_t *inner_font_cache = NULL; - if (inner_font_cache == NULL) { inner_font_cache = malloc (sizeof (cairo_cache_t)); @@ -1352,8 +1352,10 @@ _cairo_lock_global_image_glyph_cache() void _cairo_unlock_global_image_glyph_cache() { - _cairo_cache_shrink_to (_global_image_glyph_cache, - CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT); + if (_global_image_glyph_cache) { + _cairo_cache_shrink_to (_global_image_glyph_cache, + CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT); + } CAIRO_MUTEX_UNLOCK (_global_image_glyph_cache_mutex); } @@ -1380,3 +1382,24 @@ _cairo_get_global_image_glyph_cache () _global_image_glyph_cache = NULL; return NULL; } + +void +_cairo_font_reset_static_data (void) +{ + _lock_global_font_cache (); + _cairo_cache_destroy (outer_font_cache); + outer_font_cache = NULL; + _cairo_cache_destroy (inner_font_cache); + inner_font_cache = NULL; + _unlock_global_font_cache (); + + _cairo_lock_global_image_glyph_cache(); + _cairo_cache_destroy (_global_image_glyph_cache); + _global_image_glyph_cache = NULL; + _cairo_unlock_global_image_glyph_cache(); + + _lock_global_simple_cache (); + _cairo_cache_destroy (global_simple_cache); + global_simple_cache = NULL; + _unlock_global_simple_cache (); +} diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 4a142b9d..fd16e071 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2440,3 +2440,16 @@ _cairo_ft_unscaled_font_unlock_face (cairo_unscaled_font_t *unscaled_font) { _ft_unscaled_font_unlock_face ((ft_unscaled_font_t *)unscaled_font); } + +void +_cairo_ft_font_reset_static_data (void) +{ + _lock_global_ft_cache (); + if (_global_ft_cache) { + FT_Done_FreeType (_global_ft_cache->lib); + _global_ft_cache->lib = NULL; + } + _cairo_cache_destroy (&_global_ft_cache->base); + _global_ft_cache = NULL; + _unlock_global_ft_cache (); +} diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c index 6a4efdbd..e71d10ec 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -245,34 +245,59 @@ _cairo_xlib_init_screen_font_options (cairo_xlib_screen_info_t *info) CAIRO_MUTEX_DECLARE(_xlib_screen_mutex); -static cairo_xlib_screen_info_t *_cairo_xlib_screen_list; +static cairo_xlib_screen_info_t *_cairo_xlib_screen_list = NULL; static int _cairo_xlib_close_display (Display *dpy, XExtCodes *codes) { - cairo_xlib_screen_info_t *info; - cairo_xlib_screen_info_t **prev; + cairo_xlib_screen_info_t *info, *prev; /* * Unhook from the global list */ CAIRO_MUTEX_LOCK (_xlib_screen_mutex); - for (prev = &_cairo_xlib_screen_list; (info = *prev); prev = &(*prev)->next) { + prev = NULL; + for (info = _cairo_xlib_screen_list; info; info = info->next) { if (info->display == dpy) { - *prev = info->next; + if (prev) + prev->next = info->next; + else + _cairo_xlib_screen_list = info->next; free (info); - if (!*prev) - break; + break; } + prev = info; } CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex); - + + /* Return value in accordance with requirements of + * XESetCloseDisplay */ return 0; } +static void +_cairo_xlib_screen_info_reset (void) +{ + cairo_xlib_screen_info_t *info, *next; + + /* + * Delete everything in the list. + */ + CAIRO_MUTEX_LOCK (_xlib_screen_mutex); + + for (info = _cairo_xlib_screen_list; info; info = next) { + next = info->next; + free (info); + } + + _cairo_xlib_screen_list = NULL; + + CAIRO_MUTEX_UNLOCK (_xlib_screen_mutex); + +} -cairo_private cairo_xlib_screen_info_t * +cairo_xlib_screen_info_t * _cairo_xlib_screen_info_get (Display *dpy, Screen *screen) { cairo_xlib_screen_info_t *info; @@ -344,3 +369,13 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen) return info; } +void +_cairo_xlib_screen_reset_static_data (void) +{ + _cairo_xlib_screen_info_reset (); + +#if HAVE_XRMFINALIZE + XrmFinalize (); +#endif + +} diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 5f26a2f4..e4d52552 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -1943,8 +1943,10 @@ _lock_xlib_glyphset_caches (void) static void _unlock_xlib_glyphset_caches (glyphset_cache_t *cache) { - _cairo_cache_shrink_to (&cache->base, - CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT); + if (cache) { + _cairo_cache_shrink_to (&cache->base, + CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT); + } CAIRO_MUTEX_UNLOCK(_xlib_glyphset_caches_mutex); } @@ -2452,3 +2454,23 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font, return status; } + +static void +_destroy_glyphset_cache_recurse (glyphset_cache_t *cache) +{ + if (cache == NULL) + return; + + _destroy_glyphset_cache_recurse (cache->next); + _cairo_cache_destroy (&cache->base); + free (cache); +} + +void +_cairo_xlib_surface_reset_static_data (void) +{ + _lock_xlib_glyphset_caches (); + _destroy_glyphset_cache_recurse (_xlib_glyphset_caches); + _xlib_glyphset_caches = NULL; + _unlock_xlib_glyphset_caches (NULL); +} diff --git a/src/cairo.h b/src/cairo.h index ca4157a4..f43d9c58 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -38,14 +38,6 @@ #ifndef CAIRO_H #define CAIRO_H -#ifdef __cplusplus -# define CAIRO_BEGIN_DECLS extern "C" { -# define CAIRO_END_DECLS } -#else -# define CAIRO_BEGIN_DECLS -# define CAIRO_END_DECLS -#endif - #include CAIRO_BEGIN_DECLS diff --git a/src/cairoint.h b/src/cairoint.h index 74e70b94..794f3409 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -63,6 +63,7 @@ #include #include "cairo.h" +#include "cairo-debug.h" #include #if __GNUC__ >= 3 && defined(__ELF__) @@ -518,6 +519,18 @@ _cairo_unlock_global_image_glyph_cache (void); cairo_private cairo_cache_t * _cairo_get_global_image_glyph_cache (void); +cairo_private void +_cairo_font_reset_static_data (void); + +cairo_private void +_cairo_ft_font_reset_static_data (void); + +cairo_private void +_cairo_xlib_surface_reset_static_data (void); + +cairo_private void +_cairo_xlib_screen_reset_static_data (void); + /* Some glyph cache functions you can reuse. */ cairo_private unsigned long diff --git a/test/cairo-test.c b/test/cairo-test.c index 456d7d85..7e6d48de 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "cairo-test.h" @@ -469,6 +470,9 @@ cairo_test_for_target (cairo_test_t *test, UNWIND_CAIRO: cairo_destroy (cr); cairo_surface_destroy (surface); + + cairo_debug_reset_static_data (); + target->cleanup_target (target->closure); UNWIND_STRINGS: @@ -557,6 +561,8 @@ cairo_test_expecting (cairo_test_t *test, cairo_test_draw_function_t draw, fclose (cairo_test_log_file); + FcFini (); + return ret; } diff --git a/test/cairo-test.h b/test/cairo-test.h index beabc6a5..d35faab8 100644 --- a/test/cairo-test.h +++ b/test/cairo-test.h @@ -28,6 +28,7 @@ #include #include +#include typedef enum cairo_test_status { CAIRO_TEST_SUCCESS = 0, diff --git a/test/xlib-surface.c b/test/xlib-surface.c index 2921eb85..805ce18f 100644 --- a/test/xlib-surface.c +++ b/test/xlib-surface.c @@ -267,6 +267,8 @@ main (void) XCloseDisplay (dpy); + cairo_debug_reset_static_data (); + fclose (log_file); return result; -- cgit v1.2.3 From 500cc6fed1858d5e9240ce61bbbf00781ae4c097 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 1 Aug 2005 14:39:01 +0000 Subject: src/cairo-gstate.c src/cairo-gstate-private.h: Store the inverse CTM at the time of cairo_gstate_set_source() to "lock" the user space matrix. Move the source pattern transformation to the outside of _cairo_gstate_clip_and_composite_trapezoids() instead of doing it at the leaves. Change size of output surface for aesthetics. Updated to correspond to the current definition. Remove source-surface-scale-paint. reviewed by: cworth --- ChangeLog | 23 +++++- src/cairo-gstate-private.h | 1 + src/cairo-gstate.c | 119 ++++++++++++++++++-------------- test/Makefile.am | 1 - test/source-surface-scale-paint-ref.png | Bin 147 -> 139 bytes test/source-surface-scale-paint.c | 5 +- 6 files changed, 91 insertions(+), 58 deletions(-) diff --git a/ChangeLog b/ChangeLog index 055550a3..a224f8d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2005-08-01 Owen Taylor + + reviewed by: cworth + + * src/cairo-gstate.c src/cairo-gstate-private.h: Store the + inverse CTM at the time of cairo_gstate_set_source() to + "lock" the user space matrix. + + * src/cairo-gstate.c: Move the source pattern transformation + to the outside of _cairo_gstate_clip_and_composite_trapezoids() + instead of doing it at the leaves. + + * test/source-surface-scale-paint.c: Change size of output + surface for aesthetics. + + * test/source-surface-scale-paint-ref.png: Updated to correspond + to the current definition. + + * test/Makefile.am (XFAIL_TESTS): + Remove source-surface-scale-paint. + 2005-08-01 Carl Worth * src/cairo-debug.h: New public header file. @@ -99,7 +120,7 @@ src/cairoint.h: Move the font options into the base cairo_scaled_font_t object so that we have them available to use when we are removing a scaled font from the cache. - (http://bugzilla.gnome.org/show_bug.cgi?id=#311299, + (http://bugzilla.gnome.org/show_bug.cgi?id=311299, Ali Akcaagac, Behdad Esfahbod) 2005-07-28 Carl Worth diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index 0d4d499f..06352576 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -103,6 +103,7 @@ struct _cairo_gstate { cairo_matrix_t ctm; cairo_matrix_t ctm_inverse; + cairo_matrix_t source_ctm_inverse; /* At the time ->source was set */ cairo_pen_t pen_regular; diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 50a6f2d2..121899f0 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -53,10 +53,7 @@ _cairo_gstate_fini (cairo_gstate_t *gstate); static cairo_status_t _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, - cairo_pattern_t *src, - cairo_operator_t operator, - cairo_surface_t *dst, - cairo_traps_t *traps); + cairo_traps_t *traps); static cairo_status_t _cairo_gstate_ensure_font (cairo_gstate_t *gstate); @@ -131,6 +128,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate, gstate->clip.path = NULL; _cairo_gstate_identity_matrix (gstate); + cairo_matrix_init_identity (&gstate->source_ctm_inverse); _cairo_pen_init_empty (&gstate->pen_regular); @@ -414,6 +412,7 @@ _cairo_gstate_set_source (cairo_gstate_t *gstate, cairo_pattern_reference (source); cairo_pattern_destroy (gstate->source); gstate->source = source; + gstate->source_ctm_inverse = gstate->ctm_inverse; return CAIRO_STATUS_SUCCESS; } @@ -717,11 +716,15 @@ _cairo_gstate_stroke_to_path (cairo_gstate_t *gstate) */ static void -_cairo_gstate_pattern_transform (cairo_gstate_t *gstate, - cairo_pattern_t *pattern) +_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, + cairo_pattern_t *pattern, + cairo_pattern_t *original, + cairo_matrix_t *ctm_inverse) { - cairo_matrix_t tmp_matrix = gstate->ctm_inverse; - + cairo_matrix_t tmp_matrix = *ctm_inverse; + + _cairo_pattern_init_copy (pattern, original); + if (gstate->target) cairo_matrix_translate (&tmp_matrix, - gstate->target->device_x_offset, @@ -730,6 +733,25 @@ _cairo_gstate_pattern_transform (cairo_gstate_t *gstate, _cairo_pattern_transform (pattern, &tmp_matrix); } +static void +_cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate, + cairo_pattern_t *pattern) +{ + _cairo_gstate_copy_transformed_pattern (gstate, pattern, + gstate->source, + &gstate->source_ctm_inverse); +} + +static void +_cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate, + cairo_pattern_t *pattern, + cairo_pattern_t *mask) +{ + _cairo_gstate_copy_transformed_pattern (gstate, pattern, + mask, + &gstate->ctm_inverse); +} + cairo_status_t _cairo_gstate_paint (cairo_gstate_t *gstate) { @@ -757,11 +779,7 @@ _cairo_gstate_paint (cairo_gstate_t *gstate) if (status) return status; - _cairo_gstate_clip_and_composite_trapezoids (gstate, - gstate->source, - gstate->operator, - gstate->target, - &traps); + _cairo_gstate_clip_and_composite_trapezoids (gstate, &traps); _cairo_traps_fini (&traps); @@ -937,11 +955,8 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, mask_x = mask_y = 0; } - _cairo_pattern_init_copy (&source_pattern.base, gstate->source); - _cairo_gstate_pattern_transform (gstate, &source_pattern.base); - - _cairo_pattern_init_copy (&mask_pattern.base, effective_mask); - _cairo_gstate_pattern_transform (gstate, &mask_pattern.base); + _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); + _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, effective_mask); status = _cairo_surface_composite (gstate->operator, &source_pattern.base, @@ -986,11 +1001,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) return status; } - _cairo_gstate_clip_and_composite_trapezoids (gstate, - gstate->source, - gstate->operator, - gstate->target, - &traps); + _cairo_gstate_clip_and_composite_trapezoids (gstate, &traps); _cairo_traps_fini (&traps); @@ -1152,7 +1163,6 @@ _composite_trap_region (cairo_gstate_t *gstate, cairo_rectangle_t *extents) { cairo_status_t status; - cairo_pattern_union_t pattern; cairo_pattern_union_t mask; int num_rects = pixman_region_num_rects (trap_region); unsigned int clip_serial; @@ -1173,14 +1183,11 @@ _composite_trap_region (cairo_gstate_t *gstate, return status; } - _cairo_pattern_init_copy (&pattern.base, src); - _cairo_gstate_pattern_transform (gstate, &pattern.base); - if (gstate->clip.surface) _cairo_pattern_init_for_surface (&mask.surface, gstate->clip.surface); status = _cairo_surface_composite (gstate->operator, - &pattern.base, + src, gstate->clip.surface ? &mask.base : NULL, dst, extents->x, extents->y, @@ -1189,7 +1196,6 @@ _composite_trap_region (cairo_gstate_t *gstate, extents->x, extents->y, extents->width, extents->height); - _cairo_pattern_fini (&pattern.base); if (gstate->clip.surface) _cairo_pattern_fini (&mask.base); @@ -1274,11 +1280,9 @@ _composite_traps_intermediate_surface (cairo_gstate_t *gstate, goto out; _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); - _cairo_pattern_init_copy (&pattern.base, src); - _cairo_gstate_pattern_transform (gstate, &pattern.base); status = _cairo_surface_composite (operator, - &pattern.base, + src, &intermediate_pattern.base, dst, extents->x, extents->y, @@ -1286,7 +1290,6 @@ _composite_traps_intermediate_surface (cairo_gstate_t *gstate, extents->x, extents->y, extents->width, extents->height); - _cairo_pattern_fini (&pattern.base); _cairo_pattern_fini (&intermediate_pattern.base); out: @@ -1345,14 +1348,10 @@ _composite_traps (cairo_gstate_t *gstate, cairo_traps_t *traps, cairo_rectangle_t *extents) { - cairo_pattern_union_t pattern; cairo_status_t status; - _cairo_pattern_init_copy (&pattern.base, src); - _cairo_gstate_pattern_transform (gstate, &pattern.base); - status = _cairo_surface_composite_trapezoids (gstate->operator, - &pattern.base, dst, + src, dst, extents->x, extents->y, extents->x, extents->y, extents->width, @@ -1360,18 +1359,16 @@ _composite_traps (cairo_gstate_t *gstate, traps->traps, traps->num_traps); - _cairo_pattern_fini (&pattern.base); - return status; } /* Warning: This call modifies the coordinates of traps */ static cairo_status_t -_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, - cairo_pattern_t *src, - cairo_operator_t operator, - cairo_surface_t *dst, - cairo_traps_t *traps) +_clip_and_composite_trapezoids_transformed (cairo_gstate_t *gstate, + cairo_pattern_t *src, + cairo_operator_t operator, + cairo_surface_t *dst, + cairo_traps_t *traps) { cairo_status_t status; pixman_region16_t *trap_region; @@ -1445,6 +1442,27 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, return status; } +/* Warning: This call modifies the coordinates of traps */ +static cairo_status_t +_cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, + cairo_traps_t *traps) +{ + cairo_pattern_union_t pattern; + cairo_status_t status; + + _cairo_gstate_copy_transformed_source (gstate, &pattern.base); + + status = _clip_and_composite_trapezoids_transformed (gstate, + &pattern.base, + gstate->operator, + gstate->target, + traps); + + _cairo_pattern_fini (&pattern.base); + + return status; +} + cairo_status_t _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { @@ -1476,11 +1494,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) return status; } - _cairo_gstate_clip_and_composite_trapezoids (gstate, - gstate->source, - gstate->operator, - gstate->target, - &traps); + _cairo_gstate_clip_and_composite_trapezoids (gstate, &traps); _cairo_traps_fini (&traps); @@ -2217,8 +2231,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, goto BAIL2; _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); - _cairo_pattern_init_copy (&pattern.base, gstate->source); - _cairo_gstate_pattern_transform (gstate, &pattern.base); + _cairo_gstate_copy_transformed_source (gstate, &pattern.base); status = _cairo_surface_composite (gstate->operator, &pattern.base, @@ -2239,7 +2252,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, else { _cairo_pattern_init_copy (&pattern.base, gstate->source); - _cairo_gstate_pattern_transform (gstate, &pattern.base); + _cairo_gstate_copy_transformed_source (gstate, &pattern.base); status = _cairo_scaled_font_show_glyphs (gstate->scaled_font, gstate->operator, &pattern.base, diff --git a/test/Makefile.am b/test/Makefile.am index 0f3a23ea..bdbf5856 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -113,7 +113,6 @@ XFAIL_TESTS = \ filter-nearest-offset \ pixman-rotate \ self-intersecting \ -source-surface-scale-paint \ text-antialias-subpixel \ text-rotate diff --git a/test/source-surface-scale-paint-ref.png b/test/source-surface-scale-paint-ref.png index ec3c059f..a81f93d9 100644 Binary files a/test/source-surface-scale-paint-ref.png and b/test/source-surface-scale-paint-ref.png differ diff --git a/test/source-surface-scale-paint.c b/test/source-surface-scale-paint.c index 9862ba59..1af972f2 100644 --- a/test/source-surface-scale-paint.c +++ b/test/source-surface-scale-paint.c @@ -28,7 +28,7 @@ cairo_test_t test = { "source-surface-scale-paint", "Test call sequence: cairo_set_source_surface; cairo_scale; cairo_paint", - 12, 12 + 8, 8 }; static cairo_test_status_t @@ -59,6 +59,5 @@ draw (cairo_t *cr, int width, int height) int main (void) { - return cairo_test_expect_failure (&test, draw, - "cairo_set_source needs user space locking semantics"); + return cairo_test (&test, draw); } -- cgit v1.2.3 From ba87f1324fda84ea816ad8f18442444c2ad1ed93 Mon Sep 17 00:00:00 2001 From: Billy Biggs Date: Mon, 1 Aug 2005 18:01:24 +0000 Subject: Optimize spans where the same value is being added to multiple pixels. This improves the speed of rasterizing wide trapezoids. Add an INLINE macro that matches the one from fbpict.h in xserver/fb. --- pixman/ChangeLog | 10 +++ pixman/src/fbedge.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++------ pixman/src/icint.h | 6 ++ 3 files changed, 220 insertions(+), 26 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index d9f1d935..06402abd 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,13 @@ +2005-08-01 Billy Biggs + + * src/fbedge.c: (clip255), (add_saturate_8), + (fbRasterizeEdges8): Optimize spans where the same value is + being added to multiple pixels. This improves the speed of + rasterizing wide trapezoids. + + * src/icint.h: Add an INLINE macro that matches the one from + fbpict.h in xserver/fb. + 2005-08-01 Amaury Jacquot * NEWS: fix typo diff --git a/pixman/src/fbedge.c b/pixman/src/fbedge.c index 6839317d..2ee6e6cd 100644 --- a/pixman/src/fbedge.c +++ b/pixman/src/fbedge.c @@ -1,5 +1,5 @@ /* - * $Id: fbedge.c,v 1.2 2005-01-21 18:26:28 cworth Exp $ + * $Id: fbedge.c,v 1.3 2005-08-02 01:01:24 vektor Exp $ * * Copyright © 2004 Keith Packard * @@ -22,35 +22,11 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include #include "pixman-xserver-compat.h" #ifdef RENDER -/* - * 8 bit alpha - */ - -#define N_BITS 8 -#define rasterizeEdges fbRasterizeEdges8 - -#define DefineAlpha(line,x) \ - CARD8 *__ap = (CARD8 *) line + (x) - -#define StepAlpha __ap++ - -#define AddAlpha(a) { \ - CARD16 __a = a + *__ap; \ - *__ap = ((CARD8) ((__a) | (0 - ((__a) >> 8)))); \ -} - -#include "fbedgeimp.h" - -#undef AddAlpha -#undef StepAlpha -#undef DefineAlpha -#undef rasterizeEdges -#undef N_BITS - /* * 4 bit alpha */ @@ -100,6 +76,208 @@ #undef rasterizeEdges #undef N_BITS +/* + * 8 bit alpha + */ + +static INLINE CARD8 +clip255 (int x) +{ + if (x > 255) return 255; + return x; +} + +static INLINE void +add_saturate_8 (CARD8 *buf, int value, int length) +{ + while (length--) + { + *buf = clip255 (*buf + value); + buf++; + } +} + +/* + * We want to detect the case where we add the same value to a long + * span of pixels. The triangles on the end are filled in while we + * count how many sub-pixel scanlines contribute to the middle section. + * + * +--------------------------+ + * fill_height =| \ / + * +------------------+ + * |================| + * fill_start fill_end + */ +static void +fbRasterizeEdges8 (FbBits *buf, + int width, + int stride, + RenderEdge *l, + RenderEdge *r, + xFixed t, + xFixed b) +{ + xFixed y = t; + FbBits *line; + int fill_start = -1, fill_end = -1; + int fill_size = 0; + + line = buf + xFixedToInt (y) * stride; + + for (;;) + { + CARD8 *ap = (CARD8 *) line; + xFixed lx, rx; + int lxi, rxi; + + /* clip X */ + lx = l->x; + if (lx < 0) + lx = 0; + rx = r->x; + if (xFixedToInt (rx) >= width) + rx = IntToxFixed (width); + + /* Skip empty (or backwards) sections */ + if (rx > lx) + { + int lxs, rxs; + + /* Find pixel bounds for span. */ + lxi = xFixedToInt (lx); + rxi = xFixedToInt (rx); + + /* Sample coverage for edge pixels */ + lxs = RenderSamplesX (lx, 8); + rxs = RenderSamplesX (rx, 8); + + /* Add coverage across row */ + if (lxi == rxi) + { + ap[lxi] = clip255 (ap[lxi] + rxs - lxs); + } + else + { + ap[lxi] = clip255 (ap[lxi] + N_X_FRAC(8) - lxs); + + /* Move forward so that lxi/rxi is the pixel span */ + lxi++; + + /* Don't bother trying to optimize the fill unless + * the span is longer than 4 pixels. */ + if (rxi - lxi > 4) + { + if (fill_start < 0) + { + fill_start = lxi; + fill_end = rxi; + fill_size++; + } + else + { + if (lxi >= fill_end || rxi < fill_start) + { + /* We're beyond what we saved, just fill it */ + add_saturate_8 (ap + fill_start, + fill_size * N_X_FRAC(8), + fill_end - fill_start); + fill_start = lxi; + fill_end = rxi; + fill_size = 1; + } + else + { + /* Update fill_start */ + if (lxi > fill_start) + { + add_saturate_8 (ap + fill_start, + fill_size * N_X_FRAC(8), + lxi - fill_start); + fill_start = lxi; + } + else if (lxi < fill_start) + { + add_saturate_8 (ap + lxi, N_X_FRAC(8), + fill_start - lxi); + } + + /* Update fill_end */ + if (rxi < fill_end) + { + add_saturate_8 (ap + rxi, + fill_size * N_X_FRAC(8), + fill_end - rxi); + fill_end = rxi; + } + else if (fill_end < rxi) + { + add_saturate_8 (ap + fill_end, + N_X_FRAC(8), + rxi - fill_end); + } + fill_size++; + } + } + } + else + { + add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi); + } + + /* Do not add in a 0 alpha here. This check is + * necessary to avoid a buffer overrun, (when rx + * is exactly on a pixel boundary). */ + if (rxs) + ap[rxi] = clip255 (ap[rxi] + rxs); + } + } + + if (y == b) { + /* We're done, make sure we clean up any remaining fill. */ + if (fill_start != fill_end) { + if (fill_size == N_Y_FRAC(8)) + { + memset (ap + fill_start, 0xff, fill_end - fill_start); + } + else + { + add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), + fill_end - fill_start); + } + } + break; + } + + if (xFixedFrac (y) != Y_FRAC_LAST(8)) + { + RenderEdgeStepSmall (l); + RenderEdgeStepSmall (r); + y += STEP_Y_SMALL(8); + } + else + { + RenderEdgeStepBig (l); + RenderEdgeStepBig (r); + y += STEP_Y_BIG(8); + if (fill_start != fill_end) + { + if (fill_size == N_Y_FRAC(8)) + { + memset (ap + fill_start, 0xff, fill_end - fill_start); + } + else + { + add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8), + fill_end - fill_start); + } + fill_start = fill_end = -1; + fill_size = 0; + } + line += stride; + } + } +} + void fbRasterizeEdges (FbBits *buf, int bpp, diff --git a/pixman/src/icint.h b/pixman/src/icint.h index a5f0aff2..7567388f 100644 --- a/pixman/src/icint.h +++ b/pixman/src/icint.h @@ -39,6 +39,12 @@ #define __inline #endif +#if defined(__GNUC__) +#define INLINE __inline__ +#else +#define INLINE +#endif + #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) -- cgit v1.2.3 From b45f68876528050107b6e8c4b24fb8edb7ded12e Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 3 Aug 2005 10:32:50 +0000 Subject: Fix for bug #3951: Add new _CHECK_FUNCS_WITH_FLAGS to abstract out the pain of temporarily setting flags for AC_CHECK_FUNCS. Use this to check for the existence of FcFini. Make call to FcFini conditional on HAVE_FCFINI. Remove stale comment about cleaning up memory which is now handled by cairo-test.c. --- ChangeLog | 14 ++++++++++++++ configure.in | 30 +++++++++++++++++++++++------- test/cairo-test.c | 2 ++ test/text-cache-crash.c | 14 -------------- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index a224f8d2..c2f05293 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-08-03 Carl Worth + + Fix for bug #3951: + + * configure.in: Add new _CHECK_FUNCS_WITH_FLAGS to abstract out + the pain of temporarily setting flags for AC_CHECK_FUNCS. Use this + to check for the existence of FcFini. + + * test/cairo-test.c: (cairo_test_expecting): Make call to FcFini + conditional on HAVE_FCFINI. + + * test/text-cache-crash.c: (main): Remove stale comment about + cleaning up memory which is now handled by cairo-test.c. + 2005-08-01 Owen Taylor reviewed by: cworth diff --git a/configure.in b/configure.in index 656db948..7b849abf 100644 --- a/configure.in +++ b/configure.in @@ -37,6 +37,27 @@ AM_PROG_LIBTOOL AC_STDC_HEADERS AC_C_BIGENDIAN +dnl =========================================================================== +dnl === Local macros +dnl =========================================================================== + +# _CHECK_FUNCS_WITH_FLAGS(FUNCTION..., CFLAGS, LIBS +# [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) +# Like AC_CHECK_FUNCS but with additional CFLAGS and LIBS +# -------------------------------------------------------------------- +AC_DEFUN([_CHECK_FUNCS_WITH_FLAGS], +[ + save_cflags="$CFLAGS" + save_libs="$LIBS" + CFLAGS="$CFLAGS $2" + LIBS="$LIBS $3" + AC_CHECK_FUNCS($1, $4, $5) + CFLAGS="$save_cflags" + LIBS="$save_libs" +]) + +dnl =========================================================================== + AC_CHECK_FUNCS(vasnprintf) AC_CHECK_LIBM @@ -61,13 +82,7 @@ if test "x$use_xlib" = "xyes"; then XRENDER_LIBS="$X_LIBS -lXrender -lXext -lX11 $X_EXTRA_LIBS" use_xlib=yes], [ use_xlib="no (requires Xrender http://freedesktop.org/Software/xlibs)"])]) - save_cflags="$CFLAGS" - save_libs="$LIBS" - CFLAGS="$CFLAGS $XRENDER_CFLAGS" - LIBS="$LIBS $XRENDER_LIBS" - AC_CHECK_FUNCS(XrmFinalize) - CFLAGS="$save_cflags" - LIBS="$save_libs" + _CHECK_FUNCS_WITH_FLAGS(XrmFinalize, $XRENDER_CFLAGS, $XRENDER_LIBS) fi AM_CONDITIONAL(CAIRO_HAS_XLIB_SURFACE, test "x$use_xlib" = "xyes") @@ -232,6 +247,7 @@ AC_ARG_ENABLE(freetype, if test "x$use_freetype" = "xyes"; then PKG_CHECK_MODULES(FONTCONFIG, fontconfig, [use_freetype=yes], [use_freetype=no]) + _CHECK_FUNCS_WITH_FLAGS(FcFini, $FONTCONFIG_CFLAGS, $FONTCONFIG_LIBS) fi CAIRO_CFLAGS="$CAIRO_CFLAGS $FONTCONFIG_CFLAGS" diff --git a/test/cairo-test.c b/test/cairo-test.c index 7e6d48de..aff2125b 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -561,7 +561,9 @@ cairo_test_expecting (cairo_test_t *test, cairo_test_draw_function_t draw, fclose (cairo_test_log_file); +#if HAVE_FCFINI FcFini (); +#endif return ret; } diff --git a/test/text-cache-crash.c b/test/text-cache-crash.c index 547e2a34..08e85739 100644 --- a/test/text-cache-crash.c +++ b/test/text-cache-crash.c @@ -118,20 +118,6 @@ main (void) ret = cairo_test (&test, draw); - /* It's convenient to be able to free all memory (including - * statically allocated memory). This makes it quite easy to use - * tools such as valgrind to verify that there are no memory leaks - * whatsoever. - * - * But I'm not sure what would be a sensible cairo API function - * for this. The cairo_destroy_caches call below is just something - * I made as a local modification to cairo. - */ - /* - cairo_destroy_caches (); - FcFini (); - */ - return ret; } -- cgit v1.2.3 From b5ab1741e9f9e73283dd18266834ecae2b03d93e Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 4 Aug 2005 13:22:15 +0000 Subject: Originally 2005-07-13 Carl Worth Export opaque cairo_ft_unscaled_font_t and change _cairo_ft_unscaled_font_[un]lock_face to accept cairo_ft_unscaled_font_t rather than cairo_unscaled_font_t. Cast explicitly to cairo_ft_unscaled_font_t to track change in prototype of _cairo_ft_unscaled_font_[un]lock_face. Lots of renaming to use consistent namespacing: ft_font_transform_t -> cairo_ft_font_transform_t ft_font_face_t -> cairo_ft_font_face_t ft_unscaled_font_t -> cairo_ft_unscaled_font_t Add missing _cairo prefix to many functions. Disambiguate _ft_scaled_font_create and _cairo_ft_scaled_font_create by renaming the former to _cairo_ft_scaled_font_create_for_unscaled. Reviewed by: otaylor --- ChangeLog | 28 +++++++ src/cairo-font-subset.c | 18 +++- src/cairo-ft-font.c | 215 +++++++++++++++++++++++------------------------- src/cairo-ft-private.h | 6 +- 4 files changed, 150 insertions(+), 117 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2f05293..293d6d0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2005-08-04 Carl Worth + + Originally 2005-07-13 Carl Worth + + Reviewed by: otaylor + + * src/cairo-ft-private.h: Export opaque cairo_ft_unscaled_font_t + and change _cairo_ft_unscaled_font_[un]lock_face to accept + cairo_ft_unscaled_font_t rather than cairo_unscaled_font_t. + + * src/cairo-font-subset.c: (_cairo_font_subset_create), + (cairo_pdf_ft_font_generate): Cast explicitly to + cairo_ft_unscaled_font_t to track change in prototype of + _cairo_ft_unscaled_font_[un]lock_face. + + * src/cairo-ft-font.c: Lots of renaming to use consistent + namespacing: + + ft_font_transform_t -> cairo_ft_font_transform_t + ft_font_face_t -> cairo_ft_font_face_t + ft_unscaled_font_t -> cairo_ft_unscaled_font_t + + Add missing _cairo prefix to many functions. + + Disambiguate _ft_scaled_font_create and + _cairo_ft_scaled_font_create by renaming the former to + _cairo_ft_scaled_font_create_for_unscaled. + 2005-08-03 Carl Worth Fix for bug #3951: diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c index e3a2784c..16c52dfd 100644 --- a/src/cairo-font-subset.c +++ b/src/cairo-font-subset.c @@ -134,6 +134,7 @@ _cairo_font_subset_destroy (cairo_font_subset_t *font) cairo_font_subset_t * _cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) { + cairo_ft_unscaled_font_t *ft_unscaled_font; FT_Face face; cairo_pdf_ft_font_t *font; unsigned long size; @@ -143,7 +144,9 @@ _cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) if (! _cairo_unscaled_font_is_ft (unscaled_font)) return NULL; - face = _cairo_ft_unscaled_font_lock_face (unscaled_font); + ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font; + + face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font); /* We currently only support freetype truetype fonts. */ size = 0; @@ -193,7 +196,7 @@ _cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) if (font->base.widths == NULL) goto fail5; - _cairo_ft_unscaled_font_unlock_face (unscaled_font); + _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font); font->status = CAIRO_STATUS_SUCCESS; @@ -589,11 +592,18 @@ static cairo_status_t cairo_pdf_ft_font_generate (void *abstract_font, const char **data, unsigned long *length) { + cairo_ft_unscaled_font_t *ft_unscaled_font; cairo_pdf_ft_font_t *font = abstract_font; unsigned long start, end, next, checksum, *checksum_location; int i; - font->face = _cairo_ft_unscaled_font_lock_face (font->base.unscaled_font); + /* XXX: It would be cleaner to do something besides this cast + * here. Perhaps cairo_pdf_ft_font_t should just have the + * cairo_ft_unscaled_font_t rather than having the generic + * cairo_unscaled_font_t in the base class? */ + ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font; + + font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font); if (cairo_pdf_ft_font_write_offset_table (font)) goto fail; @@ -622,7 +632,7 @@ cairo_pdf_ft_font_generate (void *abstract_font, *length = _cairo_array_num_elements (&font->output); fail: - _cairo_ft_unscaled_font_unlock_face (font->base.unscaled_font); + _cairo_ft_unscaled_font_unlock_face (ft_unscaled_font); font->face = NULL; return font->status; diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index fd16e071..c934c7de 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -76,10 +76,10 @@ * factors so that hinting works right */ -typedef struct { +typedef struct _cairo_ft_font_transform { double x_scale, y_scale; double shape[2][2]; -} ft_font_transform_t; +} cairo_ft_font_transform_t; /* * We create an object that corresponds to a single font on the disk; @@ -88,9 +88,9 @@ typedef struct { * just create a one-off version with a permanent face value. */ -typedef struct _ft_font_face ft_font_face_t; +typedef struct _cairo_ft_font_face cairo_ft_font_face_t; -typedef struct { +struct _cairo_ft_unscaled_font { cairo_unscaled_font_t base; cairo_bool_t from_face; /* from cairo_ft_scaled_font_create_for_ft_face()? */ @@ -109,22 +109,22 @@ typedef struct { int lock; /* count of how many times this font has been locked */ - ft_font_face_t *faces; /* Linked list of faces for this font */ -} ft_unscaled_font_t; + cairo_ft_font_face_t *faces; /* Linked list of faces for this font */ +}; -struct _ft_font_face { +struct _cairo_ft_font_face { cairo_font_face_t base; - ft_unscaled_font_t *unscaled; + cairo_ft_unscaled_font_t *unscaled; int load_flags; - ft_font_face_t *next_face; + cairo_ft_font_face_t *next_face; }; const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend; -static ft_unscaled_font_t * -_ft_unscaled_font_create_from_face (FT_Face face) +static cairo_ft_unscaled_font_t * +_cairo_ft_unscaled_font_create_from_face (FT_Face face) { - ft_unscaled_font_t *unscaled = malloc (sizeof(ft_unscaled_font_t)); + cairo_ft_unscaled_font_t *unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); if (!unscaled) return NULL; @@ -150,18 +150,18 @@ _cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font) return unscaled_font->backend == &cairo_ft_unscaled_font_backend; } -static ft_unscaled_font_t * -_ft_unscaled_font_create_from_filename (const char *filename, - int id) +static cairo_ft_unscaled_font_t * +_cairo_ft_unscaled_font_create_from_filename (const char *filename, + int id) { - ft_unscaled_font_t *unscaled; + cairo_ft_unscaled_font_t *unscaled; char *new_filename; new_filename = strdup (filename); if (!new_filename) return NULL; - unscaled = malloc (sizeof (ft_unscaled_font_t)); + unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); if (!unscaled) { free (new_filename); return NULL; @@ -199,7 +199,7 @@ typedef struct { typedef struct { cairo_ft_cache_key_t key; - ft_unscaled_font_t *unscaled; + cairo_ft_unscaled_font_t *unscaled; } cairo_ft_cache_entry_t; typedef struct { @@ -209,7 +209,7 @@ typedef struct { } ft_cache_t; static unsigned long -_ft_font_cache_hash (void *cache, void *key) +_cairo_ft_font_cache_hash (void *cache, void *key) { cairo_ft_cache_key_t *in = (cairo_ft_cache_key_t *) key; unsigned long hash; @@ -222,9 +222,9 @@ _ft_font_cache_hash (void *cache, void *key) } static int -_ft_font_cache_keys_equal (void *cache, - void *k1, - void *k2) +_cairo_ft_font_cache_keys_equal (void *cache, + void *k1, + void *k2) { cairo_ft_cache_key_t *a; cairo_ft_cache_key_t *b; @@ -236,9 +236,9 @@ _ft_font_cache_keys_equal (void *cache, } static cairo_status_t -_ft_font_cache_create_entry (void *cache, - void *key, - void **return_entry) +_cairo_ft_font_cache_create_entry (void *cache, + void *key, + void **return_entry) { cairo_ft_cache_key_t *k = key; cairo_ft_cache_entry_t *entry; @@ -247,8 +247,8 @@ _ft_font_cache_create_entry (void *cache, if (entry == NULL) return CAIRO_STATUS_NO_MEMORY; - entry->unscaled = _ft_unscaled_font_create_from_filename (k->filename, - k->id); + entry->unscaled = _cairo_ft_unscaled_font_create_from_filename (k->filename, + k->id); if (!entry->unscaled) { free (entry); return CAIRO_STATUS_NO_MEMORY; @@ -268,8 +268,8 @@ _ft_font_cache_create_entry (void *cache, * in the code that removes the entry from the cache */ static void -_ft_font_cache_destroy_entry (void *cache, - void *entry) +_cairo_ft_font_cache_destroy_entry (void *cache, + void *entry) { cairo_ft_cache_entry_t *e = (cairo_ft_cache_entry_t *) entry; @@ -277,7 +277,7 @@ _ft_font_cache_destroy_entry (void *cache, } static void -_ft_font_cache_destroy_cache (void *cache) +_cairo_ft_font_cache_destroy_cache (void *cache) { ft_cache_t *fc = (ft_cache_t *) cache; @@ -286,11 +286,11 @@ _ft_font_cache_destroy_cache (void *cache) } static const cairo_cache_backend_t _ft_font_cache_backend = { - _ft_font_cache_hash, - _ft_font_cache_keys_equal, - _ft_font_cache_create_entry, - _ft_font_cache_destroy_entry, - _ft_font_cache_destroy_cache + _cairo_ft_font_cache_hash, + _cairo_ft_font_cache_keys_equal, + _cairo_ft_font_cache_create_entry, + _cairo_ft_font_cache_destroy_entry, + _cairo_ft_font_cache_destroy_cache }; static ft_cache_t *_global_ft_cache = NULL; @@ -339,8 +339,8 @@ _get_global_ft_cache (void) /* Finds or creates a ft_unscaled_font for the filename/id from pattern. * Returns a new reference to the unscaled font. */ -static ft_unscaled_font_t * -_ft_unscaled_font_get_for_pattern (FcPattern *pattern) +static cairo_ft_unscaled_font_t * +_cairo_ft_unscaled_font_get_for_pattern (FcPattern *pattern) { cairo_ft_cache_entry_t *entry; cairo_ft_cache_key_t key; @@ -384,9 +384,12 @@ _has_unlocked_face (void *entry) /* Ensures that an unscaled font has a face object. If we exceed * MAX_OPEN_FACES, try to close some. + * + * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't + * set the scale on the face, but just returns it at the last scale. */ -static FT_Face -_ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled) +FT_Face +_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled) { ft_cache_t *ftcache; FT_Face face = NULL; @@ -433,8 +436,8 @@ _ft_unscaled_font_lock_face (ft_unscaled_font_t *unscaled) /* Unlock unscaled font locked with _ft_unscaled_font_lock_face */ -static void -_ft_unscaled_font_unlock_face (ft_unscaled_font_t *unscaled) +void +_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled) { assert (unscaled->lock > 0); @@ -442,7 +445,7 @@ _ft_unscaled_font_unlock_face (ft_unscaled_font_t *unscaled) } static void -_compute_transform (ft_font_transform_t *sf, +_compute_transform (cairo_ft_font_transform_t *sf, cairo_matrix_t *scale) { cairo_matrix_t normalized = *scale; @@ -476,10 +479,10 @@ _compute_transform (ft_font_transform_t *sf, * scaling to the same size, since changing a FT_Face is expensive. */ static void -_ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled, - cairo_matrix_t *scale) +_cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, + cairo_matrix_t *scale) { - ft_font_transform_t sf; + cairo_ft_font_transform_t sf; FT_Matrix mat; FT_UInt pixel_width, pixel_height; FT_Error error; @@ -558,7 +561,7 @@ _ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled, static void _cairo_ft_unscaled_font_destroy (void *abstract_font) { - ft_unscaled_font_t *unscaled = abstract_font; + cairo_ft_unscaled_font_t *unscaled = abstract_font; if (unscaled == NULL) return; @@ -996,7 +999,7 @@ _render_glyph_bitmap (FT_Face face, static cairo_status_t _transform_glyph_bitmap (cairo_image_glyph_cache_entry_t *val) { - ft_font_transform_t sf; + cairo_ft_font_transform_t sf; cairo_matrix_t original_to_transformed; cairo_matrix_t transformed_to_original; cairo_image_surface_t *old_image; @@ -1116,21 +1119,21 @@ static cairo_status_t _cairo_ft_unscaled_font_create_glyph (void *abstract_font, cairo_image_glyph_cache_entry_t *val) { - ft_unscaled_font_t *unscaled = abstract_font; + cairo_ft_unscaled_font_t *unscaled = abstract_font; FT_GlyphSlot glyphslot; FT_Face face; FT_Glyph_Metrics *metrics; cairo_status_t status = CAIRO_STATUS_SUCCESS; double x_factor, y_factor; - face = _ft_unscaled_font_lock_face (unscaled); + face = _cairo_ft_unscaled_font_lock_face (unscaled); if (!face) return CAIRO_STATUS_NO_MEMORY; glyphslot = face->glyph; metrics = &glyphslot->metrics; - _ft_unscaled_font_set_scale (unscaled, &val->key.scale); + _cairo_ft_unscaled_font_set_scale (unscaled, &val->key.scale); if (FT_Load_Glyph (face, val->key.index, val->key.flags & ~PRIVATE_FLAGS_MASK) != 0) { status = CAIRO_STATUS_NO_MEMORY; @@ -1209,7 +1212,7 @@ _cairo_ft_unscaled_font_create_glyph (void *abstract_ val->image = NULL; } - _ft_unscaled_font_unlock_face (unscaled); + _cairo_ft_unscaled_font_unlock_face (unscaled); return status; } @@ -1221,10 +1224,10 @@ const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = { /* cairo_ft_scaled_font_t */ -typedef struct { +typedef struct _cairo_ft_scaled_font { cairo_scaled_font_t base; int load_flags; - ft_unscaled_font_t *unscaled; + cairo_ft_unscaled_font_t *unscaled; } cairo_ft_scaled_font_t; const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend; @@ -1375,11 +1378,11 @@ _get_options_load_flags (const cairo_font_options_t *options) } static cairo_scaled_font_t * -_ft_scaled_font_create (ft_unscaled_font_t *unscaled, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - int load_flags) +_cairo_ft_scaled_font_create_for_unscaled (cairo_ft_unscaled_font_t *unscaled, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + int load_flags) { cairo_ft_scaled_font_t *f = NULL; @@ -1416,13 +1419,14 @@ _cairo_ft_scaled_font_create (const char *family, cairo_scaled_font_t **font) { FcPattern *pattern, *resolved; - ft_unscaled_font_t *unscaled; + cairo_ft_unscaled_font_t *unscaled; cairo_scaled_font_t *new_font; FcResult result; int fcslant; int fcweight; cairo_matrix_t scale; - ft_font_transform_t sf; + cairo_ft_font_transform_t sf; + int load_flags; pattern = FcPatternCreate (); if (!pattern) @@ -1473,13 +1477,15 @@ _cairo_ft_scaled_font_create (const char *family, if (!resolved) goto FREE_PATTERN; - unscaled = _ft_unscaled_font_get_for_pattern (resolved); + unscaled = _cairo_ft_unscaled_font_get_for_pattern (resolved); if (!unscaled) goto FREE_RESOLVED; - - new_font = _ft_scaled_font_create (unscaled, - font_matrix, ctm, - options, _get_pattern_load_flags (pattern)); + + load_flags = _get_pattern_load_flags (pattern); + new_font = _cairo_ft_scaled_font_create_for_unscaled (unscaled, + font_matrix, ctm, + options, load_flags); + _cairo_unscaled_font_destroy (&unscaled->base); FcPatternDestroy (resolved); @@ -1602,13 +1608,14 @@ _cairo_ft_scaled_font_font_extents (void *abstract_font, FT_Face face; FT_Size_Metrics *metrics; - face = _ft_unscaled_font_lock_face (scaled_font->unscaled); + face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled); if (!face) return CAIRO_STATUS_NO_MEMORY; metrics = &face->size->metrics; - _ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale); + _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, + &scaled_font->base.scale); /* * Get to unscaled metrics so that the upper level can get back to @@ -1643,7 +1650,7 @@ _cairo_ft_scaled_font_font_extents (void *abstract_font, /* FIXME: this doesn't do vertical layout atm. */ extents->max_y_advance = 0.0; - _ft_unscaled_font_unlock_face (scaled_font->unscaled); + _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled); return CAIRO_STATUS_SUCCESS; } @@ -2035,12 +2042,12 @@ const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = { /* ft_font_face_t */ static void -_ft_font_face_destroy (void *abstract_face) +_cairo_ft_font_face_destroy (void *abstract_face) { - ft_font_face_t *font_face = abstract_face; + cairo_ft_font_face_t *font_face = abstract_face; - ft_font_face_t *tmp_face = NULL; - ft_font_face_t *last_face = NULL; + cairo_ft_font_face_t *tmp_face = NULL; + cairo_ft_font_face_t *last_face = NULL; if (font_face == NULL) return; @@ -2089,13 +2096,13 @@ _ft_font_face_destroy (void *abstract_face) } static cairo_status_t -_ft_font_face_create_font (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font) +_cairo_ft_font_face_create_font (void *abstract_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **scaled_font) { - ft_font_face_t *font_face = abstract_face; + cairo_ft_font_face_t *font_face = abstract_face; int load_flags; /* The handling of font options is different depending on how the @@ -2112,9 +2119,9 @@ _ft_font_face_create_font (void *abstract_face, else load_flags = font_face->load_flags; - *scaled_font = _ft_scaled_font_create (font_face->unscaled, - font_matrix, ctm, - options, load_flags); + *scaled_font = _cairo_ft_scaled_font_create_for_unscaled (font_face->unscaled, + font_matrix, ctm, + options, load_flags); if (*scaled_font) return CAIRO_STATUS_SUCCESS; else @@ -2122,15 +2129,15 @@ _ft_font_face_create_font (void *abstract_face, } static const cairo_font_face_backend_t _ft_font_face_backend = { - _ft_font_face_destroy, - _ft_font_face_create_font, + _cairo_ft_font_face_destroy, + _cairo_ft_font_face_create_font, }; static cairo_font_face_t * -_ft_font_face_create (ft_unscaled_font_t *unscaled, - int load_flags) +_cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, + int load_flags) { - ft_font_face_t *font_face; + cairo_ft_font_face_t *font_face; /* Looked for an existing matching font face */ for (font_face = unscaled->faces; font_face; font_face = font_face->next_face) { @@ -2141,7 +2148,7 @@ _ft_font_face_create (ft_unscaled_font_t *unscaled, } /* No match found, create a new one */ - font_face = malloc (sizeof (ft_font_face_t)); + font_face = malloc (sizeof (cairo_ft_font_face_t)); if (!font_face) return NULL; @@ -2275,16 +2282,17 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options, cairo_font_face_t * cairo_ft_font_face_create_for_pattern (FcPattern *pattern) { - ft_unscaled_font_t *unscaled; + cairo_ft_unscaled_font_t *unscaled; cairo_font_face_t *font_face; - unscaled = _ft_unscaled_font_get_for_pattern (pattern); + unscaled = _cairo_ft_unscaled_font_get_for_pattern (pattern); if (unscaled == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_font_face_t *)&_cairo_font_face_nil; } - font_face = _ft_font_face_create (unscaled, _get_pattern_load_flags (pattern)); + font_face = _cairo_ft_font_face_create (unscaled, + _get_pattern_load_flags (pattern)); _cairo_unscaled_font_destroy (&unscaled->base); if (font_face) @@ -2324,16 +2332,16 @@ cairo_font_face_t * cairo_ft_font_face_create_for_ft_face (FT_Face face, int load_flags) { - ft_unscaled_font_t *unscaled; + cairo_ft_unscaled_font_t *unscaled; cairo_font_face_t *font_face; - unscaled = _ft_unscaled_font_create_from_face (face); + unscaled = _cairo_ft_unscaled_font_create_from_face (face); if (unscaled == NULL) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_font_face_t *)&_cairo_font_face_nil; } - font_face = _ft_font_face_create (unscaled, load_flags); + font_face = _cairo_ft_font_face_create (unscaled, load_flags); _cairo_unscaled_font_destroy (&unscaled->base); if (font_face) { @@ -2382,13 +2390,13 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font) if (scaled_font->base.status) return NULL; - face = _ft_unscaled_font_lock_face (scaled_font->unscaled); + face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled); if (face == NULL) { _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY); return NULL; } - _ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale); + _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale); return face; } @@ -2411,7 +2419,7 @@ cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font) if (scaled_font->base.status) return; - _ft_unscaled_font_unlock_face (scaled_font->unscaled); + _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled); } /* We expose our unscaled font implementation internally for the the @@ -2426,21 +2434,6 @@ _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *abstract_font) return &scaled_font->unscaled->base; } -/* This differs from _cairo_ft_scaled_font_lock_face in that it doesn't - * set the scale on the face, but just returns it at the last scale. - */ -FT_Face -_cairo_ft_unscaled_font_lock_face (cairo_unscaled_font_t *unscaled_font) -{ - return _ft_unscaled_font_lock_face ((ft_unscaled_font_t *)unscaled_font); -} - -void -_cairo_ft_unscaled_font_unlock_face (cairo_unscaled_font_t *unscaled_font) -{ - _ft_unscaled_font_unlock_face ((ft_unscaled_font_t *)unscaled_font); -} - void _cairo_ft_font_reset_static_data (void) { diff --git a/src/cairo-ft-private.h b/src/cairo-ft-private.h index e92048b2..8bd43413 100644 --- a/src/cairo-ft-private.h +++ b/src/cairo-ft-private.h @@ -44,6 +44,8 @@ CAIRO_BEGIN_DECLS +typedef struct _cairo_ft_unscaled_font cairo_ft_unscaled_font_t; + cairo_bool_t _cairo_unscaled_font_is_ft (cairo_unscaled_font_t *unscaled_font); @@ -57,10 +59,10 @@ cairo_private cairo_unscaled_font_t * _cairo_ft_scaled_font_get_unscaled_font (cairo_scaled_font_t *scaled_font); cairo_private FT_Face -_cairo_ft_unscaled_font_lock_face (cairo_unscaled_font_t *unscaled_font); +_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled); cairo_private void -_cairo_ft_unscaled_font_unlock_face (cairo_unscaled_font_t *unscaled_font); +_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled); CAIRO_END_DECLS -- cgit v1.2.3 From a8ccf316201e5241bcde2359f6dcbe3557cca79b Mon Sep 17 00:00:00 2001 From: Tor Lillqvist Date: Thu, 4 Aug 2005 15:53:30 +0000 Subject: Check for render bug involving repeated patterns with a general transform matrix. --- ChangeLog | 8 ++++++++ src/cairo-xlib-surface.c | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 293d6d0f..05d583d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-07-29 T Rowley + + Reviewed by: otaylor + + * src/cairo-xlib-surface.c ( _categorize_composite_operation): + Check for render bug involving repeated patterns with a general + transform matrix. + 2005-08-04 Carl Worth Originally 2005-07-13 Carl Worth diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index e4d52552..22fc6301 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -91,6 +91,14 @@ struct _cairo_xlib_surface { * * We can't test for this because it depends on whether the * picture is in video memory or not. + * + * We also use this variable as a guard against a second + * independent bug with transformed repeating pictures: + * + * http://lists.freedesktop.org/archives/cairo/2004-September/001839.html + * + * Both are fixed in xorg >= 6.9 and hopefully in > 6.8.2, so + * we can reuse the test for now. */ cairo_bool_t buggy_repeat; @@ -878,11 +886,13 @@ _operator_needs_alpha_composite (cairo_operator_t operator, return TRUE; } -/* There is a bug in most older X servers with compositing using a repeating - * source pattern when the source is in off-screen video memory. When that - * bug could be triggered, we need a fallback: in the common case where we have no - * transformation and the source and destination have the same format/visual, - * we can do the operation using the core protocol, otherwise, we need +/* There is a bug in most older X servers with compositing using a + * untransformed repeating source pattern when the source is in off-screen + * video memory, and another with repeated transformed images using a + * general tranform matrix. When these bugs could be triggered, we need a + * fallback: in the common case where we have no transformation and the + * source and destination have the same format/visual, we can do the + * operation using the core protocol for the first bug, otherwise, we need * a software fallback. * * We can also often optimize a compositing operation by calling XCopyArea @@ -896,9 +906,11 @@ typedef enum { DO_UNSUPPORTED /* software fallback */ } composite_operation_t; -/* Initial check for the bug; we need to recheck after we turn - * patterns into surfaces, since that may introduce a repeating - * pattern for gradient patterns. +/* Initial check for the render bugs; we need to recheck for the + * offscreen-memory bug after we turn patterns into surfaces, since that + * may introduce a repeating pattern for gradient patterns. We don't need + * to check for the repeat+transform bug because gradient surfaces aren't + * transformed. * * All we do here is reject cases where we *know* are going to * hit the bug and won't be able to use a core protocol fallback. @@ -920,8 +932,10 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst, if (_cairo_matrix_is_integer_translation (&src_pattern->matrix, NULL, NULL) && src_pattern->extend == CAIRO_EXTEND_REPEAT) { - /* This is the case where we have a bug; reject some cases where a - * core protocol fallback is impossible. + /* This is the case where we have the bug involving + * untransformed repeating source patterns with off-screen + * video memory; reject some cases where a core protocol + * fallback is impossible. */ if (have_mask || !(operator == CAIRO_OPERATOR_SOURCE || operator == CAIRO_OPERATOR_OVER)) @@ -942,6 +956,12 @@ _categorize_composite_operation (cairo_xlib_surface_t *dst, return DO_UNSUPPORTED; } } + + /* Check for the other bug involving repeat patterns with general + * transforms. */ + if (!_cairo_matrix_is_integer_translation (&src_pattern->matrix, NULL, NULL) && + src_pattern->extend == CAIRO_EXTEND_REPEAT) + return DO_UNSUPPORTED; } return DO_RENDER; -- cgit v1.2.3 From 27573750eb9f2655d0b4cb5640a9f3f6c1316bc0 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 4 Aug 2005 18:44:29 +0000 Subject: Change *_reference() functions to return the object being referenced. --- ChangeLog | 14 ++++++++++++++ src/cairo-font-subset.c | 3 +-- src/cairo-font.c | 26 ++++++++++++++++++-------- src/cairo-ft-font.c | 6 ++---- src/cairo-glitz-surface.c | 3 +-- src/cairo-gstate.c | 11 ++++++----- src/cairo-image-surface.c | 3 +-- src/cairo-meta-surface.c | 3 +-- src/cairo-pattern.c | 13 ++++++++----- src/cairo-pdf-surface.c | 9 +++++---- src/cairo-surface.c | 26 +++++++++++++++++++++++--- src/cairo-xcb-surface.c | 3 +-- src/cairo-xlib-surface.c | 3 +-- src/cairo.c | 8 ++++++-- src/cairo.h | 10 +++++----- src/cairoint.h | 2 +- 16 files changed, 94 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05d583d5..ef841af7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-08-04 Kristian Høgsberg + + * src/cairo-font.c: (cairo_font_face_reference), + (_cairo_unscaled_font_reference), (cairo_scaled_font_reference): + * src/cairo-gstate.c: (_cairo_clip_path_reference): + * src/cairo-pattern.c: (cairo_pattern_reference): + * src/cairo-pdf-surface.c: (_cairo_pdf_document_reference): + * src/cairo-surface.c: (cairo_surface_reference): + * src/cairo.c: (cairo_reference): + * src/cairo.h: + * src/cairoint.h: + Change *_reference() functions to return the object being + referenced. + 2005-07-29 T Rowley Reviewed by: otaylor diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c index 16c52dfd..88008d7e 100644 --- a/src/cairo-font-subset.c +++ b/src/cairo-font-subset.c @@ -158,8 +158,7 @@ _cairo_font_subset_create (cairo_unscaled_font_t *unscaled_font) if (font == NULL) return NULL; - font->base.unscaled_font = unscaled_font; - _cairo_unscaled_font_reference (unscaled_font); + font->base.unscaled_font = _cairo_unscaled_font_reference (unscaled_font); font->base.backend = &cairo_pdf_ft_font_backend; _cairo_array_init (&font->output, sizeof (char)); diff --git a/src/cairo-font.c b/src/cairo-font.c index dc34ef61..c510bb55 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -72,17 +72,21 @@ _cairo_font_face_init (cairo_font_face_t *font_face, * Increases the reference count on @font_face by one. This prevents * @font_face from being destroyed until a matching call to * cairo_font_face_destroy() is made. + * + * Return value: the referenced #cairo_font_face_t. **/ -void +cairo_font_face_t * cairo_font_face_reference (cairo_font_face_t *font_face) { if (font_face == NULL) - return; + return NULL; if (font_face->ref_count == (unsigned int)-1) - return; + return font_face; font_face->ref_count++; + + return font_face; } /** @@ -999,13 +1003,15 @@ _cairo_unscaled_font_init (cairo_unscaled_font_t *unscaled_font, unscaled_font->backend = backend; } -void +cairo_unscaled_font_t * _cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font) { if (unscaled_font == NULL) - return; + return NULL; unscaled_font->ref_count++; + + return unscaled_font; } void @@ -1034,17 +1040,21 @@ _cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font) * Increases the reference count on @scaled_font by one. This prevents * @scaled_font from being destroyed until a matching call to * cairo_scaled_font_destroy() is made. + * + * Return value: the referenced #cairo_scaled_font_t. **/ -void +cairo_scaled_font_t * cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font) { if (scaled_font == NULL) - return; + return NULL; if (scaled_font->ref_count == (unsigned int)-1) - return; + return scaled_font; scaled_font->ref_count++; + + return scaled_font; } /** diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index c934c7de..5587b15a 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2141,10 +2141,8 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, /* Looked for an existing matching font face */ for (font_face = unscaled->faces; font_face; font_face = font_face->next_face) { - if (font_face->load_flags == load_flags) { - cairo_font_face_reference (&font_face->base); - return &font_face->base; - } + if (font_face->load_flags == load_flags) + return cairo_font_face_reference (&font_face->base); } /* No match found, create a new one */ diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 96e92033..402b34f1 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -349,8 +349,7 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface, if (src->backend == surface->base.backend) { - *clone_out = src; - cairo_surface_reference (src); + *clone_out = cairo_surface_reference (src); return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 121899f0..8db78505 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -67,7 +67,7 @@ _cairo_gstate_unset_font (cairo_gstate_t *gstate); static void _cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src); -static void +static cairo_clip_path_t * _cairo_clip_path_reference (cairo_clip_path_t *clip_path); static void @@ -132,8 +132,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate, _cairo_pen_init_empty (&gstate->pen_regular); - gstate->target = target; - cairo_surface_reference (gstate->target); + gstate->target = cairo_surface_reference (target); gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK); if (gstate->source->status) @@ -1654,13 +1653,15 @@ _cairo_gstate_intersect_clip_path (cairo_gstate_t *gstate, return CAIRO_STATUS_SUCCESS; } -static void +static cairo_clip_path_t * _cairo_clip_path_reference (cairo_clip_path_t *clip_path) { if (clip_path == NULL) - return; + return NULL; clip_path->ref_count++; + + return clip_path; } static void diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index b21cf122..e86ed172 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -408,8 +408,7 @@ _cairo_image_surface_clone_similar (void *abstract_surface, cairo_image_surface_t *surface = abstract_surface; if (src->backend == surface->base.backend) { - *clone_out = src; - cairo_surface_reference (src); + *clone_out = cairo_surface_reference (src); return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index 8a893d66..c2be862e 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -387,8 +387,7 @@ _cairo_meta_surface_show_glyphs (cairo_scaled_font_t *scaled_font, return CAIRO_STATUS_NO_MEMORY; command->type = CAIRO_COMMAND_SHOW_GLYPHS; - command->scaled_font = scaled_font; - cairo_scaled_font_reference (scaled_font); + command->scaled_font = cairo_scaled_font_reference (scaled_font); command->operator = operator; _cairo_pattern_init_copy (&command->pattern.base, pattern); command->source_x = source_x; diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 1fb17217..ca93dde4 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -236,8 +236,7 @@ _cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern, { _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_SURFACE); - pattern->surface = surface; - cairo_surface_reference (surface); + pattern->surface = cairo_surface_reference (surface); } static void @@ -489,17 +488,21 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0, * Increases the reference count on @pattern by one. This prevents * @pattern from being destroyed until a matching call to * cairo_pattern_destroy() is made. + * + * Return value: the referenced #cairo_pattern_t. **/ -void +cairo_pattern_t * cairo_pattern_reference (cairo_pattern_t *pattern) { if (pattern == NULL) - return; + return NULL; if (pattern->ref_count == (unsigned int)-1) - return; + return pattern; pattern->ref_count++; + + return pattern; } /** diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 485c1a0e..c068c8aa 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -159,7 +159,7 @@ _cairo_pdf_document_destroy (cairo_pdf_document_t *document); static cairo_status_t _cairo_pdf_document_finish (cairo_pdf_document_t *document); -static void +static cairo_pdf_document_t * _cairo_pdf_document_reference (cairo_pdf_document_t *document); static unsigned int @@ -365,8 +365,7 @@ _cairo_pdf_surface_create_for_document (cairo_pdf_document_t *document, surface->width = width; surface->height = height; - _cairo_pdf_document_reference (document); - surface->document = document; + surface->document = _cairo_pdf_document_reference (document); _cairo_array_init (&surface->streams, sizeof (cairo_pdf_stream_t *)); _cairo_array_init (&surface->patterns, sizeof (cairo_pdf_resource_t)); _cairo_array_init (&surface->xobjects, sizeof (cairo_pdf_resource_t)); @@ -1658,10 +1657,12 @@ _cairo_pdf_document_write_xref (cairo_pdf_document_t *document) return offset; } -static void +static cairo_pdf_document_t * _cairo_pdf_document_reference (cairo_pdf_document_t *document) { document->ref_count++; + + return document; } static void diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 1920270e..4ff8c700 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -245,18 +245,38 @@ _cairo_surface_get_clip_mode (cairo_surface_t *surface) return CAIRO_CLIP_MODE_MASK; } -void +/** + * cairo_surface_reference: + * @surface: a #cairo_surface_t + * + * Increases the reference count on @surface by one. This prevents + * @surface from being destroyed until a matching call to + * cairo_surface_destroy() is made. + * + * Return value: the referenced #cairo_surface_t. + **/ +cairo_surface_t * cairo_surface_reference (cairo_surface_t *surface) { if (surface == NULL) - return; + return NULL; if (surface->ref_count == (unsigned int)-1) - return; + return surface; surface->ref_count++; + + return surface; } +/** + * cairo_surface_destroy: + * @surface: a #cairo_t + * + * Decreases the reference count on @surface by one. If the result is + * zero, then @surface and all associated resources are freed. See + * cairo_surface_reference(). + **/ void cairo_surface_destroy (cairo_surface_t *surface) { diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index b743cf4d..05e39b55 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -643,8 +643,7 @@ _cairo_xcb_surface_clone_similar (void *abstract_surface, cairo_xcb_surface_t *xcb_src = (cairo_xcb_surface_t *)src; if (xcb_src->dpy == surface->dpy) { - *clone_out = src; - cairo_surface_reference (src); + *clone_out = cairo_surface_reference (src); return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 22fc6301..4f4e47e3 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -670,8 +670,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, cairo_xlib_surface_t *xlib_src = (cairo_xlib_surface_t *)src; if (_cairo_xlib_surface_same_screen (surface, xlib_src)) { - *clone_out = src; - cairo_surface_reference (src); + *clone_out = cairo_surface_reference (src); return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo.c b/src/cairo.c index b4fc5464..060d8fd6 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -178,14 +178,18 @@ cairo_create (cairo_surface_t *target) * Increases the reference count on @cr by one. This prevents * @cr from being destroyed until a matching call to cairo_destroy() * is made. + * + * Return value: the referenced #cairo_t. **/ -void +cairo_t * cairo_reference (cairo_t *cr) { if (cr->ref_count == (unsigned int)-1) - return; + return cr; cr->ref_count++; + + return cr; } /** diff --git a/src/cairo.h b/src/cairo.h index f43d9c58..41310be3 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -222,7 +222,7 @@ typedef cairo_status_t (*cairo_read_func_t) (void *closure, cairo_t * cairo_create (cairo_surface_t *target); -void +cairo_t * cairo_reference (cairo_t *cr); void @@ -863,7 +863,7 @@ cairo_glyph_path (cairo_t *cr, cairo_glyph_t *glyphs, int num_glyphs); /* Generic identifier for a font style */ -void +cairo_font_face_t * cairo_font_face_reference (cairo_font_face_t *font_face); void @@ -890,7 +890,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, const cairo_matrix_t *ctm, const cairo_font_options_t *options); -void +cairo_scaled_font_t * cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font); void @@ -1101,7 +1101,7 @@ cairo_surface_create_similar (cairo_surface_t *other, int width, int height); -void +cairo_surface_t * cairo_surface_reference (cairo_surface_t *surface); void @@ -1241,7 +1241,7 @@ cairo_pattern_t * cairo_pattern_create_radial (double cx0, double cy0, double radius0, double cx1, double cy1, double radius1); -void +cairo_pattern_t * cairo_pattern_reference (cairo_pattern_t *pattern); void diff --git a/src/cairoint.h b/src/cairoint.h index 794f3409..78387fb0 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1353,7 +1353,7 @@ cairo_private void _cairo_unscaled_font_init (cairo_unscaled_font_t *font, const cairo_unscaled_font_backend_t *backend); -cairo_private void +cairo_private cairo_unscaled_font_t * _cairo_unscaled_font_reference (cairo_unscaled_font_t *font); cairo_private void -- cgit v1.2.3 From ebf985c87688f090c27c3906a6b441522b2f702a Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 4 Aug 2005 22:45:59 +0000 Subject: New files. Move code for manipulating cairo_clip_t out into cairo_clip_* functions and put them in cairo-clip.c. Rewrite to use new cairo_clip_t functions for manipulating the clip state, change the clip_and_composite_trapezoids call tree to use cairo_clip_t instead of cairo_gstate_t. Use new cairo_clip_t function to maintain clip state while replaying. Pass fill rule and tolerance directly, to break gstate dependency. New function. Set the clip for a surface as specified by the cairo_clip_t. Move translate_traps() from cairo-gstate.c to here and rename it. Reviewed by: otaylor --- ChangeLog | 29 +++ src/Makefile.am | 2 + src/cairo-clip-private.h | 118 +++++++++ src/cairo-clip.c | 457 ++++++++++++++++++++++++++++++++ src/cairo-gstate-private.h | 41 +-- src/cairo-gstate.c | 637 +++++++-------------------------------------- src/cairo-meta-surface.c | 132 +++++----- src/cairo-path-fill.c | 20 +- src/cairo-surface.c | 23 +- src/cairo-traps.c | 29 +++ src/cairoint.h | 35 ++- 11 files changed, 849 insertions(+), 674 deletions(-) create mode 100644 src/cairo-clip-private.h create mode 100644 src/cairo-clip.c diff --git a/ChangeLog b/ChangeLog index ef841af7..13fe22e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2005-08-05 Kristian Høgsberg + + Reviewed by: otaylor + + * src/Makefile.am: + * src/cairo-clip-private.h: + * src/cairo-clip.c: New files. Move code for manipulating + cairo_clip_t out into cairo_clip_* functions and put them in + cairo-clip.c. + + * src/cairo-gstate-private.h: + * src/cairo-gstate.c: Rewrite to use new cairo_clip_t functions + for manipulating the clip state, change the + clip_and_composite_trapezoids call tree to use cairo_clip_t + instead of cairo_gstate_t. + + * src/cairo-meta-surface.c: Use new cairo_clip_t function to + maintain clip state while replaying. + + * src/cairo-path-fill.c: (_cairo_filler_init), + (_cairo_filler_curve_to), (_cairo_path_fixed_fill_to_traps): Pass + fill rule and tolerance directly, to break gstate dependency. + + * src/cairo-surface.c: (_cairo_surface_set_clip): New function. + Set the clip for a surface as specified by the cairo_clip_t. + + * src/cairo-traps.c: (_cairo_traps_translate): Move + translate_traps() from cairo-gstate.c to here and rename it. + 2005-08-04 Kristian Høgsberg * src/cairo-font.c: (cairo_font_face_reference), diff --git a/src/Makefile.am b/src/Makefile.am index 4456bdc9..b518392e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -92,6 +92,8 @@ libcairo_la_SOURCES = \ cairo-font-options.c \ cairo-gstate.c \ cairo-gstate-private.h \ + cairo-clip.c \ + cairo-clip-private.h \ cairo-hull.c \ cairo-image-surface.c \ cairo-matrix.c \ diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h new file mode 100644 index 00000000..f8846b5c --- /dev/null +++ b/src/cairo-clip-private.h @@ -0,0 +1,118 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Kristian Høgsberg + */ + +#ifndef CAIRO_CLIP_PRIVATE_H +#define CAIRO_CLIP_PRIVATE_H + +#include "cairo-path-fixed-private.h" + +enum _cairo_clip_mode { + CAIRO_CLIP_MODE_PATH, + CAIRO_CLIP_MODE_REGION, + CAIRO_CLIP_MODE_MASK +}; + +struct _cairo_clip_path { + unsigned int ref_count; + cairo_path_fixed_t path; + cairo_fill_rule_t fill_rule; + double tolerance; + cairo_clip_path_t *prev; +}; + +struct _cairo_clip { + cairo_clip_mode_t mode; + + /* + * Mask-based clipping for cases where the backend + * clipping isn't sufficiently able. + * + * The rectangle here represents the + * portion of the destination surface that this + * clip surface maps to, it does not + * represent the extents of the clip region or + * clip paths + */ + cairo_surface_t *surface; + cairo_rectangle_t surface_rect; + /* + * Surface clip serial number to store + * in the surface when this clip is set + */ + unsigned int serial; + /* + * A clip region that can be placed in the surface + */ + pixman_region16_t *region; + /* + * If the surface supports path clipping, we store the list of + * clipping paths that has been set here as a linked list. + */ + cairo_clip_path_t *path; +}; + +cairo_private void +_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target); + +cairo_private void +_cairo_clip_fini (cairo_clip_t *clip); + +cairo_private void +_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other); + +cairo_private cairo_status_t +_cairo_clip_reset (cairo_clip_t *clip); + +cairo_private cairo_status_t +_cairo_clip_clip (cairo_clip_t *clip, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_surface_t *target); + +cairo_private cairo_status_t +_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, + cairo_rectangle_t *rectangle); + +cairo_private cairo_status_t +_cairo_clip_intersect_to_region (cairo_clip_t *clip, + pixman_region16_t *region); + +cairo_private cairo_status_t +_cairo_clip_combine_to_surface (cairo_clip_t *clip, + cairo_surface_t *intermediate, + cairo_rectangle_t *extents); + +#endif /* CAIRO_CLIP_PRIVATE_H */ diff --git a/src/cairo-clip.c b/src/cairo-clip.c new file mode 100644 index 00000000..c211e2b8 --- /dev/null +++ b/src/cairo-clip.c @@ -0,0 +1,457 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2002 University of Southern California + * Copyright © 2005 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is University of Southern + * California. + * + * Contributor(s): + * Carl D. Worth + * Kristian Høgsberg + */ + +#include "cairoint.h" +#include "cairo-clip-private.h" + +static cairo_clip_path_t * +_cairo_clip_path_reference (cairo_clip_path_t *clip_path); + +static void +_cairo_clip_path_destroy (cairo_clip_path_t *clip_path); + +/* Creates a region from a cairo_rectangle_t */ +static cairo_status_t +_region_new_from_rect (cairo_rectangle_t *rect, + pixman_region16_t **region) +{ + *region = pixman_region_create (); + if (pixman_region_union_rect (*region, *region, + rect->x, rect->y, + rect->width, rect->height) != PIXMAN_REGION_STATUS_SUCCESS) { + pixman_region_destroy (*region); + return CAIRO_STATUS_NO_MEMORY; + } + + return CAIRO_STATUS_SUCCESS; +} + +/* Gets the bounding box of a region as a cairo_rectangle_t */ +static void +_region_rect_extents (pixman_region16_t *region, + cairo_rectangle_t *rect) +{ + pixman_box16_t *region_extents = pixman_region_extents (region); + + rect->x = region_extents->x1; + rect->y = region_extents->y1; + rect->width = region_extents->x2 - region_extents->x1; + rect->height = region_extents->y2 - region_extents->y1; +} + +void +_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target) +{ + clip->mode = _cairo_surface_get_clip_mode (target); + clip->region = NULL; + clip->surface = NULL; + clip->serial = 0; + clip->path = NULL; +} + +void +_cairo_clip_fini (cairo_clip_t *clip) +{ + if (clip->surface) + cairo_surface_destroy (clip->surface); + clip->surface = NULL; + + if (clip->path) + _cairo_clip_path_destroy (clip->path); + clip->path = NULL; + + if (clip->region) + pixman_region_destroy (clip->region); + clip->region = NULL; + clip->serial = 0; +} + +void +_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) +{ + if (other->region) { + clip->region = pixman_region_create (); + pixman_region_copy (clip->region, other->region); + } + + cairo_surface_reference (other->surface); + clip->surface = other->surface; + _cairo_clip_path_reference (other->path); + clip->path = other->path; +} + +cairo_status_t +_cairo_clip_reset (cairo_clip_t *clip) +{ + /* destroy any existing clip-region artifacts */ + if (clip->surface) + cairo_surface_destroy (clip->surface); + clip->surface = NULL; + + if (clip->region) + pixman_region_destroy (clip->region); + clip->region = NULL; + + if (clip->path) + _cairo_clip_path_destroy (clip->path); + clip->path = NULL; + + clip->serial = 0; + + return CAIRO_STATUS_SUCCESS; +} + +cairo_status_t +_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, + cairo_rectangle_t *rectangle) +{ + if (clip->path) { + /* Intersect path extents here. */ + } + + if (clip->region) { + pixman_region16_t *intersection; + cairo_status_t status; + pixman_region_status_t pixman_status; + + status = _region_new_from_rect (rectangle, &intersection); + if (status) + return status; + + pixman_status = pixman_region_intersect (intersection, + clip->region, + intersection); + if (pixman_status == PIXMAN_REGION_STATUS_SUCCESS) + _region_rect_extents (intersection, rectangle); + else + status = CAIRO_STATUS_NO_MEMORY; + + pixman_region_destroy (intersection); + + if (status) + return status; + } + + if (clip->surface) + _cairo_rectangle_intersect (rectangle, &clip->surface_rect); + + return CAIRO_STATUS_SUCCESS; +} + +cairo_status_t +_cairo_clip_intersect_to_region (cairo_clip_t *clip, + pixman_region16_t *region) +{ + if (clip->path) { + /* Intersect clip path into region. */ + } + + if (clip->region) + pixman_region_intersect (region, clip->region, region); + + if (clip->surface) { + pixman_region16_t *clip_rect; + pixman_region_status_t pixman_status; + cairo_status_t status; + + status = _region_new_from_rect (&clip->surface_rect, &clip_rect); + if (status) + return status; + + pixman_status = pixman_region_intersect (region, + clip_rect, + region); + if (pixman_status != PIXMAN_REGION_STATUS_SUCCESS) + status = CAIRO_STATUS_NO_MEMORY; + + pixman_region_destroy (clip_rect); + + if (status) + return status; + } + + return CAIRO_STATUS_SUCCESS; +} + +/* Combines clip->surface using the IN operator with the given + * intermediate surface, which corresponds to the rectangle of the + * destination space given by @extents. + */ +cairo_status_t +_cairo_clip_combine_to_surface (cairo_clip_t *clip, + cairo_surface_t *intermediate, + cairo_rectangle_t *extents) +{ + cairo_pattern_union_t pattern; + cairo_status_t status; + + _cairo_pattern_init_for_surface (&pattern.surface, clip->surface); + + status = _cairo_surface_composite (CAIRO_OPERATOR_IN, + &pattern.base, + NULL, + intermediate, + extents->x - clip->surface_rect.x, + extents->y - clip->surface_rect.y, + 0, 0, + 0, 0, + extents->width, extents->height); + + _cairo_pattern_fini (&pattern.base); + + return status; +} + +static cairo_status_t +_cairo_clip_intersect_path (cairo_clip_t *clip, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_surface_t *target) +{ + cairo_clip_path_t *clip_path; + cairo_status_t status; + + if (clip->mode != CAIRO_CLIP_MODE_PATH) + return CAIRO_INT_STATUS_UNSUPPORTED; + + clip_path = malloc (sizeof (cairo_clip_path_t)); + if (clip_path == NULL) + return CAIRO_STATUS_NO_MEMORY; + + status = _cairo_path_fixed_init_copy (&clip_path->path, path); + if (status) + return status; + + clip_path->ref_count = 1; + clip_path->fill_rule = fill_rule; + clip_path->tolerance = tolerance; + clip_path->prev = clip->path; + clip->path = clip_path; + clip->serial = _cairo_surface_allocate_clip_serial (target); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_clip_path_t * +_cairo_clip_path_reference (cairo_clip_path_t *clip_path) +{ + if (clip_path == NULL) + return NULL; + + clip_path->ref_count++; + + return clip_path; +} + +static void +_cairo_clip_path_destroy (cairo_clip_path_t *clip_path) +{ + if (clip_path == NULL) + return; + + clip_path->ref_count--; + if (clip_path->ref_count) + return; + + _cairo_path_fixed_fini (&clip_path->path); + _cairo_clip_path_destroy (clip_path->prev); + free (clip_path); +} + +static cairo_status_t +_cairo_clip_intersect_region (cairo_clip_t *clip, + cairo_traps_t *traps, + cairo_surface_t *target) +{ + pixman_region16_t *region; + cairo_status_t status; + + if (clip->mode != CAIRO_CLIP_MODE_REGION) + return CAIRO_INT_STATUS_UNSUPPORTED; + + status = _cairo_traps_extract_region (traps, ®ion); + if (status) + return status; + + if (region == NULL) + return CAIRO_INT_STATUS_UNSUPPORTED; + + status = CAIRO_STATUS_SUCCESS; + if (clip->region == NULL) { + clip->region = region; + } else { + pixman_region16_t *intersection = pixman_region_create(); + + if (pixman_region_intersect (intersection, + clip->region, region) + == PIXMAN_REGION_STATUS_SUCCESS) { + pixman_region_destroy (clip->region); + clip->region = intersection; + } else { + status = CAIRO_STATUS_NO_MEMORY; + } + pixman_region_destroy (region); + } + + clip->serial = _cairo_surface_allocate_clip_serial (target); + + return status; +} + +static cairo_status_t +_cairo_clip_intersect_mask (cairo_clip_t *clip, + cairo_traps_t *traps, + cairo_surface_t *target) +{ + cairo_pattern_union_t pattern; + cairo_box_t extents; + cairo_rectangle_t surface_rect; + cairo_surface_t *surface; + cairo_status_t status; + + /* Represent the clip as a mask surface. We create a new surface + * the size of the intersection of the old mask surface and the + * extents of the new clip path. */ + + _cairo_traps_extents (traps, &extents); + _cairo_box_round_to_rectangle (&extents, &surface_rect); + + if (clip->surface != NULL) + _cairo_rectangle_intersect (&surface_rect, &clip->surface_rect); + + surface = _cairo_surface_create_similar_solid (target, + CAIRO_CONTENT_ALPHA, + surface_rect.width, + surface_rect.height, + CAIRO_COLOR_WHITE); + if (surface->status) + return CAIRO_STATUS_NO_MEMORY; + + /* Render the new clipping path into the new mask surface. */ + + _cairo_traps_translate (traps, -surface_rect.x, -surface_rect.y); + _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); + + status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN, + &pattern.base, + surface, + 0, 0, + 0, 0, + surface_rect.width, + surface_rect.height, + traps->traps, + traps->num_traps); + + _cairo_pattern_fini (&pattern.base); + + if (status) { + cairo_surface_destroy (surface); + return status; + } + + /* If there was a clip surface already, combine it with the new + * mask surface using the IN operator, so we get the intersection + * of the old and new clipping paths. */ + + if (clip->surface != NULL) { + _cairo_pattern_init_for_surface (&pattern.surface, clip->surface); + + status = _cairo_surface_composite (CAIRO_OPERATOR_IN, + &pattern.base, + NULL, + surface, + surface_rect.x - clip->surface_rect.x, + surface_rect.y - clip->surface_rect.y, + 0, 0, + 0, 0, + surface_rect.width, + surface_rect.height); + + _cairo_pattern_fini (&pattern.base); + + if (status) { + cairo_surface_destroy (surface); + return status; + } + + cairo_surface_destroy (clip->surface); + } + + clip->surface = surface; + clip->surface_rect = surface_rect; + clip->serial = _cairo_surface_allocate_clip_serial (target); + + return status; +} + +cairo_status_t +_cairo_clip_clip (cairo_clip_t *clip, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_surface_t *target) +{ + cairo_status_t status; + cairo_traps_t traps; + + status = _cairo_clip_intersect_path (clip, + path, fill_rule, tolerance, + target); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; + + _cairo_traps_init (&traps); + status = _cairo_path_fixed_fill_to_traps (path, + fill_rule, + tolerance, + &traps); + if (status) + goto bail; + + status = _cairo_clip_intersect_region (clip, &traps, target); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + goto bail; + + status = _cairo_clip_intersect_mask (clip, &traps, target); + + bail: + _cairo_traps_fini (&traps); + + return status; +} diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index 06352576..7e82883d 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -36,46 +36,7 @@ #ifndef CAIRO_GSTATE_PRIVATE_H #define CAIRO_GSTATE_PRIVATE_H -#include "cairo-path-fixed-private.h" - -struct _cairo_clip_path { - unsigned int ref_count; - cairo_path_fixed_t path; - cairo_fill_rule_t fill_rule; - double tolerance; - cairo_clip_path_t *prev; -}; - -typedef struct _cairo_clip { - cairo_clip_mode_t mode; - - /* - * Mask-based clipping for cases where the backend - * clipping isn't sufficiently able. - * - * The rectangle here represents the - * portion of the destination surface that this - * clip surface maps to, it does not - * represent the extents of the clip region or - * clip paths - */ - cairo_surface_t *surface; - cairo_rectangle_t surface_rect; - /* - * Surface clip serial number to store - * in the surface when this clip is set - */ - unsigned int serial; - /* - * A clip region that can be placed in the surface - */ - pixman_region16_t *region; - /* - * If the surface supports path clipping, we store the list of - * clipping paths that has been set here as a linked list. - */ - cairo_clip_path_t *path; -} cairo_clip_t; +#include "cairo-clip-private.h" struct _cairo_gstate { cairo_operator_t operator; diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 8db78505..f38d76ca 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -39,6 +39,7 @@ #include "cairoint.h" +#include "cairo-clip-private.h" #include "cairo-gstate-private.h" static cairo_status_t @@ -64,15 +65,6 @@ _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate); static void _cairo_gstate_unset_font (cairo_gstate_t *gstate); -static void -_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src); - -static cairo_clip_path_t * -_cairo_clip_path_reference (cairo_clip_path_t *clip_path); - -static void -_cairo_clip_path_destroy (cairo_clip_path_t *clip_path); - cairo_gstate_t * _cairo_gstate_create (cairo_surface_t *target) { @@ -121,11 +113,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate, _cairo_font_options_init_default (&gstate->font_options); - gstate->clip.mode = _cairo_surface_get_clip_mode (target); - gstate->clip.region = NULL; - gstate->clip.surface = NULL; - gstate->clip.serial = 0; - gstate->clip.path = NULL; + _cairo_clip_init (&gstate->clip, target); _cairo_gstate_identity_matrix (gstate); cairo_matrix_init_identity (&gstate->source_ctm_inverse); @@ -162,10 +150,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) memcpy (gstate->dash, other->dash, other->num_dashes * sizeof (double)); } - if (other->clip.region) { - gstate->clip.region = pixman_region_create (); - pixman_region_copy (gstate->clip.region, other->clip.region); - } + _cairo_clip_init_copy (&gstate->clip, &other->clip); if (gstate->font_face) cairo_font_face_reference (gstate->font_face); @@ -174,8 +159,6 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) cairo_scaled_font_reference (gstate->scaled_font); cairo_surface_reference (gstate->target); - cairo_surface_reference (gstate->clip.surface); - _cairo_clip_path_reference (gstate->clip.path); cairo_pattern_reference (gstate->source); @@ -209,18 +192,7 @@ _cairo_gstate_fini (cairo_gstate_t *gstate) gstate->target = NULL; } - if (gstate->clip.surface) - cairo_surface_destroy (gstate->clip.surface); - gstate->clip.surface = NULL; - - if (gstate->clip.path) - _cairo_clip_path_destroy (gstate->clip.path); - gstate->clip.path = NULL; - - if (gstate->clip.region) - pixman_region_destroy (gstate->clip.region); - gstate->clip.region = NULL; - gstate->clip.serial = 0; + _cairo_clip_fini (&gstate->clip); cairo_pattern_destroy (gstate->source); @@ -340,61 +312,6 @@ _cairo_gstate_end_group (cairo_gstate_t *gstate) } */ -static cairo_status_t -_cairo_gstate_set_clip (cairo_gstate_t *gstate) -{ - cairo_surface_t *surface = gstate->target; - - if (!surface) - return CAIRO_STATUS_NULL_POINTER; - if (gstate->clip.serial == _cairo_surface_get_current_clip_serial (surface)) - return CAIRO_STATUS_SUCCESS; - - if (gstate->clip.path) - return _cairo_surface_set_clip_path (surface, - gstate->clip.path, - gstate->clip.serial); - - if (gstate->clip.region) - return _cairo_surface_set_clip_region (surface, - gstate->clip.region, - gstate->clip.serial); - - return _cairo_surface_reset_clip (surface); -} - -static cairo_status_t -_cairo_gstate_get_clip_extents (cairo_gstate_t *gstate, - cairo_rectangle_t *rectangle) -{ - cairo_status_t status; - - status = _cairo_surface_get_extents (gstate->target, rectangle); - if (status) - return status; - /* check path extents here */ - - if (gstate->clip.region) { - pixman_box16_t *clip_box; - cairo_rectangle_t clip_rect; - - /* get region extents as a box */ - clip_box = pixman_region_extents (gstate->clip.region); - /* convert to a rectangle */ - clip_rect.x = clip_box->x1; - clip_rect.width = clip_box->x2 - clip_box->x1; - clip_rect.y = clip_box->y1; - clip_rect.height = clip_box->y2 - clip_box->y1; - /* intersect with surface extents */ - _cairo_rectangle_intersect (rectangle, &clip_rect); - } - - if (gstate->clip.surface) - _cairo_rectangle_intersect (rectangle, &gstate->clip.surface_rect); - - return CAIRO_STATUS_SUCCESS; -} - cairo_surface_t * _cairo_gstate_get_target (cairo_gstate_t *gstate) { @@ -762,11 +679,14 @@ _cairo_gstate_paint (cairo_gstate_t *gstate) if (gstate->source->status) return gstate->source->status; - status = _cairo_gstate_set_clip (gstate); + status = _cairo_surface_set_clip (gstate->target, &gstate->clip); if (status) return status; - status = _cairo_gstate_get_clip_extents (gstate, &rectangle); + status = _cairo_surface_get_extents (gstate->target, &rectangle); + if (status) + return status; + status = _cairo_clip_intersect_to_rectangle (&gstate->clip, &rectangle); if (status) return status; @@ -785,108 +705,23 @@ _cairo_gstate_paint (cairo_gstate_t *gstate) return CAIRO_STATUS_SUCCESS; } -/* Combines @gstate->clip_surface using the IN operator with - * the given intermediate surface, which corresponds to the - * rectangle of the destination space given by @extents. - */ -static cairo_status_t -_cairo_gstate_combine_clip_surface (cairo_gstate_t *gstate, - cairo_surface_t *intermediate, - cairo_rectangle_t *extents) -{ - cairo_pattern_union_t pattern; - cairo_status_t status; - - _cairo_pattern_init_for_surface (&pattern.surface, - gstate->clip.surface); - - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, - &pattern.base, - NULL, - intermediate, - extents->x - gstate->clip.surface_rect.x, - extents->y - gstate->clip.surface_rect.y, - 0, 0, - 0, 0, - extents->width, extents->height); - - _cairo_pattern_fini (&pattern.base); - - return status; -} - -/* Creates a region from a cairo_rectangle_t */ -static cairo_status_t -_region_new_from_rect (cairo_rectangle_t *rect, - pixman_region16_t **region) -{ - *region = pixman_region_create (); - if (pixman_region_union_rect (*region, *region, - rect->x, rect->y, - rect->width, rect->height) != PIXMAN_REGION_STATUS_SUCCESS) { - pixman_region_destroy (*region); - return CAIRO_STATUS_NO_MEMORY; - } - - return CAIRO_STATUS_SUCCESS; -} - -/* Gets the bounding box of a region as a cairo_rectangle_t */ -static void -_region_rect_extents (pixman_region16_t *region, - cairo_rectangle_t *rect) -{ - pixman_box16_t *region_extents = pixman_region_extents (region); - - rect->x = region_extents->x1; - rect->y = region_extents->y1; - rect->width = region_extents->x2 - region_extents->x1; - rect->height = region_extents->y2 - region_extents->y1; -} - -/* Intersects @region with the clipping bounds (both region - * and surface) of @gstate - */ -static cairo_status_t -_cairo_gstate_intersect_clip (cairo_gstate_t *gstate, - pixman_region16_t *region) -{ - if (gstate->clip.region) - pixman_region_intersect (region, gstate->clip.region, region); - - if (gstate->clip.surface) { - pixman_region16_t *clip_rect; - cairo_status_t status; - - status = _region_new_from_rect (&gstate->clip.surface_rect, &clip_rect); - if (status) - return status; - - if (pixman_region_intersect (region, - clip_rect, - region) != PIXMAN_REGION_STATUS_SUCCESS) - status = CAIRO_STATUS_NO_MEMORY; - - pixman_region_destroy (clip_rect); - - if (status) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - static cairo_status_t _get_mask_extents (cairo_gstate_t *gstate, cairo_pattern_t *mask, cairo_rectangle_t *extents) { + cairo_status_t status; + /* * XXX should take mask extents into account, but * that involves checking the transform... For now, * be lazy and just use the destination extents */ - return _cairo_gstate_get_clip_extents (gstate, extents); + status = _cairo_surface_get_extents (gstate->target, extents); + if (status) + return status; + + return _cairo_clip_intersect_to_rectangle (&gstate->clip, extents); } cairo_status_t @@ -906,7 +741,7 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, if (gstate->source->status) return gstate->source->status; - status = _cairo_gstate_set_clip (gstate); + status = _cairo_surface_set_clip (gstate->target, &gstate->clip); if (status) return status; @@ -936,7 +771,7 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, return status; } - status = _cairo_gstate_combine_clip_surface (gstate, intermediate, &extents); + status = _cairo_clip_combine_to_surface (&gstate->clip, intermediate, &extents); if (status) { cairo_surface_destroy (intermediate); return status; @@ -986,7 +821,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) if (gstate->line_width <= 0.0) return CAIRO_STATUS_SUCCESS; - status = _cairo_gstate_set_clip (gstate); + status = _cairo_surface_set_clip (gstate->target, &gstate->clip); if (status) return status; @@ -1049,7 +884,7 @@ BAIL: * _cairo_rectangle_fixed_round. */ -static void +void _cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle) { rectangle->x = _cairo_fixed_integer_floor (box->p1.x); @@ -1058,7 +893,7 @@ _cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle) rectangle->height = _cairo_fixed_integer_ceil (box->p2.y) - rectangle->y; } -static void +void _cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src) { int x1, y1, x2, y2; @@ -1087,74 +922,10 @@ _cairo_rectangle_empty (cairo_rectangle_t *rect) return rect->width == 0 || rect->height == 0; } -/* Given a region representing a set of trapezoids that will be - * drawn, clip the region according to the gstate and compute - * the overall extents. - */ -static cairo_status_t -_clip_and_compute_extents_region (cairo_gstate_t *gstate, - pixman_region16_t *trap_region, - cairo_rectangle_t *extents) -{ - cairo_status_t status; - - status = _cairo_gstate_intersect_clip (gstate, trap_region); - if (status) - return status; - - _region_rect_extents (trap_region, extents); - - return CAIRO_STATUS_SUCCESS; -} - -/* Given a a set of trapezoids to draw, find a bounding box (non-exact) - * of the trapezoids clipped by the gstate - */ -static cairo_status_t -_clip_and_compute_extents_arbitrary (cairo_gstate_t *gstate, - cairo_traps_t *traps, - cairo_rectangle_t *extents) -{ - cairo_box_t trap_extents; - - _cairo_traps_extents (traps, &trap_extents); - _cairo_box_round_to_rectangle (&trap_extents, extents); - - if (gstate->clip.region) { - pixman_region16_t *intersection; - cairo_status_t status; - - status = _region_new_from_rect (extents, &intersection); - if (status) - return status; - - if (pixman_region_intersect (intersection, - gstate->clip.region, - intersection) == PIXMAN_REGION_STATUS_SUCCESS) - { - _region_rect_extents (intersection, extents); - } - else - { - status = CAIRO_STATUS_NO_MEMORY; - } - - pixman_region_destroy (intersection); - - if (status) - return status; - } - - if (gstate->clip.surface) - _cairo_rectangle_intersect (extents, &gstate->clip.surface_rect); - - return CAIRO_STATUS_SUCCESS; -} - /* Composites a region representing a set of trapezoids. */ static cairo_status_t -_composite_trap_region (cairo_gstate_t *gstate, +_composite_trap_region (cairo_clip_t *clip, cairo_pattern_t *src, cairo_operator_t operator, cairo_surface_t *dst, @@ -1170,73 +941,43 @@ _composite_trap_region (cairo_gstate_t *gstate, return CAIRO_STATUS_SUCCESS; if (num_rects > 1) { - - if (gstate->clip.mode != CAIRO_CLIP_MODE_REGION) + if (clip->mode != CAIRO_CLIP_MODE_REGION) return CAIRO_INT_STATUS_UNSUPPORTED; - clip_serial = _cairo_surface_allocate_clip_serial (gstate->target); - status = _cairo_surface_set_clip_region (gstate->target, + clip_serial = _cairo_surface_allocate_clip_serial (dst); + status = _cairo_surface_set_clip_region (dst, trap_region, clip_serial); if (status) return status; } - if (gstate->clip.surface) - _cairo_pattern_init_for_surface (&mask.surface, gstate->clip.surface); + if (clip->surface) + _cairo_pattern_init_for_surface (&mask.surface, clip->surface); - status = _cairo_surface_composite (gstate->operator, + status = _cairo_surface_composite (operator, src, - gstate->clip.surface ? &mask.base : NULL, + clip->surface ? &mask.base : NULL, dst, extents->x, extents->y, - extents->x - (gstate->clip.surface ? gstate->clip.surface_rect.x : 0), - extents->y - (gstate->clip.surface ? gstate->clip.surface_rect.y : 0), + extents->x - (clip->surface ? clip->surface_rect.x : 0), + extents->y - (clip->surface ? clip->surface_rect.y : 0), extents->x, extents->y, extents->width, extents->height); - if (gstate->clip.surface) + if (clip->surface) _cairo_pattern_fini (&mask.base); return status; } -static void -translate_traps (cairo_traps_t *traps, int x, int y) -{ - cairo_fixed_t xoff, yoff; - cairo_trapezoid_t *t; - int i; - - /* Ugh. The cairo_composite/(Render) interface doesn't allow - an offset for the trapezoids. Need to manually shift all - the coordinates to align with the offset origin of the - intermediate surface. */ - - xoff = _cairo_fixed_from_int (x); - yoff = _cairo_fixed_from_int (y); - - for (i = 0, t = traps->traps; i < traps->num_traps; i++, t++) { - t->top += yoff; - t->bottom += yoff; - t->left.p1.x += xoff; - t->left.p1.y += yoff; - t->left.p2.x += xoff; - t->left.p2.y += yoff; - t->right.p1.x += xoff; - t->right.p1.y += yoff; - t->right.p2.x += xoff; - t->right.p2.y += yoff; - } -} - /* Composites a set of trapezoids in the case where we need to create - * an intermediate surface to handle gstate->clip.surface + * an intermediate surface to handle clip->surface * * Warning: This call modifies the coordinates of traps */ static cairo_status_t -_composite_traps_intermediate_surface (cairo_gstate_t *gstate, +_composite_traps_intermediate_surface (cairo_clip_t *clip, cairo_pattern_t *src, cairo_operator_t operator, cairo_surface_t *dst, @@ -1248,9 +989,9 @@ _composite_traps_intermediate_surface (cairo_gstate_t *gstate, cairo_surface_pattern_t intermediate_pattern; cairo_status_t status; - translate_traps (traps, -extents->x, -extents->y); + _cairo_traps_translate (traps, -extents->x, -extents->y); - intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface, + intermediate = _cairo_surface_create_similar_solid (clip->surface, CAIRO_CONTENT_ALPHA, extents->width, extents->height, @@ -1274,7 +1015,7 @@ _composite_traps_intermediate_surface (cairo_gstate_t *gstate, if (status) goto out; - status = _cairo_gstate_combine_clip_surface (gstate, intermediate, extents); + status = _cairo_clip_combine_to_surface (clip, intermediate, extents); if (status) goto out; @@ -1302,7 +1043,7 @@ _composite_traps_intermediate_surface (cairo_gstate_t *gstate, * _cairo_surface_fill_rectangles). */ static cairo_status_t -_composite_trap_region_solid (cairo_gstate_t *gstate, +_composite_trap_region_solid (cairo_clip_t *clip, cairo_solid_pattern_t *src, cairo_operator_t operator, cairo_surface_t *dst, @@ -1337,10 +1078,10 @@ _composite_trap_region_solid (cairo_gstate_t *gstate, } /* Composites a set of trapezoids in the general case where - gstate->clip.surface == NULL + clip->surface == NULL */ static cairo_status_t -_composite_traps (cairo_gstate_t *gstate, +_composite_traps (cairo_clip_t *clip, cairo_pattern_t *src, cairo_operator_t operator, cairo_surface_t *dst, @@ -1349,7 +1090,7 @@ _composite_traps (cairo_gstate_t *gstate, { cairo_status_t status; - status = _cairo_surface_composite_trapezoids (gstate->operator, + status = _cairo_surface_composite_trapezoids (operator, src, dst, extents->x, extents->y, extents->x, extents->y, @@ -1361,13 +1102,26 @@ _composite_traps (cairo_gstate_t *gstate, return status; } +/* Gets the bounding box of a region as a cairo_rectangle_t */ +static void +_region_rect_extents (pixman_region16_t *region, + cairo_rectangle_t *rect) +{ + pixman_box16_t *region_extents = pixman_region_extents (region); + + rect->x = region_extents->x1; + rect->y = region_extents->y1; + rect->width = region_extents->x2 - region_extents->x1; + rect->height = region_extents->y2 - region_extents->y1; +} + /* Warning: This call modifies the coordinates of traps */ -static cairo_status_t -_clip_and_composite_trapezoids_transformed (cairo_gstate_t *gstate, - cairo_pattern_t *src, - cairo_operator_t operator, - cairo_surface_t *dst, - cairo_traps_t *traps) +cairo_status_t +_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_status_t status; pixman_region16_t *trap_region; @@ -1380,10 +1134,15 @@ _clip_and_composite_trapezoids_transformed (cairo_gstate_t *gstate, if (status) return status; - if (trap_region) - status = _clip_and_compute_extents_region (gstate, trap_region, &extents); - else - status = _clip_and_compute_extents_arbitrary (gstate, traps, &extents); + if (trap_region) { + status = _cairo_clip_intersect_to_region (clip, trap_region); + _region_rect_extents (trap_region, &extents); + } else { + cairo_box_t trap_extents; + _cairo_traps_extents (traps, &trap_extents); + _cairo_box_round_to_rectangle (&trap_extents, &extents); + status = _cairo_clip_intersect_to_rectangle (clip, &extents); + } if (status) goto out; @@ -1392,27 +1151,27 @@ _clip_and_composite_trapezoids_transformed (cairo_gstate_t *gstate, /* Nothing to do */ goto out; - if (gstate->clip.surface) { + if (clip->surface) { if (trap_region) { /* If we are compositing a set of rectangles, we can set them as the * clip region for the destination surface and use the clip surface * as the mask. A clip region might not be supported, in which case * we fall through to the next method */ - status = _composite_trap_region (gstate, src, operator, dst, + status = _composite_trap_region (clip, src, operator, dst, trap_region, &extents); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto out; } /* Handle a clip surface by creating an intermediate surface. */ - status = _composite_traps_intermediate_surface (gstate, src, operator, + status = _composite_traps_intermediate_surface (clip, src, operator, dst, traps, &extents); } else { /* No clip surface */ if (trap_region && src->type == CAIRO_PATTERN_SOLID) { /* Solid rectangles are handled specially */ - status = _composite_trap_region_solid (gstate, (cairo_solid_pattern_t *)src, + status = _composite_trap_region_solid (clip, (cairo_solid_pattern_t *)src, operator, dst, trap_region); } else { if (trap_region) { @@ -1421,7 +1180,7 @@ _clip_and_composite_trapezoids_transformed (cairo_gstate_t *gstate, * trapezoids is pretty high for most backends currently, so it's * worthwhile even if a region is needed. */ - status = _composite_trap_region (gstate, src, operator, dst, + status = _composite_trap_region (clip, src, operator, dst, trap_region, &extents); if (status != CAIRO_INT_STATUS_UNSUPPORTED) goto out; @@ -1429,7 +1188,7 @@ _clip_and_composite_trapezoids_transformed (cairo_gstate_t *gstate, /* If a clip regions aren't supported, fall through */ } - status = _composite_traps (gstate, src, operator, + status = _composite_traps (clip, src, operator, dst, traps, &extents); } } @@ -1451,11 +1210,11 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, _cairo_gstate_copy_transformed_source (gstate, &pattern.base); - status = _clip_and_composite_trapezoids_transformed (gstate, - &pattern.base, - gstate->operator, - gstate->target, - traps); + status = _cairo_surface_clip_and_composite_trapezoids (&pattern.base, + gstate->operator, + gstate->target, + traps, + &gstate->clip); _cairo_pattern_fini (&pattern.base); @@ -1471,7 +1230,7 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) if (gstate->source->status) return gstate->source->status; - status = _cairo_gstate_set_clip (gstate); + status = _cairo_surface_set_clip (gstate->target, &gstate->clip); if (status) return status; @@ -1487,7 +1246,10 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) _cairo_traps_init (&traps); - status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps); + status = _cairo_path_fixed_fill_to_traps (path, + gstate->fill_rule, + gstate->tolerance, + &traps); if (status) { _cairo_traps_fini (&traps); return status; @@ -1514,7 +1276,10 @@ _cairo_gstate_in_fill (cairo_gstate_t *gstate, _cairo_traps_init (&traps); - status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps); + status = _cairo_path_fixed_fill_to_traps (path, + gstate->fill_rule, + gstate->tolerance, + &traps); if (status) goto BAIL; @@ -1584,7 +1349,10 @@ _cairo_gstate_fill_extents (cairo_gstate_t *gstate, _cairo_traps_init (&traps); - status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps); + status = _cairo_path_fixed_fill_to_traps (path, + gstate->fill_rule, + gstate->tolerance, + &traps); if (status) goto BAIL; @@ -1607,224 +1375,15 @@ BAIL: cairo_status_t _cairo_gstate_reset_clip (cairo_gstate_t *gstate) { - /* destroy any existing clip-region artifacts */ - if (gstate->clip.surface) - cairo_surface_destroy (gstate->clip.surface); - gstate->clip.surface = NULL; - - if (gstate->clip.region) - pixman_region_destroy (gstate->clip.region); - gstate->clip.region = NULL; - - if (gstate->clip.path) - _cairo_clip_path_destroy (gstate->clip.path); - gstate->clip.path = NULL; - - gstate->clip.serial = 0; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gstate_intersect_clip_path (cairo_gstate_t *gstate, - cairo_path_fixed_t *path) -{ - cairo_clip_path_t *clip_path; - cairo_status_t status; - - if (gstate->clip.mode != CAIRO_CLIP_MODE_PATH) - return CAIRO_INT_STATUS_UNSUPPORTED; - - clip_path = malloc (sizeof (cairo_clip_path_t)); - if (clip_path == NULL) - return CAIRO_STATUS_NO_MEMORY; - - status = _cairo_path_fixed_init_copy (&clip_path->path, path); - if (status) - return status; - - clip_path->ref_count = 1; - clip_path->fill_rule = gstate->fill_rule; - clip_path->tolerance = gstate->tolerance; - clip_path->prev = gstate->clip.path; - gstate->clip.path = clip_path; - gstate->clip.serial = _cairo_surface_allocate_clip_serial (gstate->target); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_clip_path_t * -_cairo_clip_path_reference (cairo_clip_path_t *clip_path) -{ - if (clip_path == NULL) - return NULL; - - clip_path->ref_count++; - - return clip_path; -} - -static void -_cairo_clip_path_destroy (cairo_clip_path_t *clip_path) -{ - if (clip_path == NULL) - return; - - clip_path->ref_count--; - if (clip_path->ref_count) - return; - - _cairo_path_fixed_fini (&clip_path->path); - _cairo_clip_path_destroy (clip_path->prev); - free (clip_path); -} - -static cairo_status_t -_cairo_gstate_intersect_clip_region (cairo_gstate_t *gstate, - cairo_traps_t *traps) -{ - pixman_region16_t *region; - cairo_status_t status; - - if (gstate->clip.mode != CAIRO_CLIP_MODE_REGION) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_traps_extract_region (traps, ®ion); - if (status) - return status; - - if (region == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = CAIRO_STATUS_SUCCESS; - if (gstate->clip.region == NULL) { - gstate->clip.region = region; - } else { - pixman_region16_t *intersection = pixman_region_create(); - - if (pixman_region_intersect (intersection, - gstate->clip.region, region) - == PIXMAN_REGION_STATUS_SUCCESS) { - pixman_region_destroy (gstate->clip.region); - gstate->clip.region = intersection; - } else { - status = CAIRO_STATUS_NO_MEMORY; - } - pixman_region_destroy (region); - } - gstate->clip.serial = _cairo_surface_allocate_clip_serial (gstate->target); - return status; -} - -static cairo_status_t -_cairo_gstate_intersect_clip_mask (cairo_gstate_t *gstate, - cairo_traps_t *traps) -{ - cairo_pattern_union_t pattern; - cairo_box_t extents; - cairo_rectangle_t surface_rect; - cairo_surface_t *surface; - cairo_status_t status; - - /* Represent the clip as a mask surface. We create a new surface - * the size of the intersection of the old mask surface and the - * extents of the new clip path. */ - - _cairo_traps_extents (traps, &extents); - _cairo_box_round_to_rectangle (&extents, &surface_rect); - - if (gstate->clip.surface != NULL) - _cairo_rectangle_intersect (&surface_rect, &gstate->clip.surface_rect); - - surface = _cairo_surface_create_similar_solid (gstate->target, - CAIRO_CONTENT_ALPHA, - surface_rect.width, - surface_rect.height, - CAIRO_COLOR_WHITE); - if (surface->status) - return CAIRO_STATUS_NO_MEMORY; - - /* Render the new clipping path into the new mask surface. */ - - translate_traps (traps, -surface_rect.x, -surface_rect.y); - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); - - status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN, - &pattern.base, - surface, - 0, 0, - 0, 0, - surface_rect.width, - surface_rect.height, - traps->traps, - traps->num_traps); - - _cairo_pattern_fini (&pattern.base); - - if (status) { - cairo_surface_destroy (surface); - return status; - } - - /* If there was a clip surface already, combine it with the new - * mask surface using the IN operator, so we get the intersection - * of the old and new clipping paths. */ - - if (gstate->clip.surface != NULL) { - _cairo_pattern_init_for_surface (&pattern.surface, gstate->clip.surface); - - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, - &pattern.base, - NULL, - surface, - surface_rect.x - gstate->clip.surface_rect.x, - surface_rect.y - gstate->clip.surface_rect.y, - 0, 0, - 0, 0, - surface_rect.width, - surface_rect.height); - - _cairo_pattern_fini (&pattern.base); - - if (status) { - cairo_surface_destroy (surface); - return status; - } - - cairo_surface_destroy (gstate->clip.surface); - } - - gstate->clip.surface = surface; - gstate->clip.surface_rect = surface_rect; - - return status; + return _cairo_clip_reset (&gstate->clip); } cairo_status_t _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path) { - cairo_status_t status; - cairo_traps_t traps; - - status = _cairo_gstate_intersect_clip_path (gstate, path); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - _cairo_traps_init (&traps); - status = _cairo_path_fixed_fill_to_traps (path, gstate, &traps); - if (status) - goto bail; - - status = _cairo_gstate_intersect_clip_region (gstate, &traps); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto bail; - - status = _cairo_gstate_intersect_clip_mask (gstate, &traps); - - bail: - _cairo_traps_fini (&traps); - - return status; + return _cairo_clip_clip (&gstate->clip, + path, gstate->fill_rule, gstate->tolerance, + gstate->target); } static void @@ -2140,7 +1699,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, if (gstate->source->status) return gstate->source->status; - status = _cairo_gstate_set_clip (gstate); + status = _cairo_surface_set_clip (gstate->target, &gstate->clip); if (status) return status; diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index c2be862e..3781fabc 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -35,15 +35,7 @@ #include "cairoint.h" #include "cairo-meta-surface-private.h" - -/* - * Notes: - * - * Can't use cairo_surface_* calls since we often don't want - * fallbacks. For example, when determining the font subsets or the - * fallback areas. Hmm... but maybe those passes could be integrated - * into the delegation wrappers and the ps output pass, respectively. - */ +#include "cairo-gstate-private.h" static const cairo_surface_backend_t cairo_meta_surface_backend; @@ -106,10 +98,6 @@ _cairo_meta_surface_finish (void *abstract_surface) free (command); break; - case CAIRO_COMMAND_SET_CLIP_REGION: - free (command); - break; - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: if (command->intersect_clip_path.path_pointer) _cairo_path_fixed_fini (&command->intersect_clip_path.path); @@ -275,38 +263,6 @@ _cairo_meta_surface_composite_trapezoids (cairo_operator_t operator, return CAIRO_STATUS_SUCCESS; } -static cairo_int_status_t -_cairo_meta_surface_set_clip_region (void *abstract_surface, - pixman_region16_t *region) -{ - cairo_meta_surface_t *meta = abstract_surface; - cairo_command_set_clip_region_t *command; - - command = malloc (sizeof (cairo_command_set_clip_region_t)); - if (command == NULL) - return CAIRO_STATUS_NO_MEMORY; - - command->type = CAIRO_COMMAND_SET_CLIP_REGION; - - if (region) { - command->region = pixman_region_create (); - pixman_region_copy (command->region, region); - } else { - command->region = NULL; - } - - command->serial = meta->base.current_clip_serial; - - if (_cairo_array_append (&meta->commands, &command, 1) == NULL) { - if (command->region) - pixman_region_destroy (command->region); - free (command); - return CAIRO_STATUS_NO_MEMORY; - } - - return CAIRO_STATUS_SUCCESS; -} - static cairo_int_status_t _cairo_meta_surface_intersect_clip_path (void *dst, cairo_path_fixed_t *path, @@ -468,7 +424,7 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = { _cairo_meta_surface_composite_trapezoids, NULL, /* copy_page */ NULL, /* show_page */ - _cairo_meta_surface_set_clip_region, + NULL, /* set_clip_region */ _cairo_meta_surface_intersect_clip_path, _cairo_meta_surface_get_extents, _cairo_meta_surface_show_glyphs, @@ -483,16 +439,24 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, cairo_command_t *command, **elements; int i, num_elements; cairo_int_status_t status; + cairo_traps_t traps; + cairo_clip_t clip; meta = (cairo_meta_surface_t *) surface; status = CAIRO_STATUS_SUCCESS; + _cairo_clip_init (&clip, target); + num_elements = meta->commands.num_elements; elements = (cairo_command_t **) meta->commands.elements; for (i = 0; i < num_elements; i++) { command = elements[i]; switch (command->type) { case CAIRO_COMMAND_COMPOSITE: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_composite (command->composite.operator, &command->composite.src_pattern.base, @@ -509,6 +473,10 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; case CAIRO_COMMAND_FILL_RECTANGLES: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_fill_rectangles (target, command->fill_rectangles.operator, @@ -518,6 +486,10 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; case CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_composite_trapezoids (command->composite_trapezoids.operator, &command->composite_trapezoids.pattern.base, @@ -532,27 +504,24 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, command->composite_trapezoids.num_traps); break; - case CAIRO_COMMAND_SET_CLIP_REGION: - status = _cairo_surface_set_clip_region - (target, - command->set_clip_region.region, - command->set_clip_region.serial); - break; - case CAIRO_COMMAND_INTERSECT_CLIP_PATH: /* XXX Meta surface clipping is broken and requires some * cairo-gstate.c rewriting. Work around it for now. */ - if (target->backend->intersect_clip_path == NULL) - break; - - status = _cairo_surface_intersect_clip_path - (target, - command->intersect_clip_path.path_pointer, - command->intersect_clip_path.fill_rule, - command->intersect_clip_path.tolerance); + if (command->intersect_clip_path.path_pointer == NULL) + status = _cairo_clip_reset (&clip); + else + status = _cairo_clip_clip (&clip, + command->intersect_clip_path.path_pointer, + command->intersect_clip_path.fill_rule, + command->intersect_clip_path.tolerance, + target); break; case CAIRO_COMMAND_SHOW_GLYPHS: + status = _cairo_surface_set_clip (target, &clip); + if (status) + break; + status = _cairo_surface_show_glyphs (command->show_glyphs.scaled_font, command->show_glyphs.operator, @@ -569,18 +538,37 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; case CAIRO_COMMAND_FILL_PATH: - /* XXX Meta surface fill_path is broken and requires some - * cairo-gstate.c rewriting. Work around it for now. */ - if (target->backend->fill_path == NULL) + status = _cairo_surface_set_clip (target, &clip); + if (status) break; - status = _cairo_surface_fill_path - (command->fill_path.operator, - &command->fill_path.pattern.base, - target, - &command->fill_path.path, - command->fill_path.fill_rule, - command->fill_path.tolerance); + status = _cairo_surface_fill_path (command->fill_path.operator, + &command->fill_path.pattern.base, + target, + &command->fill_path.path, + command->fill_path.fill_rule, + command->fill_path.tolerance); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + break; + + _cairo_traps_init (&traps); + + status = _cairo_path_fixed_fill_to_traps (&command->fill_path.path, + command->fill_path.fill_rule, + command->fill_path.tolerance, + &traps); + if (status) { + _cairo_traps_fini (&traps); + break; + } + + status = _cairo_surface_clip_and_composite_trapezoids (&command->fill_path.pattern.base, + command->fill_path.operator, + target, + &traps, + &clip); + + _cairo_traps_fini (&traps); break; default: @@ -591,5 +579,7 @@ _cairo_meta_surface_replay (cairo_surface_t *surface, break; } + _cairo_clip_fini (&clip); + return status; } diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index c0015fc9..31b83ade 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -36,10 +36,8 @@ #include "cairoint.h" -#include "cairo-gstate-private.h" - typedef struct cairo_filler { - cairo_gstate_t *gstate; + double tolerance; cairo_traps_t *traps; cairo_point_t current_point; @@ -48,7 +46,7 @@ typedef struct cairo_filler { } cairo_filler_t; static void -_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps); +_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps); static void _cairo_filler_fini (cairo_filler_t *filler); @@ -69,9 +67,9 @@ static cairo_status_t _cairo_filler_close_path (void *closure); static void -_cairo_filler_init (cairo_filler_t *filler, cairo_gstate_t *gstate, cairo_traps_t *traps) +_cairo_filler_init (cairo_filler_t *filler, double tolerance, cairo_traps_t *traps) { - filler->gstate = gstate; + filler->tolerance = tolerance; filler->traps = traps; filler->current_point.x = 0; @@ -132,7 +130,6 @@ _cairo_filler_curve_to (void *closure, cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; - cairo_gstate_t *gstate = filler->gstate; cairo_spline_t spline; status = _cairo_spline_init (&spline, &filler->current_point, b, c, d); @@ -140,7 +137,7 @@ _cairo_filler_curve_to (void *closure, if (status == CAIRO_INT_STATUS_DEGENERATE) return CAIRO_STATUS_SUCCESS; - _cairo_spline_decompose (&spline, gstate->tolerance); + _cairo_spline_decompose (&spline, filler->tolerance); if (status) goto CLEANUP_SPLINE; @@ -174,13 +171,14 @@ _cairo_filler_close_path (void *closure) cairo_status_t _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, - cairo_gstate_t *gstate, + cairo_fill_rule_t fill_rule, + double tolerance, cairo_traps_t *traps) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_filler_t filler; - _cairo_filler_init (&filler, gstate, traps); + _cairo_filler_init (&filler, tolerance, traps); status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, @@ -198,7 +196,7 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, status = _cairo_traps_tessellate_polygon (filler.traps, &filler.polygon, - filler.gstate->fill_rule); + fill_rule); if (status) goto BAIL; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 4ff8c700..52804ebb 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1283,7 +1283,7 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface, * Sets the clipping path to be the intersection of the current * clipping path of the surface and the given path. **/ -cairo_status_t +static cairo_status_t _cairo_surface_set_clip_path (cairo_surface_t *surface, cairo_clip_path_t *clip_path, unsigned int serial) @@ -1314,6 +1314,27 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface, return CAIRO_STATUS_SUCCESS; } +cairo_status_t +_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip) +{ + if (!surface) + return CAIRO_STATUS_NULL_POINTER; + if (clip->serial == _cairo_surface_get_current_clip_serial (surface)) + return CAIRO_STATUS_SUCCESS; + + if (clip->path) + return _cairo_surface_set_clip_path (surface, + clip->path, + clip->serial); + + if (clip->region) + return _cairo_surface_set_clip_region (surface, + clip->region, + clip->serial); + + return _cairo_surface_reset_clip (surface); +} + /** * _cairo_surface_get_extents: * @surface: the #cairo_surface_t to fetch extents for diff --git a/src/cairo-traps.c b/src/cairo-traps.c index a97d5848..18b944c1 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -229,6 +229,35 @@ _compare_point_fixed_by_y (const void *av, const void *bv) return ret; } +void +_cairo_traps_translate (cairo_traps_t *traps, int x, int y) +{ + cairo_fixed_t xoff, yoff; + cairo_trapezoid_t *t; + int i; + + /* Ugh. The cairo_composite/(Render) interface doesn't allow + an offset for the trapezoids. Need to manually shift all + the coordinates to align with the offset origin of the + intermediate surface. */ + + xoff = _cairo_fixed_from_int (x); + yoff = _cairo_fixed_from_int (y); + + for (i = 0, t = traps->traps; i < traps->num_traps; i++, t++) { + t->top += yoff; + t->bottom += yoff; + t->left.p1.x += xoff; + t->left.p1.y += yoff; + t->left.p2.x += xoff; + t->left.p2.y += yoff; + t->right.p1.x += xoff; + t->right.p1.y += yoff; + t->right.p2.x += xoff; + t->right.p2.y += yoff; + } +} + cairo_status_t _cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3]) { diff --git a/src/cairoint.h b/src/cairoint.h index 78387fb0..74e58c96 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -240,6 +240,9 @@ typedef enum cairo_direction { } cairo_direction_t; typedef struct _cairo_path_fixed cairo_path_fixed_t; +typedef enum _cairo_clip_mode cairo_clip_mode_t; +typedef struct _cairo_clip_path cairo_clip_path_t; +typedef struct _cairo_clip cairo_clip_t; typedef struct _cairo_edge { cairo_line_t edge; @@ -289,6 +292,13 @@ typedef struct _cairo_pen { typedef struct _cairo_color cairo_color_t; typedef struct _cairo_image_surface cairo_image_surface_t; +cairo_private void +_cairo_box_round_to_rectangle (cairo_box_t *box, cairo_rectangle_t *rectangle); + +cairo_private void +_cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src); + + /* cairo_array.c structures and functions */ typedef struct _cairo_array cairo_array_t; @@ -813,12 +823,6 @@ typedef struct _cairo_format_masks { unsigned long blue_mask; } cairo_format_masks_t; -typedef enum _cairo_clip_mode { - CAIRO_CLIP_MODE_PATH, - CAIRO_CLIP_MODE_REGION, - CAIRO_CLIP_MODE_MASK -} cairo_clip_mode_t; - struct _cairo_surface { const cairo_surface_backend_t *backend; @@ -1499,7 +1503,8 @@ _cairo_path_fixed_bounds (cairo_path_fixed_t *path, /* cairo_path_fill.c */ cairo_private cairo_status_t _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, - cairo_gstate_t *gstate, + cairo_fill_rule_t fill_rule, + double tolerance, cairo_traps_t *traps); /* cairo_path_stroke.c */ @@ -1585,6 +1590,13 @@ _cairo_surface_composite_trapezoids (cairo_operator_t operator, cairo_trapezoid_t *traps, int ntraps); +cairo_status_t +_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_private cairo_status_t _cairo_surface_copy_page (cairo_surface_t *surface); @@ -1640,12 +1652,8 @@ _cairo_surface_intersect_clip_path (cairo_surface_t *surface, cairo_fill_rule_t fill_rule, double tolerance); -typedef struct _cairo_clip_path cairo_clip_path_t; - cairo_private cairo_status_t -_cairo_surface_set_clip_path (cairo_surface_t *surface, - cairo_clip_path_t *clip_path, - unsigned int serial); +_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip); cairo_private cairo_status_t _cairo_surface_get_extents (cairo_surface_t *surface, @@ -1800,6 +1808,9 @@ _cairo_traps_init_box (cairo_traps_t *traps, cairo_private void _cairo_traps_fini (cairo_traps_t *traps); +cairo_private void +_cairo_traps_translate (cairo_traps_t *traps, int x, int y); + cairo_private cairo_status_t _cairo_traps_tessellate_triangle (cairo_traps_t *traps, cairo_point_t t[3]); -- cgit v1.2.3 From fd27af574d544d8adfd8cb6d5ac84837e6db43d2 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 4 Aug 2005 23:10:26 +0000 Subject: Patch from Adrian Johnson Remap composite glyps to use subset font glyph indices. --- ChangeLog | 8 ++++++ src/cairo-font-subset.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 13fe22e5..fe987515 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-08-05 Kristian Høgsberg + + Patch from Adrian Johnson + + * src/cairo-font-subset.c (cairo_pdf_ft_font_write_glyf_table) + (cairo_pdf_ft_font_remap_composite_glyph): Remap composite glyps + to use subset font glyph indices. + 2005-08-05 Kristian Høgsberg Reviewed by: otaylor diff --git a/src/cairo-font-subset.c b/src/cairo-font-subset.c index 88008d7e..bd113f98 100644 --- a/src/cairo-font-subset.c +++ b/src/cairo-font-subset.c @@ -71,6 +71,10 @@ struct cairo_pdf_ft_font { cairo_status_t status; }; +static int +cairo_pdf_ft_font_use_glyph (void *abstract_font, int glyph); + + #define ARRAY_LENGTH(a) ( (sizeof (a)) / (sizeof ((a)[0])) ) #define SFNT_VERSION 0x00010000 @@ -312,6 +316,62 @@ cairo_pdf_ft_font_write_generic_table (cairo_pdf_ft_font_t *font, return 0; } + +typedef struct composite_glyph composite_glyph_t; +struct composite_glyph { + unsigned short flags; + unsigned short index; + unsigned short args[7]; /* 1 to 7 arguments depending on value of flags */ +}; + +typedef struct glyph_data glyph_data_t; +struct glyph_data { + short num_contours; + char data[8]; + composite_glyph_t glyph; +}; + +/* composite_glyph_t flags */ +#define ARG_1_AND_2_ARE_WORDS 0x0001 +#define WE_HAVE_A_SCALE 0x0008 +#define MORE_COMPONENTS 0x0020 +#define WE_HAVE_AN_X_AND_Y_SCALE 0x0040 +#define WE_HAVE_A_TWO_BY_TWO 0x0080 + +static void +cairo_pdf_ft_font_remap_composite_glyph (cairo_pdf_ft_font_t *font, + unsigned char *buffer) +{ + glyph_data_t *glyph_data; + composite_glyph_t *composite_glyph; + int num_args; + int has_more_components; + unsigned short flags; + unsigned short index; + + glyph_data = (glyph_data_t *) buffer; + if ((short)be16_to_cpu (glyph_data->num_contours) >= 0) + return; + + composite_glyph = &glyph_data->glyph; + do { + flags = be16_to_cpu (composite_glyph->flags); + has_more_components = flags & MORE_COMPONENTS; + index = cairo_pdf_ft_font_use_glyph (font, be16_to_cpu (composite_glyph->index)); + composite_glyph->index = cpu_to_be16 (index); + num_args = 1; + if (flags & ARG_1_AND_2_ARE_WORDS) + num_args += 1; + if (flags & WE_HAVE_A_SCALE) + num_args += 1; + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) + num_args += 2; + else if (flags & WE_HAVE_A_TWO_BY_TWO) + num_args += 3; + composite_glyph = (composite_glyph_t *) &(composite_glyph->args[num_args]); + } while (has_more_components); +} + static int cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font, unsigned long tag) @@ -359,8 +419,10 @@ cairo_pdf_ft_font_write_glyf_table (cairo_pdf_ft_font_t *font, buffer = cairo_pdf_ft_font_write (font, NULL, size); if (buffer == NULL) break; - FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size); - /* FIXME: remap composite glyphs */ + if (size != 0) { + FT_Load_Sfnt_Table (font->face, TTAG_glyf, begin, buffer, &size); + cairo_pdf_ft_font_remap_composite_glyph (font, buffer); + } } font->glyphs[i].location = @@ -515,10 +577,14 @@ struct table { }; static const table_t truetype_tables[] = { + /* As we write out the glyf table we remap composite glyphs. + * Remapping composite glyphs will reference the sub glyphs the + * composite glyph is made up of. That needs to be done first so + * we have all the glyphs in the subset before going further. */ + { TTAG_glyf, cairo_pdf_ft_font_write_glyf_table }, { TTAG_cmap, cairo_pdf_ft_font_write_cmap_table }, { TTAG_cvt, cairo_pdf_ft_font_write_generic_table }, { TTAG_fpgm, cairo_pdf_ft_font_write_generic_table }, - { TTAG_glyf, cairo_pdf_ft_font_write_glyf_table }, { TTAG_head, cairo_pdf_ft_font_write_head_table }, { TTAG_hhea, cairo_pdf_ft_font_write_hhea_table }, { TTAG_hmtx, cairo_pdf_ft_font_write_hmtx_table }, -- cgit v1.2.3 From 0586daaa2927bfde9605487eef8e9b95c49d7d2f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 07:48:18 +0000 Subject: Patch from John Ehresman to aid win32 compilation: Define snprintf as _snprintf when under the influence of _MSC_VER. Define int32_t and friends as __int32 and friends when under the influence of _MSC_VER. Make include of unistd.h conditional on HAVE_UNISTD_H. --- ChangeLog | 16 ++++++++++++++++ src/cairo-output-stream.c | 4 ++++ src/cairo-wideint.h | 14 +++++++++++++- test/buffer-diff.c | 2 ++ test/cairo-test.c | 6 ++++++ test/read-png.c | 14 +++++++++++++- 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fe987515..c553f87d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-08-05 Carl Worth + + Patch from John Ehresman to aid win32 + compilation: + + * src/cairo-output-stream.c: Define snprintf as _snprintf when + under the influence of _MSC_VER. + + * test/read-png.c: (read_png_argb32): + * src/cairo-wideint.h: Define int32_t and friends as __int32 and + friends when under the influence of _MSC_VER. + + * test/buffer-diff.c: + * test/cairo-test.c: Make include of unistd.h conditional on + HAVE_UNISTD_H. + 2005-08-05 Kristian Høgsberg Patch from Adrian Johnson diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c index 17ef7e2c..afb4d428 100644 --- a/src/cairo-output-stream.c +++ b/src/cairo-output-stream.c @@ -39,6 +39,10 @@ #include #include "cairoint.h" +#ifdef _MSC_VER +#define snprintf _snprintf +#endif /* _MSC_VER */ + struct _cairo_output_stream { cairo_write_func_t write_data; void *closure; diff --git a/src/cairo-wideint.h b/src/cairo-wideint.h index 8870df7b..b008b5d5 100644 --- a/src/cairo-wideint.h +++ b/src/cairo-wideint.h @@ -1,5 +1,5 @@ /* - * $Id: cairo-wideint.h,v 1.11 2005-07-30 19:57:54 keithp Exp $ + * $Id: cairo-wideint.h,v 1.12 2005-08-05 14:48:19 cworth Exp $ * * Copyright © 2004 Keith Packard * @@ -44,6 +44,18 @@ # include #elif HAVE_SYS_INT_TYPES_H # include +#elif defined(_MSC_VER) + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef __int16 int16_t; + typedef unsigned __int16 uint16_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# ifndef HAVE_UINT64_T +# define HAVE_UINT64_T 1 +# endif #else #error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.) #endif diff --git a/test/buffer-diff.c b/test/buffer-diff.c index e5ba513a..967ab424 100644 --- a/test/buffer-diff.c +++ b/test/buffer-diff.c @@ -24,7 +24,9 @@ * Author: Richard D. Worth */ #include +#ifdef HAVE_UNISTD_H #include +#endif #include #include diff --git a/test/cairo-test.c b/test/cairo-test.c index aff2125b..136252ce 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -26,7 +26,9 @@ #include #include #include +#ifdef HAVE_UNISTD_H #include +#endif #include #include #include @@ -38,6 +40,10 @@ #include "write-png.h" #include "xmalloc.h" +#ifdef _MSC_VER +#define vsnprintf _vsnprintf +#endif + #define CAIRO_TEST_LOG_SUFFIX ".log" #define CAIRO_TEST_PNG_SUFFIX "-out.png" #define CAIRO_TEST_REF_SUFFIX "-ref.png" diff --git a/test/read-png.c b/test/read-png.c index 96259dfe..ff311c28 100644 --- a/test/read-png.c +++ b/test/read-png.c @@ -35,6 +35,18 @@ # include #elif HAVE_SYS_INT_TYPES_H # include +#elif defined(_MSC_VER) + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef __int16 int16_t; + typedef unsigned __int16 uint16_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; +# ifndef HAVE_UINT64_T +# define HAVE_UINT64_T 1 +# endif #else #error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.) #endif @@ -79,7 +91,7 @@ read_png_argb32 (const char *filename, { int i; FILE *file; - static const int PNG_SIG_SIZE = 8; +#define PNG_SIG_SIZE 8 unsigned char png_sig[PNG_SIG_SIZE]; int sig_bytes; png_struct *png; -- cgit v1.2.3 From 2eabc47b853f08614d829acecb277388dcb4e046 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 09:49:38 +0000 Subject: Sort cairo-clip.c --- src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index b518392e..a48cce5a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -85,6 +85,8 @@ libcairo_la_SOURCES = \ cairo-arc-private.h \ cairo-array.c \ cairo-cache.c \ + cairo-clip.c \ + cairo-clip-private.h \ cairo-color.c \ cairo-debug.c \ cairo-fixed.c \ @@ -92,8 +94,6 @@ libcairo_la_SOURCES = \ cairo-font-options.c \ cairo-gstate.c \ cairo-gstate-private.h \ - cairo-clip.c \ - cairo-clip-private.h \ cairo-hull.c \ cairo-image-surface.c \ cairo-matrix.c \ -- cgit v1.2.3 From 72f40f58bbaf1b80c82f9447007cd4c8d7a4916f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 10:03:04 +0000 Subject: More obnoxious tmpl churn --- doc/public/tmpl/cairo-font.sgml | 2 ++ doc/public/tmpl/cairo-pattern.sgml | 1 + doc/public/tmpl/cairo-surface.sgml | 1 + doc/public/tmpl/cairo.sgml | 1 + 4 files changed, 5 insertions(+) diff --git a/doc/public/tmpl/cairo-font.sgml b/doc/public/tmpl/cairo-font.sgml index a41b7cce..e04d4354 100644 --- a/doc/public/tmpl/cairo-font.sgml +++ b/doc/public/tmpl/cairo-font.sgml @@ -35,6 +35,7 @@ Font Handling @font_face: +@Returns: @@ -85,6 +86,7 @@ Font Handling @scaled_font: +@Returns: diff --git a/doc/public/tmpl/cairo-pattern.sgml b/doc/public/tmpl/cairo-pattern.sgml index a837252c..78964ef4 100644 --- a/doc/public/tmpl/cairo-pattern.sgml +++ b/doc/public/tmpl/cairo-pattern.sgml @@ -87,6 +87,7 @@ cairo_pattern_t @pattern: +@Returns: diff --git a/doc/public/tmpl/cairo-surface.sgml b/doc/public/tmpl/cairo-surface.sgml index a33459d8..3f8cccad 100644 --- a/doc/public/tmpl/cairo-surface.sgml +++ b/doc/public/tmpl/cairo-surface.sgml @@ -43,6 +43,7 @@ cairo_surface_t @surface: +@Returns: diff --git a/doc/public/tmpl/cairo.sgml b/doc/public/tmpl/cairo.sgml index c3398425..0afc90fa 100644 --- a/doc/public/tmpl/cairo.sgml +++ b/doc/public/tmpl/cairo.sgml @@ -48,6 +48,7 @@ Drawing contexts. @cr: +@Returns: -- cgit v1.2.3 From a2dc18fd0c89e267bd810d42c8e0965487a22058 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 10:05:29 +0000 Subject: Remove include of math.h since cairoint.h does it more carefully, (for annoying platforms for which just including math.h without extra defines is not enough). Replace Cairo with cairo. Include config.h so HAVE_UNISTD_H gets picked up as necessary. Fix non-UTF-8 copyright symbol. --- ChangeLog | 14 ++++++++++++++ src/cairo-arc.c | 2 -- src/cairo-matrix.c | 1 - src/cairo.c | 2 +- test/buffer-diff.c | 4 ++++ test/cairo-test.c | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c553f87d..c4904553 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-08-05 Carl Worth + + * src/cairo-arc.c: + * src/cairo-matrix.c: Remove include of math.h since cairoint.h + does it more carefully, (for annoying platforms for which just + including math.h without extra defines is not enough). + + * src/cairo.c: Replace Cairo with cairo. + + * test/buffer-diff.c: Include config.h so HAVE_UNISTD_H gets + picked up as necessary. + + * test/cairo-test.c: Fix non-UTF-8 copyright symbol. + 2005-08-05 Carl Worth Patch from John Ehresman to aid win32 diff --git a/src/cairo-arc.c b/src/cairo-arc.c index e653fcda..e9f35993 100644 --- a/src/cairo-arc.c +++ b/src/cairo-arc.c @@ -34,8 +34,6 @@ * Carl D. Worth */ -#include - #include "cairo-arc-private.h" /* Spline deviation from the circle in radius would be given by: diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c index 98feb571..7596b084 100644 --- a/src/cairo-matrix.c +++ b/src/cairo-matrix.c @@ -36,7 +36,6 @@ #define _GNU_SOURCE #include -#include #include "cairoint.h" diff --git a/src/cairo.c b/src/cairo.c index 060d8fd6..9df4574f 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1649,7 +1649,7 @@ cairo_reset_clip (cairo_t *cr) * for operations such as listing all available fonts on the system, * and it is expected that most applications will need to use a more * comprehensive font handling and text layout library in addition to - * Cairo. + * cairo. **/ void cairo_select_font_face (cairo_t *cr, diff --git a/test/buffer-diff.c b/test/buffer-diff.c index 967ab424..8e0031b1 100644 --- a/test/buffer-diff.c +++ b/test/buffer-diff.c @@ -23,6 +23,10 @@ * * Author: Richard D. Worth */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include #ifdef HAVE_UNISTD_H #include diff --git a/test/cairo-test.c b/test/cairo-test.c index 136252ce..284a1d7b 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -1,5 +1,5 @@ /* - * Copyright  2004 Red Hat, Inc. + * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without -- cgit v1.2.3 From 59d7f60249c9b0d01b01548907c792c324cb9bc8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 10:30:31 +0000 Subject: Add some missing declarations to the appropriate sections. churn Rename cairo_path_nil to _cairo_path_nil since it may be exported, and tag it cairo_private to try to avoid exporting it. Qualify it as const well. Track new name of _cairo_path_nil and cast away the const as required. --- ChangeLog | 19 +++++++++++++++++++ doc/public/cairo-sections.txt | 5 +++++ doc/public/tmpl/cairo-font.sgml | 18 ++++++++++++++++++ doc/public/tmpl/cairo-surface.sgml | 9 +++++++++ doc/public/tmpl/cairo-xlib.sgml | 11 +++++++++++ doc/public/tmpl/cairo.sgml | 7 +++++++ src/cairo-path-data-private.h | 2 +- src/cairo-path-data.c | 8 ++++---- src/cairo.c | 4 ++-- 9 files changed, 76 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4904553..c719db5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2005-08-05 Carl Worth + + * doc/public/cairo-sections.txt: Add some missing declarations to + the appropriate sections. + + * doc/public/tmpl/cairo-font.sgml: + * doc/public/tmpl/cairo-surface.sgml: + * doc/public/tmpl/cairo-xlib.sgml: + * doc/public/tmpl/cairo.sgml: churn + + * src/cairo-path-data-private.h: Rename cairo_path_nil to + _cairo_path_nil since it may be exported, and tag it cairo_private + to try to avoid exporting it. Qualify it as const well. + + * src/cairo-path-data.c: (_cairo_path_data_create_real): + * src/cairo.c: (cairo_copy_path), (cairo_copy_path_flat): + Track new name of _cairo_path_nil and cast away the const as + required. + 2005-08-05 Carl Worth * src/cairo-arc.c: diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index 24551ace..93125722 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -75,6 +75,7 @@ cairo_xcb_surface_create_with_xrender_format cairo_xlib_surface_create cairo_xlib_surface_create_for_bitmap cairo_xlib_surface_set_size +cairo_xlib_surface_set_drawable
@@ -90,6 +91,7 @@ cairo_surface_t cairo_surface_create_similar cairo_surface_reference cairo_surface_destroy +cairo_surface_status cairo_surface_finish cairo_surface_get_font_options cairo_surface_set_user_data @@ -148,11 +150,13 @@ cairo_font_face_t cairo_scaled_font_t cairo_font_face_reference cairo_font_face_destroy +cairo_font_face_status cairo_font_face_get_user_data cairo_font_face_set_user_data cairo_scaled_font_create cairo_scaled_font_reference cairo_scaled_font_destroy +cairo_scaled_font_status cairo_font_extents_t cairo_scaled_font_extents cairo_text_extents_t @@ -296,6 +300,7 @@ cairo_destroy_func_t cairo_user_data_key_t cairo_read_func_t cairo_write_func_t +cairo_debug_reset_static_data CAIRO_BEGIN_DECLS CAIRO_END_DECLS diff --git a/doc/public/tmpl/cairo-font.sgml b/doc/public/tmpl/cairo-font.sgml index e04d4354..6fd8e163 100644 --- a/doc/public/tmpl/cairo-font.sgml +++ b/doc/public/tmpl/cairo-font.sgml @@ -46,6 +46,15 @@ Font Handling @font_face: + + + + + +@font_face: +@Returns: + + @@ -97,6 +106,15 @@ Font Handling @scaled_font: + + + + + +@scaled_font: +@Returns: + + diff --git a/doc/public/tmpl/cairo-surface.sgml b/doc/public/tmpl/cairo-surface.sgml index 3f8cccad..64e65f9d 100644 --- a/doc/public/tmpl/cairo-surface.sgml +++ b/doc/public/tmpl/cairo-surface.sgml @@ -54,6 +54,15 @@ cairo_surface_t @surface: + + + + + +@surface: +@Returns: + + diff --git a/doc/public/tmpl/cairo-xlib.sgml b/doc/public/tmpl/cairo-xlib.sgml index cc106e8c..d4cda456 100644 --- a/doc/public/tmpl/cairo-xlib.sgml +++ b/doc/public/tmpl/cairo-xlib.sgml @@ -53,3 +53,14 @@ XLib Backend @height: + + + + + +@surface: +@drawable: +@width: +@height: + + diff --git a/doc/public/tmpl/cairo.sgml b/doc/public/tmpl/cairo.sgml index 0afc90fa..8b29acc7 100644 --- a/doc/public/tmpl/cairo.sgml +++ b/doc/public/tmpl/cairo.sgml @@ -1116,3 +1116,10 @@ Drawing contexts. @Returns: + + + + + + + diff --git a/src/cairo-path-data-private.h b/src/cairo-path-data-private.h index d680f901..9947b515 100644 --- a/src/cairo-path-data-private.h +++ b/src/cairo-path-data-private.h @@ -38,7 +38,7 @@ #include "cairoint.h" -extern cairo_path_t cairo_path_nil; +cairo_private const cairo_path_t _cairo_path_nil; cairo_private cairo_path_t * _cairo_path_data_create (cairo_path_fixed_t *path, diff --git a/src/cairo-path-data.c b/src/cairo-path-data.c index b3bd3123..11a0d0f0 100644 --- a/src/cairo-path-data.c +++ b/src/cairo-path-data.c @@ -37,7 +37,7 @@ #include "cairo-path-fixed-private.h" #include "cairo-gstate-private.h" -cairo_path_t cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 }; +const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 }; /* Closure for path interpretation. */ typedef struct cairo_path_data_count { @@ -346,7 +346,7 @@ _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed, path = malloc (sizeof (cairo_path_t)); if (path == NULL) - return &cairo_path_nil; + return (cairo_path_t*) &_cairo_path_nil; path->num_data = _cairo_path_data_count (path, path_fixed, gstate->tolerance, flatten); @@ -354,7 +354,7 @@ _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed, path->data = malloc (path->num_data * sizeof (cairo_path_data_t)); if (path->data == NULL) { free (path); - return &cairo_path_nil; + return (cairo_path_t*) &_cairo_path_nil; } path->status = CAIRO_STATUS_SUCCESS; @@ -382,7 +382,7 @@ _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed, void cairo_path_destroy (cairo_path_t *path) { - if (path == NULL || path == &cairo_path_nil) + if (path == NULL || path == &_cairo_path_nil) return; free (path->data); diff --git a/src/cairo.c b/src/cairo.c index 9df4574f..ef8aa3c8 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -2261,7 +2261,7 @@ cairo_path_t * cairo_copy_path (cairo_t *cr) { if (cr->status) - return &cairo_path_nil; + return (cairo_path_t*) &_cairo_path_nil; return _cairo_path_data_create (&cr->path, cr->gstate); } @@ -2300,7 +2300,7 @@ cairo_path_t * cairo_copy_path_flat (cairo_t *cr) { if (cr->status) - return &cairo_path_nil; + return (cairo_path_t*) &_cairo_path_nil; else return _cairo_path_data_create_flat (&cr->path, cr->gstate); } -- cgit v1.2.3 From e59d1dff7f8096c497ca4e70df1259b16c264f25 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 10:40:32 +0000 Subject: Ignore cairo-clip-private.h. Drop non-existent cairo-atsui.xml. Fix misnamed parameters in comment blocks. Include config.h so HAVE_UNISTD_H gets picked up as necessary. --- ChangeLog | 16 ++++++++++++++++ doc/public/Makefile.am | 1 + doc/public/cairo-docs.xml | 1 - src/cairo-font.c | 7 ++----- test/cairo-test.c | 4 ++++ 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c719db5b..5382a926 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-08-05 Carl Worth + + * doc/public/Makefile.am: Ignore cairo-clip-private.h. + + * doc/public/cairo-docs.xml: Drop non-existent cairo-atsui.xml. + + * src/cairo-font.c: Fix misnamed parameters in comment blocks. + + * test/cairo-test.c: Include config.h so HAVE_UNISTD_H gets + picked up as necessary. + +2005-08-05 Carl Worth + + * doc/public/Makefile.am (IGNORE_HFILES): Ignore + cairo-clip-private.h. + 2005-08-05 Carl Worth * doc/public/cairo-sections.txt: Add some missing declarations to diff --git a/doc/public/Makefile.am b/doc/public/Makefile.am index a9faef84..fdd421cb 100644 --- a/doc/public/Makefile.am +++ b/doc/public/Makefile.am @@ -20,6 +20,7 @@ CFILE_GLOB=$(top_srcdir)/src/*.c $(top_srcdir)/src/*.h # Headers to ignore IGNORE_HFILES= \ + cairo-clip-private.h \ cairo-features.h \ cairo-font-subset-private.h \ cairo-ft-private.h \ diff --git a/doc/public/cairo-docs.xml b/doc/public/cairo-docs.xml index 729738aa..5270f950 100644 --- a/doc/public/cairo-docs.xml +++ b/doc/public/cairo-docs.xml @@ -13,7 +13,6 @@ - diff --git a/src/cairo-font.c b/src/cairo-font.c index c510bb55..db4ad731 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -125,7 +125,7 @@ cairo_font_face_destroy (cairo_font_face_t *font_face) /** * cairo_font_face_status: - * @surface: a #cairo_font_face_t + * @font_face: a #cairo_font_face_t * * Checks whether an error has previously occurred for this * font face @@ -505,7 +505,7 @@ _cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font, /** * cairo_scaled_font_status: - * @surface: a #cairo_scaled_font_t + * @scaled_font: a #cairo_scaled_font_t * * Checks whether an error has previously occurred for this * scaled_font. @@ -1107,9 +1107,6 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font) * @extents: a #cairo_font_extents_t which to store the retrieved extents. * * Gets the metrics for a #cairo_scaled_font_t. - * - * Return value: %CAIRO_STATUS_SUCCESS on success. Otherwise, an - * error such as %CAIRO_STATUS_NO_MEMORY. **/ void cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font, diff --git a/test/cairo-test.c b/test/cairo-test.c index 284a1d7b..6759c849 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -23,6 +23,10 @@ * Author: Carl D. Worth */ +#if HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include -- cgit v1.2.3 From 7d88cdd15bbf8ccb82b7bd45313396ea6f93054f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 10:43:07 +0000 Subject: Remove unused variable. --- ChangeLog | 4 ++++ test/surface-finish-twice.c | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5382a926..0ddefc4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2005-08-05 Carl Worth + * test/surface-finish-twice.c (draw): Remove unused variable. + +2005-08-05 Carl Worth + * doc/public/Makefile.am: Ignore cairo-clip-private.h. * doc/public/cairo-docs.xml: Drop non-existent cairo-atsui.xml. diff --git a/test/surface-finish-twice.c b/test/surface-finish-twice.c index ce4f0659..ad6c0e94 100644 --- a/test/surface-finish-twice.c +++ b/test/surface-finish-twice.c @@ -52,7 +52,6 @@ static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_surface_t *surface; - cairo_status_t status; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); -- cgit v1.2.3 From 2e1eaa88ff07fbd2048c76587cd6b9ca565fa047 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 10:46:40 +0000 Subject: Remove CAIRO_BEGIN_DECLS and CAIRO_END_DECLS which don't belong here. --- ChangeLog | 5 +++++ doc/public/cairo-sections.txt | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ddefc4d..fd0152ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-05 Carl Worth + + * doc/public/cairo-sections.txt: Remove CAIRO_BEGIN_DECLS and + CAIRO_END_DECLS which don't belong here. + 2005-08-05 Carl Worth * test/surface-finish-twice.c (draw): Remove unused variable. diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index 93125722..1c0edccb 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -302,8 +302,6 @@ cairo_read_func_t cairo_write_func_t cairo_debug_reset_static_data -CAIRO_BEGIN_DECLS -CAIRO_END_DECLS cairo_current_font_extents cairo_get_font_extents cairo_current_operator -- cgit v1.2.3 From 5f78feda5d9819f82ff99911b90cd09e228466a9 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 11:15:04 +0000 Subject: rewrite buffer_diff to be endian safe and add a new fuction buffer_diff_noalpha --- ChangeLog | 7 +++++ test/buffer-diff.c | 83 +++++++++++++++++++++++++++++++++++++----------------- test/buffer-diff.h | 14 ++++++++- 3 files changed, 77 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd0152ab..3863d93e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-08-05 Jeff Muizelaar + + * test/buffer-diff.c: (buffer_diff_core), (buffer_diff), + (buffer_diff_noalpha): + * test/buffer-diff.h: rewrite buffer_diff to be endian safe + and add a new fuction buffer_diff_noalpha + 2005-08-05 Carl Worth * doc/public/cairo-sections.txt: Remove CAIRO_BEGIN_DECLS and diff --git a/test/buffer-diff.c b/test/buffer-diff.c index 8e0031b1..78284efc 100644 --- a/test/buffer-diff.c +++ b/test/buffer-diff.c @@ -33,6 +33,7 @@ #endif #include #include +#include #include "cairo-test.h" @@ -51,18 +52,27 @@ xunlink (const char *pathname) } } -int -buffer_diff (unsigned char *buf_a, - unsigned char *buf_b, - unsigned char *buf_diff, - int width, - int height, - int stride) + +/* This function should be rewritten to compare all formats supported by + * cairo_format_t instead of taking a mask as a parameter. + */ +static int +buffer_diff_core (unsigned char *_buf_a, + unsigned char *_buf_b, + unsigned char *_buf_diff, + int width, + int height, + int stride, + pixman_bits_t mask) { int x, y; - unsigned char *row_a, *row_b, *row; + pixman_bits_t *row_a, *row_b, *row; int pixels_changed = 0; + pixman_bits_t *buf_a = (pixman_bits_t*)_buf_a; + pixman_bits_t *buf_b = (pixman_bits_t*)_buf_b; + pixman_bits_t *buf_diff = (pixman_bits_t*)_buf_diff; + stride /= sizeof(pixman_bits_t); for (y = 0; y < height; y++) { row_a = buf_a + y * stride; @@ -70,33 +80,54 @@ buffer_diff (unsigned char *buf_a, row = buf_diff + y * stride; for (x = 0; x < width; x++) { - int channel; - unsigned char value_a, value_b; - int pixel_differs = 0; - for (channel = 0; channel < 4; channel++) - { - double diff; - value_a = row_a[x * 4 + channel]; - value_b = row_b[x * 4 + channel]; - if (value_a != value_b) - pixel_differs = 1; - diff = value_a - value_b; - row[x * 4 + channel] = 128 + diff / 3.0; - } - if (pixel_differs) { + /* check if the pixels are the same */ + if ((row_a[x] & mask) != (row_b[x] & mask)) { + int channel; + pixman_bits_t diff_pixel = 0; + + /* calculate a difference value for all 4 channels */ + for (channel = 0; channel < 4; channel++) { + unsigned char value_a = (row_a[x] >> (channel*8)); + unsigned char value_b = (row_b[x] >> (channel*8)); + double diff; + diff = value_a - value_b; + diff_pixel |= (unsigned char)(128 + diff / 3.0) << (channel*8); + } + pixels_changed++; + row[x] = diff_pixel; } else { - row[x*4+0] = 0; - row[x*4+1] = 0; - row[x*4+2] = 0; + row[x] = 0; } - row[x * 4 + 3] = 0xff; /* Set ALPHA to 100% (opaque) */ + row[x] |= 0xff000000; /* Set ALPHA to 100% (opaque) */ } } return pixels_changed; } +int +buffer_diff (unsigned char *buf_a, + unsigned char *buf_b, + unsigned char *buf_diff, + int width, + int height, + int stride) +{ + return buffer_diff_core(buf_a, buf_b, buf_diff, width, height, stride, 0xffffffff); +} + +int +buffer_diff_noalpha (unsigned char *buf_a, + unsigned char *buf_b, + unsigned char *buf_diff, + int width, + int height, + int stride) +{ + return buffer_diff_core(buf_a, buf_b, buf_diff, width, height, stride, 0x00ffffff); +} + /* Image comparison code courtesy of Richard Worth * Returns number of pixels changed, (or -1 on error). * Also saves a "diff" image intended to visually show where the diff --git a/test/buffer-diff.h b/test/buffer-diff.h index a02834f3..2734713a 100644 --- a/test/buffer-diff.h +++ b/test/buffer-diff.h @@ -26,7 +26,7 @@ #ifndef BUFFER_DIFF_H #define BUFFER_DIFF_H -/* Returns number of pixels changed, (or -1 on error). +/* Returns number of pixels changed. * Also fills in a "diff" buffer intended to visually show where the * images differ. */ @@ -38,6 +38,18 @@ buffer_diff (unsigned char *buf_a, int height, int stride); +/* Returns number of pixels changed ignoring the alpha channel. + * Also fills in a "diff" buffer intended to visually show where the + * images differ. + */ +int +buffer_diff_noalpha (unsigned char *buf_a, + unsigned char *buf_b, + unsigned char *buf_diff, + int width, + int height, + int stride); + /* Returns number of pixels changed, (or -1 on error). * Also saves a "diff" image intended to visually show where the * images differ. -- cgit v1.2.3 From 594ba3ef69509d9c13258449f4b636bc52d77cd4 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 11:23:51 +0000 Subject: use the newly added buffer_diff_noalpha for comparing buffers of CAIRO_FORMAT_RGB24. --- ChangeLog | 6 ++++++ test/xlib-surface.c | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3863d93e..4f9e1bd0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-08-05 Jeff Muizelaar + + * test/xlib-surface.c: (do_test): use the newly added + buffer_diff_noalpha for comparing buffers of + CAIRO_FORMAT_RGB24. + 2005-08-05 Jeff Muizelaar * test/buffer-diff.c: (buffer_diff_core), (buffer_diff), diff --git a/test/xlib-surface.c b/test/xlib-surface.c index 805ce18f..0df5514f 100644 --- a/test/xlib-surface.c +++ b/test/xlib-surface.c @@ -155,19 +155,19 @@ do_test (Display *dpy, if (offscreen) { size_t offset = 4 * (SIZE * OFFSCREEN_OFFSET + OFFSCREEN_OFFSET); - result = !buffer_diff (reference_data + offset, - test_data + offset, - diff_data + offset, - SIZE - OFFSCREEN_OFFSET, - SIZE - OFFSCREEN_OFFSET, - 4 * SIZE); + result = !buffer_diff_noalpha (reference_data + offset, + test_data + offset, + diff_data + offset, + SIZE - OFFSCREEN_OFFSET, + SIZE - OFFSCREEN_OFFSET, + 4 * SIZE); } else { - result = !buffer_diff (reference_data, - test_data, - diff_data, - SIZE, - SIZE, - 4 * SIZE); + result = !buffer_diff_noalpha (reference_data, + test_data, + diff_data, + SIZE, + SIZE, + 4 * SIZE); } fprintf (log_file, "xlib-surface: %s, %s, %s%s: %s\n", -- cgit v1.2.3 From 2b20b7a23022a22a460b9441984ccdb7fdce5061 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 11:44:49 +0000 Subject: Fix up the fast-path compositing operators; those are useful for sources without alpha, but can't be used for sources with alpha. Also, replaced fbCompositeSrcSrc_nxn with call to fbBlt as this function must handle 1, 4, 8, 16, 24, 32 bpp objects. Would be nice to optimize fbBlt for common cases involving 8, 16, 24 and 32bpp. From Keith Packard. --- pixman/ChangeLog | 17 +++ pixman/src/ic.c | 432 +++++++++++++++++++++++++++++-------------------------- 2 files changed, 244 insertions(+), 205 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 06402abd..e7ff8a9c 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,20 @@ +2005-08-05 Jeff Muizelaar + + * src/ic.c: (fbCompositeSolidMask_nx8x8888), + (fbCompositeSolidMask_nx8x0888), (fbCompositeSolidMask_nx8x0565), + (fbCompositeSolidMask_nx8888x0565), + (fbCompositeSolidMask_nx8888x0565C), (fbCompositeSrc_8888x0565), + (fbCompositeTrans_0565xnx0565), (fbCompositeTrans_0888xnx0888), + (fbCompositeSrcSrc_nxn), (pixman_composite): + Fix up the fast-path compositing operators; those are useful + for sources without alpha, but can't be used for sources with + alpha. Also, replaced fbCompositeSrcSrc_nxn with call to + fbBlt as this function must handle 1, 4, 8, 16, 24, 32 bpp + objects. Would be nice to optimize fbBlt for common cases + involving 8, 16, 24 and 32bpp. + + From Keith Packard. + 2005-08-01 Billy Biggs * src/fbedge.c: (clip255), (add_saturate_8), diff --git a/pixman/src/ic.c b/pixman/src/ic.c index 327b39b6..20643ea8 100644 --- a/pixman/src/ic.c +++ b/pixman/src/ic.c @@ -26,7 +26,7 @@ #define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \ (((s) >> 5) & 0x07e0) | \ (((s) >> 8) & 0xf800)) -#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ +#define cvt0565to0888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \ ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \ ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) @@ -121,7 +121,7 @@ fbIn24 (CARD32 x, CARD8 y) break; \ case 16: \ (bits) = *(CARD16 *) __bits__; \ - (bits) = cvt0565to8888(bits); \ + (bits) = cvt0565to0888(bits); \ break; \ case 8: \ (bits) = *(CARD8 *) __bits__; \ @@ -152,25 +152,31 @@ fbIn24 (CARD32 x, CARD8 y) #define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d))) -#define fastcombine32(alpha, source, destval, destptr) { \ +/* + * This macro does src IN mask OVER dst when src and dst are 0888. + * If src has alpha, this will not work + */ +#define inOver0888(alpha, source, destval, dest) { \ CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \ CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \ - *destptr++=((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ + dest =((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00)); \ } -/* Note: this macro expects 5 bits of alpha, not 8! - * (single op can actually be changed to take 6 bits, but double op can't) +/* + * This macro does src IN mask OVER dst when src and dst are 0565 and + * mask is a 5-bit alpha value. Again, if src has alpha, this will not + * work. */ -#define fastCombine0565(alpha, source, destval, destptr) { \ +#define inOver0565(alpha, source, destval, dest) { \ CARD16 dstrb = destval & 0xf81f; CARD16 dstg = destval & 0x7e0; \ CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \ - destptr= ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5) + dstg) & 0x7e0)); \ + dest = ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5) + dstg) & 0x7e0)); \ } -#define fastCombine2x0565(alpha, source, destval, destptr) { \ +#define inOver2x0565(alpha, source, destval, dest) { \ CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg = (destval & 0xf81f07e0)>>5; \ CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \ - destptr= ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5) + dstg)<<5) & 0xf81f07e0)); \ + dest = ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5) + dstg)<<5) & 0xf81f07e0)); \ } #if IMAGE_BYTE_ORDER == LSBFirst @@ -234,7 +240,7 @@ fbCompositeSolidMask_nx8x8888 (pixman_operator_t op, fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - + while (height--) { dst = dstLine; @@ -353,7 +359,6 @@ fbCompositeSolidMask_nx8x0888 (pixman_operator_t op, { CARD32 src, srca, srcia; CARD8 *dstLine, *dst, *edst; - CARD32 d; CARD8 *maskLine, *mask, m; FbStride dstStride, maskStride; CARD16 w; @@ -447,62 +452,149 @@ fbCompositeSolidMask_nx8x0565 (pixman_operator_t op, CARD16 width, CARD16 height) { - CARD32 src, srca,na, rsrca; + CARD32 src, srca8, srca5; CARD16 *dstLine, *dst; CARD16 d; + CARD32 t; CARD8 *maskLine, *mask, m; FbStride dstStride, maskStride; CARD16 w,src16; fbComposeGetSolid(pSrc, src); - src16 = cvt8888to0565(src); - - rsrca = src >> 24; - srca=rsrca>>3; + if (src == 0) - return; + return; + + srca8 = (src >> 24); + srca5 = (srca8 >> 3); + + src16 = cvt8888to0565(src); fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - - while (height--) - { - dst = dstLine; - dstLine += dstStride; - mask = maskLine; - maskLine += maskStride; - w = width; + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; - while (w--) + while (w--) + { + m = *mask++; + if (m == 0) + dst++; + else if (srca5 == (0xff >> 3)) + { + if (m == 0xff) + *dst++ = src16; + else { - m = *mask++; - if (m == 0xff) - { - if (srca == 0xff) - { - *dst=src16; - } - else - { - d = *dst; - fastCombine0565(srca, src16, d, *dst++); - } - } - else if (m) - { - na=(rsrca*(int)m)>>11; - d = *dst; - fastCombine0565(na, src16, d, *dst++); - } - else - dst++; + d = *dst; + m >>= 3; + inOver0565 (m, src16, d, *dst++); } + } + else + { + d = *dst; + if (m == 0xff) + { + t = fbOver24 (src, cvt0565to0888 (d)); + } + else + { + t = fbIn (src, m); + t = fbOver (t, cvt0565to0888 (d)); + } + *dst++ = cvt8888to0565 (t); + } } + } } +static void +fbCompositeSolidMask_nx8888x0565 (pixman_operator_t op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + CARD32 src, srca8, srca5; + CARD16 *dstLine, *dst; + CARD16 d; + CARD32 *maskLine, *mask; + CARD32 t; + CARD8 m; + FbStride dstStride, maskStride; + CARD16 w, src16; + + fbComposeGetSolid(pSrc, src); + + if (src == 0) + return; + + srca8 = src >> 24; + srca5 = srca8 >> 3; + src16 = cvt8888to0565(src); + + fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); + fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1); + + while (height--) + { + dst = dstLine; + dstLine += dstStride; + mask = maskLine; + maskLine += maskStride; + w = width; + + while (w--) + { + m = *mask++ >> 24; + if (m == 0) + dst++; + else if (srca5 == (0xff >> 3)) + { + if (m == 0xff) + *dst++ = src16; + else + { + d = *dst; + m >>= 3; + inOver0565 (m, src16, d, *dst++); + } + } + else + { + if (m == 0xff) + { + d = *dst; + t = fbOver24 (src, cvt0565to0888 (d)); + *dst++ = cvt8888to0565 (t); + } + else + { + d = *dst; + t = fbIn (src, m); + t = fbOver (t, cvt0565to0888 (d)); + *dst++ = cvt8888to0565 (t); + } + } + } + } +} static void -fbCompositeSolidMask_nx8888x0565C (pixman_operator_t op, +fbCompositeSolidMask_nx8888x0565C (pixman_operator_t op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, @@ -555,14 +647,14 @@ fbCompositeSolidMask_nx8888x0565C (pixman_operator_t op, else { d = *dst; - d = fbOver24 (src, cvt0565to8888(d)); + d = fbOver24 (src, cvt0565to0888(d)); *dst = cvt8888to0565(d); } } else if (ma) { d = *dst; - d = cvt0565to8888(d); + d = cvt0565to0888(d); FbInOverC (src, srca, ma, d, 0, m); FbInOverC (src, srca, ma, d, 8, n); FbInOverC (src, srca, ma, d, 16, o); @@ -712,7 +804,7 @@ fbCompositeSrc_8888x0565 (pixman_operator_t op, else { d = *dst; - d = fbOver24 (s, cvt0565to8888(d)); + d = fbOver24 (s, cvt0565to0888(d)); } *dst = cvt8888to0565(d); } @@ -721,41 +813,7 @@ fbCompositeSrc_8888x0565 (pixman_operator_t op, } } -static void -fbCompositeSrc_0565x0565 (pixman_operator_t op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - CARD16 *dstLine, *dst; - CARD16 *srcLine, *src; - FbStride dstStride, srcStride; - CARD16 w; - - fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1); - fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1); - - while (height--) - { - dst = dstLine; - dstLine += dstStride; - src = srcLine; - srcLine += srcStride; - w = width; - - while (w--) - *dst++ = *src++; - } -} static void fbCompositeSrcAdd_8000x8000 (pixman_operator_t op, @@ -971,10 +1029,23 @@ fbCompositeSolidMask_nx1xn (pixman_operator_t op, 0x0); } +/* prototype to help with merging */ +static void +fbCompositeSrcSrc_nxn (pixman_operator_t op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); /* * Apply a constant alpha value in an over computation */ - static void fbCompositeTrans_0565xnx0565(pixman_operator_t op, PicturePtr pSrc, @@ -995,8 +1066,8 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, CARD16 w; FbBits mask; CARD8 maskAlpha; - CARD16 s_16, d_16, r_16; - CARD32 s_32, d_32, i_32, r_32; + CARD16 s_16, d_16; + CARD32 s_32, d_32; fbComposeGetSolid (pMask, mask); maskAlpha = mask >> 27; @@ -1005,9 +1076,9 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, return; if (maskAlpha == 0xff) { - fbCompositeSrc_0565x0565 (op, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, yDst, - width, height); + fbCompositeSrcSrc_nxn (PIXMAN_OPERATOR_SRC, pSrc, pMask, pDst, + xSrc, ySrc, xMask, yMask, xDst, yDst, + width, height); return; } @@ -1027,7 +1098,7 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, { s_16 = *src++; d_16 = *dst; - fastCombine0565(maskAlpha, s_16, d_16, *dst++); + inOver0565(maskAlpha, s_16, d_16, *dst++); w--; } isrc=(CARD32 *)src; @@ -1038,38 +1109,39 @@ fbCompositeTrans_0565xnx0565(pixman_operator_t op, { s_32 = *isrc++; d_32 = *idst; - fastCombine2x0565(maskAlpha,s_32,d_32,*idst++); + inOver2x0565(maskAlpha,s_32,d_32,*idst++); w-=2; } dst=(CARD16 *)idst; } else { - if(w>1) - { + while (w > 1) + { + s_32 = *isrc++; #if IMAGE_BYTE_ORDER == LSBFirst s_16=s_32&0xffff; #else s_16=s_32>>16; #endif d_16 = *dst; - fastCombine0565(maskAlpha, s_16, d_16, *dst++); + inOver0565(maskAlpha, s_16, d_16, *dst++); #if IMAGE_BYTE_ORDER == LSBFirst s_16=s_32>>16; #else s_16=s_32&0xffff; #endif - d_16 = *dst; - fastCombine0565(maskAlpha, s_16, d_16, *dst++); - w-=2; - } + d_16 = *dst; + inOver0565(maskAlpha, s_16, d_16, *dst++); + w-=2; + } } src=(CARD16 *)isrc; if(w!=0) { s_16 = *src; d_16 = *dst; - fastCombine0565(maskAlpha, s_16, d_16, *dst); + inOver0565(maskAlpha, s_16, d_16, *dst); } } } @@ -1119,7 +1191,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op, fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3); { - unsigned int ws,wt,ww; + unsigned int ws,wt; CARD32 workingSource; CARD32 *wsrc, *wdst, *widst; CARD32 rs, rd, nd; @@ -1185,7 +1257,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op, readPackedSource(rs); nd|=rs; #endif - fastcombine32(maskAlpha, nd, rd, wdst) + inOver0888(maskAlpha, nd, rd, *wdst++) w-=4; } dst=(CARD8 *)wdst; @@ -1238,7 +1310,7 @@ fbCompositeTrans_0888xnx0888(pixman_operator_t op, { rs = *wsrc++; rd = *widst; - fastcombine32(maskAlpha, rs, rd, widst); + inOver0888(maskAlpha, rs, rd, *widst++); w-=4; } src=(CARD8 *)wsrc; @@ -1280,85 +1352,34 @@ fbCompositeSrcSrc_nxn (pixman_operator_t op, { FbBits *dst; FbBits *src; - CARD8 *isrc; - CARD8 *idst; - int dstStride, srcStride; - int srcXoff, srcYoff; - int dstXoff, dstYoff; - int srcBpp; - int dstBpp; - /* these need to be signed now! */ - int iwidth=width; - int iheight=height; - int bytesPerPixel; - int initialWidth=width; - int initialX=xDst; - - /* FIXME: this is possibly the second worst piece of code I've ever written. - * (the worst being the previous imlementation of this) - * -- jj - */ - - Bool srcRepeat=pSrc->repeat; - CARD32 srcHeight=pSrc->pDrawable->height; - CARD32 srcWidth=pSrc->pDrawable->width; + FbStride dstStride, srcStride; + int srcXoff, srcYoff; + int dstXoff, dstYoff; + int srcBpp; + int dstBpp; + Bool reverse = FALSE; + Bool upsidedown = FALSE; + + FbGetPixels(pSrc->pixels,src,srcStride,srcBpp,srcXoff,srcYoff); + FbGetPixels(pDst->pixels,dst,dstStride,dstBpp,dstXoff,dstYoff); - FbGetPixels(pSrc->pixels,src,srcStride,srcBpp,srcXoff,srcYoff); - FbGetPixels(pDst->pixels,dst,dstStride,dstBpp,dstXoff,dstYoff); - - src+=(srcXoff+(srcYoff*srcStride)); - dst+=(dstXoff+(dstYoff*dstStride)); - - isrc=(CARD8 *)src; - idst=(CARD8 *)dst; + fbBlt (src + (ySrc + srcYoff) * srcStride, + srcStride, + (xSrc + srcXoff) * srcBpp, - bytesPerPixel=(srcBpp>>3); - srcStride*=sizeof(FbBits); - dstStride*=sizeof(FbBits); - if(srcRepeat) - { - xSrc%=srcWidth; - ySrc%=srcHeight; - } - - while(iheight>0) - { - int wheight=iheight; - if(wheight>(srcHeight-ySrc)) - wheight=(srcHeight-ySrc); - iwidth=initialWidth; - xDst=initialX; - while(iwidth>0) - { - int wwidth=iwidth; - int j; - if(wwidth>(srcWidth-xSrc)) - wwidth=(srcWidth-xSrc); - - for(j=0;jformat_code) { + case PICT_r5g6b5: + func = fbCompositeSolidMask_nx8888x0565; + break; + } + } break; case PICT_a8b8g8r8: if (pMask->componentAlpha) { @@ -1498,6 +1527,14 @@ pixman_composite (pixman_operator_t op, break; } } + else + { + switch (pDst->format_code) { + case PICT_r5g6b5: + func = fbCompositeSolidMask_nx8888x0565; + break; + } + } break; case PICT_a1: switch (pDst->format_code) { @@ -1540,7 +1577,14 @@ pixman_composite (pixman_operator_t op, } else { - switch (pSrc->format_code) { + /* + * Formats without alpha bits are just Copy with Over + */ + if (pSrc->format_code == pDst->format_code && !PICT_FORMAT_A(pSrc->format_code)) + { + func = fbCompositeSrcSrc_nxn; + } + else switch (pSrc->format_code) { case PICT_a8r8g8b8: switch (pDst->format_code) { case PICT_a8r8g8b8: @@ -1569,20 +1613,6 @@ pixman_composite (pixman_operator_t op, break; } break; - case PICT_r5g6b5: - switch (pDst->format_code) { - case PICT_r5g6b5: - func = fbCompositeSrc_0565x0565; - break; - } - break; - case PICT_b5g6r5: - switch (pDst->format_code) { - case PICT_b5g6r5: - func = fbCompositeSrc_0565x0565; - break; - } - break; } } break; @@ -1641,14 +1671,6 @@ pixman_composite (pixman_operator_t op, n = pixman_region_num_rects (region); pbox = pixman_region_rects (region); - /* FIXME: this is bascially a "white list" of composites that work - * with repeat until they are all implented. Once that's done, we - * remove the checks below entirely - */ - if(func==fbCompositeSrcSrc_nxn) - { - srcRepeat=maskRepeat=FALSE; - } while (n--) { h = pbox->y2 - pbox->y1; -- cgit v1.2.3 From 3ef2488265a1671d42224f4dca1b62c007ef5b0a Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 12:14:12 +0000 Subject: Fix some of the 4 bit per channel PICT definitions Patch from Billy Biggs . --- pixman/ChangeLog | 6 ++++++ pixman/src/icint.h | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index e7ff8a9c..4cb1244e 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,9 @@ +2005-08-05 Jeff Muizelaar + + * src/icint.h: Fix some of the 4 bit per channel PICT definitions + + Patch from Billy Biggs . + 2005-08-05 Jeff Muizelaar * src/ic.c: (fbCompositeSolidMask_nx8x8888), diff --git a/pixman/src/icint.h b/pixman/src/icint.h index 7567388f..1a1dc700 100644 --- a/pixman/src/icint.h +++ b/pixman/src/icint.h @@ -929,9 +929,9 @@ typedef struct _PictFormat *PictFormatPtr; #define PICT_a1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,1,5,5,5) #define PICT_x1b5g5r5 PICT_FORMAT(16,PICT_TYPE_ABGR,0,5,5,5) #define PICT_a4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4) -#define PICT_x4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4) -#define PICT_a4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4) -#define PICT_x4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ARGB,4,4,4,4) +#define PICT_x4r4g4b4 PICT_FORMAT(16,PICT_TYPE_ARGB,0,4,4,4) +#define PICT_a4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ABGR,4,4,4,4) +#define PICT_x4b4g4r4 PICT_FORMAT(16,PICT_TYPE_ABGR,0,4,4,4) /* 8bpp formats */ #define PICT_a8 PICT_FORMAT(8,PICT_TYPE_A,8,0,0,0) -- cgit v1.2.3 From ec93e241b0cf161216dab27eeee3917a71230aa7 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 12:26:33 +0000 Subject: Fix fbGetDrawable Patch from Billy Biggs . --- pixman/ChangeLog | 6 ++++++ pixman/src/pixman-xserver-compat.h | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 4cb1244e..ae22cd98 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,9 @@ +2005-08-05 Jeff Muizelaar + + * src/pixman-xserver-compat.h: Fix fbGetDrawable + + Patch from Billy Biggs . + 2005-08-05 Jeff Muizelaar * src/icint.h: Fix some of the 4 bit per channel PICT definitions diff --git a/pixman/src/pixman-xserver-compat.h b/pixman/src/pixman-xserver-compat.h index 35238768..c92ba668 100644 --- a/pixman/src/pixman-xserver-compat.h +++ b/pixman/src/pixman-xserver-compat.h @@ -78,10 +78,10 @@ typedef pixman_triangle_t xTriangle; /* XXX: We changed some function and field names which makes for some * ugly hacks... */ #define pDrawable pixels -#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ +#define fbGetDrawable(pDrawable, buf, outstride, outbpp, xoff, yoff) { \ (buf) = (pDrawable)->data; \ - (stride) = ((int) pDrawable->stride) / sizeof (pixman_bits_t); \ - (bpp) = (pDrawable)->bpp; \ + (outstride) = ((int) pDrawable->stride) / sizeof (pixman_bits_t); \ + (outbpp) = (pDrawable)->bpp; \ (xoff) = 0; \ (yoff) = 0; \ } -- cgit v1.2.3 From 549b7ff2a66335dc18434790895d4b4a25a76ba4 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 15:01:55 +0000 Subject: Bump automake_min_vers up to 1.7 since we clearly don't work with 1.4 anymore. --- ChangeLog | 5 +++++ autogen.sh | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f9e1bd0..2a0d7753 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-05 Carl Worth + + * autogen.sh (automake_min_vers): Bump automake_min_vers up to 1.7 + since we clearly don't work with 1.4 anymore. + 2005-08-05 Jeff Muizelaar * test/xlib-surface.c: (do_test): use the newly added diff --git a/autogen.sh b/autogen.sh index ae8acc60..8dd21ea6 100755 --- a/autogen.sh +++ b/autogen.sh @@ -14,8 +14,7 @@ AUTOCONF=${AUTOCONF-autoconf} # automake 1.8 requires autoconf 2.58 # automake 1.7 requires autoconf 2.54 -# I don't know what automake 1.4 wants, but the following seems to work... -automake_min_vers=1.4 +automake_min_vers=1.7 aclocal_min_vers=$automake_min_vers autoconf_min_vers=2.54 libtoolize_min_vers=1.4 -- cgit v1.2.3 From 53bd9879bb802606789be76e5653e2fb6781f676 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 15:07:45 +0000 Subject: Add a test case for CAIRO_FORMAT_A8 masks that fails with libpixman. --- ChangeLog | 8 ++++++ test/Makefile.am | 4 +++ test/a8-mask-ref.png | Bin 0 -> 128 bytes test/a8-mask.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 test/a8-mask-ref.png create mode 100644 test/a8-mask.c diff --git a/ChangeLog b/ChangeLog index 2a0d7753..3d6bf61c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-08-05 Jeff Muizelaar + + * test/Makefile.am: + * test/a8-mask-ref.png: + * test/a8-mask.c: (draw), (main): + Add a test case for CAIRO_FORMAT_A8 masks that fails with + libpixman. + 2005-08-05 Carl Worth * autogen.sh (automake_min_vers): Bump automake_min_vers up to 1.7 diff --git a/test/Makefile.am b/test/Makefile.am index bdbf5856..8a2db852 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,5 +1,6 @@ # All test cases go here TESTS = \ +a8-mask \ clip-nesting \ clip-twice \ composite-integer-translate-source \ @@ -59,6 +60,7 @@ endif # I really don't like having to repeat this list. Anyone know a good # way to avoid it? Can I use a wildcard here? EXTRA_DIST = \ +a8-mask.png \ clip-nesting-ref.png \ clip-twice-ref.png \ composite-integer-translate-source-ref.png \ @@ -110,6 +112,7 @@ rel-path-ref.png # Also, any test listed here should call cairo_test_expect_failure and # provide an explanation for the expected failure. XFAIL_TESTS = \ +a8-mask \ filter-nearest-offset \ pixman-rotate \ self-intersecting \ @@ -148,6 +151,7 @@ LDADDS = libcairotest.la $(top_builddir)/src/libcairo.la # ARGH! I have to repeat the list of tests a third time. Maybe it's # time to break down and auto-generate the Makefile.am or something # from autogen.sh. My, but this is painful... +a8_mask_LDADD = $(LDADDS) clip_nesting_LDADD = $(LDADDS) clip_twice_LDADD = $(LDADDS) composite_integer_translate_source_LDADD = $(LDADDS) diff --git a/test/a8-mask-ref.png b/test/a8-mask-ref.png new file mode 100644 index 00000000..38556156 Binary files /dev/null and b/test/a8-mask-ref.png differ diff --git a/test/a8-mask.c b/test/a8-mask.c new file mode 100644 index 00000000..e255c4ff --- /dev/null +++ b/test/a8-mask.c @@ -0,0 +1,71 @@ +/* + * Copyright © Jeff Muizelaar + * + * 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 + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * JEFF MUIZELAAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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: Jeff Muizelaar + */ + +#include "cairo-test.h" + +cairo_test_t test = { + "a8-mask", + "test masks of CAIRO_FORMAT_A8", + 8, 8 +}; + +static unsigned char mask[] = { + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, + 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0 +}; + + + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_surface_t *image; + cairo_pattern_t *pattern; + + cairo_set_source_rgb (cr, 0, 0, 1); + cairo_paint (cr); + + image = cairo_image_surface_create_for_data (mask, CAIRO_FORMAT_A8, + 7, 8, 7); + pattern = cairo_pattern_create_for_surface (image); + + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_mask (cr, pattern); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test_expect_failure (&test, draw, + "only image fails"); +} -- cgit v1.2.3 From 5925e3520fbf6223804d5c5e81698d7cdd888620 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 15:48:42 +0000 Subject: Patch memory leaks. --- ChangeLog | 4 ++++ test/a8-mask.c | 15 ++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3d6bf61c..54eca88e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-08-05 Carl Worth + + * test/a8-mask.c (draw): Patch memory leaks. + 2005-08-05 Jeff Muizelaar * test/Makefile.am: diff --git a/test/a8-mask.c b/test/a8-mask.c index e255c4ff..2895037e 100644 --- a/test/a8-mask.c +++ b/test/a8-mask.c @@ -42,24 +42,25 @@ static unsigned char mask[] = { 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0 }; - - static cairo_test_status_t draw (cairo_t *cr, int width, int height) { - cairo_surface_t *image; + cairo_surface_t *surface; cairo_pattern_t *pattern; cairo_set_source_rgb (cr, 0, 0, 1); cairo_paint (cr); - image = cairo_image_surface_create_for_data (mask, CAIRO_FORMAT_A8, - 7, 8, 7); - pattern = cairo_pattern_create_for_surface (image); + surface = cairo_image_surface_create_for_data (mask, CAIRO_FORMAT_A8, + 7, 8, 7); + pattern = cairo_pattern_create_for_surface (surface); cairo_set_source_rgb (cr, 1, 0, 0); cairo_mask (cr, pattern); + cairo_pattern_destroy (pattern); + cairo_surface_destroy (surface); + return CAIRO_TEST_SUCCESS; } @@ -67,5 +68,5 @@ int main (void) { return cairo_test_expect_failure (&test, draw, - "only image fails"); + "image backend fails (unknown cause)"); } -- cgit v1.2.3 From 8d0452c1ee7ba7466b7bb06ec5c4e9746fce2482 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 15:49:52 +0000 Subject: ignore a8-mask --- ChangeLog | 4 ++++ test/.cvsignore | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 54eca88e..b98c0beb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-08-05 Carl Worth + + * test/.cvsignore: ignore a8-mask + 2005-08-05 Carl Worth * test/a8-mask.c (draw): Patch memory leaks. diff --git a/test/.cvsignore b/test/.cvsignore index 557831c0..e228c3e6 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -2,6 +2,7 @@ .libs Makefile Makefile.in +a8-mask clip-nesting clip-twice composite-integer-translate-source -- cgit v1.2.3 From 76f80cc42e442abaf52d6582d16be91258f3f8a9 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 16:44:20 +0000 Subject: Rename scaled_font_backend->create to create_toy. Move declaration of cairo_simple_font_face_t from cairo_font.c to cairoint.h and rename it cairo_toy_font_face_t. Rework create_toy to accept a cairo_toy_font_face_t rather than separate family, slant, and weight. Track change in create_toy interface. Partial rename of simple->toy. It's not complete as this is a step in the process of merging in a large patch of mine which actually removes most of the affected code. --- ChangeLog | 22 ++++++++++++++++++++++ src/cairo-atsui-font.c | 21 +++++++++------------ src/cairo-font.c | 33 ++++++++++----------------------- src/cairo-ft-font.c | 21 ++++++++++----------- src/cairo-win32-font.c | 21 ++++++++++----------- src/cairoint.h | 23 ++++++++++++++++------- 6 files changed, 77 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index b98c0beb..57d53491 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2005-08-05 Carl Worth + + * src/cairoint.h: Rename scaled_font_backend->create to + create_toy. Move declaration of cairo_simple_font_face_t from + cairo_font.c to cairoint.h and rename it + cairo_toy_font_face_t. Rework create_toy to accept a + cairo_toy_font_face_t rather than separate family, slant, and + weight. + + * src/cairo-atsui-font.c: (_cairo_atsui_font_create_toy): + * src/cairo-ft-font.c: (_cairo_ft_scaled_font_create_toy): + * src/cairo-win32-font.c: (_cairo_win32_scaled_font_create_toy): + Track change in create_toy interface. + + * src/cairo-font.c: (_cairo_toy_font_face_create_from_cache_key), + (_cairo_simple_font_cache_create_entry), + (_cairo_simple_font_face_destroy), + (_cairo_simple_font_face_create_font): + Partial rename of simple->toy. It's not complete as this is a step + in the process of merging in a large patch of mine which actually + removes most of the affected code. + 2005-08-05 Carl Worth * test/.cvsignore: ignore a8-mask diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c index 8792faa4..5dce70cd 100644 --- a/src/cairo-atsui-font.c +++ b/src/cairo-atsui-font.c @@ -105,13 +105,11 @@ CreateSizedCopyOfStyle(ATSUStyle inStyle, cairo_matrix_t *scale) static cairo_status_t -_cairo_atsui_font_create(const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **font_out) +_cairo_atsui_font_create_toy(const cairo_toy_font_face *toy_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **font_out) { cairo_atsui_font_t *font = NULL; ATSUStyle style; @@ -119,11 +117,11 @@ _cairo_atsui_font_create(const char *family, OSStatus err; Boolean isItalic, isBold; cairo_matrix_t scale; + const char *family = toy_face->family; err = ATSUCreateStyle(&style); - - switch (weight) { + switch (toy_face->weight) { case CAIRO_FONT_WEIGHT_BOLD: isBold = true; break; @@ -133,7 +131,7 @@ _cairo_atsui_font_create(const char *family, break; } - switch (slant) { + switch (toy_face->slant) { case CAIRO_FONT_SLANT_ITALIC: isItalic = true; break; @@ -214,7 +212,6 @@ _cairo_atsui_font_create(const char *family, return CAIRO_STATUS_SUCCESS; } - static void _cairo_atsui_font_destroy_font(void *abstract_font) { @@ -691,7 +688,7 @@ _cairo_atsui_font_glyph_path(void *abstract_font, } const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = { - _cairo_atsui_font_create, + _cairo_atsui_font_create_toy, _cairo_atsui_font_destroy_font, _cairo_atsui_font_font_extents, _cairo_atsui_font_text_to_glyphs, diff --git a/src/cairo-font.c b/src/cairo-font.c index db4ad731..c79cad8f 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -188,19 +188,6 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face, key, user_data, destroy); } -/* cairo_simple_font_face_t - simple family/slant/weight font faces used for - * the built-in font API - */ - -typedef struct _cairo_simple_font_face cairo_simple_font_face_t; - -struct _cairo_simple_font_face { - cairo_font_face_t base; - char *family; - cairo_font_slant_t slant; - cairo_font_weight_t weight; -}; - /* We maintain a global cache from family/weight/slant => cairo_font_face_t * for cairo_simple_font_t. The primary purpose of this cache is to provide * unique cairo_font_face_t values so that our cache from @@ -218,7 +205,7 @@ typedef struct { typedef struct { cairo_simple_cache_key_t key; - cairo_simple_font_face_t *font_face; + cairo_toy_font_face_t *font_face; } cairo_simple_cache_entry_t; static const cairo_cache_backend_t _cairo_simple_font_cache_backend; @@ -291,12 +278,12 @@ _cairo_simple_font_cache_keys_equal (void *cache, a->weight == b->weight; } -static cairo_simple_font_face_t * -_cairo_simple_font_face_create_from_cache_key (cairo_simple_cache_key_t *key) +static cairo_toy_font_face_t * +_cairo_toy_font_face_create_from_cache_key (cairo_simple_cache_key_t *key) { - cairo_simple_font_face_t *simple_face; + cairo_toy_font_face_t *simple_face; - simple_face = malloc (sizeof (cairo_simple_font_face_t)); + simple_face = malloc (sizeof (cairo_toy_font_face_t)); if (!simple_face) return NULL; @@ -326,7 +313,7 @@ _cairo_simple_font_cache_create_entry (void *cache, if (entry == NULL) return CAIRO_STATUS_NO_MEMORY; - entry->font_face = _cairo_simple_font_face_create_from_cache_key (k); + entry->font_face = _cairo_toy_font_face_create_from_cache_key (k); if (!entry->font_face) { free (entry); return CAIRO_STATUS_NO_MEMORY; @@ -372,7 +359,7 @@ static const cairo_cache_backend_t _cairo_simple_font_cache_backend = { static void _cairo_simple_font_face_destroy (void *abstract_face) { - cairo_simple_font_face_t *simple_face = abstract_face; + cairo_toy_font_face_t *simple_face = abstract_face; cairo_cache_t *cache; cairo_simple_cache_key_t key; @@ -403,10 +390,10 @@ _cairo_simple_font_face_create_font (void *abstract_face, { const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT; - cairo_simple_font_face_t *simple_face = abstract_face; + cairo_toy_font_face_t *simple_face = abstract_face; - return backend->create (simple_face->family, simple_face->slant, simple_face->weight, - font_matrix, ctm, options, scaled_font); + return backend->create_toy (simple_face, + font_matrix, ctm, options, scaled_font); } static const cairo_font_face_backend_t _cairo_simple_font_face_backend = { diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 5587b15a..412901fc 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -1410,13 +1410,11 @@ _cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font) } static cairo_status_t -_cairo_ft_scaled_font_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **font) +_cairo_ft_scaled_font_create_toy (const cairo_toy_font_face_t *toy_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **font) { FcPattern *pattern, *resolved; cairo_ft_unscaled_font_t *unscaled; @@ -1427,12 +1425,13 @@ _cairo_ft_scaled_font_create (const char *family, cairo_matrix_t scale; cairo_ft_font_transform_t sf; int load_flags; + unsigned char *family = (unsigned char*) toy_face->family; pattern = FcPatternCreate (); if (!pattern) return CAIRO_STATUS_NO_MEMORY; - switch (weight) + switch (toy_face->weight) { case CAIRO_FONT_WEIGHT_BOLD: fcweight = FC_WEIGHT_BOLD; @@ -1443,7 +1442,7 @@ _cairo_ft_scaled_font_create (const char *family, break; } - switch (slant) + switch (toy_face->slant) { case CAIRO_FONT_SLANT_ITALIC: fcslant = FC_SLANT_ITALIC; @@ -1457,7 +1456,7 @@ _cairo_ft_scaled_font_create (const char *family, break; } - if (!FcPatternAddString (pattern, FC_FAMILY, (unsigned char *) family)) + if (!FcPatternAddString (pattern, FC_FAMILY, family)) goto FREE_PATTERN; if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) goto FREE_PATTERN; @@ -2028,7 +2027,7 @@ _cairo_ft_scaled_font_glyph_path (void *abstract_font, } const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = { - _cairo_ft_scaled_font_create, + _cairo_ft_scaled_font_create_toy, _cairo_ft_scaled_font_destroy, _cairo_ft_scaled_font_font_extents, _cairo_ft_scaled_font_text_to_glyphs, diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index 2867ab15..f75fc752 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -427,13 +427,11 @@ _cairo_win32_scaled_font_done_unscaled_font (cairo_scaled_font_t *scaled_font) /* implement the font backend interface */ static cairo_status_t -_cairo_win32_scaled_font_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font_out) +_cairo_win32_scaled_font_create_toy (const cairo_toy_font_face_t *toy_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **scaled_font_out) { LOGFONTW logfont; cairo_scaled_font_t *scaled_font; @@ -441,7 +439,8 @@ _cairo_win32_scaled_font_create (const char *family, int face_name_len; cairo_status_t status; - status = _cairo_utf8_to_utf16 (family, -1, &face_name, &face_name_len); + status = _cairo_utf8_to_utf16 (toy_face->family, -1, + &face_name, &face_name_len); if (status) return status; @@ -458,7 +457,7 @@ _cairo_win32_scaled_font_create (const char *family, logfont.lfEscapement = 0; /* filled in later */ logfont.lfOrientation = 0; /* filled in later */ - switch (weight) { + switch (toy_face->weight) { case CAIRO_FONT_WEIGHT_NORMAL: default: logfont.lfWeight = FW_NORMAL; @@ -468,7 +467,7 @@ _cairo_win32_scaled_font_create (const char *family, break; } - switch (slant) { + switch (toy_face->slant) { case CAIRO_FONT_SLANT_NORMAL: default: logfont.lfItalic = FALSE; @@ -1272,7 +1271,7 @@ FAIL: } const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = { - _cairo_win32_scaled_font_create, + _cairo_win32_scaled_font_create_toy, _cairo_win32_scaled_font_destroy, _cairo_win32_scaled_font_font_extents, _cairo_win32_scaled_font_text_to_glyphs, diff --git a/src/cairoint.h b/src/cairoint.h index 74e58c96..8f69d935 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -559,14 +559,23 @@ struct _cairo_unscaled_font_backend { cairo_image_glyph_cache_entry_t *entry); }; +/* cairo_toy_font_face_t - simple family/slant/weight font faces used for + * the built-in font API + */ + +typedef struct _cairo_toy_font_face { + cairo_font_face_t base; + char *family; + cairo_font_slant_t slant; + cairo_font_weight_t weight; +} cairo_toy_font_face_t; + struct _cairo_scaled_font_backend { - cairo_status_t (*create) (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **font); + cairo_status_t (*create_toy) (const cairo_toy_font_face_t *toy_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **font); void (*destroy) (void *font); -- cgit v1.2.3 From b482e1e25e57c7ae1422f4737a2702d3cb53c0eb Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 17:00:38 +0000 Subject: Rename scaled_font_backend->destroy to the more accurate fini, (since it frees only the dependent data within the scaled_font and not the scaled_font itself). Track rename of scaled_font_backend->fini. --- ChangeLog | 12 ++++++++++++ src/cairo-atsui-font.c | 4 ++-- src/cairo-font.c | 2 +- src/cairo-ft-font.c | 4 ++-- src/cairo-win32-font.c | 4 ++-- src/cairoint.h | 2 +- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 57d53491..c68ecf50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2005-08-05 Carl Worth + + * src/cairoint.h: Rename scaled_font_backend->destroy to the more + accurate fini, (since it frees only the dependent data within the + scaled_font and not the scaled_font itself). + + * src/cairo-atsui-font.c: (_cairo_atsui_font_fini): + * src/cairo-font.c: (cairo_scaled_font_destroy): + * src/cairo-ft-font.c: (_cairo_ft_scaled_font_fini): + * src/cairo-win32-font.c: (_cairo_win32_scaled_font_fini): + Track rename of scaled_font_backend->fini. + 2005-08-05 Carl Worth * src/cairoint.h: Rename scaled_font_backend->create to diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c index 5dce70cd..8aff8cd6 100644 --- a/src/cairo-atsui-font.c +++ b/src/cairo-atsui-font.c @@ -213,7 +213,7 @@ _cairo_atsui_font_create_toy(const cairo_toy_font_face *toy_face, } static void -_cairo_atsui_font_destroy_font(void *abstract_font) +_cairo_atsui_font_fini(void *abstract_font) { cairo_atsui_font_t *font = abstract_font; @@ -689,7 +689,7 @@ _cairo_atsui_font_glyph_path(void *abstract_font, const cairo_scaled_font_backend_t cairo_atsui_scaled_font_backend = { _cairo_atsui_font_create_toy, - _cairo_atsui_font_destroy_font, + _cairo_atsui_font_fini, _cairo_atsui_font_font_extents, _cairo_atsui_font_text_to_glyphs, _cairo_atsui_font_glyph_extents, diff --git a/src/cairo-font.c b/src/cairo-font.c index c79cad8f..2caecc62 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -1083,7 +1083,7 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font) cairo_font_face_destroy (scaled_font->font_face); } - scaled_font->backend->destroy (scaled_font); + scaled_font->backend->fini (scaled_font); free (scaled_font); } diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 412901fc..5d77d20f 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -1507,7 +1507,7 @@ _cairo_ft_scaled_font_create_toy (const cairo_toy_font_face_t *toy_face, } static void -_cairo_ft_scaled_font_destroy (void *abstract_font) +_cairo_ft_scaled_font_fini (void *abstract_font) { cairo_ft_scaled_font_t *scaled_font = abstract_font; @@ -2028,7 +2028,7 @@ _cairo_ft_scaled_font_glyph_path (void *abstract_font, const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = { _cairo_ft_scaled_font_create_toy, - _cairo_ft_scaled_font_destroy, + _cairo_ft_scaled_font_fini, _cairo_ft_scaled_font_font_extents, _cairo_ft_scaled_font_text_to_glyphs, _cairo_ft_scaled_font_glyph_extents, diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index f75fc752..b048b912 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -503,7 +503,7 @@ _cairo_win32_scaled_font_create_toy (const cairo_toy_font_face_t *toy_face, } static void -_cairo_win32_scaled_font_destroy (void *abstract_font) +_cairo_win32_scaled_font_fini (void *abstract_font) { cairo_win32_scaled_font_t *scaled_font = abstract_font; @@ -1272,7 +1272,7 @@ FAIL: const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = { _cairo_win32_scaled_font_create_toy, - _cairo_win32_scaled_font_destroy, + _cairo_win32_scaled_font_fini, _cairo_win32_scaled_font_font_extents, _cairo_win32_scaled_font_text_to_glyphs, _cairo_win32_scaled_font_glyph_extents, diff --git a/src/cairoint.h b/src/cairoint.h index 8f69d935..056682bb 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -577,7 +577,7 @@ struct _cairo_scaled_font_backend { const cairo_font_options_t *options, cairo_scaled_font_t **font); - void (*destroy) (void *font); + void (*fini) (void *font); cairo_status_t (*font_extents) (void *font, cairo_font_extents_t *extents); -- cgit v1.2.3 From d150513c6af3a7d1f52d7251ab0d097337f40ab3 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 17:27:57 +0000 Subject: Rename parameters to scalend_font_backend from font to scaled_font. --- ChangeLog | 5 +++++ src/cairoint.h | 19 ++++++++++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index c68ecf50..84619e30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-05 Carl Worth + + * src/cairoint.h: Rename parameters to scalend_font_backend from + font to scaled_font. + 2005-08-05 Carl Worth * src/cairoint.h: Rename scaled_font_backend->destroy to the more diff --git a/src/cairoint.h b/src/cairoint.h index 056682bb..30ccd488 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -575,29 +575,29 @@ struct _cairo_scaled_font_backend { const cairo_matrix_t *font_matrix, const cairo_matrix_t *ctm, const cairo_font_options_t *options, - cairo_scaled_font_t **font); + cairo_scaled_font_t **scaled_font); - void (*fini) (void *font); + void (*fini) (void *scaled_font); - cairo_status_t (*font_extents) (void *font, + cairo_status_t (*font_extents) (void *scaled_font, cairo_font_extents_t *extents); - cairo_status_t (*text_to_glyphs) (void *font, + cairo_status_t (*text_to_glyphs) (void *scaled_font, const char *utf8, cairo_glyph_t **glyphs, int *num_glyphs); - cairo_status_t (*glyph_extents) (void *font, + cairo_status_t (*glyph_extents) (void *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, cairo_text_extents_t *extents); - cairo_status_t (*glyph_bbox) (void *font, + cairo_status_t (*glyph_bbox) (void *scaled_font, const cairo_glyph_t *glyphs, int num_glyphs, cairo_box_t *bbox); - cairo_status_t (*show_glyphs) (void *font, + cairo_status_t (*show_glyphs) (void *scaled_font, cairo_operator_t operator, cairo_pattern_t *pattern, cairo_surface_t *surface, @@ -610,11 +610,12 @@ struct _cairo_scaled_font_backend { const cairo_glyph_t *glyphs, int num_glyphs); - cairo_status_t (*glyph_path) (void *font, + cairo_status_t (*glyph_path) (void *scaled_font, cairo_glyph_t *glyphs, int num_glyphs, cairo_path_fixed_t *path); - void (*get_glyph_cache_key) (void *font, + + void (*get_glyph_cache_key) (void *scaled_font, cairo_glyph_cache_key_t *key); }; -- cgit v1.2.3 From 4ad365f1834bf0204e44156a62b8e8539fb65ef9 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 20:15:19 +0000 Subject: Document the implicit closing of sub-paths for cairo_fill and cairo_fill_preserve. --- ChangeLog | 5 +++++ src/cairo.c | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84619e30..362a5719 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-05 Carl Worth + + * src/cairo.c: Document the implicit closing of sub-paths for + cairo_fill and cairo_fill_preserve. + 2005-08-05 Carl Worth * src/cairoint.h: Rename parameters to scalend_font_backend from diff --git a/src/cairo.c b/src/cairo.c index ef8aa3c8..f0eebab9 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1405,8 +1405,9 @@ slim_hidden_def(cairo_stroke_preserve); * @cr: a cairo context * * A drawing operator that fills the current path according to the - * current fill rule. After cairo_fill, the current path will be - * cleared from the cairo context. See cairo_set_fill_rule() and + * current fill rule, (each sub-path is implicitly closed before being + * filled). After cairo_fill, the current path will be cleared from + * the cairo context. See cairo_set_fill_rule() and * cairo_fill_preserve(). **/ void @@ -1422,8 +1423,9 @@ cairo_fill (cairo_t *cr) * @cr: a cairo context * * A drawing operator that fills the current path according to the - * current fill rule. Unlike cairo_fill(), cairo_fill_preserve - * preserves the path within the cairo context. + * current fill rule, (each sub-path is implicitly closed before being + * filled). Unlike cairo_fill(), cairo_fill_preserve preserves the + * path within the cairo context. * * See cairo_set_fill_rule() and cairo_fill(). **/ -- cgit v1.2.3 From 9c1fe21cd70bed9fd9e77ec757751df723cb9c42 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 20:30:43 +0000 Subject: Rather gratuitous (though mostly harmless) whitespace changes for font backend tables. --- ChangeLog | 5 +++ src/cairoint.h | 104 ++++++++++++++++++++++++++++++++------------------------- 2 files changed, 63 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 362a5719..54197bb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-05 Carl Worth + + * src/cairoint.h: Rather gratuitous (though mostly harmless) + whitespace changes for font backend tables. + 2005-08-05 Carl Worth * src/cairo.c: Document the implicit closing of sub-paths for diff --git a/src/cairoint.h b/src/cairoint.h index 30ccd488..31978e70 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -571,64 +571,76 @@ typedef struct _cairo_toy_font_face { } cairo_toy_font_face_t; struct _cairo_scaled_font_backend { - cairo_status_t (*create_toy) (const cairo_toy_font_face_t *toy_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font); - - void (*fini) (void *scaled_font); + cairo_status_t + (*create_toy) (const cairo_toy_font_face_t *toy_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **scaled_font); + + void + (*fini) (void *scaled_font); - cairo_status_t (*font_extents) (void *scaled_font, - cairo_font_extents_t *extents); + cairo_status_t + (*font_extents) (void *scaled_font, + cairo_font_extents_t *extents); - cairo_status_t (*text_to_glyphs) (void *scaled_font, - const char *utf8, - cairo_glyph_t **glyphs, - int *num_glyphs); + cairo_status_t + (*text_to_glyphs) (void *scaled_font, + const char *utf8, + cairo_glyph_t **glyphs, + int *num_glyphs); - cairo_status_t (*glyph_extents) (void *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents); + cairo_status_t + (*glyph_extents) (void *scaled_font, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_text_extents_t *extents); - cairo_status_t (*glyph_bbox) (void *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_box_t *bbox); - - cairo_status_t (*show_glyphs) (void *scaled_font, - cairo_operator_t operator, - cairo_pattern_t *pattern, - cairo_surface_t *surface, - int source_x, - int source_y, - int dest_x, - int dest_y, - unsigned int width, - unsigned int height, - const cairo_glyph_t *glyphs, - int num_glyphs); + cairo_status_t + (*glyph_bbox) (void *scaled_font, + const cairo_glyph_t *glyphs, + int num_glyphs, + cairo_box_t *bbox); + + cairo_status_t + (*show_glyphs) (void *scaled_font, + cairo_operator_t operator, + cairo_pattern_t *pattern, + cairo_surface_t *surface, + int source_x, + int source_y, + int dest_x, + int dest_y, + unsigned int width, + unsigned int height, + const cairo_glyph_t *glyphs, + int num_glyphs); - cairo_status_t (*glyph_path) (void *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_fixed_t *path); + cairo_status_t + (*glyph_path) (void *scaled_font, + cairo_glyph_t *glyphs, + int num_glyphs, + cairo_path_fixed_t *path); - void (*get_glyph_cache_key) (void *scaled_font, - cairo_glyph_cache_key_t *key); + void + (*get_glyph_cache_key) (void *scaled_font, + cairo_glyph_cache_key_t *key); }; struct _cairo_font_face_backend { /* The destroy() function is allowed to resurrect the font face * by re-referencing. This is needed for the FreeType backend. */ - void (*destroy) (void *font_face); - cairo_status_t (*create_font) (void *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font); + void + (*destroy) (void *font_face); + + cairo_status_t + (*create_font) (void *font_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **scaled_font); }; /* concrete font backends */ -- cgit v1.2.3 From c14f2252b1b3a4499e65c13a146b9f8c5e9c5550 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 20:53:09 +0000 Subject: Rename font_face_backend->create_font to scaled_font_create. Group the scaled_font prototypes together. A little more simple -> toy renaming. A little more simple -> toy renaming. Track rename of font_face_backend->scaled_font_create. --- ChangeLog | 19 +++++++++++++++++++ src/cairo-font.c | 42 +++++++++++++++++++++--------------------- src/cairo-ft-font.c | 14 +++++++------- src/cairo-gstate.c | 8 ++++---- src/cairo-win32-font.c | 14 +++++++------- src/cairoint.h | 30 +++++++++++++++--------------- 6 files changed, 73 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index 54197bb8..07211897 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2005-08-05 Carl Worth + + * src/cairoint.h: Rename font_face_backend->create_font to + scaled_font_create. Group the scaled_font prototypes together. A + little more simple -> toy renaming. + + * src/cairo-font.c: (_cairo_toy_font_face_create_from_cache_key), + (_cairo_toy_font_face_destroy), + (_cairo_toy_font_face_create): + * src/cairo-gstate.c: (_cairo_gstate_select_font_face), + (_cairo_gstate_ensure_font_face): + A little more simple -> toy renaming. + + * src/cairo-font.c: (_cairo_toy_font_face_scaled_font_create), + (_cairo_inner_font_cache_create_entry): + * src/cairo-ft-font.c: (_cairo_ft_font_face_scaled_font_create): + * src/cairo-win32-font.c: (_cairo_win32_font_face_scaled_font_create): + Track rename of font_face_backend->scaled_font_create. + 2005-08-05 Carl Worth * src/cairoint.h: Rather gratuitous (though mostly harmless) diff --git a/src/cairo-font.c b/src/cairo-font.c index 2caecc62..10fcb5f5 100644 --- a/src/cairo-font.c +++ b/src/cairo-font.c @@ -42,7 +42,7 @@ /* Forward declare so we can use it as an arbitrary backend for * _cairo_font_face_nil. */ -static const cairo_font_face_backend_t _cairo_simple_font_face_backend; +static const cairo_font_face_backend_t _cairo_toy_font_face_backend; /* cairo_font_face_t */ @@ -50,7 +50,7 @@ const cairo_font_face_t _cairo_font_face_nil = { CAIRO_STATUS_NO_MEMORY, /* status */ -1, /* ref_count */ { 0, 0, 0, NULL }, /* user_data */ - &_cairo_simple_font_face_backend + &_cairo_toy_font_face_backend }; void @@ -296,7 +296,7 @@ _cairo_toy_font_face_create_from_cache_key (cairo_simple_cache_key_t *key) simple_face->slant = key->slant; simple_face->weight = key->weight; - _cairo_font_face_init (&simple_face->base, &_cairo_simple_font_face_backend); + _cairo_font_face_init (&simple_face->base, &_cairo_toy_font_face_backend); return simple_face; } @@ -357,7 +357,7 @@ static const cairo_cache_backend_t _cairo_simple_font_cache_backend = { }; static void -_cairo_simple_font_face_destroy (void *abstract_face) +_cairo_toy_font_face_destroy (void *abstract_face) { cairo_toy_font_face_t *simple_face = abstract_face; cairo_cache_t *cache; @@ -382,11 +382,11 @@ _cairo_simple_font_face_destroy (void *abstract_face) } static cairo_status_t -_cairo_simple_font_face_create_font (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font) +_cairo_toy_font_face_scaled_font_create (void *abstract_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **scaled_font) { const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT; @@ -396,13 +396,13 @@ _cairo_simple_font_face_create_font (void *abstract_face, font_matrix, ctm, options, scaled_font); } -static const cairo_font_face_backend_t _cairo_simple_font_face_backend = { - _cairo_simple_font_face_destroy, - _cairo_simple_font_face_create_font, +static const cairo_font_face_backend_t _cairo_toy_font_face_backend = { + _cairo_toy_font_face_destroy, + _cairo_toy_font_face_scaled_font_create }; /** - * _cairo_simple_font_face_create: + * _cairo_toy_font_face_create: * @family: a font family name, encoded in UTF-8 * @slant: the slant for the font * @weight: the weight for the font @@ -415,9 +415,9 @@ static const cairo_font_face_backend_t _cairo_simple_font_face_backend = { * cairo_font_face_destroy() **/ cairo_font_face_t * -_cairo_simple_font_face_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) +_cairo_toy_font_face_create (const char *family, + cairo_font_slant_t slant, + cairo_font_weight_t weight) { cairo_simple_cache_entry_t *entry; cairo_simple_cache_key_t key; @@ -738,11 +738,11 @@ _cairo_inner_font_cache_create_entry (void *cache, if (entry == NULL) return CAIRO_STATUS_NO_MEMORY; - status = k->font_face->backend->create_font (k->font_face, - k->font_matrix, - k->ctm, - &k->options, - &entry->scaled_font); + status = k->font_face->backend->scaled_font_create (k->font_face, + k->font_matrix, + k->ctm, + &k->options, + &entry->scaled_font); if (status) { free (entry); return status; diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 5d77d20f..5520b20f 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2035,7 +2035,7 @@ const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend = { _cairo_ft_scaled_font_glyph_bbox, _cairo_ft_scaled_font_show_glyphs, _cairo_ft_scaled_font_glyph_path, - _cairo_ft_scaled_font_get_glyph_cache_key, + _cairo_ft_scaled_font_get_glyph_cache_key }; /* ft_font_face_t */ @@ -2095,11 +2095,11 @@ _cairo_ft_font_face_destroy (void *abstract_face) } static cairo_status_t -_cairo_ft_font_face_create_font (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font) +_cairo_ft_font_face_scaled_font_create (void *abstract_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **scaled_font) { cairo_ft_font_face_t *font_face = abstract_face; int load_flags; @@ -2129,7 +2129,7 @@ _cairo_ft_font_face_create_font (void *abstract_face, static const cairo_font_face_backend_t _ft_font_face_backend = { _cairo_ft_font_face_destroy, - _cairo_ft_font_face_create_font, + _cairo_ft_font_face_scaled_font_create }; static cairo_font_face_t * diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index f38d76ca..8820b761 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1403,7 +1403,7 @@ _cairo_gstate_select_font_face (cairo_gstate_t *gstate, { cairo_font_face_t *font_face; - font_face = _cairo_simple_font_face_create (family, slant, weight); + font_face = _cairo_toy_font_face_create (family, slant, weight); if (font_face->status) return font_face->status; @@ -1557,9 +1557,9 @@ _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate) if (!gstate->font_face) { cairo_font_face_t *font_face; - font_face = _cairo_simple_font_face_create (CAIRO_FONT_FAMILY_DEFAULT, - CAIRO_FONT_SLANT_DEFAULT, - CAIRO_FONT_WEIGHT_DEFAULT); + font_face = _cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT, + CAIRO_FONT_SLANT_DEFAULT, + CAIRO_FONT_WEIGHT_DEFAULT); if (font_face->status) return font_face->status; else diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index b048b912..51dab1b7 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -1279,7 +1279,7 @@ const cairo_scaled_font_backend_t cairo_win32_scaled_font_backend = { _cairo_win32_scaled_font_glyph_bbox, _cairo_win32_scaled_font_show_glyphs, _cairo_win32_scaled_font_glyph_path, - _cairo_win32_scaled_font_get_glyph_cache_key, + _cairo_win32_scaled_font_get_glyph_cache_key }; /* cairo_win32_font_face_t */ @@ -1299,11 +1299,11 @@ _cairo_win32_font_face_destroy (void *abstract_face) } static cairo_status_t -_cairo_win32_font_face_create_font (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **font) +_cairo_win32_font_face_scaled_font_create (void *abstract_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **font) { cairo_win32_font_face_t *font_face = abstract_face; @@ -1317,7 +1317,7 @@ _cairo_win32_font_face_create_font (void *abstract_face, static const cairo_font_face_backend_t _cairo_win32_font_face_backend = { _cairo_win32_font_face_destroy, - _cairo_win32_font_face_create_font, + _cairo_win32_font_face_scaled_font_create }; /** diff --git a/src/cairoint.h b/src/cairoint.h index 31978e70..3e90865d 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -636,11 +636,11 @@ struct _cairo_font_face_backend { (*destroy) (void *font_face); cairo_status_t - (*create_font) (void *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font); + (*scaled_font_create) (void *font_face, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + cairo_scaled_font_t **scaled_font); }; /* concrete font backends */ @@ -1364,16 +1364,9 @@ _cairo_font_face_init (cairo_font_face_t *font_face, const cairo_font_face_backend_t *backend); cairo_private cairo_font_face_t * -_cairo_simple_font_face_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight); - -cairo_private void -_cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - const cairo_scaled_font_backend_t *backend); +_cairo_toy_font_face_create (const char *family, + cairo_font_slant_t slant, + cairo_font_weight_t weight); cairo_private void _cairo_unscaled_font_init (cairo_unscaled_font_t *font, @@ -1385,6 +1378,13 @@ _cairo_unscaled_font_reference (cairo_unscaled_font_t *font); cairo_private void _cairo_unscaled_font_destroy (cairo_unscaled_font_t *font); +cairo_private void +_cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + const cairo_scaled_font_backend_t *backend); + cairo_private cairo_status_t _cairo_scaled_font_font_extents (cairo_scaled_font_t *scaled_font, cairo_font_extents_t *extents); -- cgit v1.2.3 From 75e3d2883409220350a688716c908bea7b6e2c13 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 21:02:25 +0000 Subject: Entagle the cairo_unscaled_font_t typedef. --- ChangeLog | 4 ++++ src/cairoint.h | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07211897..2b9399ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-08-05 Carl Worth + + * src/cairoint.h: Entagle the cairo_unscaled_font_t typedef. + 2005-08-05 Carl Worth * src/cairoint.h: Rename font_face_backend->create_font to diff --git a/src/cairoint.h b/src/cairoint.h index 3e90865d..c6717a43 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -454,8 +454,6 @@ _cairo_hash_string (const char *c); #define CAIRO_IMAGE_GLYPH_CACHE_MEMORY_DEFAULT 0x100000 #define CAIRO_XLIB_GLYPH_CACHE_MEMORY_DEFAULT 0x100000 -typedef struct _cairo_unscaled_font cairo_unscaled_font_t; - typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t; typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t; typedef struct _cairo_font_face_backend cairo_font_face_backend_t; @@ -464,10 +462,10 @@ typedef struct _cairo_font_face_backend cairo_font_face_backend_t; * A cairo_unscaled_font_t is just an opaque handle we use in the * glyph cache. */ -struct _cairo_unscaled_font { +typedef struct _cairo_unscaled_font { int ref_count; const cairo_unscaled_font_backend_t *backend; -}; +} cairo_unscaled_font_t; struct _cairo_font_options { cairo_antialias_t antialias; -- cgit v1.2.3 From 80b944418cab51fcc2178080fe0c9a5ffd512479 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 21:27:21 +0000 Subject: Rename two functions: _cairo_gstate_unset_font -> _cairo_gstate_unset_scaled_font _cairo_gstate_ensure_font -> _cairo_gstate_ensure_scaled_font --- ChangeLog | 17 +++++++++++++++++ src/cairo-gstate.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b9399ed..1606e454 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2005-08-05 Carl Worth + + * src/cairo-gstate.c: (_cairo_gstate_translate), + (_cairo_gstate_scale), (_cairo_gstate_rotate), + (_cairo_gstate_transform), (_cairo_gstate_set_matrix), + (_cairo_gstate_identity_matrix), (_cairo_gstate_unset_scaled_font), + (_cairo_gstate_set_font_size), (_cairo_gstate_set_font_matrix), + (_cairo_gstate_set_font_options), + (_cairo_gstate_ensure_scaled_font), + (_cairo_gstate_get_font_extents), (_cairo_gstate_text_to_glyphs), + (_cairo_gstate_set_font_face), (_cairo_gstate_glyph_extents), + (_cairo_gstate_show_glyphs), (_cairo_gstate_glyph_path): + Rename two functions: + + _cairo_gstate_unset_font -> _cairo_gstate_unset_scaled_font + _cairo_gstate_ensure_font -> _cairo_gstate_ensure_scaled_font + 2005-08-05 Carl Worth * src/cairoint.h: Entagle the cairo_unscaled_font_t typedef. diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 8820b761..d07051c4 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -57,13 +57,13 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, cairo_traps_t *traps); static cairo_status_t -_cairo_gstate_ensure_font (cairo_gstate_t *gstate); +_cairo_gstate_ensure_font_face (cairo_gstate_t *gstate); static cairo_status_t -_cairo_gstate_ensure_font_face (cairo_gstate_t *gstate); +_cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate); static void -_cairo_gstate_unset_font (cairo_gstate_t *gstate); +_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate); cairo_gstate_t * _cairo_gstate_create (cairo_surface_t *target) @@ -474,7 +474,7 @@ _cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty) { cairo_matrix_t tmp; - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_translate (&tmp, tx, ty); cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); @@ -493,7 +493,7 @@ _cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy) if (sx == 0 || sy == 0) return CAIRO_STATUS_INVALID_MATRIX; - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_scale (&tmp, sx, sy); cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); @@ -509,7 +509,7 @@ _cairo_gstate_rotate (cairo_gstate_t *gstate, double angle) { cairo_matrix_t tmp; - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_rotate (&tmp, angle); cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); @@ -526,7 +526,7 @@ _cairo_gstate_transform (cairo_gstate_t *gstate, { cairo_matrix_t tmp; - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); tmp = *matrix; cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); @@ -543,7 +543,7 @@ _cairo_gstate_set_matrix (cairo_gstate_t *gstate, { cairo_status_t status; - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); gstate->ctm = *matrix; @@ -558,7 +558,7 @@ _cairo_gstate_set_matrix (cairo_gstate_t *gstate, cairo_status_t _cairo_gstate_identity_matrix (cairo_gstate_t *gstate) { - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_identity (&gstate->ctm); cairo_matrix_init_identity (&gstate->ctm_inverse); @@ -1387,7 +1387,7 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path) } static void -_cairo_gstate_unset_font (cairo_gstate_t *gstate) +_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate) { if (gstate->scaled_font) { cairo_scaled_font_destroy (gstate->scaled_font); @@ -1417,7 +1417,7 @@ cairo_status_t _cairo_gstate_set_font_size (cairo_gstate_t *gstate, double size) { - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); cairo_matrix_init_scale (&gstate->font_matrix, size, size); @@ -1428,7 +1428,7 @@ cairo_status_t _cairo_gstate_set_font_matrix (cairo_gstate_t *gstate, const cairo_matrix_t *matrix) { - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); gstate->font_matrix = *matrix; @@ -1446,7 +1446,7 @@ cairo_status_t _cairo_gstate_set_font_options (cairo_gstate_t *gstate, const cairo_font_options_t *options) { - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); gstate->font_options = *options; @@ -1570,7 +1570,7 @@ _cairo_gstate_ensure_font_face (cairo_gstate_t *gstate) } static cairo_status_t -_cairo_gstate_ensure_font (cairo_gstate_t *gstate) +_cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate) { cairo_status_t status; cairo_font_options_t options; @@ -1600,7 +1600,7 @@ cairo_status_t _cairo_gstate_get_font_extents (cairo_gstate_t *gstate, cairo_font_extents_t *extents) { - cairo_status_t status = _cairo_gstate_ensure_font (gstate); + cairo_status_t status = _cairo_gstate_ensure_scaled_font (gstate); if (status) return status; @@ -1620,7 +1620,7 @@ _cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate, cairo_status_t status; int i; - status = _cairo_gstate_ensure_font (gstate); + status = _cairo_gstate_ensure_scaled_font (gstate); if (status) return status; @@ -1660,7 +1660,7 @@ _cairo_gstate_set_font_face (cairo_gstate_t *gstate, cairo_font_face_reference (gstate->font_face); } - _cairo_gstate_unset_font (gstate); + _cairo_gstate_unset_scaled_font (gstate); return CAIRO_STATUS_SUCCESS; } @@ -1673,7 +1673,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, { cairo_status_t status; - status = _cairo_gstate_ensure_font (gstate); + status = _cairo_gstate_ensure_scaled_font (gstate); if (status) return status; @@ -1703,7 +1703,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, if (status) return status; - status = _cairo_gstate_ensure_font (gstate); + status = _cairo_gstate_ensure_scaled_font (gstate); if (status) return status; @@ -1841,7 +1841,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, int i; cairo_glyph_t *transformed_glyphs = NULL; - status = _cairo_gstate_ensure_font (gstate); + status = _cairo_gstate_ensure_scaled_font (gstate); if (status) return status; -- cgit v1.2.3 From 417a66da5e8a98583661d08703a5c5562732678a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 21:33:41 +0000 Subject: Simplify the implementation by taking advantage of the fact that destroy and reference are safe for NULL, and that reference returns its argument. --- ChangeLog | 7 +++++++ src/cairo-gstate.c | 7 ++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1606e454..a653655a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-08-05 Carl Worth + + * src/cairo-gstate.c: (_cairo_gstate_set_font_face): Simplify the + implementation by taking advantage of the fact that destroy and + reference are safe for NULL, and that reference returns its + argument. + 2005-08-05 Carl Worth * src/cairo-gstate.c: (_cairo_gstate_translate), diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index d07051c4..916b701f 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1653,11 +1653,8 @@ _cairo_gstate_set_font_face (cairo_gstate_t *gstate, return font_face->status; if (font_face != gstate->font_face) { - if (gstate->font_face) - cairo_font_face_destroy (gstate->font_face); - gstate->font_face = font_face; - if (gstate->font_face) - cairo_font_face_reference (gstate->font_face); + cairo_font_face_destroy (gstate->font_face); + gstate->font_face = cairo_font_face_reference (font_face); } _cairo_gstate_unset_scaled_font (gstate); -- cgit v1.2.3 From 71e560a8fa78d9fd6f83cce820de9f4acb3829eb Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 21:35:51 +0000 Subject: Temporarily disable the 24bpp WORKING_UNALIGNED_INT because of a crash when using electric-fence when accessing hte last pixel of a drawable (last pixel is 3 bytes, read it as a 4 byte word, and you're reading one extra pixel, which doesn't normally matter, but does in a few rare cases). Should be easy to work around, but that will come later. From jaymz --- pixman/ChangeLog | 11 +++++++++++ pixman/src/iccompose.c | 10 +++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index ae22cd98..9bc397df 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,14 @@ +2005-08-06 Jeff Muizelaar + + * src/iccompose.c: (fbFetch_r8g8b8): + Temporarily disable the 24bpp WORKING_UNALIGNED_INT because of a crash + when using electric-fence when accessing hte last pixel of a drawable + (last pixel is 3 bytes, read it as a 4 byte word, and you're reading one + extra pixel, which doesn't normally matter, but does in a few rare cases). + Should be easy to work around, but that will come later. + + From jaymz + 2005-08-05 Jeff Muizelaar * src/pixman-xserver-compat.h: Fix fbGetDrawable diff --git a/pixman/src/iccompose.c b/pixman/src/iccompose.c index 906f27b1..e96a740c 100644 --- a/pixman/src/iccompose.c +++ b/pixman/src/iccompose.c @@ -1561,14 +1561,18 @@ fbFetch_r8g8b8 (FbCompositeOperand *op) (pixel[1] << 8) | (pixel[2])); #else - #ifdef WORKING_UNALIGNED_INT +/* Read the changelog entry for 2004-02-24 before you turn this back on - the bug + * is incredibly rare, but if you're using a malloc() debugger, it can really + * ruin your day + */ +/* #ifdef WORKING_UNALIGNED_INT return *(CARD32 *)pixel|0xff000000; - #else + #else*/ return (0xff000000 | (pixel[2] << 16) | (pixel[1] << 8) | (pixel[0])); - #endif +/* #endif*/ #endif } -- cgit v1.2.3 From de87ebcc1c53d9daa4f77b618766215b1723778e Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 5 Aug 2005 22:17:08 +0000 Subject: Fix problems in render fb implementation found by rendercheck: - fbCombineSaturate was pointed at fbCombineDisjointOver, instead of fbCombineDisjointOverReverse as it should. Instead, point fbCombineDisjointOverReverse at fbCombineSaturate (which is likely to be faster). - fix previously-unused fbCombineSaturate implementation. - fbCombineMaskAlphaC was just a copy of fbCombineMaskValueC. Make it do what it's supposed to (return a cs.alpha). - fbCombineAtopC didn't invert the source alpha value. - fix copy'n'paste errors in fbCombine(Dis/Con)jointGeneralC, also source alpha wasn't treated in a component fashion. From anholt. --- pixman/ChangeLog | 20 +++++ pixman/src/iccompose.c | 195 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 156 insertions(+), 59 deletions(-) diff --git a/pixman/ChangeLog b/pixman/ChangeLog index 9bc397df..84757b07 100644 --- a/pixman/ChangeLog +++ b/pixman/ChangeLog @@ -1,3 +1,23 @@ +2005-08-06 Jeff Muizelaar + + * src/iccompose.c: (fbCombineMaskAlphaC), (fbCombineAtopC), + (fbCombineXorC), (fbCombineSaturateU), (fbCombineSaturateC), + (fbCombineDisjointGeneralC), (fbCombineConjointGeneralC): + Fix problems in render fb implementation found by rendercheck: + - fbCombineSaturate was pointed at fbCombineDisjointOver, instead of + fbCombineDisjointOverReverse as it should. Instead, point + fbCombineDisjointOverReverse at fbCombineSaturate (which is likely + to be faster). + - fix previously-unused fbCombineSaturate implementation. + - fbCombineMaskAlphaC was just a copy of fbCombineMaskValueC. Make + it do what it's supposed to (return a cs.alpha). + - fbCombineAtopC didn't invert the source alpha value. + - fix copy'n'paste errors in fbCombine(Dis/Con)jointGeneralC, also + source alpha wasn't treated in a component fashion. + + From anholt. + + 2005-08-06 Jeff Muizelaar * src/iccompose.c: (fbFetch_r8g8b8): diff --git a/pixman/src/iccompose.c b/pixman/src/iccompose.c index e96a740c..1bc490bb 100644 --- a/pixman/src/iccompose.c +++ b/pixman/src/iccompose.c @@ -186,15 +186,15 @@ fbCombineMaskAlphaC (FbCompositeOperand *src, a = (*msk->fetcha) (msk); if (!a) return 0; - - x = (*src->fetcha) (src); - if (a == 0xffffffff) - return x; - - m = FbInC(x,0,a,t); - n = FbInC(x,8,a,t); - o = FbInC(x,16,a,t); - p = FbInC(x,24,a,t); + + x = (*src->fetch) (src) >> 24; + if (x == 0xff) + return a; + + m = FbInU(a,0,x,t); + n = FbInU(a,8,x,t); + o = FbInU(a,16,x,t); + p = FbInU(a,24,x,t); return m|n|o|p; } @@ -603,7 +603,7 @@ fbCombineAtopC (FbCompositeOperand *src, cs = fbCombineMaskC (src, msk); d = (*dst->fetch) (dst); s = cs.value; - ad = cs.alpha; + ad = ~cs.alpha; as = d >> 24; m = FbGen(s,d,0,as,FbGet8(ad,0),t,u,v); n = FbGen(s,d,8,as,FbGet8(ad,8),t,u,v); @@ -693,10 +693,10 @@ fbCombineXorC (FbCompositeOperand *src, s = cs.value; ad = ~cs.alpha; as = ~d >> 24; - m = FbGen(s,d,0,as,ad,t,u,v); - n = FbGen(s,d,8,as,ad,t,u,v); - o = FbGen(s,d,16,as,ad,t,u,v); - p = FbGen(s,d,24,as,ad,t,u,v); + m = FbGen(s,d,0,as,FbGet8(ad,0),t,u,v); + n = FbGen(s,d,8,as,FbGet8(ad,8),t,u,v); + o = FbGen(s,d,16,as,FbGet8(ad,16),t,u,v); + p = FbGen(s,d,24,as,FbGet8(ad,24),t,u,v); (*dst->store) (dst, m|n|o|p); } @@ -752,6 +752,82 @@ fbCombineAddC (FbCompositeOperand *src, } } +static void +fbCombineSaturateU (FbCompositeOperand *src, + FbCompositeOperand *msk, + FbCompositeOperand *dst) +{ + CARD32 s = fbCombineMaskU (src, msk), d; + CARD16 sa, da; + CARD16 ad, as; + CARD16 t, u, v; + CARD32 m,n,o,p; + + d = (*dst->fetch) (dst); + sa = s >> 24; + da = ~d >> 24; + if (sa <= da) + { + m = FbAdd(s,d,0,t); + n = FbAdd(s,d,8,t); + o = FbAdd(s,d,16,t); + p = FbAdd(s,d,24,t); + } + else + { + as = (da << 8) / sa; + ad = 0xff; + m = FbGen(s,d,0,as,ad,t,u,v); + n = FbGen(s,d,8,as,ad,t,u,v); + o = FbGen(s,d,16,as,ad,t,u,v); + p = FbGen(s,d,24,as,ad,t,u,v); + } + (*dst->store) (dst, m|n|o|p); +} + +static void +fbCombineSaturateC (FbCompositeOperand *src, + FbCompositeOperand *msk, + FbCompositeOperand *dst) +{ + FbCompSrc cs; + CARD32 s, d; + CARD16 sa, sr, sg, sb, da; + CARD16 t, u, v; + CARD32 m,n,o,p; + + cs = fbCombineMaskC (src, msk); + d = (*dst->fetch) (dst); + s = cs.value; + sa = (cs.alpha >> 24) & 0xff; + sr = (cs.alpha >> 16) & 0xff; + sg = (cs.alpha >> 8) & 0xff; + sb = (cs.alpha ) & 0xff; + da = ~d >> 24; + + if (sb <= da) + m = FbAdd(s,d,0,t); + else + m = FbGen (s, d, 0, (da << 8) / sb, 0xff, t, u, v); + + if (sg <= da) + n = FbAdd(s,d,8,t); + else + n = FbGen (s, d, 8, (da << 8) / sg, 0xff, t, u, v); + + if (sr <= da) + o = FbAdd(s,d,16,t); + else + o = FbGen (s, d, 16, (da << 8) / sr, 0xff, t, u, v); + + if (sa <= da) + p = FbAdd(s,d,24,t); + else + p = FbGen (s, d, 24, (da << 8) / sa, 0xff, t, u, v); + + (*dst->store) (dst, m|n|o|p); +} + /* * All of the disjoint composing functions @@ -880,8 +956,8 @@ fbCombineDisjointGeneralC (FbCompositeOperand *src, FbCompSrc cs; CARD32 s, d; CARD32 m,n,o,p; - CARD32 Fa; - CARD16 Fb, t, u, v; + CARD32 Fa, Fb; + CARD16 t, u, v; CARD32 sa; CARD8 da; @@ -904,10 +980,10 @@ fbCombineDisjointGeneralC (FbCompositeOperand *src, Fa = m|n|o|p; break; case CombineAIn: - m = fbCombineDisjointOutPart ((CARD8) (sa >> 0), da); - n = fbCombineDisjointOutPart ((CARD8) (sa >> 8), da) << 8; - o = fbCombineDisjointOutPart ((CARD8) (sa >> 16), da) << 16; - p = fbCombineDisjointOutPart ((CARD8) (sa >> 24), da) << 24; + m = fbCombineDisjointInPart ((CARD8) (sa >> 0), da); + n = fbCombineDisjointInPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineDisjointInPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineDisjointInPart ((CARD8) (sa >> 24), da) << 24; Fa = m|n|o|p; break; case CombineA: @@ -920,19 +996,27 @@ fbCombineDisjointGeneralC (FbCompositeOperand *src, Fb = 0; break; case CombineBOut: - Fb = fbCombineDisjointOutPart (da, sa); + m = fbCombineDisjointOutPart (da, (CARD8) (sa >> 0)); + n = fbCombineDisjointOutPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineDisjointOutPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineDisjointOutPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineBIn: - Fb = fbCombineDisjointInPart (da, sa); + m = fbCombineDisjointInPart (da, (CARD8) (sa >> 0)); + n = fbCombineDisjointInPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineDisjointInPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineDisjointInPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineB: - Fb = 0xff; + Fb = 0xffffffff; break; } - m = FbGen (s,d,0,FbGet8(Fa,0),Fb,t,u,v); - n = FbGen (s,d,8,FbGet8(Fa,8),Fb,t,u,v); - o = FbGen (s,d,16,FbGet8(Fa,16),Fb,t,u,v); - p = FbGen (s,d,24,FbGet8(Fa,24),Fb,t,u,v); + m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t,u,v); + n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t,u,v); + o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t,u,v); + p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t,u,v); s = m|n|o|p; (*dst->store) (dst, s); } @@ -973,21 +1057,6 @@ fbCombineDisjointOverC (FbCompositeOperand *src, fbCombineDisjointGeneralC (src, msk, dst, CombineAOver); } -static void -fbCombineDisjointOverReverseU (FbCompositeOperand *src, - FbCompositeOperand *msk, - FbCompositeOperand *dst) -{ - fbCombineDisjointGeneralU (src, msk, dst, CombineBOver); -} - -static void -fbCombineDisjointOverReverseC (FbCompositeOperand *src, - FbCompositeOperand *msk, - FbCompositeOperand *dst) -{ - fbCombineDisjointGeneralC (src, msk, dst, CombineBOver); -} static void fbCombineDisjointInU (FbCompositeOperand *src, @@ -1189,8 +1258,8 @@ fbCombineConjointGeneralC (FbCompositeOperand *src, FbCompSrc cs; CARD32 s, d; CARD32 m,n,o,p; - CARD32 Fa; - CARD16 Fb, t, u, v; + CARD32 Fa, Fb; + CARD16 t, u, v; CARD32 sa; CARD8 da; @@ -1213,10 +1282,10 @@ fbCombineConjointGeneralC (FbCompositeOperand *src, Fa = m|n|o|p; break; case CombineAIn: - m = fbCombineConjointOutPart ((CARD8) (sa >> 0), da); - n = fbCombineConjointOutPart ((CARD8) (sa >> 8), da) << 8; - o = fbCombineConjointOutPart ((CARD8) (sa >> 16), da) << 16; - p = fbCombineConjointOutPart ((CARD8) (sa >> 24), da) << 24; + m = fbCombineConjointInPart ((CARD8) (sa >> 0), da); + n = fbCombineConjointInPart ((CARD8) (sa >> 8), da) << 8; + o = fbCombineConjointInPart ((CARD8) (sa >> 16), da) << 16; + p = fbCombineConjointInPart ((CARD8) (sa >> 24), da) << 24; Fa = m|n|o|p; break; case CombineA: @@ -1229,19 +1298,27 @@ fbCombineConjointGeneralC (FbCompositeOperand *src, Fb = 0; break; case CombineBOut: - Fb = fbCombineConjointOutPart (da, sa); + m = fbCombineConjointOutPart (da, (CARD8) (sa >> 0)); + n = fbCombineConjointOutPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineConjointOutPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineConjointOutPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineBIn: - Fb = fbCombineConjointInPart (da, sa); + m = fbCombineConjointInPart (da, (CARD8) (sa >> 0)); + n = fbCombineConjointInPart (da, (CARD8) (sa >> 8)) << 8; + o = fbCombineConjointInPart (da, (CARD8) (sa >> 16)) << 16; + p = fbCombineConjointInPart (da, (CARD8) (sa >> 24)) << 24; + Fb = m|n|o|p; break; case CombineB: - Fb = 0xff; + Fb = 0xffffffff; break; } - m = FbGen (s,d,0,FbGet8(Fa,0),Fb,t,u,v); - n = FbGen (s,d,8,FbGet8(Fa,8),Fb,t,u,v); - o = FbGen (s,d,16,FbGet8(Fa,16),Fb,t,u,v); - p = FbGen (s,d,24,FbGet8(Fa,24),Fb,t,u,v); + m = FbGen (s,d,0,FbGet8(Fa,0),FbGet8(Fb,0),t,u,v); + n = FbGen (s,d,8,FbGet8(Fa,8),FbGet8(Fb,8),t,u,v); + o = FbGen (s,d,16,FbGet8(Fa,16),FbGet8(Fb,16),t,u,v); + p = FbGen (s,d,24,FbGet8(Fa,24),FbGet8(Fb,24),t,u,v); s = m|n|o|p; (*dst->store) (dst, s); } @@ -1427,14 +1504,14 @@ static FbCombineFunc const fbCombineFuncU[] = { fbCombineAtopReverseU, fbCombineXorU, fbCombineAddU, - fbCombineDisjointOverU, /* Saturate */ + fbCombineSaturateU, 0, 0, fbCombineClear, fbCombineSrcU, fbCombineDst, fbCombineDisjointOverU, - fbCombineDisjointOverReverseU, + fbCombineSaturateU, /* DisjointOverReverse */ fbCombineDisjointInU, fbCombineDisjointInReverseU, fbCombineDisjointOutU, @@ -1474,14 +1551,14 @@ static FbCombineFunc const fbCombineFuncC[] = { fbCombineAtopReverseC, fbCombineXorC, fbCombineAddC, - fbCombineDisjointOverC, /* Saturate */ + fbCombineSaturateC, 0, 0, fbCombineClear, /* 0x10 */ fbCombineSrcC, fbCombineDst, fbCombineDisjointOverC, - fbCombineDisjointOverReverseC, + fbCombineSaturateC, /* DisjointOverReverse */ fbCombineDisjointInC, fbCombineDisjointInReverseC, fbCombineDisjointOutC, -- cgit v1.2.3 From cfcab8fe4467095381c7a4d32182580649db6f00 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 22:29:06 +0000 Subject: Include cairo-hash-private.h. Add cairo-hash.c and cairo-hash-private.h since we're actually going to start using them now. --- ChangeLog | 8 ++++++++ src/Makefile.am | 2 ++ src/cairoint.h | 2 ++ 3 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index a653655a..337aec80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2005-08-05 Carl Worth + + * src/cairoint.h: Include cairo-hash-private.h. + + * src/Makefile.am (libcairo_la_SOURCES): Add cairo-hash.c and + cairo-hash-private.h since we're actually going to start using + them now. + 2005-08-05 Carl Worth * src/cairo-gstate.c: (_cairo_gstate_set_font_face): Simplify the diff --git a/src/Makefile.am b/src/Makefile.am index a48cce5a..f71d09d9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -94,6 +94,8 @@ libcairo_la_SOURCES = \ cairo-font-options.c \ cairo-gstate.c \ cairo-gstate-private.h \ + cairo-hash.c \ + cairo-hash-private.h \ cairo-hull.c \ cairo-image-surface.c \ cairo-matrix.c \ diff --git a/src/cairoint.h b/src/cairoint.h index c6717a43..f6dabd81 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -189,6 +189,8 @@ typedef cairo_fixed_16_16_t cairo_fixed_t; #define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) >= ((double)0xff00 / (double)0xffff)) +#include "cairo-hash-private.h" + typedef struct _cairo_point { cairo_fixed_t x; cairo_fixed_t y; -- cgit v1.2.3 From ff147497e54ef7573b35bd023d11e4e7d4272979 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 22:35:04 +0000 Subject: Rename cairo_ft_font_face->next_face to next. --- ChangeLog | 6 ++++++ src/cairo-ft-font.c | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 337aec80..c4a9df20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-08-05 Carl Worth + + * src/cairo-ft-font.c: (_cairo_ft_font_face_destroy), + (_cairo_ft_font_face_create): Rename cairo_ft_font_face->next_face + to next. + 2005-08-05 Carl Worth * src/cairoint.h: Include cairo-hash-private.h. diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 5520b20f..2c18e1a1 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -116,7 +116,7 @@ struct _cairo_ft_font_face { cairo_font_face_t base; cairo_ft_unscaled_font_t *unscaled; int load_flags; - cairo_ft_font_face_t *next_face; + cairo_ft_font_face_t *next; }; const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend; @@ -2078,12 +2078,15 @@ _cairo_ft_font_face_destroy (void *abstract_face) if (font_face->unscaled) { /* Remove face from linked list */ - for (tmp_face = font_face->unscaled->faces; tmp_face; tmp_face = tmp_face->next_face) { + for (tmp_face = font_face->unscaled->faces; + tmp_face; + tmp_face = tmp_face->next) + { if (tmp_face == font_face) { if (last_face) - last_face->next_face = tmp_face->next_face; + last_face->next = tmp_face->next; else - font_face->unscaled->faces = tmp_face->next_face; + font_face->unscaled->faces = tmp_face->next; } last_face = tmp_face; @@ -2139,7 +2142,10 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, cairo_ft_font_face_t *font_face; /* Looked for an existing matching font face */ - for (font_face = unscaled->faces; font_face; font_face = font_face->next_face) { + for (font_face = unscaled->faces; + font_face; + font_face = font_face->next) + { if (font_face->load_flags == load_flags) return cairo_font_face_reference (&font_face->base); } @@ -2154,7 +2160,7 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, font_face->load_flags = load_flags; - font_face->next_face = unscaled->faces; + font_face->next = unscaled->faces; unscaled->faces = font_face; _cairo_font_face_init (&font_face->base, &_ft_font_face_backend); -- cgit v1.2.3 From c4a806f21c2b6c3081b953497daf25108a734787 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 22:37:29 +0000 Subject: Rename _ft_font_face_backend to be preoperly namespaced as _cairo_ft_font_face_backend. --- ChangeLog | 6 ++++++ src/cairo-ft-font.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4a9df20..d7a71568 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-08-05 Carl Worth + + * src/cairo-ft-font.c: (_cairo_ft_font_face_create): Rename + _ft_font_face_backend to be preoperly namespaced as + _cairo_ft_font_face_backend. + 2005-08-05 Carl Worth * src/cairo-ft-font.c: (_cairo_ft_font_face_destroy), diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 2c18e1a1..11ef2123 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2130,7 +2130,7 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, return CAIRO_STATUS_NO_MEMORY; } -static const cairo_font_face_backend_t _ft_font_face_backend = { +static const cairo_font_face_backend_t _cairo_ft_font_face_backend = { _cairo_ft_font_face_destroy, _cairo_ft_font_face_scaled_font_create }; @@ -2163,7 +2163,7 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, font_face->next = unscaled->faces; unscaled->faces = font_face; - _cairo_font_face_init (&font_face->base, &_ft_font_face_backend); + _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend); return &font_face->base; } -- cgit v1.2.3 From e63e0578b1edf2b60c818b3e6741cf97c5a53359 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 5 Aug 2005 23:41:41 +0000 Subject: Unify initialization for _cairo_ft_unscaled_font_create_from_face and _cairo_ft_unscaled_font_create_from_filename through new _cairo_ft_unscaled_font_init. --- ChangeLog | 9 +++++ src/cairo-ft-font.c | 102 ++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 80 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7a71568..482a4fbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-08-05 Carl Worth + + * src/cairo-ft-font.c: (_cairo_ft_unscaled_font_init), + (_cairo_ft_unscaled_font_create_from_face), + (_cairo_ft_unscaled_font_create_from_filename): Unify + initialization for _cairo_ft_unscaled_font_create_from_face and + _cairo_ft_unscaled_font_create_from_filename through new + _cairo_ft_unscaled_font_init. + 2005-08-05 Carl Worth * src/cairo-ft-font.c: (_cairo_ft_font_face_create): Rename diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 11ef2123..69a21a35 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -121,26 +121,79 @@ struct _cairo_ft_font_face { const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend; -static cairo_ft_unscaled_font_t * -_cairo_ft_unscaled_font_create_from_face (FT_Face face) +/** + * _cairo_ft_unscaled_font_init: + * + * Initialize a cairo_ft_unscaled_font_t. + * + * There are two basic flavors of cairo_ft_unscaled_font_t, one + * created from an FT_Face and the other created from a filename/id + * pair. These two flavors are identified as from_face and !from_face. + * + * To initialize a from_face font, pass filename==NULL, id=0 and the + * desired face. + * + * To initialize a !from_face font, pass the filename/id as desired + * and face==NULL. + * + * Note that the code handles these two flavors in very distinct + * ways. For example there is a hash_table mapping + * filename/id->cairo_unscaled_font_t in the !from_face case, but no + * parallel in the from_face case, (where the calling code would have + * to do its own mapping to ensure similar sharing). + **/ +static cairo_status_t +_cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled, + const char *filename, + int id, + FT_Face face) { - cairo_ft_unscaled_font_t *unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); - if (!unscaled) - return NULL; - - unscaled->from_face = 1; - unscaled->face = face; + char *filename_copy = NULL; + + if (filename) { + filename_copy = strdup (filename); + if (filename_copy == NULL) + return CAIRO_STATUS_NO_MEMORY; + } + + unscaled->filename = filename_copy; + unscaled->id = id; + + if (face) { + unscaled->from_face = 1; + unscaled->face = face; + } else { + unscaled->from_face = 0; + unscaled->face = NULL; + } - unscaled->filename = NULL; - unscaled->id = 0; - unscaled->have_scale = 0; unscaled->lock = 0; - + unscaled->faces = NULL; _cairo_unscaled_font_init (&unscaled->base, &cairo_ft_unscaled_font_backend); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_ft_unscaled_font_t * +_cairo_ft_unscaled_font_create_from_face (FT_Face face) +{ + cairo_status_t status; + cairo_ft_unscaled_font_t *unscaled; + + unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); + if (unscaled == NULL) + return NULL; + + status = _cairo_ft_unscaled_font_init (unscaled, NULL, 0, face); + if (status) { + free (unscaled); + return NULL; + } + return unscaled; } @@ -154,32 +207,19 @@ static cairo_ft_unscaled_font_t * _cairo_ft_unscaled_font_create_from_filename (const char *filename, int id) { + cairo_status_t status; cairo_ft_unscaled_font_t *unscaled; - char *new_filename; - new_filename = strdup (filename); - if (!new_filename) + unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); + if (unscaled == NULL) return NULL; - unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); - if (!unscaled) { - free (new_filename); + status = _cairo_ft_unscaled_font_init (unscaled, filename, id, NULL); + if (status) { + free (unscaled); return NULL; } - - unscaled->from_face = 0; - unscaled->face = NULL; - - unscaled->filename = new_filename; - unscaled->id = id; - - unscaled->have_scale = 0; - unscaled->lock = 0; - - unscaled->faces = NULL; - _cairo_unscaled_font_init (&unscaled->base, - &cairo_ft_unscaled_font_backend); return unscaled; } -- cgit v1.2.3 From f367e693322b1cf04040521080cc65403c292a28 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 6 Aug 2005 00:09:17 +0000 Subject: Fix up some stale comments. Rename _cairo_ft_scaled_font_create_for_unscaled to its proper name of _cairo_ft_scaled_font_create (which is available now that _cairo_ft_scaled_font_create_toy has its correct name). Also prefer 'scaled_font' over 'f' as an identifier. --- ChangeLog | 11 +++++++++++ src/cairo-ft-font.c | 46 ++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 482a4fbd..2a9e0b0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-08-06 Carl Worth + + * src/cairo-ft-font.c: (_cairo_ft_scaled_font_create), + (_cairo_ft_scaled_font_create_toy), + (_cairo_ft_scaled_font_glyph_extents), + (_cairo_ft_font_face_scaled_font_create): Fix up some stale + comments. Rename _cairo_ft_scaled_font_create_for_unscaled to its + proper name of _cairo_ft_scaled_font_create (which is available + now that _cairo_ft_scaled_font_create_toy has its correct + name). Also prefer 'scaled_font' over 'f' as an identifier. + 2005-08-05 Carl Worth * src/cairo-ft-font.c: (_cairo_ft_unscaled_font_init), diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 69a21a35..8f7b2e94 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -84,7 +84,7 @@ typedef struct _cairo_ft_font_transform { /* * We create an object that corresponds to a single font on the disk; * (identified by a filename/id pair) these are shared between all - * fonts using that file. For cairo_ft_scaled_font_create_for_ft_face(), we + * fonts using that file. For cairo_ft_font_face_create_for_ft_face(), we * just create a one-off version with a permanent face value. */ @@ -93,14 +93,14 @@ typedef struct _cairo_ft_font_face cairo_ft_font_face_t; struct _cairo_ft_unscaled_font { cairo_unscaled_font_t base; - cairo_bool_t from_face; /* from cairo_ft_scaled_font_create_for_ft_face()? */ + cairo_bool_t from_face; /* from cairo_ft_font_face_create_for_ft_face()? */ FT_Face face; /* provided or cached face */ /* only set if from_face is false */ char *filename; int id; - /* We temporarily scale the unscaled font as neede */ + /* We temporarily scale the unscaled font as needed */ cairo_bool_t have_scale; cairo_matrix_t current_scale; double x_scale; /* Extracted X scale factor */ @@ -1418,29 +1418,31 @@ _get_options_load_flags (const cairo_font_options_t *options) } static cairo_scaled_font_t * -_cairo_ft_scaled_font_create_for_unscaled (cairo_ft_unscaled_font_t *unscaled, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - int load_flags) +_cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled, + const cairo_matrix_t *font_matrix, + const cairo_matrix_t *ctm, + const cairo_font_options_t *options, + int load_flags) { - cairo_ft_scaled_font_t *f = NULL; + cairo_ft_scaled_font_t *scaled_font = NULL; - f = malloc (sizeof(cairo_ft_scaled_font_t)); - if (f == NULL) + scaled_font = malloc (sizeof(cairo_ft_scaled_font_t)); + if (scaled_font == NULL) return NULL; - f->unscaled = unscaled; + scaled_font->unscaled = unscaled; _cairo_unscaled_font_reference (&unscaled->base); if (options->hint_metrics != CAIRO_HINT_METRICS_OFF) load_flags |= PRIVATE_FLAG_HINT_METRICS; - f->load_flags = load_flags; + scaled_font->load_flags = load_flags; - _cairo_scaled_font_init (&f->base, font_matrix, ctm, options, &cairo_ft_scaled_font_backend); + _cairo_scaled_font_init (&scaled_font->base, + font_matrix, ctm, options, + &cairo_ft_scaled_font_backend); - return (cairo_scaled_font_t *)f; + return (cairo_scaled_font_t*) scaled_font; } cairo_bool_t @@ -1521,9 +1523,9 @@ _cairo_ft_scaled_font_create_toy (const cairo_toy_font_face_t *toy_face, goto FREE_RESOLVED; load_flags = _get_pattern_load_flags (pattern); - new_font = _cairo_ft_scaled_font_create_for_unscaled (unscaled, - font_matrix, ctm, - options, load_flags); + new_font = _cairo_ft_scaled_font_create (unscaled, + font_matrix, ctm, + options, load_flags); _cairo_unscaled_font_destroy (&unscaled->base); @@ -1746,7 +1748,7 @@ _cairo_ft_scaled_font_glyph_extents (void *abstract_font, /* XXX: Need to add code here to check the font's FcPattern for FC_VERTICAL_LAYOUT and if set get vertBearingX/Y instead. This will require that - cairo_ft_scaled_font_create_for_ft_face accept an + cairo_ft_font_face_create_for_ft_face accept an FcPattern. */ glyph_min.x = glyphs[i].x + img->extents.x_bearing; glyph_min.y = glyphs[i].y + img->extents.y_bearing; @@ -2161,9 +2163,9 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, else load_flags = font_face->load_flags; - *scaled_font = _cairo_ft_scaled_font_create_for_unscaled (font_face->unscaled, - font_matrix, ctm, - options, load_flags); + *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled, + font_matrix, ctm, + options, load_flags); if (*scaled_font) return CAIRO_STATUS_SUCCESS; else -- cgit v1.2.3 From 158b338fb2817996c5191332951b6957416c2e77 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Sat, 6 Aug 2005 10:22:07 +0000 Subject: Remove a non-sensical XXX that crept in at some point; for a solid color, there is no difference between premultiplied and non-premultiplied colors. --- ChangeLog | 7 +++++++ src/cairo-win32-font.c | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2a9e0b0f..8974d658 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-08-06 Owen Taylor + + * src/cairo-win32-font.c (_cairo_win32_scaled_font_show_glyphs): + Remove a non-sensical XXX that crept in at some point; for + a solid color, there is no difference between premultiplied + and non-premultiplied colors. + 2005-08-06 Carl Worth * src/cairo-ft-font.c: (_cairo_ft_scaled_font_create), diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index 51dab1b7..4867fc0f 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -1056,7 +1056,6 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font, */ COLORREF new_color; - /* XXX Use the unpremultiplied or premultiplied color? */ new_color = RGB (((int)solid_pattern->color.red_short) >> 8, ((int)solid_pattern->color.green_short) >> 8, ((int)solid_pattern->color.blue_short) >> 8); -- cgit v1.2.3 From 8c52b287f37f8361653030024d7a4a42fc6e54ed Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Sat, 6 Aug 2005 15:10:36 +0000 Subject: Give reason for failure. --- ChangeLog | 4 ++++ test/a8-mask.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8974d658..6a4d3942 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-08-06 Jeff Muizelaar + + * test/a8-mask.c: (main): Give reason for failure. + 2005-08-06 Owen Taylor * src/cairo-win32-font.c (_cairo_win32_scaled_font_show_glyphs): diff --git a/test/a8-mask.c b/test/a8-mask.c index 2895037e..e547ecce 100644 --- a/test/a8-mask.c +++ b/test/a8-mask.c @@ -68,5 +68,5 @@ int main (void) { return cairo_test_expect_failure (&test, draw, - "image backend fails (unknown cause)"); + "image backend fails because libpixman only handles (stride % sizeof(pixman_bits) == 0)"); } -- cgit v1.2.3 From 2f1024f83fc971516224b910cec8d3e787740c53 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 6 Aug 2005 16:38:33 +0000 Subject: Fix to return &_cairo_font_face_nil instead of NULL on error. --- ChangeLog | 5 +++++ src/cairo.c | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a4d3942..630ca003 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-06 Carl Worth + + * src/cairo.c (cairo_get_font_face): Fix to return + &_cairo_font_face_nil instead of NULL on error. + 2005-08-06 Jeff Muizelaar * test/a8-mask.c: (main): Give reason for failure. diff --git a/src/cairo.c b/src/cairo.c index f0eebab9..05c87a42 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -1687,16 +1687,13 @@ cairo_get_font_face (cairo_t *cr) if (cr->status) { _cairo_set_error (cr, cr->status); - return NULL; + return (cairo_font_face_t*) &_cairo_font_face_nil; } cr->status = _cairo_gstate_get_font_face (cr->gstate, &font_face); if (cr->status) { _cairo_set_error (cr, cr->status); - /* XXX: When available: - return _cairo_font_face_nil; - */ - return NULL; + return (cairo_font_face_t*) &_cairo_font_face_nil; } return font_face; -- cgit v1.2.3 From 1fadb8065600d5b9cbab9a14232e08daec450e4d Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 6 Aug 2005 16:57:14 +0000 Subject: Remove several bugs that have been fixed. Slip group support off of the 1.0 roadmap. Update status of clipping work which otaylor is working on. Update for progress on cairo_surface_mark_dirty (committed), non-antialiased rendering (patch), cairo_arc_to (patch), consistent error handling (committed), cairo_content_t (committed). Remove details for some completed items. Don't crash if font_face is NULL, (this is a documented mechanism for returning to the default font_face). --- BUGS | 29 ------------------------ ChangeLog | 16 ++++++++++++++ ROADMAP | 22 +++++++++--------- TODO | 65 +++++------------------------------------------------- src/cairo-gstate.c | 2 +- 5 files changed, 34 insertions(+), 100 deletions(-) diff --git a/BUGS b/BUGS index ea529cb7..1a0c3b09 100644 --- a/BUGS +++ b/BUGS @@ -5,40 +5,11 @@ that display. -- -cairo_show_surface fails when given a non-default CTM, see the -show_surface.cairo snippet in: - - From: Per Bjornsson - To: Cairo mailing list - Date: Wed, 09 Feb 2005 20:05:35 -0800 - Message-Id: <1108008335.5349.46.camel@localhost.localdomain> - Subject: [cairo] How is cairo_show_surface supposed to work? - --- - cairo_image_surface_create should return a blank image (eg. transparent black) instead of an image with random data in it. -- -cairo_surface_create_for_image is claiming ownership of the user's data. - --- - -cairo_font_set_transform should be renamed cairo_font_set_matrix -cairo_font_current_transform should be renamed cairo_font_get_matrix - --- - -Alexis Georges reports a segfault on AMD64 with a simple program, -(that works in a 32bit chroot). - --- - -The caches need to have some locking (see: [cairo] Static caches and thread-safety) - --- - Scaling of surface patterns is all broken, (try xsvg gradPatt-pattern-BE-07.svg and zoom in and out). diff --git a/ChangeLog b/ChangeLog index 630ca003..cf15bbbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-08-06 Carl Worth + + * BUGS: Remove several bugs that have been fixed. + + * ROADMAP: Slip group support off of the 1.0 roadmap. Update + status of clipping work which otaylor is working on. + + * TODO: Update for progress on cairo_surface_mark_dirty + (committed), non-antialiased rendering (patch), cairo_arc_to + (patch), consistent error handling (committed), cairo_content_t + (committed). Remove details for some completed items. + + * src/cairo-gstate.c (_cairo_gstate_set_font_face): Don't crash if + font_face is NULL, (this is a documented mechanism for returning + to the default font_face). + 2005-08-06 Carl Worth * src/cairo.c (cairo_get_font_face): Fix to return diff --git a/ROADMAP b/ROADMAP index b4fef0d1..6f3b12ef 100644 --- a/ROADMAP +++ b/ROADMAP @@ -4,7 +4,7 @@ Implementation work ------------------- I1. Fix clipping to be sane Dificulty: moderate - Status: cworth has started looking at this + Status: otalyor is working on this. I2. Real PostScript/PDF fallbacks (cairo_meta_surface_t) Difficulty: hard @@ -32,15 +32,6 @@ Implementation work API additions (more detail in TODO file) ---------------------------------------- - A3. Add cairo_begin/end/get_group - Difficulty: easy to hard (depending on how sophisticated an - implementation is acceptable, and whether the - cairo_meta_surface_t mentioned in [I2] is done) - - Status: cworth has a posted a preliminary patch, and keithp, - krh, and otaylor answered all the tough questions it - raised. There's not much work left to finish this one. - ✓A7. cairo_surface_mark_dirty and cairo_surface_flush Difficulty: trivial to add API, moderate to actually optimize based on it @@ -60,3 +51,14 @@ Performance work P3. Glyph measurement needs to be sped up. Status: Now planned as part of I4 above ("cache lock deadlock") + +Things that have been dropped from the 1.0 roadmap +================================================== + A3. Add cairo_begin/end/get_group + Difficulty: easy to hard (depending on how sophisticated an + implementation is acceptable, and whether the + cairo_meta_surface_t mentioned in [I2] is done) + + Status: cworth has a posted a preliminary patch, and keithp, + krh, and otaylor answered all the tough questions it + raised. There's not much work left to finish this one. diff --git a/TODO b/TODO index 41f89605..bb04c887 100644 --- a/TODO +++ b/TODO @@ -10,12 +10,12 @@ Changes that are expected to impact the public API Backwards compatible (API additions only) ----------------------------------------- cairo_begin_group, cairo_end_group, cairo_get_group - cairo_surface_mark_dirty (see below for details) - Add support for non-antialiased rendering. API ? +PDR C cairo_surface_mark_dirty (see below for details) +PDR 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) - Add cairo_arc_to. +P Add cairo_arc_to. Add support for custom caps (see below for details) Add support for getting at image data from image surface Add CAIRO_STATUS_DESTROYED @@ -25,29 +25,12 @@ Backwards incompatible (API deletions or changes) ------------------------------------------------- PDR C cairo_surface_finish, cairo_surface_flush PDR C A hidden offset for the xlib backend -P Consistent error handling for all objects - Split cairo_format_t (see below for details) +PDR C Consistent error handling for all objects +PDRTC Split cairo_format_t (see below for details) P---C Remove cairo_status_string in favor of cairo_status_to_string Details on some of the above changes ------------------------------------ -* cairo_surface_mark_dirty - - One question is what the function should accept. A single - device-space rectangle seems like a consistent approach. That would - allow us to avoid needing backend-specific functions with - backend-specific region datatypes, (cf. clipping support) - - In order to get the intended efficiency benefits, we'll need to make - two changes: - - 1) In the fallback code, never fetch any data from the clean - region. - - 2) Mark clean any region drawn with device-pixel aligned - rectangles, (cairo_paint with no clip is the most iportant - one here). - * cairo_text_glyphs: It would function as a sort of bridge between the toy and the @@ -78,51 +61,13 @@ Details on some of the above changes current path. We may also need to provide the coordinates of the faces of every dash as well. -* split cairo_format_t into two things: - - - An enumeration that determines the "capabilities" of a surface - - A vs. ARGB. vs. RGB - - An enumeration that determines a specific in-memory representation - of data. (A1/A8/ARGB32/etc.. Could be extensible to things like - RGBA32_BYTES_NONPREMULTIPLIED. Some consistent naming convention would - be be good.) - - One issue here is that some interfaces, like cairo_surface_create_similar() - might be useful with either one. We might want to create an A1 surface - compatible with the backend (are there examples other than A1? Should - bilevel just be another "capability"?), or we might want to just create - an alpha surface without caring about the depth. - - If we want to support this, we could do something like: - - typedef enum cairo_pixel_format_t { - CAIRO_PIXEL_FORMAT_A8 = CAIRO_FORMAT_ALPHA, - CAIRO_PIXEL_FORMAT_RGB24 = CAIRO_FORMAT_RGB, - CAIRO_PIXEL_FORMAT_A1, - }; - - To allow passing either in. - - (I don't particularly like this idea for create_similar() because then you - aren't really saying ALPHA-dont-care, you are saying ALPHA-8. I think it - would be better to have a separate path for create_similar_with_pixel_format() - if we need that. But it might be useful for cairo_image_surface_create() ... - people are going to screw up and pass CAIRO_FORMAT_RGB into that, and if it - "just worked" that would save people trouble....) - Changes that do not affect the public API ========================================= -* Clean up the cache code a bit, (there is at least one redundant - level of cacheing, and there are some minor style issues). - * Fix clipping to work for all operators. The equation we have come up with is: ((src Op dest) In clip) Add (dest Out clip) -* Make a more interesting PS backend, (other than the current - "giant-image for every page" approach). - * Change stroke code to go through one giant polygon. This will fix problems with stroking self-intersecting paths. diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 916b701f..134586a5 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1649,7 +1649,7 @@ cairo_status_t _cairo_gstate_set_font_face (cairo_gstate_t *gstate, cairo_font_face_t *font_face) { - if (font_face->status) + if (font_face && font_face->status) return font_face->status; if (font_face != gstate->font_face) { -- cgit v1.2.3 From 31ef9a80e95c5b84439b5d668d11ab3480d22a22 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 6 Aug 2005 17:00:59 +0000 Subject: Remove several bugs that have been fixed. --- BUGS | 53 ----------------------------------------------------- 1 file changed, 53 deletions(-) diff --git a/BUGS b/BUGS index 1a0c3b09..43331d08 100644 --- a/BUGS +++ b/BUGS @@ -10,16 +10,6 @@ cairo_image_surface_create should return a blank image -- -Scaling of surface patterns is all broken, (try xsvg -gradPatt-pattern-BE-07.svg and zoom in and out). - --- - -centi_unfinished.svg has big black portions when drawn with svg2png, -(but not when drawn with xsvg). - --- - The caches need to be invalidated at font destruction time. -- @@ -67,24 +57,6 @@ confirmed on a quite default install of debian unstable. -- -cairo_scale_font modifies objects that the user expects to not change. For example: - - cairo_font_t *font; - - cairo_select_font (cr, "fixed", 0, 0); - font = cairo_current_font (cr); - cairo_scale_font (cr, 10); - cairo_show_text (cr, "all is good"); - cairo_set_font (cr, font); - cairo_scale_font (cr, 10); - cairo_show_text (cr, "WAY TOO BIG!!); - -We could fix this by not storing the scale in the font object. Or -maybe we could just force the size to its default after set_font. Need -to think about this in more detail. - --- - cairo_show_text is not updating the current point by the string's advance values. -- @@ -99,34 +71,9 @@ places. -- -Patterns are broken in various ways. The SVG test case demonstrates -some regressions, so something has changed in cairo. Also, -transformation plus repeat doesn't work in either Xrender or -libpixman, (nor in glitz?). - --- - font-size="0" in an SVG file does very bad things. -- -move_to_show_surface (see cairo/test): - - * 2004-10-25 Carl Worth - * - * It looks like cairo_show_surface has no effect if it follows a - * call to cairo_move_to to any coordinate other than 0,0. A little - * bit of poking around suggests this isn't a regression, (at least - * not since the last pixman snapshot). - --- - cairo falls over with XFree86 4.2 (probably braindead depth handling somewhere). - --- - -The caches abort when asked for a too-large item, (should be possible -to trigger by asking for a giant font, "cairo_scale_font (cr, 2000)" -perhaps). Even if the caches don't want to hold them, we need to be -able to allocate these objects. -- cgit v1.2.3 From 8f19aaf9a8a60aa2eb86e25946d04f293ed703db Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 8 Aug 2005 13:46:11 +0000 Subject: Add a function to test whether a cairo_operator_t is bounded (does nothing for 0 src/mask) cairoint.h: Add a helper function to take clearing areas that are outside the source/mask but are cleared by unbounded operations. src/cairo-xlib-surface.c (_cairo_xlib_surface_composite): Use _cairo_surface_composite_fixup_unbounded() as needed. src/cairo-image-surface.c src/cairint.h: Keep track of whether the surface has a clip or not ... we need this for determining when we can bypass an intermediate mask for composite_trapezoids(). Create an intermediate mask of the right size with pixman_add_trapezoids() and composite that. When rendering with an unbounded operator, create the intermediate mask ourselves and render with ADD to that, then composite the result. Create an intermediate surface the size of the extents, render the glyphs to that then composite the results. Add the size of the glyph Compute the size of the glyph mask, then use _cairo_surface_composite_fixup_unbounded(). Use the right mask format. (Unrelated bugfix) New function taking a drawing function as a parameter to encapsulate shared logic between compositing trapezoid, glyphs, and masks. Use _cairo_gstate_clip_and_composite(). Also fix extents computations for unbounded operators. src/cairo-clip.c src/cairo-clip-private.h (_cairo_clip_combine_to_surface): Add the destination as an extra parameter to allow combining to an intermediate surface. tests/unbounded-operator.c tests/Makefile.am: Add a test for the operation of the 6 unbounded operators against different shapes. tests/clip-operator.c tests/Makefile.am: Add a test that tests surface clipping with different shapes against all the operators. Make use OVER like the name and description. With fixed semantics, SOURCE does something different. --- ChangeLog | 60 ++ src/cairo-clip-private.h | 9 +- src/cairo-clip.c | 22 +- src/cairo-ft-font.c | 122 +++- src/cairo-gstate.c | 733 +++++++++++++++---------- src/cairo-image-surface.c | 126 ++++- src/cairo-surface.c | 151 +++++ src/cairo-xlib-surface.c | 214 +++++++- src/cairoint.h | 23 +- test/Makefile.am | 6 + test/clip-operator.c | 205 +++++++ test/composite-integer-translate-over-repeat.c | 2 +- test/unbounded-operator.c | 201 +++++++ 13 files changed, 1520 insertions(+), 354 deletions(-) create mode 100644 test/clip-operator.c create mode 100644 test/unbounded-operator.c diff --git a/ChangeLog b/ChangeLog index cf15bbbe..0516c5c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,63 @@ +2005-08-08 Owen Taylor + + * src/cairo-gstate.c (_cairo_operator_bounded): Add a function to test + whether a cairo_operator_t is bounded (does nothing for 0 src/mask) + + * src/cairo-surface.c (_cairo_surface_composite_fixup_unbounded) cairoint.h: + Add a helper function to take clearing areas that are outside the source/mask + but are cleared by unbounded operations. + + * src/cairo-image-surface.c (_cairo_image_surface_composite) + src/cairo-xlib-surface.c (_cairo_xlib_surface_composite): Use + _cairo_surface_composite_fixup_unbounded() as needed. + + * src/cairo-image-surface.c src/cairint.h: Keep track of whether the surface + has a clip or not ... we need this for determining when we can bypass + an intermediate mask for composite_trapezoids(). + + * src/cairo-image-surface.c (_cairo_image_surface_composite_trapezoids): + Create an intermediate mask of the right size with pixman_add_trapezoids() + and composite that. + + * src/cairo-xlib-surface.c (_cairo_xlib_surface_composite_trapezoids): + When rendering with an unbounded operator, create the intermediate mask + ourselves and render with ADD to that, then composite the result. + + * src/cairo-ft-font.c (_cairo_ft_scaled_font_show_glyphs): Create an + intermediate surface the size of the extents, render the glyphs to that + then composite the results. + + * src/cairo-xlib-surface.c (glyphset_cache_entry_t): Add the size of the glyph + + * src/cairo-xlib-surface.c (_show_glyphs_fixup_unbounded): Compute the size + of the glyph mask, then use _cairo_surface_composite_fixup_unbounded(). + + * src/cairo-xlib-surface.c (_cairo_xlib_surface_show_glyphs32): Use the right + mask format. (Unrelated bugfix) + + * src/cairo-gstate.c (_cairo_gstate_clip_and_composite): New function taking + a drawing function as a parameter to encapsulate shared logic between + compositing trapezoid, glyphs, and masks. + + * src/cairo-gstate.c (_cairo_gstate_mask, + _cairo_surface_clip_and_composite_trapezoids, _cairo_gstate_show_glyphs): + Use _cairo_gstate_clip_and_composite(). Also fix extents computations for + unbounded operators. + + * src/cairo-clip.c src/cairo-clip-private.h (_cairo_clip_combine_to_surface): + Add the destination as an extra parameter to allow combining to an intermediate + surface. + + * tests/unbounded-operator.c tests/Makefile.am: Add a test for the + operation of the 6 unbounded operators against different shapes. + + * tests/clip-operator.c tests/Makefile.am: Add a test that tests + surface clipping with different shapes against all the operators. + + * test/composite-integer-translate-over-repeat.c (draw): Make use OVER + like the name and description. With fixed semantics, SOURCE does something + different. + 2005-08-06 Carl Worth * BUGS: Remove several bugs that have been fixed. diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h index f8846b5c..a56f5798 100644 --- a/src/cairo-clip-private.h +++ b/src/cairo-clip-private.h @@ -111,8 +111,11 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, pixman_region16_t *region); cairo_private cairo_status_t -_cairo_clip_combine_to_surface (cairo_clip_t *clip, - cairo_surface_t *intermediate, - cairo_rectangle_t *extents); +_cairo_clip_combine_to_surface (cairo_clip_t *clip, + cairo_operator_t operator, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_t *extents); #endif /* CAIRO_CLIP_PRIVATE_H */ diff --git a/src/cairo-clip.c b/src/cairo-clip.c index c211e2b8..a4b8d533 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -208,28 +208,32 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, return CAIRO_STATUS_SUCCESS; } -/* Combines clip->surface using the IN operator with the given - * intermediate surface, which corresponds to the rectangle of the - * destination space given by @extents. +/* Combines the region of clip->surface given by extents in + * device backend coordinates into the given temporary surface, + * which has its origin at dst_x, dst_y in backend coordinates */ cairo_status_t -_cairo_clip_combine_to_surface (cairo_clip_t *clip, - cairo_surface_t *intermediate, - cairo_rectangle_t *extents) +_cairo_clip_combine_to_surface (cairo_clip_t *clip, + cairo_operator_t operator, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_t *extents) { cairo_pattern_union_t pattern; cairo_status_t status; _cairo_pattern_init_for_surface (&pattern.surface, clip->surface); - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, + status = _cairo_surface_composite (operator, &pattern.base, NULL, - intermediate, + dst, extents->x - clip->surface_rect.x, extents->y - clip->surface_rect.y, 0, 0, - 0, 0, + extents->x - dst_x, + extents->y - dst_y, extents->width, extents->height); _cairo_pattern_fini (&pattern.base); diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 8f7b2e94..36a0c674 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -1844,6 +1844,26 @@ _cairo_ft_scaled_font_glyph_bbox (void *abstract_font, return CAIRO_STATUS_SUCCESS; } +static cairo_format_t +_select_text_mask_format (cairo_bool_t have_a1_glyphs, + cairo_bool_t have_a8_glyphs, + cairo_bool_t have_argb32_glyphs) +{ + if (have_a8_glyphs) + return CAIRO_FORMAT_A8; + + if (have_a1_glyphs && have_argb32_glyphs) + return CAIRO_FORMAT_A8; + + if (have_a1_glyphs) + return CAIRO_FORMAT_A1; + + if (have_argb32_glyphs) + return CAIRO_FORMAT_ARGB32; + + /* when there are no glyphs to draw, just pick something */ + return CAIRO_FORMAT_A8; +} static cairo_status_t _cairo_ft_scaled_font_show_glyphs (void *abstract_font, @@ -1859,12 +1879,16 @@ _cairo_ft_scaled_font_show_glyphs (void *abstract_font, const cairo_glyph_t *glyphs, int num_glyphs) { - cairo_image_glyph_cache_entry_t *img; + cairo_image_glyph_cache_entry_t **entries; cairo_cache_t *cache; cairo_glyph_cache_key_t key; cairo_ft_scaled_font_t *scaled_font = abstract_font; cairo_surface_pattern_t glyph_pattern; - cairo_status_t status; + cairo_surface_t *mask; + cairo_surface_pattern_t mask_pattern; + cairo_format_t mask_format = CAIRO_FORMAT_A1; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_bool_t have_a1_glyphs, have_a8_glyphs, have_argb32_glyphs; int x, y; int i; @@ -1884,44 +1908,98 @@ _cairo_ft_scaled_font_show_glyphs (void *abstract_font, key.scale = scaled_font->base.scale; key.flags = scaled_font->load_flags; + entries = malloc (num_glyphs * sizeof (cairo_image_glyph_cache_entry_t)); + if (!entries) + goto CLEANUP_CACHE; + + have_a1_glyphs = FALSE; + have_a8_glyphs = FALSE; + have_argb32_glyphs = FALSE; + for (i = 0; i < num_glyphs; i++) { - img = NULL; + entries[i] = NULL; key.index = glyphs[i].index; - if (_cairo_cache_lookup (cache, &key, (void **) &img, NULL) - != CAIRO_STATUS_SUCCESS - || img == NULL - || img->image == NULL) + if (_cairo_cache_lookup (cache, &key, (void **) &entries[i], NULL) != CAIRO_STATUS_SUCCESS) + continue; + + switch (entries[i]->image->format) { + case CAIRO_FORMAT_A1: + have_a1_glyphs = TRUE; + break; + case CAIRO_FORMAT_A8: + have_a8_glyphs = TRUE; + break; + case CAIRO_FORMAT_ARGB32: + have_argb32_glyphs = TRUE; + break; + default: + break; + } + } + + mask_format = _select_text_mask_format (have_a1_glyphs, have_a8_glyphs, have_argb32_glyphs); + + mask = cairo_image_surface_create (mask_format, width, height); + if (!mask) + goto CLEANUP_ENTRIES; + + status = _cairo_surface_fill_rectangle (mask, CAIRO_OPERATOR_SOURCE, + CAIRO_COLOR_TRANSPARENT, + 0, 0, width, height); + if (status) + goto CLEANUP_MASK; + + for (i = 0; i < num_glyphs; i++) + { + if (entries[i] == NULL + || entries[i]->image == NULL) continue; x = (int) floor (glyphs[i].x + 0.5); y = (int) floor (glyphs[i].y + 0.5); - _cairo_pattern_init_for_surface (&glyph_pattern, &(img->image->base)); + _cairo_pattern_init_for_surface (&glyph_pattern, &(entries[i]->image->base)); - status = _cairo_surface_composite (operator, pattern, + status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, pattern, &glyph_pattern.base, - surface, - x + img->size.x, - y + img->size.y, + mask, + x + entries[i]->size.x, + y + entries[i]->size.y, 0, 0, - x + img->size.x, - y + img->size.y, - (double) img->size.width, - (double) img->size.height); + x + entries[i]->size.x - dest_x, + y + entries[i]->size.y - dest_y, + entries[i]->size.width, + entries[i]->size.height); _cairo_pattern_fini (&glyph_pattern.base); - if (status) { - _cairo_unlock_global_image_glyph_cache (); - return status; - } - } + if (status) + goto CLEANUP_MASK; + } + + _cairo_pattern_init_for_surface (&mask_pattern, mask); + + status = _cairo_surface_composite (operator, pattern, &mask_pattern.base, + surface, + source_x, source_y, + 0, 0, + dest_x, dest_y, + width, height); + _cairo_pattern_fini (&mask_pattern.base); + + CLEANUP_MASK: + cairo_surface_destroy (mask); + + CLEANUP_ENTRIES: + free (entries); + + CLEANUP_CACHE: _cairo_unlock_global_image_glyph_cache (); - return CAIRO_STATUS_SUCCESS; + return status; } diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 134586a5..1e005f84 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -705,6 +705,257 @@ _cairo_gstate_paint (cairo_gstate_t *gstate) return CAIRO_STATUS_SUCCESS; } +/** + * _cairo_operator_bounded: + * @operator: a #cairo_operator_t + * + * A bounded operator is one where a source or mask pixel + * of zero results in no effect on the destination image. + * + * Unbounded operators often require special handling; if you, for + * example, draw trapezoids with an unbounded operator, the effect + * extends past the bounding box of the trapezoids. + * + * Return value: %TRUE if the operator is bounded + **/ +cairo_bool_t +_cairo_operator_bounded (cairo_operator_t operator) +{ + switch (operator) { + case CAIRO_OPERATOR_OVER: + case CAIRO_OPERATOR_ATOP: + case CAIRO_OPERATOR_DEST: + case CAIRO_OPERATOR_DEST_OVER: + case CAIRO_OPERATOR_DEST_OUT: + case CAIRO_OPERATOR_XOR: + case CAIRO_OPERATOR_ADD: + case CAIRO_OPERATOR_SATURATE: + return TRUE; + case CAIRO_OPERATOR_CLEAR: + case CAIRO_OPERATOR_SOURCE: + case CAIRO_OPERATOR_OUT: + case CAIRO_OPERATOR_IN: + case CAIRO_OPERATOR_DEST_IN: + case CAIRO_OPERATOR_DEST_ATOP: + return FALSE; + } + + ASSERT_NOT_REACHED; +} + +typedef cairo_status_t (*cairo_draw_func_t) (void *closure, + cairo_operator_t operator, + cairo_pattern_t *src, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_t *extents); + +/* Handles compositing with a clip surface when the operator allows + * us to combine the clip with the mask + */ +static cairo_status_t +_cairo_gstate_clip_and_composite_with_mask (cairo_clip_t *clip, + cairo_operator_t operator, + cairo_pattern_t *src, + cairo_draw_func_t draw_func, + void *draw_closure, + cairo_surface_t *dst, + const cairo_rectangle_t *extents) +{ + cairo_surface_t *intermediate; + cairo_surface_pattern_t intermediate_pattern; + cairo_status_t status; + + intermediate = cairo_surface_create_similar (clip->surface, + CAIRO_CONTENT_ALPHA, + extents->width, + extents->height); + if (intermediate->status) + return CAIRO_STATUS_NO_MEMORY; + + status = (*draw_func) (draw_closure, CAIRO_OPERATOR_SOURCE, + NULL, intermediate, + extents->x, extents->y, + extents); + if (status) + goto CLEANUP_SURFACE; + + status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_IN, + intermediate, + extents->x, extents->y, + extents); + if (status) + goto CLEANUP_SURFACE; + + _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); + + status = _cairo_surface_composite (operator, + src, &intermediate_pattern.base, dst, + extents->x, extents->y, + 0, 0, + extents->x, extents->y, + extents->width, extents->height); + + _cairo_pattern_fini (&intermediate_pattern.base); + + CLEANUP_SURFACE: + cairo_surface_destroy (intermediate); + + return status; +} + +/* Handles compositing with a clip surface when the operator allows + * us to combine the clip with the mask + */ +static cairo_status_t +_cairo_gstate_clip_and_composite_combine (cairo_clip_t *clip, + cairo_operator_t operator, + cairo_pattern_t *src, + cairo_draw_func_t draw_func, + void *draw_closure, + cairo_surface_t *dst, + const cairo_rectangle_t *extents) +{ + cairo_surface_t *intermediate; + cairo_surface_pattern_t dst_pattern; + cairo_surface_pattern_t intermediate_pattern; + cairo_status_t status; + + /* We'd be better off here creating a surface identical in format + * to dst, but we have no way of getting that information. + * A CAIRO_CONTENT_CLONE or something might be useful. + */ + intermediate = cairo_surface_create_similar (dst, + CAIRO_CONTENT_COLOR_ALPHA, + extents->width, + extents->height); + if (intermediate->status) + return CAIRO_STATUS_NO_MEMORY; + + /* Initialize the intermediate surface from the destination surface + */ + _cairo_pattern_init_for_surface (&dst_pattern, dst); + + status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, + &dst_pattern.base, NULL, intermediate, + extents->x, extents->y, + 0, 0, + 0, 0, + extents->width, extents->height); + + _cairo_pattern_fini (&dst_pattern.base); + + if (status) + goto CLEANUP_SURFACE; + + status = (*draw_func) (draw_closure, operator, + src, intermediate, + extents->x, extents->y, + extents); + if (status) + goto CLEANUP_SURFACE; + + /* Combine that with the clip + */ + status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_DEST_IN, + intermediate, + extents->x, extents->y, + extents); + if (status) + goto CLEANUP_SURFACE; + + /* Punch the clip out of the destination + */ + status = _cairo_clip_combine_to_surface (clip, CAIRO_OPERATOR_DEST_OUT, + dst, + 0, 0, + extents); + if (status) + goto CLEANUP_SURFACE; + + /* Now add the two results together + */ + _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); + + status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, + &intermediate_pattern.base, NULL, dst, + 0, 0, + 0, 0, + extents->x, extents->y, + extents->width, extents->height); + + _cairo_pattern_fini (&intermediate_pattern.base); + + CLEANUP_SURFACE: + cairo_surface_destroy (intermediate); + + return status; +} + +static int +_cairo_rectangle_empty (const cairo_rectangle_t *rect) +{ + return rect->width == 0 || rect->height == 0; +} + +/** + * _cairo_gstate_clip_and_composite: + * @gstate: a #cairo_gstate_t + * @operator: the operator to draw with + * @src: source pattern + * @draw_func: function that can be called to draw with the mask onto a surface. + * @draw_closure: data to pass to @draw_func. + * @dst: destination surface + * @extents: rectangle holding a bounding box for the operation; this + * rectangle will be used as the size for the temporary + * surface. + * + * When there is a surface clip, we typically need to create an intermediate + * surface. This function handles the logic of creating a temporary surface + * drawing to it, then compositing the result onto the target surface. + * + * @draw_func is to called to draw the mask; it will be called no more + * than once. + * + * Return value: %CAIRO_STATUS_SUCCESS if the drawing succeeded. + **/ +static cairo_status_t +_cairo_gstate_clip_and_composite (cairo_clip_t *clip, + cairo_operator_t operator, + cairo_pattern_t *src, + cairo_draw_func_t draw_func, + void *draw_closure, + cairo_surface_t *dst, + const cairo_rectangle_t *extents) +{ + if (_cairo_rectangle_empty (extents)) + /* Nothing to do */ + return CAIRO_STATUS_SUCCESS; + + if (clip->surface) + { + if (_cairo_operator_bounded (operator)) + return _cairo_gstate_clip_and_composite_with_mask (clip, operator, + src, + draw_func, draw_closure, + dst, extents); + else + return _cairo_gstate_clip_and_composite_combine (clip, operator, + src, + draw_func, draw_closure, + dst, extents); + } + else + { + return (*draw_func) (draw_closure, operator, + src, dst, + 0, 0, + extents); + } +} + + static cairo_status_t _get_mask_extents (cairo_gstate_t *gstate, cairo_pattern_t *mask, @@ -714,7 +965,8 @@ _get_mask_extents (cairo_gstate_t *gstate, /* * XXX should take mask extents into account, but - * that involves checking the transform... For now, + * that involves checking the transform and + * _cairo_operator_bounded (operator)... For now, * be lazy and just use the destination extents */ status = _cairo_surface_get_extents (gstate->target, extents); @@ -724,16 +976,40 @@ _get_mask_extents (cairo_gstate_t *gstate, return _cairo_clip_intersect_to_rectangle (&gstate->clip, extents); } +static cairo_status_t +_cairo_gstate_mask_draw_func (void *closure, + cairo_operator_t operator, + cairo_pattern_t *src, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_t *extents) +{ + cairo_pattern_t *mask = closure; + + if (src) + return _cairo_surface_composite (operator, + src, mask, dst, + extents->x, extents->y, + extents->x, extents->y, + extents->x - dst_x, extents->y - dst_y, + extents->width, extents->height); + else + return _cairo_surface_composite (operator, + mask, NULL, dst, + extents->x, extents->y, + 0, 0, /* unused */ + extents->x - dst_x, extents->y - dst_y, + extents->width, extents->height); +} + cairo_status_t _cairo_gstate_mask (cairo_gstate_t *gstate, cairo_pattern_t *mask) { cairo_rectangle_t extents; cairo_pattern_union_t source_pattern, mask_pattern; - cairo_surface_pattern_t intermediate_pattern; - cairo_pattern_t *effective_mask; cairo_status_t status; - int mask_x, mask_y; if (mask->status) return mask->status; @@ -745,64 +1021,17 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, if (status) return status; - _get_mask_extents (gstate, mask, &extents); - - if (gstate->clip.surface) { - /* When there is clip surface, we'll need to create a - * temporary surface that combines the clip and mask - */ - cairo_surface_t *intermediate; - - intermediate = cairo_surface_create_similar (gstate->clip.surface, - CAIRO_CONTENT_ALPHA, - extents.width, - extents.height); - if (intermediate->status) - return CAIRO_STATUS_NO_MEMORY; - - status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, - mask, NULL, intermediate, - extents.x, extents.y, - 0, 0, - 0, 0, - extents.width, extents.height); - if (status) { - cairo_surface_destroy (intermediate); - return status; - } - - status = _cairo_clip_combine_to_surface (&gstate->clip, intermediate, &extents); - if (status) { - cairo_surface_destroy (intermediate); - return status; - } - - _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); - cairo_surface_destroy (intermediate); - - effective_mask = &intermediate_pattern.base; - mask_x = extents.x; - mask_y = extents.y; - - } else { - effective_mask = mask; - mask_x = mask_y = 0; - } - _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); - _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, effective_mask); - - status = _cairo_surface_composite (gstate->operator, - &source_pattern.base, - &mask_pattern.base, - gstate->target, - extents.x, extents.y, - extents.x - mask_x, extents.y - mask_y, - extents.x, extents.y, - extents.width, extents.height); + _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask); + + _get_mask_extents (gstate, &mask_pattern.base, &extents); + + status = _cairo_gstate_clip_and_composite (&gstate->clip, gstate->operator, + &source_pattern.base, + _cairo_gstate_mask_draw_func, &mask_pattern.base, + gstate->target, + &extents); - if (gstate->clip.surface) - _cairo_pattern_fini (&intermediate_pattern.base); _cairo_pattern_fini (&source_pattern.base); _cairo_pattern_fini (&mask_pattern.base); @@ -916,12 +1145,6 @@ _cairo_rectangle_intersect (cairo_rectangle_t *dest, cairo_rectangle_t *src) } } -static int -_cairo_rectangle_empty (cairo_rectangle_t *rect) -{ - return rect->width == 0 || rect->height == 0; -} - /* Composites a region representing a set of trapezoids. */ static cairo_status_t @@ -971,73 +1194,6 @@ _composite_trap_region (cairo_clip_t *clip, return status; } -/* Composites a set of trapezoids in the case where we need to create - * an intermediate surface to handle clip->surface - * - * Warning: This call modifies the coordinates of traps - */ -static cairo_status_t -_composite_traps_intermediate_surface (cairo_clip_t *clip, - cairo_pattern_t *src, - cairo_operator_t operator, - cairo_surface_t *dst, - cairo_traps_t *traps, - cairo_rectangle_t *extents) -{ - cairo_pattern_union_t pattern; - cairo_surface_t *intermediate; - cairo_surface_pattern_t intermediate_pattern; - cairo_status_t status; - - _cairo_traps_translate (traps, -extents->x, -extents->y); - - intermediate = _cairo_surface_create_similar_solid (clip->surface, - CAIRO_CONTENT_ALPHA, - extents->width, - extents->height, - CAIRO_COLOR_TRANSPARENT); - if (intermediate->status) - return CAIRO_STATUS_NO_MEMORY; - - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); - - status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD, - &pattern.base, - intermediate, - extents->x, extents->y, - 0, 0, - extents->width, - extents->height, - traps->traps, - traps->num_traps); - _cairo_pattern_fini (&pattern.base); - - if (status) - goto out; - - status = _cairo_clip_combine_to_surface (clip, intermediate, extents); - if (status) - goto out; - - _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); - - status = _cairo_surface_composite (operator, - src, - &intermediate_pattern.base, - dst, - extents->x, extents->y, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - - _cairo_pattern_fini (&intermediate_pattern.base); - - out: - cairo_surface_destroy (intermediate); - - return status; -} - /* Composites a region representing a set of trapezoids in the * case of a solid source (so we can use * _cairo_surface_fill_rectangles). @@ -1077,27 +1233,34 @@ _composite_trap_region_solid (cairo_clip_t *clip, return status; } -/* Composites a set of trapezoids in the general case where - clip->surface == NULL - */ static cairo_status_t -_composite_traps (cairo_clip_t *clip, - cairo_pattern_t *src, - cairo_operator_t operator, - cairo_surface_t *dst, - cairo_traps_t *traps, - cairo_rectangle_t *extents) -{ +_composite_traps_draw_func (void *closure, + cairo_operator_t operator, + cairo_pattern_t *src, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_t *extents) +{ + cairo_traps_t *traps = 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_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); + if (!src) + src = &pattern.base; + status = _cairo_surface_composite_trapezoids (operator, src, dst, - extents->x, extents->y, - extents->x, extents->y, - extents->width, - extents->height, + extents->x, extents->y, + extents->x - dst_x, extents->y - dst_y, + extents->width, extents->height, traps->traps, traps->num_traps); + _cairo_pattern_fini (&pattern.base); return status; } @@ -1134,65 +1297,65 @@ _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src, if (status) return status; - if (trap_region) { - status = _cairo_clip_intersect_to_region (clip, trap_region); - _region_rect_extents (trap_region, &extents); - } else { - cairo_box_t trap_extents; - _cairo_traps_extents (traps, &trap_extents); - _cairo_box_round_to_rectangle (&trap_extents, &extents); + if (_cairo_operator_bounded (operator)) + { + if (trap_region) { + status = _cairo_clip_intersect_to_region (clip, trap_region); + _region_rect_extents (trap_region, &extents); + } else { + cairo_box_t trap_extents; + _cairo_traps_extents (traps, &trap_extents); + _cairo_box_round_to_rectangle (&trap_extents, &extents); + status = _cairo_clip_intersect_to_rectangle (clip, &extents); + } + } + else + { + status = _cairo_surface_get_extents (dst, &extents); + if (status) + return status; status = _cairo_clip_intersect_to_rectangle (clip, &extents); + if (status) + return status; } if (status) goto out; - if (_cairo_rectangle_empty (&extents)) - /* Nothing to do */ - goto out; - - if (clip->surface) { - if (trap_region) { - /* If we are compositing a set of rectangles, we can set them as the - * clip region for the destination surface and use the clip surface - * as the mask. A clip region might not be supported, in which case - * we fall through to the next method - */ - status = _composite_trap_region (clip, src, operator, dst, - trap_region, &extents); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto out; - } - - /* Handle a clip surface by creating an intermediate surface. */ - status = _composite_traps_intermediate_surface (clip, src, operator, - dst, traps, &extents); - } else { - /* No clip surface */ - if (trap_region && src->type == CAIRO_PATTERN_SOLID) { - /* Solid rectangles are handled specially */ + if (trap_region && _cairo_operator_bounded (operator)) + { + if (src->type == CAIRO_PATTERN_SOLID && + !clip->surface && + trap_region-> + { + /* Solid rectangles special case */ status = _composite_trap_region_solid (clip, (cairo_solid_pattern_t *)src, operator, dst, trap_region); - } else { - if (trap_region) { - /* For a simple rectangle, we can just use composite(), for more - * rectangles, we have to set a clip region. The cost of rasterizing - * trapezoids is pretty high for most backends currently, so it's - * worthwhile even if a region is needed. - */ - status = _composite_trap_region (clip, src, operator, dst, - trap_region, &extents); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto out; - - /* If a clip regions aren't supported, fall through */ - } - - status = _composite_traps (clip, src, operator, - dst, traps, &extents); + goto out; } + + /* For a simple rectangle, we can just use composite(), for more + * rectangles, we have to set a clip region. The cost of rasterizing + * trapezoids is pretty high for most backends currently, so it's + * worthwhile even if a region is needed. + * + * If we have a clip surface, we set it as the mask. + * + * CAIRO_INT_STATUS_UNSUPPORTED will be returned if the region has + * more than rectangle and the destination doesn't support clip + * regions. In that case, we fall through. + */ + status = _composite_trap_region (clip, src, operator, dst, + trap_region, &extents); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + goto out; } + status = _cairo_gstate_clip_and_composite (clip, operator, src, + _composite_traps_draw_func, traps, + dst, + &extents); + out: if (trap_region) pixman_region_destroy (trap_region); @@ -1209,7 +1372,7 @@ _cairo_gstate_clip_and_composite_trapezoids (cairo_gstate_t *gstate, cairo_status_t status; _cairo_gstate_copy_transformed_source (gstate, &pattern.base); - + status = _cairo_surface_clip_and_composite_trapezoids (&pattern.base, gstate->operator, gstate->target, @@ -1681,6 +1844,58 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, return CAIRO_STATUS_SUCCESS; } +typedef struct { + cairo_scaled_font_t *font; + cairo_glyph_t *glyphs; + int num_glyphs; +} cairo_show_glyphs_info_t; + +static cairo_status_t +_cairo_gstate_show_glyphs_draw_func (void *closure, + cairo_operator_t operator, + cairo_pattern_t *src, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_t *extents) +{ + cairo_show_glyphs_info_t *glyph_info = closure; + cairo_pattern_union_t pattern; + cairo_status_t status; + + /* Modifying the glyph array is fine because we know that this function + * will be called only once, and we've already made a copy of the + * glyphs in the wrapper. + */ + if (dst_x != 0 || dst_y != 0) { + int i; + + for (i = 0; i < glyph_info->num_glyphs; ++i) + { + glyph_info->glyphs[i].x -= dst_x; + glyph_info->glyphs[i].y -= dst_y; + } + } + + _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); + if (!src) + src = &pattern.base; + + status = _cairo_scaled_font_show_glyphs (glyph_info->font, + operator, + src, dst, + extents->x, extents->y, + extents->x - dst_x, extents->y - dst_y, + extents->width, extents->height, + glyph_info->glyphs, + glyph_info->num_glyphs); + + if (src == &pattern.base) + _cairo_pattern_fini (&pattern.base); + + return status; +} + cairo_status_t _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, cairo_glyph_t *glyphs, @@ -1692,6 +1907,7 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, cairo_pattern_union_t pattern; cairo_box_t bbox; cairo_rectangle_t extents; + cairo_show_glyphs_info_t glyph_info; if (gstate->source->status) return gstate->source->status; @@ -1715,112 +1931,41 @@ _cairo_gstate_show_glyphs (cairo_gstate_t *gstate, &transformed_glyphs[i].x, &transformed_glyphs[i].y); } - - status = _cairo_scaled_font_glyph_bbox (gstate->scaled_font, - transformed_glyphs, num_glyphs, - &bbox); - _cairo_box_round_to_rectangle (&bbox, &extents); - - if (status) - goto CLEANUP_GLYPHS; - if (gstate->clip.surface) + if (_cairo_operator_bounded (gstate->operator)) { - cairo_surface_t *intermediate; - cairo_surface_pattern_t intermediate_pattern; - - _cairo_rectangle_intersect (&extents, &gstate->clip.surface_rect); - - /* Shortcut if empty */ - if (_cairo_rectangle_empty (&extents)) { - status = CAIRO_STATUS_SUCCESS; - goto BAIL1; - } - - intermediate = _cairo_surface_create_similar_solid (gstate->clip.surface, - CAIRO_CONTENT_ALPHA, - extents.width, - extents.height, - CAIRO_COLOR_TRANSPARENT); - if (intermediate->status) { - status = CAIRO_STATUS_NO_MEMORY; - goto BAIL1; - } - - /* move the glyphs again, from dev space to intermediate space */ - for (i = 0; i < num_glyphs; ++i) - { - transformed_glyphs[i].x -= extents.x; - transformed_glyphs[i].y -= extents.y; - } - - _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE); - - status = _cairo_scaled_font_show_glyphs (gstate->scaled_font, - CAIRO_OPERATOR_ADD, - &pattern.base, intermediate, - extents.x, extents.y, - 0, 0, - extents.width, extents.height, - transformed_glyphs, num_glyphs); - - _cairo_pattern_fini (&pattern.base); - - if (status) - goto BAIL2; - - _cairo_pattern_init_for_surface (&pattern.surface, - gstate->clip.surface); - - status = _cairo_surface_composite (CAIRO_OPERATOR_IN, - &pattern.base, - NULL, - intermediate, - extents.x - gstate->clip.surface_rect.x, - extents.y - gstate->clip.surface_rect.y, - 0, 0, - 0, 0, - extents.width, extents.height); - - _cairo_pattern_fini (&pattern.base); - + status = _cairo_scaled_font_glyph_bbox (gstate->scaled_font, + transformed_glyphs, num_glyphs, + &bbox); if (status) - goto BAIL2; - - _cairo_pattern_init_for_surface (&intermediate_pattern, intermediate); - _cairo_gstate_copy_transformed_source (gstate, &pattern.base); - - status = _cairo_surface_composite (gstate->operator, - &pattern.base, - &intermediate_pattern.base, - gstate->target, - extents.x, extents.y, - 0, 0, - extents.x, extents.y, - extents.width, extents.height); - _cairo_pattern_fini (&pattern.base); - _cairo_pattern_fini (&intermediate_pattern.base); - - BAIL2: - cairo_surface_destroy (intermediate); - BAIL1: - ; + goto CLEANUP_GLYPHS; + + _cairo_box_round_to_rectangle (&bbox, &extents); } else { - _cairo_pattern_init_copy (&pattern.base, gstate->source); - _cairo_gstate_copy_transformed_source (gstate, &pattern.base); + status = _cairo_surface_get_extents (gstate->target, &extents); + if (status) + goto CLEANUP_GLYPHS; + } + + status = _cairo_clip_intersect_to_rectangle (&gstate->clip, &extents); + if (status) + goto CLEANUP_GLYPHS; + + _cairo_gstate_copy_transformed_source (gstate, &pattern.base); - status = _cairo_scaled_font_show_glyphs (gstate->scaled_font, - gstate->operator, &pattern.base, - gstate->target, - extents.x, extents.y, - extents.x, extents.y, - extents.width, extents.height, - transformed_glyphs, num_glyphs); + glyph_info.font = gstate->scaled_font; + glyph_info.glyphs = transformed_glyphs; + glyph_info.num_glyphs = num_glyphs; + + status = _cairo_gstate_clip_and_composite (&gstate->clip, gstate->operator, + &pattern.base, + _cairo_gstate_show_glyphs_draw_func, &glyph_info, + gstate->target, + &extents); - _cairo_pattern_fini (&pattern.base); - } + _cairo_pattern_fini (&pattern.base); CLEANUP_GLYPHS: free (transformed_glyphs); diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index e86ed172..7c284b46 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -69,7 +69,8 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, surface->format = format; surface->data = (unsigned char *) pixman_image_get_data (pixman_image); - surface->owns_data = 0; + surface->owns_data = FALSE; + surface->has_clip = FALSE; surface->width = pixman_image_get_width (pixman_image); surface->height = pixman_image_get_height (pixman_image); @@ -613,6 +614,16 @@ _cairo_image_surface_composite (cairo_operator_t operator, } } + if (!_cairo_operator_bounded (operator)) + _cairo_surface_composite_fixup_unbounded (&dst->base, + &src_attr, src->width, src->height, + mask ? &mask_attr : NULL, + mask ? mask->width : 0, + mask ? mask->height : 0, + src_x, src_y, + mask_x, mask_y, + dst_x, dst_y, width, height); + if (mask) _cairo_pattern_release_surface (mask_pattern, &mask->base, &mask_attr); @@ -644,6 +655,48 @@ _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) +{ + int bpp, alpha, red, green, blue; + + if (surface->format != (cairo_format_t) -1) + return surface->format == CAIRO_FORMAT_A1 || surface->format == CAIRO_FORMAT_A8; + + pixman_format_get_masks (pixman_image_get_format (surface->pixman_image), + &bpp, &alpha, &red, &green, &blue); + + return red == 0 && blue == 0 && green == 0; +} + static cairo_int_status_t _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, @@ -661,8 +714,30 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, cairo_image_surface_t *dst = abstract_dst; cairo_image_surface_t *src; cairo_int_status_t status; - int render_reference_x, render_reference_y; - int render_src_x, render_src_y; + pixman_image_t *mask; + + /* Special case adding trapezoids onto a mask surface; we want to avoid + * creating an intermediate temporary mask unecessarily. + * + * We make the assumption here that the portion of the trapezoids + * contained within the surface is bounded by [dst_x,dst_y,width,height]; + * the Cairo core code passes bounds based on the trapezoid extents. + * + * Currently the check surface->has_clip is needed for correct + * functioning, since pixman_add_trapezoids() doesn't obey the + * surface clip, which is a libpixman bug , but there's no harm in + * falling through to the general case when the surface is clipped + * since libpixman would have to generate an intermediate mask anyways. + */ + if (operator == CAIRO_OPERATOR_ADD && + _cairo_pattern_is_opaque_solid (pattern) && + _cairo_image_surface_is_alpha_only (dst) && + !dst->has_clip) + { + pixman_add_trapezoids (dst->pixman_image, 0, 0, + (pixman_trapezoid_t *) traps, num_traps); + return CAIRO_STATUS_SUCCESS; + } status = _cairo_pattern_acquire_surface (pattern, &dst->base, src_x, src_y, width, height, @@ -671,28 +746,35 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t operator, if (status) return status; - if (traps[0].left.p1.y < traps[0].left.p2.y) { - render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x); - render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p1.y); - } else { - render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p2.x); - render_reference_y = _cairo_fixed_integer_floor (traps[0].left.p2.y); - } + status = _cairo_image_surface_set_attributes (src, &attributes); + if (status) + goto CLEANUP_SOURCE; - render_src_x = src_x + render_reference_x - dst_x; - render_src_y = src_y + render_reference_y - dst_y; + mask = _create_mask_image (width, height); + if (!mask) { + status = CAIRO_STATUS_NO_MEMORY; + goto CLEANUP_MASK; + } /* XXX: The pixman_trapezoid_t cast is evil and needs to go away * somehow. */ - status = _cairo_image_surface_set_attributes (src, &attributes); - if (status == CAIRO_STATUS_SUCCESS) - pixman_composite_trapezoids (_pixman_operator (operator), - src->pixman_image, - dst->pixman_image, - render_src_x + attributes.x_offset, - render_src_y + attributes.y_offset, - (pixman_trapezoid_t *) traps, num_traps); - + pixman_add_trapezoids (mask, - dst_x, - dst_y, + (pixman_trapezoid_t *) traps, num_traps); + + pixman_composite (_pixman_operator (operator), + src->pixman_image, + mask, + dst->pixman_image, + src_x + attributes.x_offset, + src_y + attributes.y_offset, + 0, 0, + dst_x, dst_y, + width, height); + + CLEANUP_MASK: + pixman_image_destroy (mask); + + CLEANUP_SOURCE: _cairo_pattern_release_surface (pattern, &src->base, &attributes); return status; @@ -713,6 +795,8 @@ _cairo_image_surface_set_clip_region (cairo_image_surface_t *surface, { pixman_image_set_clip_region (surface->pixman_image, region); + surface->has_clip = region != NULL; + return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 52804ebb..5349eb52 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1396,3 +1396,154 @@ _cairo_surface_show_glyphs (cairo_scaled_font_t *scaled_font, return status; } + +/** + * _cairo_surface_composite_fixup_unbounded: + * @dst: the destination surface + * @src_attr: source surface attributes (from _cairo_pattern_acquire_surface()) + * @src_width: width of source surface + * @src_height: height of source surface + * @mask_attr: mask surface attributes or %NULL if no mask + * @mask_width: width of mask surface + * @mask_height: height of mask surface + * @src_x: @src_x from _cairo_surface_composite() + * @src_y: @src_y from _cairo_surface_composite() + * @mask_x: @mask_x from _cairo_surface_composite() + * @mask_y: @mask_y from _cairo_surface_composite() + * @dst_x: @dst_x from _cairo_surface_composite() + * @dst_y: @dst_y from _cairo_surface_composite() + * @width: @width from _cairo_surface_composite() + * @height: @height_x from _cairo_surface_composite() + * + * Eeek! Too many parameters! This is a helper function to take care of fixing + * up for bugs in libpixman and RENDER where, when asked to composite an + * untransformed surface with an unbounded operator (like CLEAR or SOURCE) + * only the region inside both the source and the mask is affected. + * This function clears the region that should have been drawn but was wasn't. + **/ +void +_cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst, + cairo_surface_attributes_t *src_attr, + int src_width, + int src_height, + cairo_surface_attributes_t *mask_attr, + int mask_width, + int mask_height, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height) +{ + cairo_bool_t have_src = TRUE; + cairo_bool_t have_mask = mask_attr != NULL; + cairo_rectangle_t dst_rectangle; + cairo_rectangle_t drawn_rectangle; + cairo_rectangle_t rects[4]; + int num_rects = 0; + + /* The RENDER/libpixman operators are clipped to the bounds of the untransformed, + * non-repeating sources and masks. Other sources and masks can be ignored. + */ + if (!_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) || + src_attr->extend != CAIRO_EXTEND_NONE) + have_src = FALSE; + + if (have_mask && + (!_cairo_matrix_is_integer_translation (&mask_attr->matrix, NULL, NULL) || + mask_attr->extend != CAIRO_EXTEND_NONE)) + have_mask = FALSE; + + /* The area that was drawn is the area in the destination rectangle but not within + * the source or the mask. + */ + dst_rectangle.x = dst_x; + dst_rectangle.y = dst_y; + dst_rectangle.width = width; + dst_rectangle.height = height; + + drawn_rectangle = dst_rectangle; + + if (have_src) { + cairo_rectangle_t src_rectangle; + + src_rectangle.x = (dst_x - (src_x + src_attr->x_offset)); + src_rectangle.y = (dst_y - (src_y + src_attr->y_offset)); + src_rectangle.width = src_width; + src_rectangle.height = src_height; + + _cairo_rectangle_intersect (&drawn_rectangle, &src_rectangle); + } + + if (have_mask) { + cairo_rectangle_t mask_rectangle; + + mask_rectangle.x = (dst_x - (mask_x + mask_attr->x_offset)); + mask_rectangle.y = (dst_y - (mask_y + mask_attr->y_offset)); + mask_rectangle.width = mask_width; + mask_rectangle.height = mask_height; + + _cairo_rectangle_intersect (&drawn_rectangle, &mask_rectangle); + } + + /* Now compute the area that is in dst_rectangle but not in drawn_rectangle; + * this is the area we must clear; This computation could be done with + * regions, but the clumsiness of the libpixman API makes this easier. + */ + if (drawn_rectangle.width == 0 || drawn_rectangle.height == 0) + { + rects[num_rects].x = dst_rectangle.x; + rects[num_rects].y = dst_rectangle.y; + rects[num_rects].width = dst_rectangle.width; + rects[num_rects].height = dst_rectangle.height; + + num_rects++; + } + else + { + if (dst_rectangle.y < drawn_rectangle.y) { + rects[num_rects].x = dst_rectangle.x; + rects[num_rects].y = dst_rectangle.y; + rects[num_rects].width = dst_rectangle.width; + rects[num_rects].height = drawn_rectangle.y - dst_rectangle.y; + + num_rects++; + } + + if (dst_rectangle.x < drawn_rectangle.x) { + rects[num_rects].x = dst_rectangle.x; + rects[num_rects].y = drawn_rectangle.y; + rects[num_rects].width = drawn_rectangle.x - dst_rectangle.x; + rects[num_rects].height = drawn_rectangle.height; + + num_rects++; + } + + if (dst_rectangle.x + dst_rectangle.width > drawn_rectangle.x + drawn_rectangle.width) { + rects[num_rects].x = drawn_rectangle.x + drawn_rectangle.width; + rects[num_rects].y = drawn_rectangle.y; + rects[num_rects].width = (dst_rectangle.x + dst_rectangle.width) - (drawn_rectangle.x + drawn_rectangle.width); + rects[num_rects].height = drawn_rectangle.height; + + num_rects++; + } + + if (dst_rectangle.y + dst_rectangle.height > drawn_rectangle.y + drawn_rectangle.height) { + rects[num_rects].x = dst_rectangle.x; + rects[num_rects].y = drawn_rectangle.y + drawn_rectangle.height; + rects[num_rects].width = dst_rectangle.width; + rects[num_rects].height = (dst_rectangle.y + dst_rectangle.height) - (drawn_rectangle.y + drawn_rectangle.height); + + num_rects++; + } + } + + if (num_rects > 0) { + _cairo_surface_fill_rectangles (dst, CAIRO_OPERATOR_SOURCE, CAIRO_COLOR_TRANSPARENT, + rects, num_rects); + } +} + diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 4f4e47e3..fc6ff8b8 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -1137,6 +1137,16 @@ _cairo_xlib_surface_composite (cairo_operator_t operator, dst_x, dst_y, width, height); } + + if (!_cairo_operator_bounded (operator)) + _cairo_surface_composite_fixup_unbounded (&dst->base, + &src_attr, src->width, src->height, + mask ? &mask_attr : NULL, + mask ? mask->width : 0, + mask ? mask->height : 0, + src_x, src_y, + mask_x, mask_y, + dst_x, dst_y, width, height); break; case DO_XCOPYAREA: @@ -1214,6 +1224,96 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } +/* Creates an A8 picture of size @width x @height, initialized with @color + */ +static Picture +_create_a8_picture (cairo_xlib_surface_t *surface, + XRenderColor *color, + int width, + int height, + cairo_bool_t repeat) +{ + XRenderPictureAttributes pa; + unsigned long mask = 0; + + Pixmap pixmap = XCreatePixmap (surface->dpy, surface->drawable, + width, height, + 8); + Picture picture; + + if (repeat) { + pa.repeat = TRUE; + mask = CPRepeat; + } + + picture = XRenderCreatePicture (surface->dpy, pixmap, + XRenderFindStandardFormat (surface->dpy, PictStandardA8), + mask, &pa); + XRenderFillRectangle (surface->dpy, PictOpSrc, picture, color, + 0, 0, width, height); + XFreePixmap (surface->dpy, pixmap); + + return picture; +} + +/* Creates a temporary mask for the trapezoids covering the area + * [@dst_x, @dst_y, @width, @height] of the destination surface. + */ +static Picture +_create_trapezoid_mask (cairo_xlib_surface_t *dst, + cairo_trapezoid_t *traps, + int num_traps, + int dst_x, + int dst_y, + int width, + int height) + +{ + XRenderColor transparent = { 0, 0, 0, 0 }; + XRenderColor solid = { 0xffff, 0xffff, 0xffff, 0xffff }; + Picture mask_picture, solid_picture; + XTrapezoid *offset_traps; + int i; + + /* This would be considerably simpler using XRenderAddTraps(), but since + * we are only using this in the unbounded-operator case, we stick with + * XRenderCompositeTrapezoids, which is available on older versions + * of RENDER rather than conditionalizing. We should still hit an + * optimization that avoids creating another intermediate surface on + * the servers that have XRenderAddTraps(). + */ + mask_picture = _create_a8_picture (dst, &transparent, width, height, FALSE); + solid_picture = _create_a8_picture (dst, &solid, width, height, TRUE); + + offset_traps = malloc (sizeof (XTrapezoid) * num_traps); + if (!offset_traps) + return None; + + for (i = 0; i < num_traps; i++) { + offset_traps[i].top = traps[i].top - 0x10000 * dst_y; + offset_traps[i].bottom = traps[i].bottom - 0x10000 * dst_y; + offset_traps[i].left.p1.x = traps[i].left.p1.x - 0x10000 * dst_x; + offset_traps[i].left.p1.y = traps[i].left.p1.y - 0x10000 * dst_y; + offset_traps[i].left.p2.x = traps[i].left.p2.x - 0x10000 * dst_x; + offset_traps[i].left.p2.y = traps[i].left.p2.y - 0x10000 * dst_y; + offset_traps[i].right.p1.x = traps[i].right.p1.x - 0x10000 * dst_x; + offset_traps[i].right.p1.y = traps[i].right.p1.y - 0x10000 * dst_y; + offset_traps[i].right.p2.x = traps[i].right.p2.x - 0x10000 * dst_x; + offset_traps[i].right.p2.y = traps[i].right.p2.y - 0x10000 * dst_y; + } + + XRenderCompositeTrapezoids (dst->dpy, PictOpAdd, + solid_picture, mask_picture, + XRenderFindStandardFormat (dst->dpy, PictStandardA8), + 0, 0, + offset_traps, num_traps); + + XRenderFreePicture (dst->dpy, solid_picture); + free (offset_traps); + + return mask_picture; +} + static cairo_int_status_t _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, cairo_pattern_t *pattern, @@ -1266,10 +1366,43 @@ _cairo_xlib_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; - /* XXX: The XTrapezoid cast is evil and needs to go away somehow. */ _cairo_xlib_surface_ensure_dst_picture (dst); status = _cairo_xlib_surface_set_attributes (src, &attributes); - if (status == CAIRO_STATUS_SUCCESS) + if (status) + goto FAIL; + + if (!_cairo_operator_bounded (operator)) { + /* XRenderCompositeTrapezoids() creates a mask only large enough for the + * trapezoids themselves, but if the operator is unbounded, then we need + * to actually composite all the way out to the bounds, so we create + * the mask and composite ourselves. There actually would + * be benefit to doing this in all cases, since RENDER implementations + * will frequently create a too temporary big mask, ignoring destination + * bounds and clip. (XRenderAddTraps() could be used to make creating + * the mask somewhat cheaper.) + */ + Picture mask_picture = _create_trapezoid_mask (dst, traps, num_traps, + dst_x, dst_y, width, height); + if (!mask_picture) { + status = CAIRO_STATUS_NO_MEMORY; + goto FAIL; + } + + XRenderComposite (dst->dpy, + _render_operator (operator), + src->src_picture, + mask_picture, + dst->dst_picture, + src_x + attributes.x_offset, + src_y + attributes.y_offset, + 0, 0, + dst_x, dst_y, + width, height); + + XRenderFreePicture (dst->dpy, mask_picture); + + } else { + /* XXX: The XTrapezoid cast is evil and needs to go away somehow. */ XRenderCompositeTrapezoids (dst->dpy, _render_operator (operator), src->src_picture, dst->dst_picture, @@ -1277,6 +1410,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t operator, render_src_x + attributes.x_offset, render_src_y + attributes.y_offset, (XTrapezoid *) traps, num_traps); + } FAIL: _cairo_pattern_release_surface (pattern, &src->base, &attributes); @@ -1735,6 +1869,7 @@ typedef struct { cairo_glyph_cache_key_t key; GlyphSet glyphset; Glyph glyph; + cairo_glyph_size_t size; } glyphset_cache_entry_t; static Glyph @@ -1789,6 +1924,7 @@ _xlib_glyphset_cache_create_entry (void *abstract_cache, entry->glyph = None; entry->glyphset = None; entry->key.base.memory = 0; + entry->size.x = entry->size.y = entry->size.width = entry->size.height = 0; goto out; } @@ -1797,6 +1933,8 @@ _xlib_glyphset_cache_create_entry (void *abstract_cache, data = im->image->data; + entry->size = im->size; + glyph_info.width = im->size.width; glyph_info.height = im->size.height; @@ -2123,7 +2261,7 @@ _cairo_xlib_surface_show_glyphs32 (cairo_scaled_font_t *scaled_font, _render_operator (operator), src->src_picture, self->dst_picture, - cache->a8_pict_format, + mask_format, source_x, source_y, 0, 0, elts, count); @@ -2351,7 +2489,70 @@ _cairo_xlib_surface_show_glyphs8 (cairo_scaled_font_t *scaled_font, return CAIRO_STATUS_NO_MEMORY; } +/* Handles clearing the regions that are outside of the temporary + * mask created by XRenderCompositeText[N] but should be affected + * by an unbounded operator like CAIRO_OPERATOR_SOURCE. + */ +static void +_show_glyphs_fixup_unbounded (cairo_xlib_surface_t *self, + cairo_surface_attributes_t *src_attr, + cairo_xlib_surface_t *src, + const cairo_glyph_t *glyphs, + glyphset_cache_entry_t **entries, + int num_glyphs, + int src_x, + int src_y, + int dst_x, + int dst_y, + int width, + int height) +{ + cairo_surface_attributes_t mask_attr; + int x1 = INT_MAX; + int x2 = INT_MIN; + int y1 = INT_MAX; + int y2 = INT_MIN; + int i; + /* Compute the size of the glyph mask as the bounding box + * of all the glyphs. + */ + for (i = 0; i < num_glyphs; ++i) { + int thisX, thisY; + + if (entries[i] == NULL || !entries[i]->glyph) + continue; + + thisX = (int) floor (glyphs[i].x + 0.5); + thisY = (int) floor (glyphs[i].y + 0.5); + + if (thisX + entries[i]->size.x < x1) + x1 = thisX + entries[i]->size.x; + if (thisX + entries[i]->size.x + entries[i]->size.width > x2) + x2 = thisX + entries[i]->size.x + entries[i]->size.width; + if (thisY + entries[i]->size.y < y1) + y1 = thisY + entries[i]->size.y; + if (thisY + entries[i]->size.y + entries[i]->size.height > y2) + y2 = thisY + entries[i]->size.y + entries[i]->size.height; + } + + if (x1 >= x2 || y1 >= y2) + x1 = x2 = y1 = y2 = 0; + + cairo_matrix_init_identity (&mask_attr.matrix); + mask_attr.extend = CAIRO_EXTEND_NONE; + mask_attr.filter = CAIRO_FILTER_NEAREST; + mask_attr.x_offset = 0; + mask_attr.y_offset = 0; + + _cairo_surface_composite_fixup_unbounded (&self->base, + src_attr, src->width, src->height, + &mask_attr, x2 - x1, y2 - y1, + src_x, src_y, + dst_x - x1, dst_y - y1, + dst_x, dst_y, width, height); +} + static cairo_int_status_t _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font, cairo_operator_t operator, @@ -2462,6 +2663,13 @@ _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t *scaled_font, glyphs, entries, num_glyphs); } + if (!_cairo_operator_bounded (operator)) + _show_glyphs_fixup_unbounded (self, + &attributes, src, + glyphs, entries, num_glyphs, + source_x, source_y, + dest_x, dest_y, width, height); + UNLOCK: _unlock_xlib_glyphset_caches (cache); diff --git a/src/cairoint.h b/src/cairoint.h index f6dabd81..b0a78784 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -879,7 +879,9 @@ struct _cairo_image_surface { /* libic-specific fields */ cairo_format_t format; unsigned char *data; - int owns_data; + cairo_bool_t owns_data; + cairo_bool_t has_clip; + int width; int height; @@ -1312,6 +1314,8 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, int num_glyphs, cairo_path_fixed_t *path); +cairo_bool_t +_cairo_operator_bounded (cairo_operator_t operator); /* cairo_color.c */ cairo_private const cairo_color_t * @@ -1695,6 +1699,23 @@ _cairo_surface_show_glyphs (cairo_scaled_font_t *scaled_font, const cairo_glyph_t *glyphs, int num_glyphs); +void +_cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst, + cairo_surface_attributes_t *src_attr, + int src_width, + int src_height, + cairo_surface_attributes_t *mask_attr, + int mask_width, + int mask_height, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height); + /* cairo_image_surface.c */ cairo_private cairo_format_t diff --git a/test/Makefile.am b/test/Makefile.am index 8a2db852..29ccb8ec 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -2,6 +2,7 @@ TESTS = \ a8-mask \ clip-nesting \ +clip-operator \ clip-twice \ composite-integer-translate-source \ composite-integer-translate-over \ @@ -41,6 +42,7 @@ text-rotate \ transforms \ translate-show-surface \ trap-clip \ +unbounded-operator \ user-data \ rel-path @@ -62,6 +64,7 @@ endif EXTRA_DIST = \ a8-mask.png \ clip-nesting-ref.png \ +clip-operator-ref.png \ clip-twice-ref.png \ composite-integer-translate-source-ref.png \ composite-integer-translate-over-ref.png \ @@ -96,6 +99,7 @@ text-antialias-none-ref.png \ transforms-ref.png \ translate-show-surface-ref.png \ trap-clip-ref.png \ +unbounded-operator-ref.png \ rel-path-ref.png # Any test for which the code committed to CVS is expected to fail @@ -153,6 +157,7 @@ LDADDS = libcairotest.la $(top_builddir)/src/libcairo.la # from autogen.sh. My, but this is painful... a8_mask_LDADD = $(LDADDS) clip_nesting_LDADD = $(LDADDS) +clip_operator_LDADD = $(LDADDS) clip_twice_LDADD = $(LDADDS) composite_integer_translate_source_LDADD = $(LDADDS) composite_integer_translate_over_LDADD = $(LDADDS) @@ -195,6 +200,7 @@ text_rotate_LDADD = $(LDADDS) transforms_LDADD = $(LDADDS) translate_show_surface_LDADD = $(LDADDS) trap_clip_LDADD = $(LDADDS) +unbounded_operator_LDADD = $(LDADDS) user_data_LDADD = $(LDADDS) rel_path_LDADD = $(LDADDS) xlib_surface_LDADD = $(LDADDS) diff --git a/test/clip-operator.c b/test/clip-operator.c new file mode 100644 index 00000000..6cc5216c --- /dev/null +++ b/test/clip-operator.c @@ -0,0 +1,205 @@ +/* + * Copyright © 2005 Red Hat, Inc. + * + * 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 + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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: Kristian Høgsberg + */ + +#include +#include "cairo-test.h" +#include + +#define WIDTH 64 +#define HEIGHT 64 +#define PAD 10 + +const char png_filename[] = "romedalen.png"; + +static void +draw_mask (cairo_t *cr, int x, int y) +{ + cairo_surface_t *mask_surface; + cairo_t *cr2; + + double width = (int)(0.9 * WIDTH); + double height = (int)(0.9 * HEIGHT); + x += 0.05 * WIDTH; + y += 0.05 * HEIGHT; + + mask_surface = cairo_surface_create_similar (cairo_get_target (cr), + CAIRO_CONTENT_ALPHA, + width, height); + cr2 = cairo_create (mask_surface); + + cairo_save (cr2); + cairo_set_source_rgba (cr2, 0, 0, 0, 0); /* transparent */ + cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr2); + cairo_restore (cr2); + + cairo_set_source_rgb (cr2, 1, 1, 1); /* white */ + + cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.45 * height, 0, 2 * M_PI); + cairo_fill (cr2); + + cairo_destroy (cr2); + + cairo_mask_surface (cr, mask_surface, x, y); + + cairo_surface_destroy (mask_surface); +} + +static void +draw_glyphs (cairo_t *cr, int x, int y) +{ + cairo_text_extents_t extents; + + cairo_set_font_size (cr, 0.8 * HEIGHT); + + cairo_text_extents (cr, "FG", &extents); + cairo_move_to (cr, + x + (WIDTH - extents.width) / 2 - extents.x_bearing, + y + (HEIGHT - extents.height) / 2 - extents.y_bearing); + cairo_show_text (cr, "FG"); +} + +static void +draw_polygon (cairo_t *cr, int x, int y) +{ + double width = (int)(0.9 * WIDTH); + double height = (int)(0.9 * HEIGHT); + x += 0.05 * WIDTH; + y += 0.05 * HEIGHT; + + cairo_new_path (cr); + cairo_move_to (cr, x, y); + cairo_line_to (cr, x, y + height); + cairo_line_to (cr, x + width / 2, y + 3 * height / 4); + cairo_line_to (cr, x + width, y + height); + cairo_line_to (cr, x + width, y); + cairo_line_to (cr, x + width / 2, y + height / 4); + cairo_close_path (cr); + cairo_fill (cr); +} + +static void +draw_rects (cairo_t *cr, int x, int y) +{ + double block_width = (int)(0.33 * WIDTH + 0.5); + double block_height = (int)(0.33 * HEIGHT + 0.5); + int i, j; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + if ((i + j) % 2 == 0) + cairo_rectangle (cr, + x + block_width * i, y + block_height * j, + block_width, block_height); + + cairo_fill (cr); +} + +static void (*draw_funcs[])(cairo_t *cr, int x, int y) = { + draw_mask, + draw_glyphs, + draw_polygon, + draw_rects +}; + +#define N_OPERATORS (1 + CAIRO_OPERATOR_SATURATE - CAIRO_OPERATOR_CLEAR) + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) +#define IMAGE_WIDTH (N_OPERATORS * (WIDTH + PAD) + PAD) +#define IMAGE_HEIGHT (ARRAY_SIZE (draw_funcs) * (HEIGHT + PAD) + PAD) + +static cairo_test_t test = { + "clip-operator", + "Surface clipping with different operators", + IMAGE_WIDTH, IMAGE_HEIGHT +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + int j, x, y; + cairo_operator_t op; + cairo_font_options_t *font_options; + cairo_pattern_t *pattern; + + cairo_select_font_face (cr, "Bitstream Vera Sans", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size (cr, 0.9 * HEIGHT); + + font_options = cairo_font_options_create (); + + cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); + cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY); + + cairo_set_font_options (cr, font_options); + cairo_font_options_destroy (font_options); + + for (j = 0; j < ARRAY_SIZE (draw_funcs); j++) { + for (op = CAIRO_OPERATOR_CLEAR; op <= CAIRO_OPERATOR_SATURATE; op++) { + x = op * (WIDTH + PAD) + PAD; + y = j * (HEIGHT + PAD) + PAD; + + cairo_save (cr); + + pattern = cairo_pattern_create_linear (x + WIDTH, y, + x, y + HEIGHT); + cairo_pattern_add_color_stop_rgba (pattern, 0.2, + 0.0, 0.0, 1.0, 1.0); /* Solid blue */ + cairo_pattern_add_color_stop_rgba (pattern, 0.8, + 0.0, 0.0, 1.0, 0.0); /* Transparent blue */ + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, x, y, WIDTH, HEIGHT); + cairo_fill (cr); + + cairo_set_operator (cr, op); + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); + + cairo_move_to (cr, x, y); + cairo_line_to (cr, x + WIDTH, y); + cairo_line_to (cr, x, y + HEIGHT); + cairo_clip (cr); + + draw_funcs[j] (cr, x, y); + if (cairo_status (cr)) + cairo_test_log ("%d %d HERE!\n", op, j); + + cairo_restore (cr); + } + } + + if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) + cairo_test_log ("%d %d .HERE!\n", op, j); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +} diff --git a/test/composite-integer-translate-over-repeat.c b/test/composite-integer-translate-over-repeat.c index ed55f63a..61a0ea71 100644 --- a/test/composite-integer-translate-over-repeat.c +++ b/test/composite-integer-translate-over-repeat.c @@ -44,7 +44,7 @@ draw (cairo_t *cr, int width, int height) cairo_fill (cr); cairo_translate (cr, OFFSET, OFFSET); - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source (cr, pat); cairo_rectangle (cr, 0, 0, SIZE - OFFSET, SIZE - OFFSET); cairo_fill (cr); diff --git a/test/unbounded-operator.c b/test/unbounded-operator.c new file mode 100644 index 00000000..45535b97 --- /dev/null +++ b/test/unbounded-operator.c @@ -0,0 +1,201 @@ +/* + * Copyright © 2005 Red Hat, Inc. + * + * 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 + * Red Hat, Inc. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Red Hat, Inc. makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RED HAT, INC. 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. + * + * Authors: Kristian Høgsberg + * Owen Taylor + */ + +#include +#include "cairo-test.h" +#include + +#define WIDTH 64 +#define HEIGHT 64 +#define PAD 10 + +static void +draw_mask (cairo_t *cr, int x, int y) +{ + cairo_surface_t *mask_surface; + cairo_t *cr2; + + double width = (int)(0.9 * WIDTH); + double height = (int)(0.9 * HEIGHT); + x += 0.05 * WIDTH; + y += 0.05 * HEIGHT; + + mask_surface = cairo_surface_create_similar (cairo_get_target (cr), + CAIRO_CONTENT_ALPHA, + width, height); + cr2 = cairo_create (mask_surface); + + cairo_save (cr2); + cairo_set_source_rgba (cr2, 0, 0, 0, 0); /* transparent */ + cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr2); + cairo_restore (cr2); + + cairo_set_source_rgb (cr2, 1, 1, 1); /* white */ + + cairo_arc (cr2, 0.5 * width, 0.5 * height, 0.45 * height, 0, 2 * M_PI); + cairo_fill (cr2); + + cairo_destroy (cr2); + + cairo_mask_surface (cr, mask_surface, x, y); + + cairo_surface_destroy (mask_surface); +} + +static void +draw_glyphs (cairo_t *cr, int x, int y) +{ + cairo_text_extents_t extents; + + cairo_set_font_size (cr, 0.8 * HEIGHT); + + cairo_text_extents (cr, "FG", &extents); + cairo_move_to (cr, + x + (WIDTH - extents.width) / 2 - extents.x_bearing, + y + (HEIGHT - extents.height) / 2 - extents.y_bearing); + cairo_show_text (cr, "FG"); +} + +static void +draw_polygon (cairo_t *cr, int x, int y) +{ + double width = (int)(0.9 * WIDTH); + double height = (int)(0.9 * HEIGHT); + x += 0.05 * WIDTH; + y += 0.05 * HEIGHT; + + cairo_new_path (cr); + cairo_move_to (cr, x, y); + cairo_line_to (cr, x, y + height); + cairo_line_to (cr, x + width / 2, y + 3 * height / 4); + cairo_line_to (cr, x + width, y + height); + cairo_line_to (cr, x + width, y); + cairo_line_to (cr, x + width / 2, y + height / 4); + cairo_close_path (cr); + cairo_fill (cr); +} + +static void +draw_rects (cairo_t *cr, int x, int y) +{ + double block_width = (int)(0.33 * WIDTH + 0.5); + double block_height = (int)(0.33 * HEIGHT + 0.5); + int i, j; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + if ((i + j) % 2 == 0) + cairo_rectangle (cr, + x + block_width * i, y + block_height * j, + block_width, block_height); + + cairo_fill (cr); +} + +static void (*draw_funcs[])(cairo_t *cr, int x, int y) = { + draw_mask, + draw_glyphs, + draw_polygon, + draw_rects +}; + +static cairo_operator_t operators[] = { + CAIRO_OPERATOR_CLEAR, CAIRO_OPERATOR_SOURCE, CAIRO_OPERATOR_IN, + CAIRO_OPERATOR_OUT, CAIRO_OPERATOR_DEST_IN, CAIRO_OPERATOR_DEST_ATOP +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) +#define IMAGE_WIDTH (ARRAY_SIZE (operators) * (WIDTH + PAD) + PAD) +#define IMAGE_HEIGHT (ARRAY_SIZE (draw_funcs) * (HEIGHT + PAD) + PAD) + +static cairo_test_t test = { + "unbounded-operator", + "Operators with an effect for transparent source/mask", + IMAGE_WIDTH, IMAGE_HEIGHT +}; + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + int i, j, x, y; + cairo_font_options_t *font_options; + cairo_pattern_t *pattern; + + cairo_select_font_face (cr, "Bitstream Vera Sans", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_NORMAL); + + font_options = cairo_font_options_create (); + + cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); + cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY); + + cairo_set_font_options (cr, font_options); + cairo_font_options_destroy (font_options); + + for (j = 0; j < ARRAY_SIZE (draw_funcs); j++) { + for (i = 0; i < ARRAY_SIZE (operators); i++) { + x = i * (WIDTH + PAD) + PAD; + y = j * (HEIGHT + PAD) + PAD; + + cairo_save (cr); + + pattern = cairo_pattern_create_linear (x + WIDTH, y, + x, y + HEIGHT); + cairo_pattern_add_color_stop_rgba (pattern, 0.2, + 0.0, 0.0, 1.0, 1.0); /* Solid blue */ + cairo_pattern_add_color_stop_rgba (pattern, 0.8, + 0.0, 0.0, 1.0, 0.0); /* Transparent blue */ + cairo_set_source (cr, pattern); + cairo_pattern_destroy (pattern); + + cairo_rectangle (cr, x, y, WIDTH, HEIGHT); + cairo_fill_preserve (cr); + cairo_clip (cr); + + cairo_set_operator (cr, operators[i]); + cairo_set_source_rgb (cr, 1.0, 0.0, 0.0); + + draw_funcs[j] (cr, x, y); + if (cairo_status (cr)) + cairo_test_log ("%d %d HERE!\n", i, j); + + cairo_restore (cr); + } + } + + if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) + cairo_test_log ("%d %d .HERE!\n", i, j); + + return CAIRO_TEST_SUCCESS; +} + +int +main (void) +{ + return cairo_test (&test, draw); +} -- cgit v1.2.3 From d4b24dc974bd4298c1ad8d06efc4f3dfea68ee03 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 8 Aug 2005 13:50:02 +0000 Subject: Add reference images --- test/clip-operator-ref.png | Bin 0 -> 37486 bytes test/unbounded-operator-ref.png | Bin 0 -> 14178 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/clip-operator-ref.png create mode 100644 test/unbounded-operator-ref.png diff --git a/test/clip-operator-ref.png b/test/clip-operator-ref.png new file mode 100644 index 00000000..551d13f7 Binary files /dev/null and b/test/clip-operator-ref.png differ diff --git a/test/unbounded-operator-ref.png b/test/unbounded-operator-ref.png new file mode 100644 index 00000000..7e3b3a07 Binary files /dev/null and b/test/unbounded-operator-ref.png differ -- cgit v1.2.3 From 7caa7cccf2e5aff083d5a88fbace0b24430397de Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Mon, 8 Aug 2005 13:50:59 +0000 Subject: Update doc comment. --- ChangeLog | 5 +++++ src/cairo-surface.c | 12 +++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0516c5c3..96a30930 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-08 Kristian Høgsberg + + * src/cairo-surface.c (_cairo_surface_set_clip_path): Update doc + comment. + 2005-08-08 Owen Taylor * src/cairo-gstate.c (_cairo_operator_bounded): Add a function to test diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 5349eb52..6c0c7691 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1274,14 +1274,12 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface, /** * _cairo_surface_set_clip_path: - * @surface: the #cairo_surface_t to reset the clip on - * @path: the path to intersect against the current clipping path - * @fill_rule: fill rule to use for clipping - * @tolerance: tesselation to use for tesselating clipping path - * @serial: the clip serial number associated with the region + * @surface: the #cairo_surface_t to set the clip on + * @clip_path: the clip path to set + * @serial: the clip serial number associated with the clip path * - * Sets the clipping path to be the intersection of the current - * clipping path of the surface and the given path. + * Sets the given clipping path for the surface and assigns the + * clipping serial to the surface. **/ static cairo_status_t _cairo_surface_set_clip_path (cairo_surface_t *surface, -- cgit v1.2.3 From 8478804d9818deb3a1f86e8e22200c40f83962bf Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 8 Aug 2005 14:11:00 +0000 Subject: Fix accidentally committed line. --- ChangeLog | 5 +++++ src/cairo-gstate.c | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96a30930..18d113fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-08 Owen Taylor + + * src/cairo-gstate.c: (_cairo_surface_clip_and_composite_trapezoids): + Fix accidentally committed line. + 2005-08-08 Kristian Høgsberg * src/cairo-surface.c (_cairo_surface_set_clip_path): Update doc diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 1e005f84..0456e846 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -1324,9 +1324,7 @@ _cairo_surface_clip_and_composite_trapezoids (cairo_pattern_t *src, if (trap_region && _cairo_operator_bounded (operator)) { - if (src->type == CAIRO_PATTERN_SOLID && - !clip->surface && - trap_region-> + if (src->type == CAIRO_PATTERN_SOLID && !clip->surface) { /* Solid rectangles special case */ status = _composite_trap_region_solid (clip, (cairo_solid_pattern_t *)src, -- cgit v1.2.3 From 69f140b654df878b9ba86d61062d235bbebef7a2 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 8 Aug 2005 14:13:50 +0000 Subject: Add a return value after ASSERT_NOT_REACHED to quiet an anxious compiler. --- ChangeLog | 5 +++++ src/cairo-gstate.c | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 18d113fd..3c37fa8e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-08 Carl Worth + + * src/cairo-gstate.c: (_cairo_operator_bounded): Add a return + value after ASSERT_NOT_REACHED to quiet an anxious compiler. + 2005-08-08 Owen Taylor * src/cairo-gstate.c: (_cairo_surface_clip_and_composite_trapezoids): diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 0456e846..e63f29f6 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -741,6 +741,7 @@ _cairo_operator_bounded (cairo_operator_t operator) } ASSERT_NOT_REACHED; + return FALSE; } typedef cairo_status_t (*cairo_draw_func_t) (void *closure, -- cgit v1.2.3 From d51a35543ca405dda788eb6433e6bb30dc3c7cf5 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Mon, 8 Aug 2005 14:27:01 +0000 Subject: Don't free the glyph if the entry doesn't have a glyph. (Maybe #3909, Carlos Garnacho Parro) --- ChangeLog | 6 ++++++ src/cairo-xlib-surface.c | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3c37fa8e..3ff445b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-08-08 Owen Taylor + + * src/cairo-xlib-surface.c (_xlib_glyphset_cache_destroy_entry): + Don't free the glyph if the entry doesn't have a glyph. + (Maybe #3909, Carlos Garnacho Parro) + 2005-08-08 Carl Worth * src/cairo-gstate.c: (_cairo_operator_bounded): Add a return diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index fc6ff8b8..9c87cc95 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2073,8 +2073,9 @@ _xlib_glyphset_cache_destroy_entry (void *abstract_cache, glyphset_cache_entry_t *entry = abstract_entry; _cairo_unscaled_font_destroy (entry->key.unscaled); - XRenderFreeGlyphs (cache->display, entry->glyphset, - &(entry->glyph), 1); + if (entry->glyph) + XRenderFreeGlyphs (cache->display, entry->glyphset, + &(entry->glyph), 1); free (entry); } -- cgit v1.2.3 From 8bdad8ffa2962c9dff1e86e9bd131d588a1ebd2f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 8 Aug 2005 15:50:55 +0000 Subject: Fix gnome-announce-list address. --- ChangeLog | 4 ++++ RELEASING | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3ff445b5..baa8473f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-08-08 Carl Worth + + * RELEASING: Fix gnome-announce-list address. + 2005-08-08 Owen Taylor * src/cairo-xlib-surface.c (_xlib_glyphset_cache_destroy_entry): diff --git a/RELEASING b/RELEASING index b25d127e..3d38068f 100644 --- a/RELEASING +++ b/RELEASING @@ -82,6 +82,6 @@ fixes are committed. Here are the steps to follow: 8) Add a "-head" to CAIRO_VERSION in configure, and commit. 9) Send a message to cairo-announce@cairographics.org and CC - gnome-announce-list to announce the + gnome-announce-list@gnome.org to announce the new snapshot using the text provided from "make release-publish". -- cgit v1.2.3 From 578b45c9032fd00b68fc1709d61e915d74a527c7 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 8 Aug 2005 17:32:24 +0000 Subject: Ignore clip-operator and unbounded-operator. --- ChangeLog | 4 ++++ test/.cvsignore | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index baa8473f..6e685b53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-08-08 Carl Worth + + * test/.cvsignore: Ignore clip-operator and unbounded-operator. + 2005-08-08 Carl Worth * RELEASING: Fix gnome-announce-list address. diff --git a/test/.cvsignore b/test/.cvsignore index e228c3e6..c1895986 100644 --- a/test/.cvsignore +++ b/test/.cvsignore @@ -4,6 +4,7 @@ Makefile Makefile.in a8-mask clip-nesting +clip-operator clip-twice composite-integer-translate-source composite-integer-translate-over @@ -52,6 +53,7 @@ text-rotate transforms translate-show-surface trap-clip +unbounded-operator user-data xlib-surface *-image-out.png -- cgit v1.2.3 From 53444c286ef45fa0054ba6ab94dac11016e9600c Mon Sep 17 00:00:00 2001 From: Billy Biggs Date: Mon, 8 Aug 2005 18:35:22 +0000 Subject: 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 6e685b53..cff7534a 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 bb04c887..7a8e1641 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 1c0edccb..a27a2945 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 6fd8e163..78c9d3bf 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 8b29acc7..3f2ec8d6 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 a56f5798..23eb78c9 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 a4b8d533..d479da8f 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 402b34f1..7e0f3387 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 7e82883d..489afdba 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 e63f29f6..a657f15e 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 7c284b46..f7dbc8cf 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 234c6ccf..f37a8916 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 3781fabc..f218ae24 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 c068c8aa..6b863721 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 0b2962c2..a897ed0e 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 6c0c7691..8353d329 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 05e39b55..2a7395f6 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 9c87cc95..7f4b8489 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 05c87a42..4c4b03eb 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 41310be3..1d871c81 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 b0a78784..2a5f45e3 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 29ccb8ec..e30af427 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 00000000..b9485922 Binary files /dev/null and b/test/unantialiased-shapes-ref.png differ diff --git a/test/unantialiased-shapes.c b/test/unantialiased-shapes.c new file mode 100644 index 00000000..eaadf417 --- /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); +} -- cgit v1.2.3 From 1278ade2297e027906ca12c7471891a08188b115 Mon Sep 17 00:00:00 2001 From: Billy Biggs Date: Mon, 8 Aug 2005 18:36:56 +0000 Subject: Declare _cairo_path_nil as extern. --- ChangeLog | 4 ++++ src/cairo-path-data-private.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cff7534a..d201cded 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-08-08 Billy Biggs + + * src/cairo-path-data-private.h: Declare _cairo_path_nil as extern. + 2005-08-08 Billy Biggs reviewed by: cworth, otaylor diff --git a/src/cairo-path-data-private.h b/src/cairo-path-data-private.h index 9947b515..06ab187d 100644 --- a/src/cairo-path-data-private.h +++ b/src/cairo-path-data-private.h @@ -38,7 +38,7 @@ #include "cairoint.h" -cairo_private const cairo_path_t _cairo_path_nil; +extern cairo_private const cairo_path_t _cairo_path_nil; cairo_private cairo_path_t * _cairo_path_data_create (cairo_path_fixed_t *path, -- cgit v1.2.3 From 4d2b8bddded15662015466046039650c20231bbf Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 8 Aug 2005 20:57:13 +0000 Subject: Fix typo that was holding up make distcheck from working. --- ChangeLog | 5 +++++ test/Makefile.am | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d201cded..915566f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-08 Carl Worth + + * test/Makefile.am (EXTRA_DIST): Fix typo that was holding up make + distcheck from working. + 2005-08-08 Billy Biggs * src/cairo-path-data-private.h: Declare _cairo_path_nil as extern. diff --git a/test/Makefile.am b/test/Makefile.am index e30af427..e630b66b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -63,7 +63,7 @@ endif # I really don't like having to repeat this list. Anyone know a good # way to avoid it? Can I use a wildcard here? EXTRA_DIST = \ -a8-mask.png \ +a8-mask-ref.png \ clip-nesting-ref.png \ clip-operator-ref.png \ clip-twice-ref.png \ -- cgit v1.2.3 From 9a088c2fad17af0564936a3b88c9d306c72f11de Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 8 Aug 2005 21:02:11 +0000 Subject: Add missing cairo-debug.h which was hold up make distcheck. --- ChangeLog | 5 +++++ src/Makefile.am | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 915566f6..70b8eed0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-08 Carl Worth + + * src/Makefile.am (libcairo_la_SOURCES): Add missing cairo-debug.h + which was hold up make distcheck. + 2005-08-08 Carl Worth * test/Makefile.am (EXTRA_DIST): Fix typo that was holding up make diff --git a/src/Makefile.am b/src/Makefile.am index f71d09d9..de7d8004 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -89,6 +89,7 @@ libcairo_la_SOURCES = \ cairo-clip-private.h \ cairo-color.c \ cairo-debug.c \ + cairo-debug.h \ cairo-fixed.c \ cairo-font.c \ cairo-font-options.c \ -- cgit v1.2.3 From 4bec3d6af49f9a720121617819700bc700ba5951 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 8 Aug 2005 21:06:44 +0000 Subject: Added notes for release 0.9.0. Increment CAIRO_VERSION to 0.9.0. Increment LT_CURRENT to 2 to mark the beginning of proper soname management. --- ChangeLog | 7 ++++++ NEWS | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ configure.in | 4 ++-- 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 70b8eed0..f1ce80ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-08-08 Carl Worth + + * NEWS: Added notes for release 0.9.0. + + * configure.in: Increment CAIRO_VERSION to 0.9.0. Increment + LT_CURRENT to 2 to mark the beginning of proper soname management. + 2005-08-08 Carl Worth * src/Makefile.am (libcairo_la_SOURCES): Add missing cairo-debug.h diff --git a/NEWS b/NEWS index e39f9574..56181fde 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,80 @@ +Release 0.9.0 (2005-08-08 Carl Worth ) +========================================================= +API additions +------------- + + * Add a new function call to set the current antialiasing mode in the + graphics state: + + cairo_set_antialias + + This call accepts the same modes recently added for font options + (NONE or GRAY) but affects the rendering of geometry other than + text. The intent of this call is to enable more precise control of + which pixels are affected by each operation, for example to allow + for full-scene antialiasing for seam-free rendering. It is not + expected that non-antialiased rendering will perform better than + anti-aliased rendering. + + * Three new functions were added to provide support for mixed cairo- + and non-cairo drawing to the same surface: + + cairo_surface_mark_dirty + cairo_surface_mark_dirty_rectangle + cairo_flush + + * The return type of the several "reference" functions was change, + (API compatibly), from void to the same type as the argument. The + affected functions are: + + cairo_font_face_reference + cairo_scaled_font_reference + cairo_pattern_reference + cairo_surface_reference + cairo_reference + + This allows a convenient way to assign and reference in a single + statement. + +cairo-win32 +----------- + * Some portability improvements, (eg. workaround for missing stdint.h). + +cairo-ft +-------- + * Updated to allow compilation with older versions of freetype. + +Bug fixes +--------- + * Fix the unbounded operators to actually produce a correct result, + (previously the results were artificially restricited to the + bounding box of whatever shape was being drawn rather than + extending out infinitely). The fixed operators are: + + CAIRO_OPERATOR_CLEAR + CAIRO_OPERATOR_SOURCE + CAIRO_OPERATOR_OUT + CAIRO_OPERATOR_IN + CAIRO_OPERATOR_DEST_IN + CAIRO_OPERATOR_DEST_ATOP + + * Fix cairo_mask and cairo_mask_surface to transform the mask by the + current transformation matrix (CTM). + + * Fix cairo_set_source to lock the CTM used to transform the pattern. + + * Workaround for X server Render bug involving repeating patterns + with a general transformation matrix. + + * cairo_get_font_face fixed to return a "nil" font face object rather + than NULL on error. + + * cairo_set_font_face fixed to not crash if given a NULL font face, + (which is the documented interface for restoring the defauly font + face). + + * Fix xlib glyphset caching to not try to free a NULL glyph. + Snapshot 0.6.0 (2005-07-28 Carl Worth ) ========================================================== API changes diff --git a/configure.in b/configure.in index 7b849abf..bb38c53c 100644 --- a/configure.in +++ b/configure.in @@ -5,12 +5,12 @@ AC_INIT(src/cairo.h) dnl =========================================================================== # Package version number, (as distinct from shared library version) -CAIRO_VERSION=0.6.0-head +CAIRO_VERSION=0.9.0 # libtool shared library version # Increment if the interface has additions, changes, removals. -LT_CURRENT=1 +LT_CURRENT=2 # Increment any time the source changes; set to # 0 if you increment CURRENT -- cgit v1.2.3