[cairo-commit] 26 commits - src/cairo-analysis-surface.c src/cairo-array.c src/cairo.c src/cairo-cff-subset.c src/cairo-clip.c src/cairo-directfb-surface.c src/cairo-glitz-surface.c src/cairo-gstate.c src/cairo-image-surface.c src/cairoint.h src/cairo-matrix.c src/cairo-meta-surface.c src/cairo-paginated-surface.c src/cairo-pattern.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-quartz-surface.c src/cairo-region.c src/cairo-scaled-font.c src/cairo-scaled-font-subsets.c src/cairo-sdl-surface.c src/cairo-surface.c src/cairo-surface-fallback.c src/cairo-surface-fallback-private.h src/cairo-svg-surface.c src/cairo-traps.c src/cairo-type3-glyph-surface.c src/cairo-user-font.c src/cairo-win32-font.c src/cairo-win32-printing-surface.c src/cairo-win32-private.h src/cairo-win32-surface.c src/cairo-xcb-surface.c src/cairo-xlib-display.c src/cairo-xlib-private.h src/cairo-xlib-screen.c src/cairo-xlib-surface.c src/test-meta-surface.c src/test-paginated-surface.c test/.gitignore
Chris Wilson
ickle at kemper.freedesktop.org
Thu Oct 30 11:01:33 PDT 2008
src/cairo-analysis-surface.c | 51 ++--
src/cairo-array.c | 16 -
src/cairo-cff-subset.c | 8
src/cairo-clip.c | 4
src/cairo-directfb-surface.c | 33 +--
src/cairo-glitz-surface.c | 42 +--
src/cairo-gstate.c | 126 +++++++----
src/cairo-image-surface.c | 6
src/cairo-matrix.c | 79 ++++++-
src/cairo-meta-surface.c | 12 -
src/cairo-paginated-surface.c | 12 -
src/cairo-pattern.c | 380 +++++++++++++++++------------------
src/cairo-pdf-surface.c | 96 +++++---
src/cairo-ps-surface.c | 43 ++-
src/cairo-quartz-surface.c | 10
src/cairo-region.c | 6
src/cairo-scaled-font-subsets.c | 4
src/cairo-scaled-font.c | 3
src/cairo-sdl-surface.c | 22 +-
src/cairo-surface-fallback-private.h | 45 ++--
src/cairo-surface-fallback.c | 65 +++--
src/cairo-surface.c | 199 +++++++++++-------
src/cairo-svg-surface.c | 50 ++--
src/cairo-traps.c | 33 +--
src/cairo-type3-glyph-surface.c | 18 -
src/cairo-user-font.c | 1
src/cairo-win32-font.c | 26 +-
src/cairo-win32-printing-surface.c | 51 ++--
src/cairo-win32-private.h | 2
src/cairo-win32-surface.c | 6
src/cairo-xcb-surface.c | 42 +--
src/cairo-xlib-display.c | 19 +
src/cairo-xlib-private.h | 26 +-
src/cairo-xlib-screen.c | 100 ++++++---
src/cairo-xlib-surface.c | 108 +++++----
src/cairo.c | 6
src/cairoint.h | 89 ++++----
src/test-meta-surface.c | 28 +-
src/test-paginated-surface.c | 40 +--
test/.gitignore | 2
40 files changed, 1082 insertions(+), 827 deletions(-)
New commits:
commit cc109df2a70e953d71e3e6fc4e6e54cce4ba0d47
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 30 15:50:20 2008 +0000
[test] Update .gitignore
Add a couple of new programs to gitignore.
diff --git a/test/.gitignore b/test/.gitignore
index 9c8995d..8da34a0 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -160,6 +160,7 @@ pdf-surface-source.pdf
png
png-test.png
png-flatten
+ps2png
ps-features
ps-features.ps
ps-surface-source
@@ -236,6 +237,7 @@ unantialiased-shapes
unbounded-operator
user-data
user-font
+user-font-mask
user-font-proxy
user-font-rescale
xlib-expose-event
commit 7d546bba213c3b89404bb3c58a5665343abfcd51
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 29 15:46:10 2008 +0000
[xlib] Eliminate shadowed variable.
Cleanup a minor -Wshadow warning.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index e8e2dd3..0d79292 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -669,7 +669,8 @@ _get_image_surface (cairo_xlib_surface_t *surface,
* temporary pixmap
*/
Pixmap pixmap;
- cairo_status_t status = _cairo_xlib_surface_ensure_gc (surface);
+
+ status = _cairo_xlib_surface_ensure_gc (surface);
if (status)
return status;
commit e3388b8180e38f79e0d5b66cc640c3d5c37db2a8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 29 15:45:09 2008 +0000
[cff-subset] Eliminate shadowed variable.
Cleanup a minor -Wshadow warning.
diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 008cc68..9a4e3d6 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -456,7 +456,7 @@ _cairo_dict_init_key (cff_dict_operator_t *key, int operator)
static cairo_status_t
cff_dict_create_operator (int operator,
unsigned char *operand,
- int operand_length,
+ int size,
cff_dict_operator_t **out)
{
cff_dict_operator_t *op;
@@ -466,14 +466,14 @@ cff_dict_create_operator (int operator,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_dict_init_key (op, operator);
- op->operand = malloc (operand_length);
+ op->operand = malloc (size);
if (op->operand == NULL) {
free (op);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
- memcpy (op->operand, operand, operand_length);
- op->operand_length = operand_length;
+ memcpy (op->operand, operand, size);
+ op->operand_length = size;
op->operand_offset = -1;
*out = op;
commit 3e18114aff21acfa73a7d13a419719375ae9b5a6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 29 15:43:23 2008 +0000
[user-font] Eliminate shadowed variable
Cleanup a minor -Wshadow warning.
diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index ddcbc77..c272966 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -187,7 +187,6 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
if (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) {
cairo_surface_t *surface;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_format_t format;
int width, height;
commit d073537e82b57738068a7e1cf1d36ce452876804
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 29 15:41:44 2008 +0000
[scaled-font] Eliminate shadowed variable.
Cleanup a minor -Wshadow warning.
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 32fd62a..c3cf17a 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1872,7 +1872,6 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
_cairo_format_bits_per_pixel (glyph_surface->format) )
{
cairo_surface_t *new_mask;
- cairo_surface_pattern_t mask_pattern;
switch (glyph_surface->format) {
case CAIRO_FORMAT_ARGB32:
commit 6429e3f39468ef4f865681b3b5988d35906deeb0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Oct 28 17:38:09 2008 +0000
[xlib] Only set Picture clip as necessary.
Only set ClipRectangles on a new Picture, avoiding redundant calls to
clear the non-existent ClipMask otherwise.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 34c86fd..e8e2dd3 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -888,8 +888,9 @@ _cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface)
surface->drawable,
surface->xrender_format,
0, NULL);
- _cairo_xlib_surface_set_picture_clip_rects (surface);
- } else if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE)
+ }
+
+ if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_PICTURE)
_cairo_xlib_surface_set_picture_clip_rects (surface);
}
commit cd45258c5bf6a06f7bd3f2bfaf928e423a9b70e1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Oct 28 16:54:10 2008 +0000
[xlib] Only clear the GC clip mask as necessary.
Avoid redundant calls to XSetClipMask() for clean GCs.
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 58edbeb..b9c84b8 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -152,9 +152,15 @@ cairo_private void
_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info);
cairo_private GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth);
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+ int depth,
+ unsigned int *need_reset);
+
cairo_private cairo_status_t
-_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip);
+_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
+ int depth,
+ GC gc,
+ cairo_bool_t reset_clip);
cairo_private cairo_font_options_t *
_cairo_xlib_screen_get_font_options (cairo_xlib_screen_info_t *info);
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 65d131c..9dd411e 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -57,6 +57,8 @@
#include "cairo-xlib-private.h"
#include "cairo-xlib-xrender-private.h"
+#include "cairo-xlib-surface-private.h"
+
#include <fontconfig/fontconfig.h>
static int
@@ -404,7 +406,9 @@ depth_to_index (int depth)
}
GC
-_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth)
+_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
+ int depth,
+ unsigned int *dirty)
{
GC gc;
cairo_bool_t needs_reset;
@@ -419,7 +423,7 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth)
CAIRO_MUTEX_UNLOCK (info->mutex);
if (needs_reset)
- XSetClipMask(info->display->display, gc, None);
+ *dirty |= CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC;
return gc;
}
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index d078dcd..34c86fd 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -900,7 +900,8 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
if (surface->gc == NULL) {
surface->gc = _cairo_xlib_screen_get_gc (surface->screen_info,
- surface->depth);
+ surface->depth,
+ &surface->clip_dirty);
if (surface->gc == NULL) {
gcv.graphics_exposures = False;
surface->gc = XCreateGC (surface->dpy, surface->drawable,
@@ -908,9 +909,9 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
if (!surface->gc)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
+ }
- _cairo_xlib_surface_set_gc_clip_rects (surface);
- } else if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC)
+ if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC)
_cairo_xlib_surface_set_gc_clip_rects (surface);
return CAIRO_STATUS_SUCCESS;
commit d384f864992fbf7513446a70158135a08e704678
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Oct 28 16:33:51 2008 +0000
[xlib] Propagate real status from get_screen_info().
Return the real error from _cairo_xlib_screen_info_get() in order to avoid
having to create a fake NO_MEMORY error.
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index cd89290..58edbeb 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -138,8 +138,10 @@ cairo_private XRenderPictFormat *
_cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display,
cairo_format_t format);
-cairo_private cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen);
+cairo_private cairo_status_t
+_cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
+ Screen *screen,
+ cairo_xlib_screen_info_t **out);
cairo_private cairo_xlib_screen_info_t *
_cairo_xlib_screen_info_reference (cairo_xlib_screen_info_t *info);
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index a864fec..65d131c 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -318,15 +318,17 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
free (info);
}
-cairo_xlib_screen_info_t *
-_cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
+cairo_status_t
+_cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
+ Screen *screen,
+ cairo_xlib_screen_info_t **out)
{
cairo_xlib_screen_info_t *info = NULL, **prev;
CAIRO_MUTEX_LOCK (display->mutex);
if (display->closed) {
CAIRO_MUTEX_UNLOCK (display->mutex);
- return NULL;
+ return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
}
for (prev = &display->screens; (info = *prev); prev = &(*prev)->next) {
@@ -348,35 +350,41 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
info = _cairo_xlib_screen_info_reference (info);
} else {
info = malloc (sizeof (cairo_xlib_screen_info_t));
- if (info != NULL) {
- CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
- CAIRO_MUTEX_INIT (info->mutex);
- info->display = _cairo_xlib_display_reference (display);
- info->screen = screen;
- info->has_render = FALSE;
- info->has_font_options = FALSE;
- memset (info->gc, 0, sizeof (info->gc));
- info->gc_needs_clip_reset = 0;
-
- _cairo_array_init (&info->visuals,
- sizeof (cairo_xlib_visual_info_t*));
-
- if (screen) {
- Display *dpy = display->display;
- int event_base, error_base;
-
- info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
- (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
- }
-
- CAIRO_MUTEX_LOCK (display->mutex);
- info->next = display->screens;
- display->screens = info;
- CAIRO_MUTEX_UNLOCK (display->mutex);
+ if (info == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+ CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
+ CAIRO_MUTEX_INIT (info->mutex);
+ info->display = _cairo_xlib_display_reference (display);
+ info->screen = screen;
+ info->has_render = FALSE;
+ info->has_font_options = FALSE;
+ memset (info->gc, 0, sizeof (info->gc));
+ info->gc_needs_clip_reset = 0;
+
+ _cairo_array_init (&info->visuals,
+ sizeof (cairo_xlib_visual_info_t*));
+
+ if (screen) {
+ Display *dpy = display->display;
+ int event_base, error_base;
+
+ info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
+ (XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
}
+
+ /* Small window of opportunity for two screen infos for the same
+ * Screen - just wastes a little bit of memory but should not cause
+ * any corruption.
+ */
+ CAIRO_MUTEX_LOCK (display->mutex);
+ info->next = display->screens;
+ display->screens = info;
+ CAIRO_MUTEX_UNLOCK (display->mutex);
}
- return info;
+ *out = info;
+ return CAIRO_STATUS_SUCCESS;
}
static int
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 4d7e6a8..d078dcd 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2545,10 +2545,10 @@ _cairo_xlib_surface_create_internal (Display *dpy,
if (status)
return _cairo_surface_create_in_error (status);
- screen_info = _cairo_xlib_screen_info_get (display, screen);
- if (screen_info == NULL) {
+ status = _cairo_xlib_screen_info_get (display, screen, &screen_info);
+ if (status) {
_cairo_xlib_display_destroy (display);
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ return _cairo_surface_create_in_error (status);
}
surface = malloc (sizeof (cairo_xlib_surface_t));
commit e25b106e9c33e220fb104afb0929e766647b6de9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Oct 28 16:27:58 2008 +0000
[xlib] Propagate real status from get_display()
Avoid throwing away the error and inventing a new NO_MEMORY error for
_cairo_xlib_display_get().
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 3c835f6..14e50d6 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -208,13 +208,15 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
return 0;
}
-cairo_xlib_display_t *
-_cairo_xlib_display_get (Display *dpy)
+cairo_status_t
+_cairo_xlib_display_get (Display *dpy,
+ cairo_xlib_display_t **out)
{
cairo_xlib_display_t *display;
cairo_xlib_display_t **prev;
XExtCodes *codes;
int render_major, render_minor;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
/* There is an apparent deadlock between this mutex and the
* mutex for the display, but it's actually safe. For the
@@ -247,7 +249,7 @@ _cairo_xlib_display_get (Display *dpy)
display = malloc (sizeof (cairo_xlib_display_t));
if (display == NULL) {
- _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto UNLOCK;
}
@@ -261,7 +263,7 @@ _cairo_xlib_display_get (Display *dpy)
codes = XAddExtension (dpy);
if (codes == NULL) {
- _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
free (display);
display = NULL;
goto UNLOCK;
@@ -316,7 +318,8 @@ _cairo_xlib_display_get (Display *dpy)
UNLOCK:
CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex);
- return display;
+ *out = display;
+ return status;
}
void
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 4b0a94d..cd89290 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -108,8 +108,8 @@ struct _cairo_xlib_screen_info {
cairo_array_t visuals;
};
-cairo_private cairo_xlib_display_t *
-_cairo_xlib_display_get (Display *display);
+cairo_private cairo_status_t
+_cairo_xlib_display_get (Display *display, cairo_xlib_display_t **out);
cairo_private cairo_xlib_display_t *
_cairo_xlib_display_reference (cairo_xlib_display_t *info);
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index c898838..4d7e6a8 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2510,6 +2510,7 @@ _cairo_xlib_surface_create_internal (Display *dpy,
cairo_xlib_surface_t *surface;
cairo_xlib_display_t *display;
cairo_xlib_screen_info_t *screen_info;
+ cairo_status_t status;
CAIRO_MUTEX_INITIALIZE ();
@@ -2540,9 +2541,9 @@ _cairo_xlib_surface_create_internal (Display *dpy,
if (depth == 0)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
- display = _cairo_xlib_display_get (dpy);
- if (display == NULL)
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+ status = _cairo_xlib_display_get (dpy, &display);
+ if (status)
+ return _cairo_surface_create_in_error (status);
screen_info = _cairo_xlib_screen_info_get (display, screen);
if (screen_info == NULL) {
@@ -3139,6 +3140,7 @@ _cairo_xlib_surface_font_init (Display *dpy,
cairo_scaled_font_t *scaled_font)
{
cairo_xlib_surface_font_private_t *font_private;
+ cairo_status_t status;
int i;
font_private = malloc (sizeof (cairo_xlib_surface_font_private_t));
@@ -3146,10 +3148,10 @@ _cairo_xlib_surface_font_init (Display *dpy,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
font_private->scaled_font = scaled_font;
- font_private->display = _cairo_xlib_display_get (dpy);
- if (font_private->display == NULL) {
+ status = _cairo_xlib_display_get (dpy, &font_private->display);
+ if (status) {
free (font_private);
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ return status;
}
/* initialize and hook into the CloseDisplay callback */
commit 2555f83b11ee23829cfdeaae703420ca3e572fa1
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Tue Oct 28 16:22:49 2008 +0000
[xlib] Avoid repeated calls to XRenderQueryVersion
Use the value determined during display initialisation in order to avoid
redundant XRenderQueryFormats requests.
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 5e6dba1..3c835f6 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -214,7 +214,7 @@ _cairo_xlib_display_get (Display *dpy)
cairo_xlib_display_t *display;
cairo_xlib_display_t **prev;
XExtCodes *codes;
- int major_unused, minor_unused;
+ int render_major, render_minor;
/* There is an apparent deadlock between this mutex and the
* mutex for the display, but it's actually safe. For the
@@ -257,7 +257,7 @@ _cairo_xlib_display_get (Display *dpy)
* add our hook. For now, that means Render, so we call into its
* QueryVersion function to ensure it gets initialized.
*/
- XRenderQueryVersion (dpy, &major_unused, &minor_unused);
+ XRenderQueryVersion (dpy, &render_major, &render_minor);
codes = XAddExtension (dpy);
if (codes == NULL) {
@@ -279,6 +279,8 @@ _cairo_xlib_display_get (Display *dpy)
display->close_display_hooks = NULL;
display->closed = FALSE;
+ display->render_major = render_major;
+ display->render_minor = render_minor;
memset (display->cached_xrender_formats, 0,
sizeof (display->cached_xrender_formats));
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index 79cd6b5..4b0a94d 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -64,6 +64,8 @@ struct _cairo_xlib_display {
Display *display;
cairo_xlib_screen_info_t *screens;
+ int render_major;
+ int render_minor;
XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_A1 + 1];
cairo_xlib_job_t *workqueue;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 154e89c..c898838 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2561,11 +2561,8 @@ _cairo_xlib_surface_create_internal (Display *dpy,
surface->close_display_hook.func = _cairo_xlib_surface_detach_display;
_cairo_xlib_add_close_display_hook (display, &surface->close_display_hook);
- if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {
- surface->render_major = -1;
- surface->render_minor = -1;
- }
-
+ surface->render_major = display->render_major;
+ surface->render_minor = display->render_minor;
if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface)) {
if (!xrender_format) {
if (visual) {
commit 0d0c6a199c5b631299c72dce80d66ac0f4936a64
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Oct 26 12:53:29 2008 +0000
[matrix] Optimise invert for simple scaling|translation matrices.
The matrix is quite often just a simple scale and translate (or even
identity!). For this class of matrix, we can skip the full adjoint
rearrangement and determinant calculation and just compute the inverse
directly.
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index 643c986..b644dec 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -525,9 +525,33 @@ _cairo_matrix_compute_adjoint (cairo_matrix_t *matrix)
cairo_status_t
cairo_matrix_invert (cairo_matrix_t *matrix)
{
- /* inv (A) = 1/det (A) * adj (A) */
double det;
+ /* Simple scaling|translation matrices are quite common... */
+ if (matrix->xy == 0. && matrix->yx == 0.) {
+ matrix->x0 = -matrix->x0;
+ matrix->y0 = -matrix->y0;
+
+ if (matrix->xx != 1.) {
+ if (matrix->xx == 0.)
+ return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+
+ matrix->xx = 1. / matrix->xx;
+ matrix->x0 *= matrix->xx;
+ }
+
+ if (matrix->yy != 1.) {
+ if (matrix->yy == 0.)
+ return _cairo_error (CAIRO_STATUS_INVALID_MATRIX);
+
+ matrix->yy = 1. / matrix->yy;
+ matrix->y0 *= matrix->yy;
+ }
+
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ /* inv (A) = 1/det (A) * adj (A) */
det = _cairo_matrix_compute_determinant (matrix);
if (! ISFINITE (det))
commit 74876b00cd969d5cfc209fa903dfad50bda59361
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Oct 25 11:33:52 2008 +0100
[xlib] Exploit compaction of XRenderFillRectangle()
libXrender amalgamates sequences of XRenderFillRectangle() into a single
XRenderFillRectangles request (when permissible). Since it is common for a
cairo application to draw rectangles individually in order to exploit fast
paths within cairo [rectilinear fills], it is a reasonably common pattern.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 6439cb1..154e89c 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1931,27 +1931,41 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface,
render_color.blue = color->blue_short;
render_color.alpha = color->alpha_short;
- if (num_rects > ARRAY_LENGTH (static_xrects)) {
- xrects = _cairo_malloc_ab (num_rects, sizeof (XRectangle));
- if (xrects == NULL)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
+ _cairo_xlib_surface_ensure_dst_picture (surface);
+ if (num_rects == 1) {
+ /* Take advantage of the protocol compaction that libXrender performs
+ * to amalgamate sequences of XRenderFillRectangle().
+ */
+ XRenderFillRectangle (surface->dpy,
+ _render_operator (op),
+ surface->dst_picture,
+ &render_color,
+ rects->x,
+ rects->y,
+ rects->width,
+ rects->height);
+ } else {
+ if (num_rects > ARRAY_LENGTH (static_xrects)) {
+ xrects = _cairo_malloc_ab (num_rects, sizeof (XRectangle));
+ if (xrects == NULL)
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
- for (i = 0; i < num_rects; i++) {
- xrects[i].x = rects[i].x;
- xrects[i].y = rects[i].y;
- xrects[i].width = rects[i].width;
- xrects[i].height = rects[i].height;
- }
+ for (i = 0; i < num_rects; i++) {
+ xrects[i].x = rects[i].x;
+ xrects[i].y = rects[i].y;
+ xrects[i].width = rects[i].width;
+ xrects[i].height = rects[i].height;
+ }
- _cairo_xlib_surface_ensure_dst_picture (surface);
- XRenderFillRectangles (surface->dpy,
- _render_operator (op),
- surface->dst_picture,
- &render_color, xrects, num_rects);
+ XRenderFillRectangles (surface->dpy,
+ _render_operator (op),
+ surface->dst_picture,
+ &render_color, xrects, num_rects);
- if (xrects != static_xrects)
- free (xrects);
+ if (xrects != static_xrects)
+ free (xrects);
+ }
return CAIRO_STATUS_SUCCESS;
}
commit 64726ccfb99ba964420f3a840fd707998927e902
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 24 17:06:04 2008 +0100
[traps] Whitespace.
Fixup whitespace in line with CODING_STYLE and rest of file.
diff --git a/src/cairo-region.c b/src/cairo-region.c
index 23a042f..a89c4d0 100644
--- a/src/cairo-region.c
+++ b/src/cairo-region.c
@@ -62,8 +62,8 @@ _cairo_region_init_boxes (cairo_region_t *region,
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
int i;
- if (count > ARRAY_LENGTH(stack_pboxes)) {
- pboxes = _cairo_malloc_ab (count, sizeof(pixman_box32_t));
+ if (count > ARRAY_LENGTH (stack_pboxes)) {
+ pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
if (pboxes == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -75,7 +75,7 @@ _cairo_region_init_boxes (cairo_region_t *region,
pboxes[i].y2 = boxes[i].p2.y;
}
- if (!pixman_region32_init_rects (®ion->rgn, pboxes, count))
+ if (! pixman_region32_init_rects (®ion->rgn, pboxes, count))
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (pboxes != stack_pboxes)
diff --git a/src/cairo-traps.c b/src/cairo-traps.c
index b76e908..4fa3656 100644
--- a/src/cairo-traps.c
+++ b/src/cairo-traps.c
@@ -615,18 +615,25 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
int i, box_count;
cairo_int_status_t status;
- for (i = 0; i < traps->num_traps; i++)
- if (!(traps->traps[i].left.p1.x == traps->traps[i].left.p2.x
- && traps->traps[i].right.p1.x == traps->traps[i].right.p2.x
- && _cairo_fixed_is_integer(traps->traps[i].top)
- && _cairo_fixed_is_integer(traps->traps[i].bottom)
- && _cairo_fixed_is_integer(traps->traps[i].left.p1.x)
- && _cairo_fixed_is_integer(traps->traps[i].right.p1.x))) {
+ if (traps->num_traps == 0) {
+ _cairo_region_init (region);
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ for (i = 0; i < traps->num_traps; i++) {
+ if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x ||
+ traps->traps[i].right.p1.x != traps->traps[i].right.p2.x ||
+ ! _cairo_fixed_is_integer (traps->traps[i].top) ||
+ ! _cairo_fixed_is_integer (traps->traps[i].bottom) ||
+ ! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) ||
+ ! _cairo_fixed_is_integer (traps->traps[i].right.p1.x))
+ {
return CAIRO_INT_STATUS_UNSUPPORTED;
}
+ }
- if (traps->num_traps > ARRAY_LENGTH(stack_boxes)) {
- boxes = _cairo_malloc_ab (traps->num_traps, sizeof(cairo_box_int_t));
+ if (traps->num_traps > ARRAY_LENGTH (stack_boxes)) {
+ boxes = _cairo_malloc_ab (traps->num_traps, sizeof (cairo_box_int_t));
if (boxes == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -635,10 +642,10 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
box_count = 0;
for (i = 0; i < traps->num_traps; i++) {
- int x1 = _cairo_fixed_integer_part(traps->traps[i].left.p1.x);
- int y1 = _cairo_fixed_integer_part(traps->traps[i].top);
- int x2 = _cairo_fixed_integer_part(traps->traps[i].right.p1.x);
- int y2 = _cairo_fixed_integer_part(traps->traps[i].bottom);
+ int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x);
+ int y1 = _cairo_fixed_integer_part (traps->traps[i].top);
+ int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x);
+ int y2 = _cairo_fixed_integer_part (traps->traps[i].bottom);
/* XXX: Sometimes we get degenerate trapezoids from the tesellator;
* skip these.
commit d5543005e7b7cc08f97578f301182ef4807a05fe
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 24 09:00:45 2008 +0100
[surface] Only copy font options if the target surface has them.
No need to copy font options if the similar surface is from the same
backend and no special options have been applied by the user. Doing so
breaks lazy initialisation of backend specific options.
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 4041790..ff75cc2 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -229,9 +229,6 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
int height)
{
cairo_surface_t *surface = NULL;
- cairo_font_options_t options;
-
- cairo_format_t format = _cairo_format_from_content (content);
if (other->status)
return _cairo_surface_create_in_error (other->status);
@@ -242,15 +239,22 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
return surface;
}
- if (surface == NULL)
- surface = cairo_image_surface_create (format, width, height);
+ if (surface == NULL) {
+ surface =
+ cairo_image_surface_create (_cairo_format_from_content (content),
+ width, height);
+ }
/* If any error occurred, then return the nil surface we received. */
if (surface->status)
return surface;
- cairo_surface_get_font_options (other, &options);
- _cairo_surface_set_font_options (surface, &options);
+ if (other->has_font_options || other->backend != surface->backend) {
+ cairo_font_options_t options;
+
+ cairo_surface_get_font_options (other, &options);
+ _cairo_surface_set_font_options (surface, &options);
+ }
cairo_surface_set_fallback_resolution (surface,
other->x_fallback_resolution,
commit a0023758104b700751ba8d7a66d75db139eea6cb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 24 08:39:29 2008 +0100
[xlib] Defer querying of font options until first use
Constructing the font options cause the initialisation of Xlc and invoke
several round-trips to the X server, significantly delaying the creation
of the first surface. By deferring that operation until the first use of
fonts then we avoid that overhead for very simple applications (like the
test suite) and should improve start-up latency for larger application.
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index e381e58..79cd6b5 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -97,6 +97,7 @@ struct _cairo_xlib_screen_info {
Screen *screen;
cairo_bool_t has_render;
+ cairo_bool_t has_font_options;
cairo_font_options_t font_options;
GC gc[9];
@@ -151,6 +152,9 @@ _cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth);
cairo_private cairo_status_t
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip);
+cairo_private cairo_font_options_t *
+_cairo_xlib_screen_get_font_options (cairo_xlib_screen_info_t *info);
+
cairo_private cairo_status_t
_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
Visual *visual,
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index f670b8a..a864fec 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -144,7 +144,8 @@ get_integer_default (Display *dpy,
#endif
static void
-_cairo_xlib_init_screen_font_options (Display *dpy, cairo_xlib_screen_info_t *info)
+_cairo_xlib_init_screen_font_options (Display *dpy,
+ cairo_xlib_screen_info_t *info)
{
cairo_bool_t xft_hinting;
cairo_bool_t xft_antialias;
@@ -353,7 +354,7 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
info->display = _cairo_xlib_display_reference (display);
info->screen = screen;
info->has_render = FALSE;
- _cairo_font_options_init_default (&info->font_options);
+ info->has_font_options = FALSE;
memset (info->gc, 0, sizeof (info->gc));
info->gc_needs_clip_reset = 0;
@@ -366,7 +367,6 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display, Screen *screen)
info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) &&
(XRenderFindVisualFormat (dpy, DefaultVisual (dpy, DefaultScreen (dpy))) != 0));
- _cairo_xlib_init_screen_font_options (dpy, info);
}
CAIRO_MUTEX_LOCK (display->mutex);
@@ -502,3 +502,25 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
*out = ret;
return CAIRO_STATUS_SUCCESS;
}
+
+cairo_font_options_t *
+_cairo_xlib_screen_get_font_options (cairo_xlib_screen_info_t *info)
+{
+ if (info->has_font_options)
+ return &info->font_options;
+
+ CAIRO_MUTEX_LOCK (info->mutex);
+ if (! info->has_font_options) {
+ Display *dpy = info->display->display;
+
+ _cairo_font_options_init_default (&info->font_options);
+
+ if (info->screen != NULL)
+ _cairo_xlib_init_screen_font_options (dpy, info);
+
+ info->has_font_options = TRUE;
+ }
+ CAIRO_MUTEX_UNLOCK (info->mutex);
+
+ return &info->font_options;
+}
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 1d35843..6439cb1 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2348,7 +2348,7 @@ _cairo_xlib_surface_get_font_options (void *abstract_surface,
{
cairo_xlib_surface_t *surface = abstract_surface;
- *options = surface->screen_info->font_options;
+ *options = *_cairo_xlib_screen_get_font_options (surface->screen_info);
}
static void
commit 6706590d4e7ad19dae0b8e3efe6f573d5688e19a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 29 16:22:48 2008 +0100
[pattern] Reduce likelihood of range overflow with large downscaling.
Exploit the auxiliary offset vector in the attributes to reduce
likelihood of range overflow in the translation components when converting
the pattern matrix to fixed-point pixman_matrix_t.
An example of this is bug 9148
Bug 9148 - invalid rendering when painting large scaled-down surfaces
(https://bugs.freedesktop.org/show_bug.cgi?id=9148)
but the issue is perhaps even more likely with high resolution fallback
images.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index e58b96c..02b0674 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1989,6 +1989,25 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
}
}
+ /* reduce likelihood of range overflow with large downscaling */
+ if (! is_identity) {
+ cairo_matrix_t m;
+ cairo_status_t invert_status;
+
+ m = attr->matrix;
+ invert_status = cairo_matrix_invert (&m);
+ assert (invert_status == CAIRO_STATUS_SUCCESS);
+
+ if (m.x0 != 0. || m.y0 != 0.) {
+ x = floor (m.x0);
+ y = floor (m.y0);
+ attr->x_offset -= x;
+ attr->y_offset -= y;
+ cairo_matrix_init_translate (&m, x, y);
+ cairo_matrix_multiply (&attr->matrix, &m, &attr->matrix);
+ }
+ }
+
BAIL:
cairo_surface_destroy (surface);
return status;
commit c0af8c70635d641fc5770afc0cd6e9285122fd72
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Oct 20 16:49:23 2008 +0100
[pattern] Tweak REFLECT HACK
In order to workaound a directfb bug, tweak the reflect->repeat pattern so
that it covers the destination rectangle. Although the number of paint()
increases, the number of read/written pixels remain the same so that
performance should not deteriorate, but instead be improved by using a
cloned source. The early return of the REFLECT surface is discarded so
that the latter optimisations for surface sources can be applied. One side
effect of this is that acquire_source_image() is removed due to its lax
reference counting which thereby exposes the ROI optimisations for image
destinations as well.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 8113ff9..e58b96c 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1359,7 +1359,6 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
attr->matrix = matrix;
attr->extend = pattern->base.extend;
attr->filter = CAIRO_FILTER_NEAREST;
- attr->acquired = FALSE;
*out = &image->base;
@@ -1450,7 +1449,6 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
cairo_matrix_init_identity (&attr->matrix);
attr->extend = repeat ? CAIRO_EXTEND_REPEAT : CAIRO_EXTEND_NONE;
attr->filter = CAIRO_FILTER_NEAREST;
- attr->acquired = FALSE;
return status;
}
@@ -1601,7 +1599,6 @@ NOCACHE:
cairo_matrix_init_identity (&attribs->matrix);
attribs->extend = CAIRO_EXTEND_REPEAT;
attribs->filter = CAIRO_FILTER_NEAREST;
- attribs->acquired = FALSE;
status = CAIRO_STATUS_SUCCESS;
@@ -1778,31 +1775,36 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
cairo_surface_t **out,
cairo_surface_attributes_t *attr)
{
- cairo_int_status_t status;
+ cairo_surface_t *surface;
+ cairo_rectangle_int_t extents;
+ cairo_rectangle_int_t sampled_area;
+ double x1, y1, x2, y2;
int tx, ty;
double pad;
+ cairo_bool_t is_identity;
+ cairo_bool_t is_empty;
+ cairo_int_status_t status;
- attr->acquired = FALSE;
+ surface = cairo_surface_reference (pattern->surface);
+ is_identity = FALSE;
+ attr->matrix = pattern->base.matrix;
attr->extend = pattern->base.extend;
attr->filter = _cairo_pattern_analyze_filter (pattern, &pad);
- if (_cairo_matrix_is_integer_translation (&pattern->base.matrix,
- &tx, &ty))
- {
+ attr->x_offset = attr->y_offset = tx = ty = 0;
+ if (_cairo_matrix_is_integer_translation (&attr->matrix, &tx, &ty)) {
cairo_matrix_init_identity (&attr->matrix);
attr->x_offset = tx;
attr->y_offset = ty;
- }
- else if (attr->filter == CAIRO_FILTER_NEAREST)
- {
+ is_identity = TRUE;
+ } else if (attr->filter == CAIRO_FILTER_NEAREST) {
/*
* For NEAREST, we can remove the fractional translation component
* from the transformation - this ensures that the pattern will always
* hit fast-paths in the backends for simple transformations that
* become (almost) identity, without loss of quality.
*/
- attr->matrix = pattern->base.matrix;
attr->matrix.x0 = 0;
attr->matrix.y0 = 0;
if (_cairo_matrix_is_pixel_exact (&attr->matrix)) {
@@ -1816,15 +1818,12 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
attr->matrix.y0 = pattern->base.matrix.y0;
}
- attr->x_offset = attr->y_offset = 0;
- tx = ty = 0;
- }
- else
- {
- attr->matrix = pattern->base.matrix;
- attr->x_offset = attr->y_offset = 0;
- tx = 0;
- ty = 0;
+ if (_cairo_matrix_is_integer_translation (&attr->matrix, &tx, &ty)) {
+ cairo_matrix_init_identity (&attr->matrix);
+ attr->x_offset = tx;
+ attr->y_offset = ty;
+ is_identity = TRUE;
+ }
}
/* XXX: Hack:
@@ -1833,156 +1832,165 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
* an image twice bigger on each side, and create a pattern of four
* images such that the new image, when repeated, has the same effect
* of reflecting the original pattern.
- *
- * This is because the reflect support in pixman is broken and we
- * pass repeat instead of reflect to pixman. See
- * _cairo_image_surface_set_attributes() for that.
*/
if (attr->extend == CAIRO_EXTEND_REFLECT) {
cairo_t *cr;
- int w,h;
+ cairo_surface_t *src;
+ int w, h;
- cairo_rectangle_int_t extents;
- status = _cairo_surface_get_extents (pattern->surface, &extents);
+ status = _cairo_surface_get_extents (surface, &extents);
if (status)
- return status;
+ goto BAIL;
- attr->extend = CAIRO_EXTEND_REPEAT;
+ status = _cairo_surface_clone_similar (dst, pattern->surface,
+ extents.x, extents.y,
+ extents.width, extents.height,
+ &extents.x, &extents.y, &src);
+ if (status)
+ goto BAIL;
- /* TODO: Instead of rendering pattern->surface four times to
- * out, we should first copy pattern->surface to surface similar
- * to dst and then copy that four times to out. This may cause
- * an extra copy in the case of image destination, but for X servers,
- * this will send pattern->surface just once over the wire instead
- * of current four.
- */
- x = extents.x;
- y = extents.y;
w = 2 * extents.width;
h = 2 * extents.height;
- *out = cairo_surface_create_similar (dst, dst->content, w, h);
- status = cairo_surface_status (*out);
- if (status) {
- cairo_surface_destroy (*out);
- *out = NULL;
- return status;
+ if (is_identity) {
+ attr->x_offset = -x;
+ x += tx;
+ while (x <= -w)
+ x += w;
+ while (x >= w)
+ x -= w;
+ extents.x += x;
+ tx = x = 0;
+
+ attr->y_offset = -y;
+ y += ty;
+ while (y <= -h)
+ y += h;
+ while (y >= h)
+ y -= h;
+ extents.y += y;
+ ty = y = 0;
}
- (*out)->device_transform = pattern->surface->device_transform;
- (*out)->device_transform_inverse = pattern->surface->device_transform_inverse;
+ cairo_surface_destroy (surface);
+ surface = cairo_surface_create_similar (dst, dst->content, w, h);
+ if (surface->status) {
+ cairo_surface_destroy (src);
+ return surface->status;
+ }
+
+ surface->device_transform = pattern->surface->device_transform;
+ surface->device_transform_inverse = pattern->surface->device_transform_inverse;
- cr = cairo_create (*out);
+ cr = cairo_create (surface);
- cairo_set_source_surface (cr, pattern->surface, -x, -y);
+ cairo_set_source_surface (cr, src, -extents.x, -extents.y);
cairo_paint (cr);
cairo_scale (cr, -1, +1);
- cairo_set_source_surface (cr, pattern->surface, x-w, -y);
+ cairo_set_source_surface (cr, src, extents.x-w, -extents.y);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, src, extents.x, -extents.y);
cairo_paint (cr);
cairo_scale (cr, +1, -1);
- cairo_set_source_surface (cr, pattern->surface, x-w, y-h);
+ cairo_set_source_surface (cr, src, extents.x-w, extents.y-h);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, src, extents.x, extents.y-h);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, src, extents.x-w, extents.y);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, src, extents.x, extents.y);
cairo_paint (cr);
cairo_scale (cr, -1, +1);
- cairo_set_source_surface (cr, pattern->surface, -x, y-h);
+ cairo_set_source_surface (cr, src, -extents.x, extents.y-h);
+ cairo_paint (cr);
+ cairo_set_source_surface (cr, src, -extents.x, extents.y);
cairo_paint (cr);
status = cairo_status (cr);
cairo_destroy (cr);
- if (status) {
- cairo_surface_destroy (*out);
- *out = NULL;
- }
+ cairo_surface_destroy (src);
- return status;
+ if (status)
+ goto BAIL;
+
+ attr->extend = CAIRO_EXTEND_REPEAT;
}
- if (_cairo_surface_is_image (dst)) {
- cairo_image_surface_t *image;
+ status = _cairo_surface_get_extents (surface, &extents);
+ if (status)
+ goto BAIL;
- status = _cairo_surface_acquire_source_image (pattern->surface,
- &image,
- &attr->extra);
- if (status)
- return status;
+ /* We first transform the rectangle to the coordinate space of the
+ * source surface so that we only need to clone that portion of the
+ * surface that will be read.
+ */
+ x1 = x;
+ y1 = y;
+ x2 = x + (int) width;
+ y2 = y + (int) height;
+ if (! is_identity) {
+ _cairo_matrix_transform_bounding_box (&attr->matrix,
+ &x1, &y1, &x2, &y2,
+ NULL);
+ }
- *out = &image->base;
- attr->acquired = TRUE;
- } else {
- cairo_rectangle_int_t extents;
- cairo_bool_t is_empty;
+ sampled_area.x = floor (x1 - pad);
+ sampled_area.y = floor (y1 - pad);
+ sampled_area.width = ceil (x2 + pad) - sampled_area.x;
+ sampled_area.height = ceil (y2 + pad) - sampled_area.y;
- status = _cairo_surface_get_extents (pattern->surface, &extents);
- if (status)
- return status;
+ sampled_area.x += tx;
+ sampled_area.y += ty;
- /* If we're repeating, we just play it safe and clone the
- * entire surface - i.e. we use the existing extents.
- */
- if (attr->extend != CAIRO_EXTEND_REPEAT) {
- cairo_rectangle_int_t sampled_area;
+ if (attr->extend != CAIRO_EXTEND_REPEAT) {
+ /* Never acquire a larger area than the source itself */
+ is_empty = _cairo_rectangle_intersect (&extents, &sampled_area);
+ } else {
+ if (sampled_area.x >= extents.x &&
+ sampled_area.y >= extents.y &&
+ sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width &&
+ sampled_area.y + (int) sampled_area.height <= extents.y + (int) extents.height)
+ {
+ /* source is wholly contained within extents, drop the REPEAT */
+ extents = sampled_area;
+ attr->extend = CAIRO_EXTEND_NONE;
+ }
- /* Otherwise, we first transform the rectangle to the
- * coordinate space of the source surface so that we can
- * clone only that portion of the surface that will be
- * read.
- */
- if (_cairo_matrix_is_identity (&attr->matrix)) {
- sampled_area.x = x;
- sampled_area.y = y;
- sampled_area.width = width;
- sampled_area.height = height;
- } else {
- double x1 = x;
- double y1 = y;
- double x2 = x + (int) width;
- double y2 = y + (int) height;
-
- _cairo_matrix_transform_bounding_box (&attr->matrix,
- &x1, &y1, &x2, &y2,
- NULL);
-
- sampled_area.x = floor (x1 - pad);
- sampled_area.y = floor (y1 - pad);
- sampled_area.width = ceil (x2 + pad) - sampled_area.x;
- sampled_area.height = ceil (y2 + pad) - sampled_area.y;
+ is_empty = extents.width == 0 || extents.height == 0;
+ }
- }
+ /* XXX can we use is_empty? */
- sampled_area.x += tx;
- sampled_area.y += ty;
+ status = _cairo_surface_clone_similar (dst, surface,
+ extents.x, extents.y,
+ extents.width, extents.height,
+ &x, &y, out);
+ if (status)
+ goto BAIL;
- /* Never acquire a larger area than the source itself */
- is_empty = _cairo_rectangle_intersect (&extents, &sampled_area);
- }
+ if (x != 0 || y != 0) {
+ if (is_identity) {
+ attr->x_offset -= x;
+ attr->y_offset -= y;
+ } else {
+ cairo_matrix_t m;
- /* XXX can we use is_empty? */
+ x -= attr->x_offset;
+ y -= attr->y_offset;
+ attr->x_offset = 0;
+ attr->y_offset = 0;
- status = _cairo_surface_clone_similar (dst, pattern->surface,
- extents.x, extents.y,
- extents.width, extents.height,
- &x, &y, out);
- if (status == CAIRO_STATUS_SUCCESS && (x != 0 || y != 0)) {
- if (_cairo_matrix_is_identity (&attr->matrix)) {
- attr->x_offset -= x;
- attr->y_offset -= y;
- } else {
- cairo_matrix_t m;
-
- x -= attr->x_offset;
- y -= attr->y_offset;
- attr->x_offset = 0;
- attr->y_offset = 0;
-
- cairo_matrix_init_translate (&m, -x, -y);
- cairo_matrix_multiply (&attr->matrix, &attr->matrix, &m);
- }
+ cairo_matrix_init_translate (&m, -x, -y);
+ cairo_matrix_multiply (&attr->matrix, &attr->matrix, &m);
}
}
+ BAIL:
+ cairo_surface_destroy (surface);
return status;
}
@@ -2020,7 +2028,6 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
if (pattern->status) {
*surface_out = NULL;
- attributes->acquired = FALSE;
return pattern->status;
}
@@ -2103,21 +2110,7 @@ _cairo_pattern_release_surface (const cairo_pattern_t *pattern,
cairo_surface_t *surface,
cairo_surface_attributes_t *attributes)
{
- if (attributes->acquired)
- {
- const cairo_surface_pattern_t *surface_pattern;
-
- assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
- surface_pattern = (const cairo_surface_pattern_t *) pattern;
-
- _cairo_surface_release_source_image (surface_pattern->surface,
- (cairo_image_surface_t *) surface,
- attributes->extra);
- }
- else
- {
- cairo_surface_destroy (surface);
- }
+ cairo_surface_destroy (surface);
}
cairo_int_status_t
diff --git a/src/cairoint.h b/src/cairoint.h
index 4340dbd..2810348 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -915,7 +915,6 @@ typedef struct _cairo_surface_attributes {
cairo_filter_t filter;
int x_offset;
int y_offset;
- cairo_bool_t acquired;
void *extra;
} cairo_surface_attributes_t;
commit 234623b3d5884b02a0619de8ddd57bbed36ef4fd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 23 14:55:26 2008 +0100
[pattern] Support unbounded surfaces.
An unbounded surface should just report an infinite pattern extent and not
return UNSUPPORTED from _cairo_pattern_get_extents().
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 5399fea..8113ff9 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -2220,6 +2220,8 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
double pad;
status = _cairo_surface_get_extents (surface, &surface_extents);
+ if (status == CAIRO_INT_STATUS_UNSUPPORTED)
+ goto UNBOUNDED;
if (status)
return status;
@@ -2266,6 +2268,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
* horizontal/vertical linear gradients).
*/
+ UNBOUNDED:
/* unbounded patterns -> 'infinite' extents */
extents->x = CAIRO_RECT_INT_MIN;
extents->y = CAIRO_RECT_INT_MIN;
commit 2836be6f7565684e86b3cc8a3d2db4ba690b3718
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 23 14:42:47 2008 +0100
Cleanup 'status && status != UNSUPPORTED'
Replace instances of 'status && status != UNSUPPORTED' with the more
readable _cairo_status_is_error().
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 940c8a8..4337e92 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -116,7 +116,7 @@ _analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
old_height = surface->height;
old_clip = surface->current_clip;
status = _cairo_surface_get_extents (surface_pattern->surface, &meta_extents);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
surface->width = meta_extents.width;
@@ -339,7 +339,7 @@ _cairo_analysis_surface_paint (void *abstract_surface,
backend_status = _analyze_meta_surface_pattern (surface, source);
status = _cairo_surface_get_extents (&surface->base, &extents);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
@@ -406,7 +406,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
}
status = _cairo_surface_get_extents (&surface->base, &extents);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
@@ -465,7 +465,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
backend_status = _analyze_meta_surface_pattern (surface, source);
status = _cairo_surface_get_extents (&surface->base, &extents);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
@@ -534,7 +534,7 @@ _cairo_analysis_surface_fill (void *abstract_surface,
backend_status = _analyze_meta_surface_pattern (surface, source);
status = _cairo_surface_get_extents (&surface->base, &extents);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
@@ -612,7 +612,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
backend_status = _analyze_meta_surface_pattern (surface, source);
status = _cairo_surface_get_extents (&surface->base, &extents);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
@@ -695,7 +695,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
backend_status = _analyze_meta_surface_pattern (surface, source);
status = _cairo_surface_get_extents (&surface->base, &extents);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (_cairo_operator_bounded_by_source (op)) {
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 8a0d4db..93bc151 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -656,7 +656,7 @@ _cairo_clip_path_reapply_clip_path (cairo_clip_t *clip,
if (clip_path->prev) {
status = _cairo_clip_path_reapply_clip_path (clip, clip_path->prev);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
}
@@ -709,7 +709,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
if (other->path) {
status = _cairo_clip_path_reapply_clip_path (clip, other->path);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
goto BAIL;
}
}
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 0154acd..4cad470 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -3027,7 +3027,7 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset, TRUE,
&to_unicode_stream);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
descriptor = _cairo_pdf_surface_new_object (surface);
@@ -3199,7 +3199,7 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset, FALSE,
&to_unicode_stream);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
descriptor = _cairo_pdf_surface_new_object (surface);
@@ -3356,7 +3356,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset, TRUE,
&to_unicode_stream);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) {
+ if (_cairo_status_is_error (status)) {
_cairo_truetype_subset_fini (&subset);
return status;
}
@@ -3658,7 +3658,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
font_subset, FALSE,
&to_unicode_stream);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) {
+ if (_cairo_status_is_error (status)) {
free (widths);
return status;
}
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 3d7afb6..9e55e9f 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -577,7 +577,7 @@ _cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_su
status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
#if CAIRO_HAS_FT_FONT
@@ -606,7 +606,7 @@ _cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subs
cairo_status_t status;
status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset);
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 066f637..815c4d8 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -342,7 +342,7 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
status = _cairo_truetype_index_to_ucs4 (scaled_font,
scaled_font_glyph_index,
&unicode);
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (unicode == (uint32_t)-1 && scaled_font->backend->index_to_ucs4) {
@@ -722,7 +722,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
&scaled_glyph);
_cairo_scaled_font_thaw_cache (scaled_font);
}
- if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
+ if (_cairo_status_is_error (status))
return status;
if (status == CAIRO_STATUS_SUCCESS &&
commit 13ba43eb8ffc3bb6c8881d91824102a8df86d928
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Thu Oct 23 12:28:25 2008 +0100
[matrix] Optimize finding the bounding box under an orthogonal matrix.
We frequently need to find the bounds of a pattern under an identity
matrix, or a simple scale+translation. For these cases we do not need to
transform each corner and search for the bounds as the matrix is x/y
separable and so allows us to inspect the results for the extreme x/y
points independently.
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index f01353e..643c986 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -371,6 +371,46 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
double min_x, max_x;
double min_y, max_y;
+ if (_cairo_matrix_is_identity (matrix)) {
+ if (is_tight)
+ *is_tight = TRUE;
+
+ return;
+ }
+
+ if (matrix->xy == 0. && matrix->yx == 0.) {
+ /* non-rotation/skew matrix, just map the two extreme points */
+ quad_x[0] = *x1;
+ quad_y[0] = *y1;
+ cairo_matrix_transform_distance (matrix, &quad_x[0], &quad_y[0]);
+
+ quad_x[1] = *x2;
+ quad_y[1] = *y2;
+ cairo_matrix_transform_distance (matrix, &quad_x[1], &quad_y[1]);
+
+ if (quad_x[0] < quad_x[1]) {
+ *x1 = quad_x[0] + matrix->x0;
+ *x2 = quad_x[1] + matrix->x0;
+ } else {
+ *x1 = quad_x[1] + matrix->x0;
+ *x2 = quad_x[0] + matrix->x0;
+ }
+
+ if (quad_y[0] < quad_y[1]) {
+ *y1 = quad_y[0] + matrix->y0;
+ *y2 = quad_y[1] + matrix->y0;
+ } else {
+ *y1 = quad_y[1] + matrix->y0;
+ *y2 = quad_y[0] + matrix->y0;
+ }
+
+ if (is_tight)
+ *is_tight = TRUE;
+
+ return;
+ }
+
+ /* general matrix */
quad_x[0] = *x1;
quad_y[0] = *y1;
cairo_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]);
@@ -406,7 +446,7 @@ _cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix,
*y1 = min_y;
*x2 = max_x;
*y2 = max_y;
-
+
if (is_tight) {
/* it's tight if and only if the four corner points form an axis-aligned
rectangle.
commit 6ed957fc242d7890117f4dea121c03ec2523470c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 22 22:02:05 2008 +0100
[gstate] Use _cairo_pattern_black for the default source.
Avoid allocating a default source pattern by using the static black pattern
object. The one complication is that we need to ensure that the static
pattern does leak to the application, so we replace it with an allocated
solid pattern within _cairo_gstate_get_source().
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index 051353f..7e56a77 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -103,8 +103,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
gstate->ctm_inverse = gstate->ctm;
gstate->source_ctm_inverse = gstate->ctm;
- gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
- CAIRO_CONTENT_COLOR);
+ gstate->source = (cairo_pattern_t *) &_cairo_pattern_black.base;
/* Now that the gstate is fully initialized and ready for the eventual
* _cairo_gstate_fini(), we can check for errors (and not worry about
@@ -402,6 +401,12 @@ _cairo_gstate_set_source (cairo_gstate_t *gstate,
cairo_pattern_t *
_cairo_gstate_get_source (cairo_gstate_t *gstate)
{
+ if (gstate->source == &_cairo_pattern_black.base) {
+ /* do not expose the static object to the user */
+ gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK,
+ CAIRO_CONTENT_COLOR);
+ }
+
return gstate->source;
}
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 516eec7..5399fea 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -31,7 +31,7 @@
#include "cairoint.h"
const cairo_solid_pattern_t _cairo_pattern_nil = {
- { CAIRO_PATTERN_TYPE_SOLID, /* type */
+ { CAIRO_PATTERN_TYPE_SOLID, /* type */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
CAIRO_STATUS_NO_MEMORY, /* status */
{ 0, 0, 0, NULL }, /* user_data */
@@ -41,7 +41,7 @@ const cairo_solid_pattern_t _cairo_pattern_nil = {
};
static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = {
- { CAIRO_PATTERN_TYPE_SOLID, /* type */
+ { CAIRO_PATTERN_TYPE_SOLID, /* type */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
CAIRO_STATUS_NULL_POINTER, /* status */
{ 0, 0, 0, NULL }, /* user_data */
@@ -50,14 +50,16 @@ static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = {
CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
};
-const cairo_solid_pattern_t _cairo_pattern_none = {
- { CAIRO_PATTERN_TYPE_SOLID, /* type */
+const cairo_solid_pattern_t _cairo_pattern_black = {
+ { CAIRO_PATTERN_TYPE_SOLID, /* type */
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
CAIRO_STATUS_SUCCESS, /* status */
{ 0, 0, 0, NULL }, /* user_data */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
CAIRO_FILTER_DEFAULT, /* filter */
- CAIRO_EXTEND_GRADIENT_DEFAULT }, /* extend */
+ CAIRO_EXTEND_GRADIENT_DEFAULT}, /* extend */
+ { 0., 0., 0., 1., 0, 0, 0, 0xffff },/* color (double rgba, short rgba) */
+ CAIRO_CONTENT_COLOR, /* content */
};
/**
diff --git a/src/cairo.c b/src/cairo.c
index cefc925..2a9f746 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -651,7 +651,7 @@ cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue)
return;
/* push the current pattern to the freed lists */
- cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_none);
+ cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
pattern = cairo_pattern_create_rgb (red, green, blue);
cairo_set_source (cr, pattern);
@@ -688,7 +688,7 @@ cairo_set_source_rgba (cairo_t *cr,
return;
/* push the current pattern to the freed lists */
- cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_none);
+ cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
pattern = cairo_pattern_create_rgba (red, green, blue, alpha);
cairo_set_source (cr, pattern);
@@ -731,7 +731,7 @@ cairo_set_source_surface (cairo_t *cr,
return;
/* push the current pattern to the freed lists */
- cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_none);
+ cairo_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black);
pattern = cairo_pattern_create_for_surface (surface);
diff --git a/src/cairoint.h b/src/cairoint.h
index 9e1cd7d..4340dbd 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -856,7 +856,7 @@ struct _cairo_solid_pattern {
};
extern const cairo_private cairo_solid_pattern_t _cairo_pattern_nil;
-extern const cairo_private cairo_solid_pattern_t _cairo_pattern_none;
+extern const cairo_private cairo_solid_pattern_t _cairo_pattern_black;
typedef struct _cairo_surface_pattern {
cairo_pattern_t base;
commit 794460186459981cd43ca38f3eba07e3f6bf8908
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 22 19:24:44 2008 +0100
[pattern] Avoid needless copying of patterns.
Only copy the pattern if we need to modify it, e.g. preserve a copy in a
snapshot or a soft-mask, or to modify the matrix. Otherwise we can
continue to use the original pattern and mark it as const in order to
generate compiler warnings if we do attempt to write to it.
diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c
index 057be52..940c8a8 100644
--- a/src/cairo-analysis-surface.c
+++ b/src/cairo-analysis-surface.c
@@ -96,10 +96,10 @@ _cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
static cairo_int_status_t
_analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
cairo_surface_t *analysis = &surface->base;
- cairo_surface_pattern_t *surface_pattern;
+ const cairo_surface_pattern_t *surface_pattern;
cairo_status_t status;
cairo_bool_t old_has_ctm;
cairo_matrix_t old_ctm, p2d;
@@ -109,7 +109,7 @@ _analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
int old_height;
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
- surface_pattern = (cairo_surface_pattern_t *) pattern;
+ surface_pattern = (const cairo_surface_pattern_t *) pattern;
assert (_cairo_surface_is_meta (surface_pattern->surface));
old_width = surface->width;
@@ -321,8 +321,8 @@ _cairo_analysis_surface_get_extents (void *abstract_surface,
static cairo_int_status_t
_cairo_analysis_surface_paint (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source)
+ cairo_operator_t op,
+ const cairo_pattern_t *source)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_status_t status, backend_status;
@@ -362,8 +362,8 @@ _cairo_analysis_surface_paint (void *abstract_surface,
static cairo_int_status_t
_cairo_analysis_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
cairo_analysis_surface_t *surface = abstract_surface;
cairo_int_status_t status, backend_status;
@@ -381,7 +381,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
- cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source;
+ const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t *) source;
if (_cairo_surface_is_meta (surface_pattern->surface)) {
backend_source_status =
_analyze_meta_surface_pattern (surface, source);
@@ -411,6 +411,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
@@ -438,7 +439,7 @@ _cairo_analysis_surface_mask (void *abstract_surface,
static cairo_int_status_t
_cairo_analysis_surface_stroke (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -510,7 +511,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_analysis_surface_fill (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -578,7 +579,7 @@ _cairo_analysis_surface_fill (void *abstract_surface,
static cairo_int_status_t
_cairo_analysis_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
@@ -653,7 +654,7 @@ _cairo_analysis_surface_has_show_text_glyphs (void *abstract_surface)
static cairo_int_status_t
_cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
@@ -897,18 +898,18 @@ typedef cairo_int_status_t
typedef cairo_int_status_t
(*_paint_func) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source);
+ const cairo_pattern_t *source);
typedef cairo_int_status_t
(*_mask_func) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask);
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask);
typedef cairo_int_status_t
(*_stroke_func) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -919,7 +920,7 @@ typedef cairo_int_status_t
typedef cairo_int_status_t
(*_fill_func) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -928,7 +929,7 @@ typedef cairo_int_status_t
typedef cairo_int_status_t
(*_show_glyphs_func) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c
index aa67b02..351e00d 100644
--- a/src/cairo-directfb-surface.c
+++ b/src/cairo-directfb-surface.c
@@ -702,8 +702,8 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
#if DFB_COMPOSITE || DFB_COMPOSITE_TRAPEZOIDS
static cairo_int_status_t
_directfb_prepare_composite (cairo_directfb_surface_t *dst,
- cairo_pattern_t *src_pattern,
- cairo_pattern_t *mask_pattern,
+ const cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *mask_pattern,
cairo_operator_t op,
int *src_x, int *src_y,
int *mask_x, int *mask_y,
@@ -732,7 +732,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
return CAIRO_INT_STATUS_UNSUPPORTED;
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID) {
- cairo_pattern_t *tmp;
+ const cairo_pattern_t *tmp;
int tmp_x, tmp_y;
if (src_pattern->type != CAIRO_PATTERN_TYPE_SOLID ||
@@ -761,11 +761,6 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
color = _cairo_stock_color (CAIRO_STOCK_WHITE);
}
- /* XXX DirectFB currently does not support filtering, so force NEAREST
- * in order to hit optimisations inside core.
- */
- src_pattern->filter = CAIRO_FILTER_NEAREST;
-
status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
*src_x, *src_y, width, height,
(cairo_surface_t **) &src,
@@ -842,7 +837,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
static void
_directfb_finish_composite (cairo_directfb_surface_t *dst,
- cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *src_pattern,
cairo_surface_t *src,
cairo_surface_attributes_t *src_attr)
{
@@ -892,8 +887,8 @@ _directfb_categorize_operation (cairo_surface_attributes_t *src_attr)
static cairo_int_status_t
_cairo_directfb_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_pattern_t *mask_pattern,
+ const cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x, int src_y,
int mask_x, int mask_y,
@@ -1160,7 +1155,7 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface
#if DFB_COMPOSITE_TRAPEZOIDS
static cairo_int_status_t
_cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x, int src_y,
@@ -1686,13 +1681,13 @@ _cairo_directfb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
}
static cairo_int_status_t
-_cairo_directfb_surface_show_glyphs (void *abstract_dst,
- cairo_operator_t op,
- cairo_pattern_t *pattern,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- int *remaining_glyphs)
+_cairo_directfb_surface_show_glyphs (void *abstract_dst,
+ cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font,
+ int *remaining_glyphs)
{
cairo_directfb_surface_t *dst = abstract_dst;
cairo_directfb_font_cache_t *cache;
diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c
index 784bff9..5bdfa70 100644
--- a/src/cairo-glitz-surface.c
+++ b/src/cairo-glitz-surface.c
@@ -718,7 +718,7 @@ typedef struct _cairo_glitz_surface_attributes {
} cairo_glitz_surface_attributes_t;
static cairo_int_status_t
-_cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
+_cairo_glitz_pattern_acquire_surface (const cairo_pattern_t *pattern,
cairo_glitz_surface_t *dst,
int x,
int y,
@@ -937,7 +937,7 @@ _cairo_glitz_pattern_acquire_surface (cairo_pattern_t *pattern,
}
static void
-_cairo_glitz_pattern_release_surface (cairo_pattern_t *pattern,
+_cairo_glitz_pattern_release_surface (const cairo_pattern_t *pattern,
cairo_glitz_surface_t *surface,
cairo_glitz_surface_attributes_t *attr)
{
@@ -948,8 +948,8 @@ _cairo_glitz_pattern_release_surface (cairo_pattern_t *pattern,
}
static cairo_int_status_t
-_cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src,
- cairo_pattern_t *mask,
+_cairo_glitz_pattern_acquire_surfaces (const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
cairo_glitz_surface_t *dst,
int src_x,
int src_y,
@@ -985,37 +985,31 @@ _cairo_glitz_pattern_acquire_surfaces (cairo_pattern_t *src,
_cairo_pattern_init_solid (&tmp, &combined, CAIRO_CONTENT_COLOR_ALPHA);
mask = NULL;
- } else {
- status = _cairo_pattern_init_copy (&tmp.base, src);
- if (status)
- return status;
+ src = &tmp.base;
}
- status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
+ status = _cairo_glitz_pattern_acquire_surface (src, dst,
src_x, src_y,
width, height,
src_out, sattr);
- _cairo_pattern_fini (&tmp.base);
+ if (src == &tmp.base)
+ _cairo_pattern_fini (&tmp.base);
if (status)
return status;
if (mask)
{
- status = _cairo_pattern_init_copy (&tmp.base, mask);
- if (status)
- return status;
-
- status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst,
+ status = _cairo_glitz_pattern_acquire_surface (mask, dst,
mask_x, mask_y,
width, height,
mask_out, mattr);
- if (status)
- _cairo_glitz_pattern_release_surface (&tmp.base, *src_out, sattr);
-
- _cairo_pattern_fini (&tmp.base);
+ if (status) {
+ /* XXX src == &tmp.base -> invalid (currently inconsequential) */
+ _cairo_glitz_pattern_release_surface (src, *src_out, sattr);
+ }
return status;
}
@@ -1039,8 +1033,8 @@ _cairo_glitz_surface_set_attributes (cairo_glitz_surface_t *surface,
static cairo_int_status_t
_cairo_glitz_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_pattern_t *mask_pattern,
+ const cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
@@ -1197,7 +1191,7 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
static cairo_int_status_t
_cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
@@ -1210,7 +1204,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
int n_traps)
{
cairo_pattern_union_t tmp_src_pattern;
- cairo_pattern_t *src_pattern;
+ const cairo_pattern_t *src_pattern;
cairo_glitz_surface_attributes_t attributes;
cairo_glitz_surface_t *dst = abstract_dst;
cairo_glitz_surface_t *src;
@@ -2101,7 +2095,7 @@ _cairo_glitz_surface_add_glyph (cairo_glitz_surface_t *surface,
static cairo_int_status_t
_cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *abstract_surface,
int src_x,
int src_y,
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index fe8d279..051353f 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -810,34 +810,53 @@ _cairo_gstate_path_extents (cairo_gstate_t *gstate,
static cairo_status_t
_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
- cairo_pattern_t *pattern,
+ cairo_pattern_t **pattern,
cairo_pattern_t *original,
cairo_matrix_t *ctm_inverse)
{
- cairo_surface_pattern_t *surface_pattern;
- cairo_surface_t *surface;
cairo_status_t status;
-
- status = _cairo_pattern_init_copy (pattern, original);
- if (status)
- return status;
+ cairo_bool_t have_copy = FALSE;
/* apply device_transform first so that it is transformed by ctm_inverse */
- if (cairo_pattern_get_type (original) == CAIRO_PATTERN_TYPE_SURFACE) {
+ if (original->type == CAIRO_PATTERN_TYPE_SURFACE) {
+ cairo_surface_pattern_t *surface_pattern;
+ cairo_surface_t *surface;
+
surface_pattern = (cairo_surface_pattern_t *) original;
surface = surface_pattern->surface;
- if (_cairo_surface_has_device_transform (surface))
- _cairo_pattern_transform (pattern, &surface->device_transform);
+
+ if (_cairo_surface_has_device_transform (surface)) {
+ status = _cairo_pattern_init_copy (*pattern, original);
+ if (status)
+ return status;
+
+ have_copy = TRUE;
+
+ _cairo_pattern_transform (*pattern, &surface->device_transform);
+ }
}
- _cairo_pattern_transform (pattern, ctm_inverse);
+ if (! _cairo_matrix_is_identity (ctm_inverse)) {
+ if (! have_copy) {
+ status = _cairo_pattern_init_copy (*pattern, original);
+ if (status)
+ return status;
+
+ have_copy = TRUE;
+ }
+
+ _cairo_pattern_transform (*pattern, ctm_inverse);
+ }
+
+ if (! have_copy)
+ *pattern = original;
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
-_cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate,
- cairo_pattern_t *pattern)
+_cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate,
+ cairo_pattern_t **pattern)
{
return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
gstate->source,
@@ -845,9 +864,9 @@ _cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate,
}
static cairo_status_t
-_cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate,
- cairo_pattern_t *pattern,
- cairo_pattern_t *mask)
+_cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate,
+ cairo_pattern_t **pattern,
+ cairo_pattern_t *mask)
{
return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
mask,
@@ -858,7 +877,8 @@ cairo_status_t
_cairo_gstate_paint (cairo_gstate_t *gstate)
{
cairo_status_t status;
- cairo_pattern_union_t pattern;
+ cairo_pattern_t *pattern;
+ cairo_pattern_union_t pattern_stack;
if (gstate->source->status)
return gstate->source->status;
@@ -867,15 +887,17 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
if (status)
return status;
- status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+ pattern = &pattern_stack.base;
+ status = _cairo_gstate_copy_transformed_source (gstate, &pattern);
if (status)
return status;
status = _cairo_surface_paint (gstate->target,
gstate->op,
- &pattern.base);
+ pattern);
- _cairo_pattern_fini (&pattern.base);
+ if (pattern == &pattern_stack.base)
+ _cairo_pattern_fini (pattern);
return status;
}
@@ -885,7 +907,8 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
cairo_pattern_t *mask)
{
cairo_status_t status;
- cairo_pattern_union_t source_pattern, mask_pattern;
+ cairo_pattern_union_t source_pattern_stack, mask_pattern_stack;
+ cairo_pattern_t *source_pattern, *mask_pattern;
if (mask->status)
return mask->status;
@@ -897,22 +920,26 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
if (status)
return status;
- status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+ source_pattern = &source_pattern_stack.base;
+ status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern);
if (status)
return status;
- status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
+ mask_pattern = &mask_pattern_stack.base;
+ status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern, mask);
if (status)
goto CLEANUP_SOURCE;
status = _cairo_surface_mask (gstate->target,
gstate->op,
- &source_pattern.base,
- &mask_pattern.base);
+ source_pattern,
+ mask_pattern);
- _cairo_pattern_fini (&mask_pattern.base);
+ if (mask_pattern == &mask_pattern_stack.base)
+ _cairo_pattern_fini (&mask_pattern_stack.base);
CLEANUP_SOURCE:
- _cairo_pattern_fini (&source_pattern.base);
+ if (source_pattern == &source_pattern_stack.base)
+ _cairo_pattern_fini (&source_pattern_stack.base);
return status;
}
@@ -921,7 +948,8 @@ cairo_status_t
_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
{
cairo_status_t status;
- cairo_pattern_union_t source_pattern;
+ cairo_pattern_union_t source_pattern_stack;
+ cairo_pattern_t *source_pattern;
if (gstate->source->status)
return gstate->source->status;
@@ -933,14 +961,15 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
if (status)
return status;
+ source_pattern = &source_pattern_stack.base;
status = _cairo_gstate_copy_transformed_source (gstate,
- &source_pattern.base);
+ &source_pattern);
if (status)
return status;
status = _cairo_surface_stroke (gstate->target,
gstate->op,
- &source_pattern.base,
+ source_pattern,
path,
&gstate->stroke_style,
&gstate->ctm,
@@ -948,10 +977,10 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
gstate->tolerance,
gstate->antialias);
- _cairo_pattern_fini (&source_pattern.base);
+ if (source_pattern == &source_pattern_stack.base)
+ _cairo_pattern_fini (&source_pattern_stack.base);
return status;
-
}
cairo_status_t
@@ -1001,7 +1030,8 @@ cairo_status_t
_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
{
cairo_status_t status;
- cairo_pattern_union_t pattern;
+ cairo_pattern_union_t pattern_stack;
+ cairo_pattern_t *pattern;
if (gstate->source->status)
return gstate->source->status;
@@ -1010,19 +1040,21 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
if (status)
return status;
- status = _cairo_gstate_copy_transformed_source (gstate, &pattern.base);
+ pattern = &pattern_stack.base;
+ status = _cairo_gstate_copy_transformed_source (gstate, &pattern);
if (status)
return status;
status = _cairo_surface_fill (gstate->target,
gstate->op,
- &pattern.base,
+ pattern,
path,
gstate->fill_rule,
gstate->tolerance,
gstate->antialias);
- _cairo_pattern_fini (&pattern.base);
+ if (pattern == &pattern_stack.base)
+ _cairo_pattern_fini (&pattern_stack.base);
return status;
}
@@ -1582,7 +1614,8 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
cairo_text_cluster_flags_t cluster_flags)
{
cairo_status_t status;
- cairo_pattern_union_t source_pattern;
+ cairo_pattern_union_t source_pattern_stack;
+ cairo_pattern_t *source_pattern;
cairo_glyph_t *transformed_glyphs;
cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
@@ -1613,7 +1646,8 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (status || num_glyphs == 0)
goto CLEANUP_GLYPHS;
- status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
+ source_pattern = &source_pattern_stack.base;
+ status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern);
if (status)
goto CLEANUP_GLYPHS;
@@ -1635,7 +1669,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
_cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240) {
status = _cairo_surface_show_text_glyphs (gstate->target,
gstate->op,
- &source_pattern.base,
+ source_pattern,
utf8, utf8_len,
transformed_glyphs, num_glyphs,
clusters, num_clusters,
@@ -1653,7 +1687,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_surface_fill (gstate->target,
gstate->op,
- &source_pattern.base,
+ source_pattern,
&path,
CAIRO_FILL_RULE_WINDING,
gstate->tolerance,
@@ -1662,7 +1696,8 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
_cairo_path_fixed_fini (&path);
}
- _cairo_pattern_fini (&source_pattern.base);
+ if (source_pattern == &source_pattern_stack.base)
+ _cairo_pattern_fini (&source_pattern_stack.base);
CLEANUP_GLYPHS:
if (transformed_glyphs != stack_transformed_glyphs)
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 4aad77f..12614c1 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -939,8 +939,8 @@ _pixman_operator (cairo_operator_t op)
static cairo_int_status_t
_cairo_image_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_pattern_t *mask_pattern,
+ const cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
@@ -1072,7 +1072,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
static cairo_int_status_t
_cairo_image_surface_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c
index b86cb51..faf4855 100644
--- a/src/cairo-meta-surface.c
+++ b/src/cairo-meta-surface.c
@@ -219,7 +219,7 @@ _cairo_meta_surface_release_source_image (void *abstract_surface,
static cairo_int_status_t
_cairo_meta_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_status_t status;
cairo_meta_surface_t *meta = abstract_surface;
@@ -259,8 +259,8 @@ _cairo_meta_surface_paint (void *abstract_surface,
static cairo_int_status_t
_cairo_meta_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
cairo_status_t status;
cairo_meta_surface_t *meta = abstract_surface;
@@ -300,7 +300,7 @@ _cairo_meta_surface_mask (void *abstract_surface,
static cairo_int_status_t
_cairo_meta_surface_stroke (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -357,7 +357,7 @@ _cairo_meta_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_meta_surface_fill (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -411,7 +411,7 @@ _cairo_meta_surface_has_show_text_glyphs (void *abstract_surface)
static cairo_int_status_t
_cairo_meta_surface_show_text_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index a94ca80..e50820c 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -526,7 +526,7 @@ _cairo_paginated_surface_get_font_options (void *abstract_surfa
static cairo_int_status_t
_cairo_paginated_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_paginated_surface_t *surface = abstract_surface;
@@ -542,8 +542,8 @@ _cairo_paginated_surface_paint (void *abstract_surface,
static cairo_int_status_t
_cairo_paginated_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
cairo_paginated_surface_t *surface = abstract_surface;
@@ -553,7 +553,7 @@ _cairo_paginated_surface_mask (void *abstract_surface,
static cairo_int_status_t
_cairo_paginated_surface_stroke (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -578,7 +578,7 @@ _cairo_paginated_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_paginated_surface_fill (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -608,7 +608,7 @@ _cairo_paginated_surface_has_show_text_glyphs (void *abstract_surface)
static cairo_int_status_t
_cairo_paginated_surface_show_text_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 064eeb6..516eec7 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1232,7 +1232,7 @@ _cairo_linear_pattern_classify (cairo_linear_pattern_t *pattern,
}
static cairo_int_status_t
-_cairo_pattern_acquire_surface_for_gradient (cairo_gradient_pattern_t *pattern,
+_cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pattern,
cairo_surface_t *dst,
int x,
int y,
@@ -1496,7 +1496,7 @@ _cairo_pattern_solid_surface_matches_color (
}
static cairo_int_status_t
-_cairo_pattern_acquire_surface_for_solid (cairo_solid_pattern_t *pattern,
+_cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *pattern,
cairo_surface_t *dst,
int x,
int y,
@@ -1716,8 +1716,8 @@ _cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern)
* backends do currently (see bug #10508)
*/
static cairo_filter_t
-_cairo_pattern_analyze_filter (cairo_surface_pattern_t *pattern,
- double *pad_out)
+_cairo_pattern_analyze_filter (const cairo_surface_pattern_t *pattern,
+ double *pad_out)
{
double pad;
cairo_filter_t optimized_filter;
@@ -1767,7 +1767,7 @@ _pixman_nearest_sample (double d)
}
static cairo_int_status_t
-_cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
+_cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pattern,
cairo_surface_t *dst,
int x,
int y,
@@ -2005,7 +2005,7 @@ _cairo_pattern_acquire_surface_for_surface (cairo_surface_pattern_t *pattern,
* Return value: %CAIRO_STATUS_SUCCESS if a surface was stored in @surface_out.
**/
cairo_int_status_t
-_cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
+_cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
cairo_surface_t *dst,
int x,
int y,
@@ -2097,16 +2097,16 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
* Releases resources obtained by _cairo_pattern_acquire_surface.
**/
void
-_cairo_pattern_release_surface (cairo_pattern_t *pattern,
+_cairo_pattern_release_surface (const cairo_pattern_t *pattern,
cairo_surface_t *surface,
cairo_surface_attributes_t *attributes)
{
if (attributes->acquired)
{
- cairo_surface_pattern_t *surface_pattern;
+ const cairo_surface_pattern_t *surface_pattern;
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
- surface_pattern = (cairo_surface_pattern_t *) pattern;
+ surface_pattern = (const cairo_surface_pattern_t *) pattern;
_cairo_surface_release_source_image (surface_pattern->surface,
(cairo_image_surface_t *) surface,
@@ -2119,8 +2119,8 @@ _cairo_pattern_release_surface (cairo_pattern_t *pattern,
}
cairo_int_status_t
-_cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
- cairo_pattern_t *mask,
+_cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
cairo_surface_t *dst,
int src_x,
int src_y,
@@ -2134,7 +2134,7 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
cairo_surface_attributes_t *mask_attributes)
{
cairo_int_status_t status;
- cairo_pattern_union_t src_tmp, mask_tmp;
+ cairo_pattern_union_t src_tmp;
if (src->status)
return src->status;
@@ -2159,48 +2159,32 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
_cairo_pattern_init_solid (&src_tmp.solid, &combined, CAIRO_CONTENT_COLOR_ALPHA);
+ src = &src_tmp.base;
mask = NULL;
}
- else
- {
- status = _cairo_pattern_init_copy (&src_tmp.base, src);
- if (status)
- return status;
- }
- status = _cairo_pattern_acquire_surface (&src_tmp.base, dst,
+ status = _cairo_pattern_acquire_surface (src, dst,
src_x, src_y,
width, height,
src_out, src_attributes);
- if (status) {
- _cairo_pattern_fini (&src_tmp.base);
- return status;
- }
+ if (status)
+ goto BAIL;
- if (mask == NULL)
- {
- _cairo_pattern_fini (&src_tmp.base);
+ if (mask == NULL) {
*mask_out = NULL;
- return CAIRO_STATUS_SUCCESS;
+ goto BAIL;
}
- status = _cairo_pattern_init_copy (&mask_tmp.base, mask);
- if (status)
- goto CLEANUP_SOURCE;
-
- status = _cairo_pattern_acquire_surface (&mask_tmp.base, dst,
+ status = _cairo_pattern_acquire_surface (mask, dst,
mask_x, mask_y,
width, height,
mask_out, mask_attributes);
-
- _cairo_pattern_fini (&mask_tmp.base);
-
-CLEANUP_SOURCE:
if (status)
- _cairo_pattern_release_surface (&src_tmp.base,
- *src_out, src_attributes);
+ _cairo_pattern_release_surface (src, *src_out, src_attributes);
- _cairo_pattern_fini (&src_tmp.base);
+ BAIL:
+ if (src == &src_tmp.base)
+ _cairo_pattern_fini (&src_tmp.base);
return status;
}
@@ -2218,16 +2202,16 @@ CLEANUP_SOURCE:
* with a little more work.
**/
cairo_status_t
-_cairo_pattern_get_extents (cairo_pattern_t *pattern,
- cairo_rectangle_int_t *extents)
+_cairo_pattern_get_extents (const cairo_pattern_t *pattern,
+ cairo_rectangle_int_t *extents)
{
if (pattern->extend == CAIRO_EXTEND_NONE &&
pattern->type == CAIRO_PATTERN_TYPE_SURFACE)
{
cairo_status_t status;
cairo_rectangle_int_t surface_extents;
- cairo_surface_pattern_t *surface_pattern =
- (cairo_surface_pattern_t *) pattern;
+ const cairo_surface_pattern_t *surface_pattern =
+ (const cairo_surface_pattern_t *) pattern;
cairo_surface_t *surface = surface_pattern->surface;
cairo_matrix_t imatrix;
double x1, y1, x2, y2;
diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 44f0ed8..0154acd 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -774,7 +774,7 @@ _cairo_pdf_surface_add_smask_group (cairo_pdf_surface_t *surface,
static cairo_status_t
_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_pdf_resource_t *pattern_res,
cairo_pdf_resource_t *gstate_res)
{
@@ -807,10 +807,13 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
}
}
- pdf_pattern.pattern = cairo_pattern_reference (pattern);
+ status = _cairo_pattern_create_copy (&pdf_pattern.pattern, pattern);
+ if (status)
+ return status;
+
pdf_pattern.pattern_res = _cairo_pdf_surface_new_object (surface);
if (pdf_pattern.pattern_res.id == 0) {
- cairo_pattern_destroy (pattern);
+ cairo_pattern_destroy (pdf_pattern.pattern);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@@ -822,7 +825,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
if (_cairo_pattern_is_opaque (pattern) == FALSE) {
pdf_pattern.gstate_res = _cairo_pdf_surface_new_object (surface);
if (pdf_pattern.gstate_res.id == 0) {
- cairo_pattern_destroy (pattern);
+ cairo_pattern_destroy (pdf_pattern.pattern);
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
}
@@ -835,7 +838,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
status = _cairo_array_append (&surface->patterns, &pdf_pattern);
if (status) {
- cairo_pattern_destroy (pattern);
+ cairo_pattern_destroy (pdf_pattern.pattern);
return status;
}
@@ -2616,16 +2619,16 @@ _cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern
static cairo_status_t
_cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_pdf_resource_t pattern_res,
cairo_bool_t is_stroke)
{
cairo_status_t status;
int alpha;
- cairo_color_t *solid_color = NULL;
+ const cairo_color_t *solid_color = NULL;
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
- cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
+ const cairo_solid_pattern_t *solid = (const cairo_solid_pattern_t *) pattern;
solid_color = &solid->color;
}
@@ -4257,11 +4260,11 @@ _surface_pattern_supported (cairo_surface_pattern_t *pattern)
}
static cairo_bool_t
-_gradient_pattern_supported (cairo_pattern_t *pattern)
+_gradient_pattern_supported (const cairo_pattern_t *pattern)
{
cairo_extend_t extend;
- extend = cairo_pattern_get_extend (pattern);
+ extend = cairo_pattern_get_extend ((cairo_pattern_t *) pattern);
/* Radial gradients are currently only supported with EXTEND_NONE
@@ -4292,7 +4295,7 @@ _gradient_pattern_supported (cairo_pattern_t *pattern)
}
static cairo_bool_t
-_pattern_supported (cairo_pattern_t *pattern)
+_pattern_supported (const cairo_pattern_t *pattern)
{
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
return TRUE;
@@ -4310,10 +4313,13 @@ _pattern_supported (cairo_pattern_t *pattern)
static cairo_int_status_t
_cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
- if (surface->force_fallbacks && surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+ if (surface->force_fallbacks &&
+ surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+ {
return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
if (! _pattern_supported (pattern))
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -4368,7 +4374,7 @@ _cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface,
static cairo_bool_t
_cairo_pdf_surface_operation_supported (cairo_pdf_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
if (_cairo_pdf_surface_analyze_operation (surface, op, pattern) != CAIRO_INT_STATUS_UNSUPPORTED)
return TRUE;
@@ -4396,7 +4402,7 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
static cairo_int_status_t
_cairo_pdf_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_status_t status;
@@ -4427,7 +4433,11 @@ _cairo_pdf_surface_paint (void *abstract_surface,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_PAINT;
- group->source = cairo_pattern_reference (source);
+ status = _cairo_pattern_create_copy (&group->source, source);
+ if (status) {
+ _cairo_pdf_smask_group_destroy (group);
+ return status;
+ }
group->source_res = pattern_res;
status = _cairo_pdf_surface_add_smask_group (surface, group);
if (status) {
@@ -4471,8 +4481,8 @@ _cairo_pdf_surface_paint (void *abstract_surface,
static cairo_int_status_t
_cairo_pdf_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
cairo_pdf_surface_t *surface = abstract_surface;
cairo_pdf_smask_group_t *group;
@@ -4505,8 +4515,16 @@ _cairo_pdf_surface_mask (void *abstract_surface,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_MASK;
- group->source = cairo_pattern_reference (source);
- group->mask = cairo_pattern_reference (mask);
+ status = _cairo_pattern_create_copy (&group->source, source);
+ if (status) {
+ _cairo_pdf_smask_group_destroy (group);
+ return status;
+ }
+ status = _cairo_pattern_create_copy (&group->mask, mask);
+ if (status) {
+ _cairo_pdf_smask_group_destroy (group);
+ return status;
+ }
group->source_res = _cairo_pdf_surface_new_object (surface);
if (group->source_res.id == 0) {
_cairo_pdf_smask_group_destroy (group);
@@ -4542,7 +4560,7 @@ _cairo_pdf_surface_mask (void *abstract_surface,
static cairo_int_status_t
_cairo_pdf_surface_stroke (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -4574,7 +4592,11 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_STROKE;
- group->source = cairo_pattern_reference (source);
+ status = _cairo_pattern_create_copy (&group->source, source);
+ if (status) {
+ _cairo_pdf_smask_group_destroy (group);
+ return status;
+ }
group->source_res = pattern_res;
status = _cairo_path_fixed_init_copy (&group->path, path);
if (status) {
@@ -4631,7 +4653,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_pdf_surface_fill (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -4666,7 +4688,11 @@ _cairo_pdf_surface_fill (void *abstract_surface,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_FILL;
- group->source = cairo_pattern_reference (source);
+ status = _cairo_pattern_create_copy (&group->source, source);
+ if (status) {
+ _cairo_pdf_smask_group_destroy (group);
+ return status;
+ }
group->source_res = pattern_res;
status = _cairo_path_fixed_init_copy (&group->path, path);
if (status) {
@@ -4719,13 +4745,13 @@ _cairo_pdf_surface_fill (void *abstract_surface,
static cairo_int_status_t
_cairo_pdf_surface_fill_stroke (void *abstract_surface,
cairo_operator_t fill_op,
- cairo_pattern_t *fill_source,
+ const cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
- cairo_pattern_t *stroke_source,
+ const cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
@@ -4812,8 +4838,8 @@ _cairo_pdf_surface_has_show_text_glyphs (void *abstract_surface)
static cairo_int_status_t
_cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
@@ -4847,7 +4873,11 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
group->operation = PDF_SHOW_GLYPHS;
- group->source = cairo_pattern_reference (source);
+ status = _cairo_pattern_create_copy (&group->source, source);
+ if (status) {
+ _cairo_pdf_smask_group_destroy (group);
+ return status;
+ }
group->source_res = pattern_res;
if (utf8_len) {
diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index bfe424d..3d7afb6 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -1437,7 +1437,7 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t
}
static cairo_bool_t
-surface_pattern_supported (cairo_surface_pattern_t *pattern)
+surface_pattern_supported (const cairo_surface_pattern_t *pattern)
{
cairo_extend_t extend;
@@ -1478,9 +1478,9 @@ surface_pattern_supported (cairo_surface_pattern_t *pattern)
static cairo_bool_t
_gradient_pattern_supported (cairo_ps_surface_t *surface,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
- cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern;
+ const cairo_gradient_pattern_t *gradient = (const cairo_gradient_pattern_t *) pattern;
uint16_t alpha;
cairo_extend_t extend;
unsigned int i;
@@ -1499,7 +1499,7 @@ _gradient_pattern_supported (cairo_ps_surface_t *surface,
return FALSE;
}
- extend = cairo_pattern_get_extend (pattern);
+ extend = cairo_pattern_get_extend ((cairo_pattern_t *) pattern);
/* Radial gradients are currently only supported when one circle
* is inside the other. */
@@ -1531,7 +1531,7 @@ _gradient_pattern_supported (cairo_ps_surface_t *surface,
}
static cairo_bool_t
-pattern_supported (cairo_ps_surface_t *surface, cairo_pattern_t *pattern)
+pattern_supported (cairo_ps_surface_t *surface, const cairo_pattern_t *pattern)
{
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
return TRUE;
@@ -1549,10 +1549,13 @@ pattern_supported (cairo_ps_surface_t *surface, cairo_pattern_t *pattern)
static cairo_int_status_t
_cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
- if (surface->force_fallbacks && surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+ if (surface->force_fallbacks &&
+ surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+ {
return CAIRO_INT_STATUS_UNSUPPORTED;
+ }
if (! pattern_supported (surface, pattern))
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1597,7 +1600,7 @@ _cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface,
static cairo_bool_t
_cairo_ps_surface_operation_supported (cairo_ps_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
if (_cairo_ps_surface_analyze_operation (surface, op, pattern) != CAIRO_INT_STATUS_UNSUPPORTED)
return TRUE;
@@ -2888,7 +2891,7 @@ _cairo_ps_surface_emit_radial_pattern (cairo_ps_surface_t *surface,
static cairo_status_t
_cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_operator_t op)
{
cairo_status_t status;
@@ -3018,7 +3021,7 @@ _cairo_ps_surface_get_font_options (void *abstract_surface,
static cairo_int_status_t
_cairo_ps_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_ps_surface_t *surface = abstract_surface;
cairo_output_stream_t *stream = surface->stream;
@@ -3077,7 +3080,7 @@ _cairo_ps_surface_paint (void *abstract_surface,
static cairo_int_status_t
_cairo_ps_surface_stroke (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -3111,12 +3114,12 @@ _cairo_ps_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_ps_surface_fill (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_fill_rule_t fill_rule,
- double tolerance,
- cairo_antialias_t antialias)
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias)
{
cairo_ps_surface_t *surface = abstract_surface;
cairo_int_status_t status;
@@ -3174,7 +3177,7 @@ _cairo_ps_surface_fill (void *abstract_surface,
static cairo_int_status_t
_cairo_ps_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c
index 41fde0b..fc9439e 100644
--- a/src/cairo-quartz-surface.c
+++ b/src/cairo-quartz-surface.c
@@ -688,7 +688,7 @@ CreateGradientFunction (cairo_gradient_pattern_t *gpat)
0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy
};
- return CGFunctionCreate (gpat,
+ return CGFunctionCreate (_cairo_pattern_create_copy (&gpat->base),
1,
input_value_range,
4,
@@ -766,7 +766,7 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface,
input_value_range[0] = 0.0 - 1.0 * rep_start;
input_value_range[1] = 1.0 + 1.0 * rep_end;
- return CGFunctionCreate (gpat,
+ return CGFunctionCreate (_cairo_pattern_create_copy (&gpat->base),
1,
input_value_range,
4,
@@ -1096,9 +1096,6 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface,
end = CGPointMake (_cairo_fixed_to_double (lpat->p2.x),
_cairo_fixed_to_double (lpat->p2.y));
- // ref will be released by the CGShading's destructor
- cairo_pattern_reference ((cairo_pattern_t*) lpat);
-
if (abspat->extend == CAIRO_EXTEND_NONE ||
abspat->extend == CAIRO_EXTEND_PAD)
{
@@ -1159,9 +1156,6 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface,
end = CGPointMake (_cairo_fixed_to_double (rpat->c2.x),
_cairo_fixed_to_double (rpat->c2.y));
- // ref will be released by the CGShading's destructor
- cairo_pattern_reference ((cairo_pattern_t*) rpat);
-
gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) rpat);
surface->sourceShading = CGShadingCreateRadial (rgb,
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 3ec07d5..32fd62a 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -1785,7 +1785,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
cairo_status_t
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *surface,
int source_x,
int source_y,
diff --git a/src/cairo-sdl-surface.c b/src/cairo-sdl-surface.c
index 411573e..b9d604e 100644
--- a/src/cairo-sdl-surface.c
+++ b/src/cairo-sdl-surface.c
@@ -208,18 +208,18 @@ _cairo_sdl_surface_clone_similar (void *abstract_surface,
}
static cairo_int_status_t
-_cairo_sdl_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_pattern_t *mask_pattern,
+_cairo_sdl_surface_composite (cairo_operator_t op,
+ const cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *mask_pattern,
void *abstract_dst,
- int src_x,
- int src_y,
- int mask_x,
- int mask_y,
- int dst_x,
- int dst_y,
- unsigned int width,
- unsigned int 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_sdl_surface_t *dst = abstract_dst;
cairo_sdl_surface_t *src;
diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h
index 2e10241..61e5b90 100644
--- a/src/cairo-surface-fallback-private.h
+++ b/src/cairo-surface-fallback-private.h
@@ -42,19 +42,20 @@
#include "cairoint.h"
cairo_private cairo_status_t
-_cairo_surface_fallback_paint (cairo_surface_t *surface,
- cairo_operator_t op,
- cairo_pattern_t *source);
+_cairo_surface_fallback_paint (cairo_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source);
+
cairo_private cairo_status_t
_cairo_surface_fallback_mask (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask);
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask);
cairo_private cairo_status_t
_cairo_surface_fallback_stroke (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *ctm,
@@ -65,16 +66,16 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_fallback_fill (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
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_fallback_show_glyphs (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font);
@@ -83,18 +84,18 @@ cairo_private cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface);
cairo_private cairo_status_t
-_cairo_surface_fallback_composite (cairo_operator_t op,
- cairo_pattern_t *src,
- cairo_pattern_t *mask,
- cairo_surface_t *dst,
- 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_surface_fallback_composite (cairo_operator_t op,
+ const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
+ cairo_surface_t *dst,
+ 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_private cairo_status_t
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
@@ -105,7 +106,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *dst,
cairo_antialias_t antialias,
int src_x,
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 5b9c99a..a5dcd57 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -103,7 +103,7 @@ _fallback_fini (fallback_state_t *state)
typedef cairo_status_t (*cairo_draw_func_t) (void *closure,
cairo_operator_t op,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_surface_t *dst,
int dst_x,
int dst_y,
@@ -156,7 +156,7 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
static cairo_status_t
_clip_and_composite_with_mask (cairo_clip_t *clip,
cairo_operator_t op,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_draw_func_t draw_func,
void *draw_closure,
cairo_surface_t *dst,
@@ -190,7 +190,7 @@ _clip_and_composite_with_mask (cairo_clip_t *clip,
static cairo_status_t
_clip_and_composite_combine (cairo_clip_t *clip,
cairo_operator_t op,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_draw_func_t draw_func,
void *draw_closure,
cairo_surface_t *dst,
@@ -278,7 +278,7 @@ _clip_and_composite_combine (cairo_clip_t *clip,
*/
static cairo_status_t
_clip_and_composite_source (cairo_clip_t *clip,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_draw_func_t draw_func,
void *draw_closure,
cairo_surface_t *dst,
@@ -352,7 +352,7 @@ _cairo_rectangle_empty (const cairo_rectangle_int_t *rect)
static cairo_status_t
_clip_and_composite (cairo_clip_t *clip,
cairo_operator_t op,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_draw_func_t draw_func,
void *draw_closure,
cairo_surface_t *dst,
@@ -408,7 +408,7 @@ _clip_and_composite (cairo_clip_t *clip,
*/
static cairo_status_t
_composite_trap_region (cairo_clip_t *clip,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_operator_t op,
cairo_surface_t *dst,
cairo_region_t *trap_region,
@@ -480,7 +480,7 @@ typedef struct {
static cairo_status_t
_composite_traps_draw_func (void *closure,
cairo_operator_t op,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_surface_t *dst,
int dst_x,
int dst_y,
@@ -512,7 +512,7 @@ _composite_traps_draw_func (void *closure,
/* Warning: This call modifies the coordinates of traps */
static cairo_status_t
-_clip_and_composite_trapezoids (cairo_pattern_t *src,
+_clip_and_composite_trapezoids (const cairo_pattern_t *src,
cairo_operator_t op,
cairo_surface_t *dst,
cairo_traps_t *traps,
@@ -671,9 +671,9 @@ out:
}
cairo_status_t
-_cairo_surface_fallback_paint (cairo_surface_t *surface,
- cairo_operator_t op,
- cairo_pattern_t *source)
+_cairo_surface_fallback_paint (cairo_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source)
{
cairo_status_t status;
cairo_rectangle_int_t extents;
@@ -686,6 +686,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
if (_cairo_operator_bounded_by_source (op)) {
cairo_rectangle_int_t source_extents;
+
status = _cairo_pattern_get_extents (source, &source_extents);
if (status)
return status;
@@ -717,7 +718,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
static cairo_status_t
_cairo_surface_mask_draw_func (void *closure,
cairo_operator_t op,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_surface_t *dst,
int dst_x,
int dst_y,
@@ -744,8 +745,8 @@ _cairo_surface_mask_draw_func (void *closure,
cairo_status_t
_cairo_surface_fallback_mask (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
cairo_status_t status;
cairo_rectangle_int_t extents, source_extents, mask_extents;
@@ -779,7 +780,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
status = _clip_and_composite (surface->clip, op,
source,
_cairo_surface_mask_draw_func,
- mask,
+ (void *) mask,
surface,
&extents);
@@ -789,7 +790,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface,
cairo_status_t
_cairo_surface_fallback_stroke (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *ctm,
@@ -852,7 +853,7 @@ FAIL:
cairo_status_t
_cairo_surface_fallback_fill (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -920,7 +921,7 @@ typedef struct {
static cairo_status_t
_cairo_surface_old_show_glyphs_draw_func (void *closure,
cairo_operator_t op,
- cairo_pattern_t *src,
+ const cairo_pattern_t *src,
cairo_surface_t *dst,
int dst_x,
int dst_y,
@@ -981,7 +982,7 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure
cairo_status_t
_cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font)
@@ -1080,18 +1081,18 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface)
}
cairo_status_t
-_cairo_surface_fallback_composite (cairo_operator_t op,
- cairo_pattern_t *src,
- cairo_pattern_t *mask,
- cairo_surface_t *dst,
- 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_surface_fallback_composite (cairo_operator_t op,
+ const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
+ cairo_surface_t *dst,
+ int src_x,
+ int src_y,
+ int mask_x,
+ int mask_y,
+ int dst_x,
+ int dst_y,
+ unsigned int width,
+ unsigned int height)
{
fallback_state_t state;
cairo_status_t status;
@@ -1197,7 +1198,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
cairo_status_t
_cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *dst,
cairo_antialias_t antialias,
int src_x,
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 609a0e0..4041790 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -89,9 +89,9 @@ static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_err
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride);
static cairo_status_t
-_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
+_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t **pattern,
cairo_surface_t *destination,
- cairo_pattern_t **pattern_out);
+ cairo_pattern_t *pattern_copy);
/**
* _cairo_surface_set_error:
@@ -337,7 +337,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
cairo_surface_t *
_cairo_surface_create_solid_pattern_surface (cairo_surface_t *other,
- cairo_solid_pattern_t *solid_pattern)
+ const cairo_solid_pattern_t *solid_pattern)
{
cairo_surface_t *surface;
@@ -357,7 +357,7 @@ _cairo_surface_create_solid_pattern_surface (cairo_surface_t *other,
cairo_int_status_t
_cairo_surface_repaint_solid_pattern_surface (cairo_surface_t *other,
cairo_surface_t *solid_surface,
- cairo_solid_pattern_t *solid_pattern)
+ const cairo_solid_pattern_t *solid_pattern)
{
if (other->backend->create_solid_pattern_surface)
/* Solid pattern surface for this backend are not trivial to make.
@@ -1254,8 +1254,8 @@ _cairo_surface_is_similar (cairo_surface_t *surface_a,
cairo_status_t
_cairo_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src,
- cairo_pattern_t *mask,
+ const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
cairo_surface_t *dst,
int src_x,
int src_y,
@@ -1469,69 +1469,78 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
cairo_status_t
_cairo_surface_paint (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_status_t status;
- cairo_pattern_t *dev_source;
+ cairo_pattern_union_t dev_source;
if (surface->status)
return surface->status;
assert (! surface->is_snapshot);
- status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
+ status = _cairo_surface_copy_pattern_for_destination (&source,
+ surface,
+ &dev_source.base);
if (status)
return _cairo_surface_set_error (surface, status);
if (surface->backend->paint) {
- status = surface->backend->paint (surface, op, dev_source);
+ status = surface->backend->paint (surface, op, source);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto FINISH;
}
- status = _cairo_surface_fallback_paint (surface, op, dev_source);
+ status = _cairo_surface_fallback_paint (surface, op, source);
FINISH:
- cairo_pattern_destroy (dev_source);
+ if (source == &dev_source.base)
+ _cairo_pattern_fini (&dev_source.base);
return _cairo_surface_set_error (surface, status);
}
cairo_status_t
-_cairo_surface_mask (cairo_surface_t *surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+_cairo_surface_mask (cairo_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
cairo_status_t status;
- cairo_pattern_t *dev_source;
- cairo_pattern_t *dev_mask;
+ cairo_pattern_union_t dev_source;
+ cairo_pattern_union_t dev_mask;
if (surface->status)
return surface->status;
assert (! surface->is_snapshot);
- status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
+ status = _cairo_surface_copy_pattern_for_destination (&source,
+ surface,
+ &dev_source.base);
if (status)
goto FINISH;
- status = _cairo_surface_copy_pattern_for_destination (mask, surface, &dev_mask);
+ status = _cairo_surface_copy_pattern_for_destination (&mask,
+ surface,
+ &dev_mask.base);
if (status)
goto CLEANUP_SOURCE;
if (surface->backend->mask) {
- status = surface->backend->mask (surface, op, dev_source, dev_mask);
+ status = surface->backend->mask (surface, op, source, mask);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
goto CLEANUP_MASK;
}
- status = _cairo_surface_fallback_mask (surface, op, dev_source, dev_mask);
+ status = _cairo_surface_fallback_mask (surface, op, source, mask);
CLEANUP_MASK:
- cairo_pattern_destroy (dev_mask);
+ if (mask == &dev_mask.base)
+ _cairo_pattern_fini (&dev_mask.base);
CLEANUP_SOURCE:
- cairo_pattern_destroy (dev_source);
+ if (source == &dev_source.base)
+ _cairo_pattern_fini (&dev_source.base);
FINISH:
return _cairo_surface_set_error (surface, status);
@@ -1540,13 +1549,13 @@ _cairo_surface_mask (cairo_surface_t *surface,
cairo_status_t
_cairo_surface_fill_stroke (cairo_surface_t *surface,
cairo_operator_t fill_op,
- cairo_pattern_t *fill_source,
+ const cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
- cairo_pattern_t *stroke_source,
+ const cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
@@ -1559,29 +1568,41 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
return surface->status;
if (surface->backend->fill_stroke) {
- cairo_pattern_t *dev_stroke_source;
- cairo_pattern_t *dev_fill_source;
+ cairo_pattern_union_t dev_stroke_source;
+ cairo_pattern_union_t dev_fill_source;
cairo_matrix_t dev_ctm = *stroke_ctm;
cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
- status = _cairo_surface_copy_pattern_for_destination (stroke_source, surface, &dev_stroke_source);
+ status = _cairo_surface_copy_pattern_for_destination (&stroke_source,
+ surface,
+ &dev_stroke_source.base);
if (status)
return _cairo_surface_set_error (surface, status);
- status = _cairo_surface_copy_pattern_for_destination (fill_source, surface, &dev_fill_source);
+ status = _cairo_surface_copy_pattern_for_destination (&fill_source,
+ surface,
+ &dev_fill_source.base);
if (status) {
- cairo_pattern_destroy (dev_stroke_source);
+ if (stroke_source == &dev_stroke_source.base)
+ _cairo_pattern_fini (&dev_stroke_source.base);
+
return _cairo_surface_set_error (surface, status);
}
- status = surface->backend->fill_stroke (surface, fill_op, dev_fill_source,
- fill_rule, fill_tolerance, fill_antialias,
- path, stroke_op, dev_stroke_source, stroke_style,
- &dev_ctm, &dev_ctm_inverse, stroke_tolerance,
- stroke_antialias);
+ status = surface->backend->fill_stroke (surface,
+ fill_op, fill_source, fill_rule,
+ fill_tolerance, fill_antialias,
+ path,
+ stroke_op, stroke_source,
+ stroke_style,
+ &dev_ctm, &dev_ctm_inverse,
+ stroke_tolerance, stroke_antialias);
+
+ if (stroke_source == &dev_stroke_source.base)
+ _cairo_pattern_fini (&dev_stroke_source.base);
- cairo_pattern_destroy (dev_stroke_source);
- cairo_pattern_destroy (dev_fill_source);
+ if (fill_source == &dev_fill_source.base)
+ _cairo_pattern_fini (&dev_fill_source.base);
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
return _cairo_surface_set_error (surface, status);
@@ -1604,7 +1625,7 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
cairo_status_t
_cairo_surface_stroke (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *ctm,
@@ -1613,7 +1634,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
cairo_antialias_t antialias)
{
cairo_status_t status;
- cairo_pattern_t *dev_source;
+ cairo_pattern_union_t dev_source;
cairo_path_fixed_t *dev_path = path;
cairo_path_fixed_t real_dev_path;
cairo_matrix_t dev_ctm = *ctm;
@@ -1624,12 +1645,14 @@ _cairo_surface_stroke (cairo_surface_t *surface,
assert (! surface->is_snapshot);
- status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
+ status = _cairo_surface_copy_pattern_for_destination (&source,
+ surface,
+ &dev_source.base);
if (status)
return _cairo_surface_set_error (surface, status);
if (surface->backend->stroke) {
- status = surface->backend->stroke (surface, op, dev_source,
+ status = surface->backend->stroke (surface, op, source,
path, stroke_style,
&dev_ctm, &dev_ctm_inverse,
tolerance, antialias);
@@ -1638,7 +1661,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
goto FINISH;
}
- status = _cairo_surface_fallback_stroke (surface, op, dev_source,
+ status = _cairo_surface_fallback_stroke (surface, op, source,
path, stroke_style,
&dev_ctm, &dev_ctm_inverse,
tolerance, antialias);
@@ -1646,7 +1669,9 @@ _cairo_surface_stroke (cairo_surface_t *surface,
FINISH:
if (dev_path == &real_dev_path)
_cairo_path_fixed_fini (&real_dev_path);
- cairo_pattern_destroy (dev_source);
+
+ if (source == &dev_source.base)
+ _cairo_pattern_fini (&dev_source.base);
return _cairo_surface_set_error (surface, status);
}
@@ -1654,26 +1679,28 @@ _cairo_surface_stroke (cairo_surface_t *surface,
cairo_status_t
_cairo_surface_fill (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias)
{
cairo_status_t status;
- cairo_pattern_t *dev_source;
+ cairo_pattern_union_t dev_source;
if (surface->status)
return surface->status;
assert (! surface->is_snapshot);
- status = _cairo_surface_copy_pattern_for_destination (source, surface, &dev_source);
+ status = _cairo_surface_copy_pattern_for_destination (&source,
+ surface,
+ &dev_source.base);
if (status)
return _cairo_surface_set_error (surface, status);
if (surface->backend->fill) {
- status = surface->backend->fill (surface, op, dev_source,
+ status = surface->backend->fill (surface, op, source,
path, fill_rule,
tolerance, antialias);
@@ -1681,19 +1708,20 @@ _cairo_surface_fill (cairo_surface_t *surface,
goto FINISH;
}
- status = _cairo_surface_fallback_fill (surface, op, dev_source,
+ status = _cairo_surface_fallback_fill (surface, op, source,
path, fill_rule,
tolerance, antialias);
FINISH:
- cairo_pattern_destroy (dev_source);
+ if (source == &dev_source.base)
+ _cairo_pattern_fini (&dev_source.base);
return _cairo_surface_set_error (surface, status);
}
cairo_status_t
_cairo_surface_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *dst,
cairo_antialias_t antialias,
int src_x,
@@ -2218,7 +2246,7 @@ slim_hidden_def (cairo_surface_has_show_text_glyphs);
cairo_status_t
_cairo_surface_show_text_glyphs (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
@@ -2230,7 +2258,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
{
cairo_status_t status;
cairo_scaled_font_t *dev_scaled_font = scaled_font;
- cairo_pattern_t *dev_source;
+ cairo_pattern_union_t dev_source;
if (surface->status)
return surface->status;
@@ -2240,9 +2268,9 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
if (!num_glyphs && !utf8_len)
return CAIRO_STATUS_SUCCESS;
- status = _cairo_surface_copy_pattern_for_destination (source,
+ status = _cairo_surface_copy_pattern_for_destination (&source,
surface,
- &dev_source);
+ &dev_source.base);
if (status)
return _cairo_surface_set_error (surface, status);
@@ -2263,7 +2291,9 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
}
status = cairo_scaled_font_status (dev_scaled_font);
if (status) {
- cairo_pattern_destroy (dev_source);
+ if (source == &dev_source.base)
+ _cairo_pattern_fini (&dev_source.base);
+
return _cairo_surface_set_error (surface, status);
}
@@ -2275,7 +2305,8 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
/* A real show_text_glyphs call. Try show_text_glyphs backend
* method first */
if (surface->backend->show_text_glyphs) {
- status = surface->backend->show_text_glyphs (surface, op, dev_source,
+ status = surface->backend->show_text_glyphs (surface, op,
+ source,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters, cluster_flags,
@@ -2283,7 +2314,8 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
}
if (status == CAIRO_INT_STATUS_UNSUPPORTED && surface->backend->show_glyphs) {
int remaining_glyphs = num_glyphs;
- status = surface->backend->show_glyphs (surface, op, dev_source,
+ status = surface->backend->show_glyphs (surface, op,
+ source,
glyphs, num_glyphs,
dev_scaled_font,
&remaining_glyphs);
@@ -2296,7 +2328,8 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
/* A mere show_glyphs call. Try show_glyphs backend method first */
if (surface->backend->show_glyphs) {
int remaining_glyphs = num_glyphs;
- status = surface->backend->show_glyphs (surface, op, dev_source,
+ status = surface->backend->show_glyphs (surface, op,
+ source,
glyphs, num_glyphs,
dev_scaled_font,
&remaining_glyphs);
@@ -2313,7 +2346,8 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
* implies that UTF-8 is not NULL, unless the text is
* zero-length).
*/
- status = surface->backend->show_text_glyphs (surface, op, dev_source,
+ status = surface->backend->show_text_glyphs (surface, op,
+ source,
utf8, utf8_len,
glyphs, num_glyphs,
clusters, num_clusters, cluster_flags,
@@ -2322,14 +2356,16 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
}
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
- status = _cairo_surface_fallback_show_glyphs (surface, op, dev_source,
+ status = _cairo_surface_fallback_show_glyphs (surface, op,
+ source,
glyphs, num_glyphs,
dev_scaled_font);
if (dev_scaled_font != scaled_font)
cairo_scaled_font_destroy (dev_scaled_font);
- cairo_pattern_destroy (dev_source);
+ if (source == &dev_source.base)
+ _cairo_pattern_fini (&dev_source.base);
return _cairo_surface_set_error (surface, status);
}
@@ -2342,7 +2378,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
cairo_status_t
_cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *dst,
int source_x,
int source_y,
@@ -2594,27 +2630,30 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
* _cairo_surface_copy_pattern_for_destination
* @pattern: the pattern to copy
* @destination: the destination surface for which the pattern is being copied
- * @pattern_out: the location to hold the copy
+ * @pattern_copy: the location to hold the copy
*
* Copies the given pattern, taking into account device scale and offsets
* of the destination surface.
*/
static cairo_status_t
-_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t *pattern,
+_cairo_surface_copy_pattern_for_destination (const cairo_pattern_t **pattern,
cairo_surface_t *destination,
- cairo_pattern_t **pattern_out)
+ cairo_pattern_t *pattern_copy)
{
cairo_status_t status;
- status = _cairo_pattern_create_copy (pattern_out, pattern);
+ if (! _cairo_surface_has_device_transform (destination))
+ return CAIRO_STATUS_SUCCESS;
+
+ status = _cairo_pattern_init_copy (pattern_copy, *pattern);
if (status)
return status;
- if (_cairo_surface_has_device_transform (destination)) {
- _cairo_pattern_transform (*pattern_out,
- &destination->device_transform_inverse);
- }
+ _cairo_pattern_transform (pattern_copy,
+ &destination->device_transform_inverse);
+
+ *pattern = pattern_copy;
return CAIRO_STATUS_SUCCESS;
}
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index f392c8e..a50f13b 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -1757,7 +1757,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
static cairo_status_t
_cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_output_stream_t *output,
cairo_bool_t is_stroke,
const cairo_matrix_t *parent_matrix)
@@ -1783,12 +1783,12 @@ _cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface,
}
static cairo_status_t
-_cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output,
- cairo_svg_surface_t *surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_fill_rule_t fill_rule,
- cairo_matrix_t *parent_matrix)
+_cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output,
+ cairo_svg_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_fill_rule_t fill_rule,
+ cairo_matrix_t *parent_matrix)
{
_cairo_output_stream_printf (output,
"fill-rule:%s;",
@@ -1799,12 +1799,12 @@ _cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output,
}
static cairo_status_t
-_cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
- cairo_svg_surface_t *surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_stroke_style_t *stroke_style,
- cairo_matrix_t *parent_matrix)
+_cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
+ cairo_svg_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_stroke_style_t *stroke_style,
+ cairo_matrix_t *parent_matrix)
{
cairo_status_t status;
const char *line_cap, *line_join;
@@ -1879,13 +1879,13 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
static cairo_int_status_t
_cairo_svg_surface_fill_stroke (void *abstract_surface,
cairo_operator_t fill_op,
- cairo_pattern_t *fill_source,
+ const cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
- cairo_pattern_t *stroke_source,
+ const cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
@@ -1921,7 +1921,7 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_svg_surface_fill (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -1974,8 +1974,8 @@ static cairo_status_t
_cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
cairo_svg_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask_source,
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask_source,
const char *extra_attributes)
{
cairo_status_t status;
@@ -2013,7 +2013,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
static cairo_int_status_t
_cairo_svg_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_status_t status;
cairo_svg_surface_t *surface = abstract_surface;
@@ -2066,8 +2066,8 @@ _cairo_svg_surface_paint (void *abstract_surface,
static cairo_int_status_t
_cairo_svg_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
cairo_status_t status;
cairo_svg_surface_t *surface = abstract_surface;
@@ -2095,8 +2095,8 @@ _cairo_svg_surface_mask (void *abstract_surface,
assert (_cairo_svg_surface_operation_supported (surface, op, source));
assert (_cairo_svg_surface_operation_supported (surface, CAIRO_OPERATOR_OVER, mask));
- if (cairo_pattern_get_type (mask) == CAIRO_PATTERN_TYPE_SURFACE) {
- cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t*) mask;
+ if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
+ const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t*) mask;
cairo_content_t content = cairo_surface_get_content (surface_pattern->surface);
if (content == CAIRO_CONTENT_ALPHA)
discard_filter = TRUE;
@@ -2148,7 +2148,7 @@ _cairo_svg_surface_mask (void *abstract_surface,
static cairo_int_status_t
_cairo_svg_surface_stroke (void *abstract_dst,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *ctm,
@@ -2185,7 +2185,7 @@ _cairo_svg_surface_stroke (void *abstract_dst,
static cairo_int_status_t
_cairo_svg_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c
index c84f5f0..ee516f5 100644
--- a/src/cairo-type3-glyph-surface.c
+++ b/src/cairo-type3-glyph-surface.c
@@ -123,7 +123,7 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
static cairo_status_t
_cairo_type3_glyph_surface_emit_image_pattern (cairo_type3_glyph_surface_t *surface,
cairo_image_surface_t *image,
- cairo_matrix_t *pattern_matrix)
+ const cairo_matrix_t *pattern_matrix)
{
cairo_matrix_t mat, upside_down;
cairo_status_t status;
@@ -182,10 +182,10 @@ _cairo_type3_glyph_surface_intersect_clip_path (void *abstract_surface,
static cairo_int_status_t
_cairo_type3_glyph_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_type3_glyph_surface_t *surface = abstract_surface;
- cairo_surface_pattern_t *pattern;
+ const cairo_surface_pattern_t *pattern;
cairo_image_surface_t *image;
void *image_extra;
cairo_status_t status;
@@ -193,7 +193,7 @@ _cairo_type3_glyph_surface_paint (void *abstract_surface,
if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
- pattern = (cairo_surface_pattern_t *) source;
+ pattern = (const cairo_surface_pattern_t *) source;
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
if (status)
goto fail;
@@ -211,8 +211,8 @@ fail:
static cairo_int_status_t
_cairo_type3_glyph_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
return _cairo_type3_glyph_surface_paint (abstract_surface, op, mask);
}
@@ -220,7 +220,7 @@ _cairo_type3_glyph_surface_mask (void *abstract_surface,
static cairo_int_status_t
_cairo_type3_glyph_surface_stroke (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -240,7 +240,7 @@ _cairo_type3_glyph_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_type3_glyph_surface_fill (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -259,7 +259,7 @@ _cairo_type3_glyph_surface_fill (void *abstract_surface,
static cairo_int_status_t
_cairo_type3_glyph_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 879cfac..3da64a6 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -1359,19 +1359,19 @@ _cairo_win32_scaled_font_glyph_init (void *abstract_font,
}
static cairo_int_status_t
-_cairo_win32_scaled_font_show_glyphs (void *abstract_font,
- cairo_operator_t op,
- cairo_pattern_t *pattern,
- cairo_surface_t *generic_surface,
- int source_x,
- int source_y,
- int dest_x,
- int dest_y,
- unsigned int width,
- unsigned int height,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- int *remaining_glyphs)
+_cairo_win32_scaled_font_show_glyphs (void *abstract_font,
+ cairo_operator_t op,
+ const cairo_pattern_t *pattern,
+ cairo_surface_t *generic_surface,
+ int source_x,
+ int source_y,
+ int dest_x,
+ int dest_y,
+ unsigned int width,
+ unsigned int height,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ int *remaining_glyphs)
{
cairo_win32_scaled_font_t *scaled_font = abstract_font;
cairo_win32_surface_t *surface = (cairo_win32_surface_t *)generic_surface;
diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c
index 2c2f061..553ef40 100644
--- a/src/cairo-win32-printing-surface.c
+++ b/src/cairo-win32-printing-surface.c
@@ -294,7 +294,7 @@ _cairo_win32_printing_surface_flatten_transparency (cairo_win32_surface_t *surfa
static cairo_status_t
_cairo_win32_printing_surface_select_solid_brush (cairo_win32_surface_t *surface,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
cairo_solid_pattern_t *pattern = (cairo_solid_pattern_t *) source;
COLORREF color;
@@ -337,7 +337,7 @@ _cairo_win32_printing_surface_get_ctm_clip_box (cairo_win32_surface_t *surface,
static cairo_status_t
_cairo_win32_printing_surface_paint_solid_pattern (cairo_win32_surface_t *surface,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
RECT clip;
cairo_status_t status;
@@ -350,7 +350,7 @@ _cairo_win32_printing_surface_paint_solid_pattern (cairo_win32_surface_t *surfac
FillRect (surface->dc, &clip, surface->brush);
_cairo_win32_printing_surface_done_solid_brush (surface);
- return 0;
+ return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
@@ -411,7 +411,9 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
surface->content = CAIRO_CONTENT_COLOR;
_cairo_pattern_init_solid (&black, CAIRO_COLOR_BLACK, CAIRO_CONTENT_COLOR);
source = (cairo_pattern_t*) &black;
- _cairo_win32_printing_surface_paint_solid_pattern (surface, source);
+ status = _cairo_win32_printing_surface_paint_solid_pattern (surface, source);
+ if (status)
+ return status;
}
for (y_tile = top; y_tile < bottom; y_tile++) {
@@ -490,7 +492,6 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
{
cairo_status_t status;
cairo_extend_t extend;
- cairo_surface_attributes_t pat_attr;
cairo_image_surface_t *image;
void *image_extra;
cairo_surface_t *opaque_surface;
@@ -820,7 +821,7 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
static cairo_int_status_t
_cairo_win32_printing_surface_paint_pattern (cairo_win32_surface_t *surface,
- cairo_pattern_t *pattern)
+ const cairo_pattern_t *pattern)
{
cairo_status_t status;
@@ -1034,9 +1035,9 @@ _cairo_win32_printing_surface_get_font_options (void *abstract_
}
static cairo_int_status_t
-_cairo_win32_printing_surface_paint (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source)
+_cairo_win32_printing_surface_paint (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_solid_pattern_t clear;
@@ -1105,15 +1106,15 @@ _cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
}
static cairo_int_status_t
-_cairo_win32_printing_surface_stroke (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_stroke_style_t *style,
- cairo_matrix_t *stroke_ctm,
- cairo_matrix_t *stroke_ctm_inverse,
- double tolerance,
- cairo_antialias_t antialias)
+_cairo_win32_printing_surface_stroke (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_stroke_style_t *style,
+ cairo_matrix_t *stroke_ctm,
+ cairo_matrix_t *stroke_ctm_inverse,
+ double tolerance,
+ cairo_antialias_t antialias)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_int_status_t status;
@@ -1229,12 +1230,12 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_cairo_win32_printing_surface_fill (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_fill_rule_t fill_rule,
- double tolerance,
- cairo_antialias_t antialias)
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_int_status_t status;
@@ -1289,7 +1290,7 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
static cairo_int_status_t
_cairo_win32_printing_surface_show_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h
index 21b04be..09f6328 100644
--- a/src/cairo-win32-private.h
+++ b/src/cairo-win32-private.h
@@ -141,7 +141,7 @@ _cairo_win32_flags_for_dc (HDC dc);
cairo_int_status_t
_cairo_win32_surface_show_glyphs (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 5787e26..05f5188 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -874,8 +874,8 @@ _cairo_win32_surface_composite_inner (cairo_win32_surface_t *src,
static cairo_int_status_t
_cairo_win32_surface_composite (cairo_operator_t op,
- cairo_pattern_t *pattern,
- cairo_pattern_t *mask_pattern,
+ const cairo_pattern_t *pattern,
+ const cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
@@ -1562,7 +1562,7 @@ _cairo_win32_surface_flush (void *abstract_surface)
cairo_int_status_t
_cairo_win32_surface_show_glyphs (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index dede00f..d514659 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -948,10 +948,10 @@ typedef enum {
* hit the bug and won't be able to use a core protocol fallback.
*/
static composite_operation_t
-_categorize_composite_operation (cairo_xcb_surface_t *dst,
- cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_bool_t have_mask)
+_categorize_composite_operation (cairo_xcb_surface_t *dst,
+ cairo_operator_t op,
+ const cairo_pattern_t *src_pattern,
+ cairo_bool_t have_mask)
{
#if XXX_BUGGY_REPEAT
@@ -1088,8 +1088,8 @@ _render_operator (cairo_operator_t op)
static cairo_int_status_t
_cairo_xcb_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_pattern_t *mask_pattern,
+ const cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
@@ -1377,7 +1377,7 @@ _create_trapezoid_mask (cairo_xcb_surface_t *dst,
static cairo_int_status_t
_cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
@@ -1622,13 +1622,13 @@ _cairo_xcb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph,
cairo_scaled_font_t *scaled_font);
static cairo_int_status_t
-_cairo_xcb_surface_show_glyphs (void *abstract_dst,
- cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- int *remaining_glyphs);
+_cairo_xcb_surface_show_glyphs (void *abstract_dst,
+ cairo_operator_t op,
+ const cairo_pattern_t *src_pattern,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font,
+ int *remaining_glyphs);
static cairo_bool_t
_cairo_xcb_surface_is_similar (void *surface_a,
@@ -2420,13 +2420,13 @@ _cairo_xcb_surface_emit_glyphs (cairo_xcb_surface_t *dst,
}
static cairo_int_status_t
-_cairo_xcb_surface_show_glyphs (void *abstract_dst,
- cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_scaled_font_t *scaled_font,
- int *remaining_glyphs)
+_cairo_xcb_surface_show_glyphs (void *abstract_dst,
+ cairo_operator_t op,
+ const cairo_pattern_t *src_pattern,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font,
+ int *remaining_glyphs)
{
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
cairo_xcb_surface_t *dst = abstract_dst;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index ba38f5d..1d35843 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -82,7 +82,7 @@ _native_byte_order_lsb (void);
static cairo_int_status_t
_cairo_xlib_surface_show_glyphs (void *abstract_dst,
cairo_operator_t op,
- cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *src_pattern,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
@@ -1229,7 +1229,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
static cairo_surface_t *
_cairo_xlib_surface_create_solid_pattern_surface (void *abstract_surface,
- cairo_solid_pattern_t *solid_pattern)
+ const cairo_solid_pattern_t *solid_pattern)
{
/* This function's only responsibility is to create a proper surface
* for when XRender is not available. The proper surface is a xlib
@@ -1531,7 +1531,7 @@ typedef enum {
static composite_operation_t
_categorize_composite_operation (cairo_xlib_surface_t *dst,
cairo_operator_t op,
- cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *src_pattern,
cairo_bool_t have_mask)
{
@@ -1680,8 +1680,8 @@ _render_operator (cairo_operator_t op)
static cairo_int_status_t
_cairo_xlib_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src_pattern,
- cairo_pattern_t *mask_pattern,
+ const cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *mask_pattern,
void *abstract_dst,
int src_x,
int src_y,
@@ -2071,7 +2071,7 @@ _create_trapezoid_mask (cairo_xlib_surface_t *dst,
static cairo_int_status_t
_cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *abstract_dst,
cairo_antialias_t antialias,
int src_x,
@@ -3945,7 +3945,7 @@ _cairo_xlib_surface_owns_font (cairo_xlib_surface_t *dst,
static cairo_int_status_t
_cairo_xlib_surface_show_glyphs (void *abstract_dst,
cairo_operator_t op,
- cairo_pattern_t *src_pattern,
+ const cairo_pattern_t *src_pattern,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
diff --git a/src/cairoint.h b/src/cairoint.h
index baa0cb5..9e1cd7d 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -453,7 +453,7 @@ struct _cairo_scaled_font_backend {
cairo_warn cairo_int_status_t
(*show_glyphs) (void *scaled_font,
cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *surface,
int source_x,
int source_y,
@@ -584,8 +584,8 @@ struct _cairo_surface_backend {
/* XXX: dst should be the first argument for consistency */
cairo_warn cairo_int_status_t
(*composite) (cairo_operator_t op,
- cairo_pattern_t *src,
- cairo_pattern_t *mask,
+ const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
void *dst,
int src_x,
int src_y,
@@ -606,7 +606,7 @@ struct _cairo_surface_backend {
/* XXX: dst should be the first argument for consistency */
cairo_warn cairo_int_status_t
(*composite_trapezoids) (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *dst,
cairo_antialias_t antialias,
int src_x,
@@ -688,7 +688,7 @@ struct _cairo_surface_backend {
cairo_warn cairo_int_status_t
(*old_show_glyphs) (cairo_scaled_font_t *font,
cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
void *surface,
int source_x,
int source_y,
@@ -726,18 +726,18 @@ struct _cairo_surface_backend {
cairo_warn cairo_int_status_t
(*paint) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source);
+ const cairo_pattern_t *source);
cairo_warn cairo_int_status_t
(*mask) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask);
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask);
cairo_warn cairo_int_status_t
(*stroke) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -748,7 +748,7 @@ struct _cairo_surface_backend {
cairo_warn cairo_int_status_t
(*fill) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -757,7 +757,7 @@ struct _cairo_surface_backend {
cairo_warn cairo_int_status_t
(*show_glyphs) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
@@ -777,13 +777,13 @@ struct _cairo_surface_backend {
cairo_warn cairo_int_status_t
(*fill_stroke) (void *surface,
cairo_operator_t fill_op,
- cairo_pattern_t *fill_source,
+ const cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
- cairo_pattern_t *stroke_source,
+ const cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
@@ -792,8 +792,8 @@ struct _cairo_surface_backend {
cairo_surface_t *
(*create_solid_pattern_surface)
- (void *surface,
- cairo_solid_pattern_t *solid_pattern);
+ (void *surface,
+ const cairo_solid_pattern_t *solid_pattern);
cairo_bool_t
(*has_show_text_glyphs) (void *surface);
@@ -801,7 +801,7 @@ struct _cairo_surface_backend {
cairo_warn cairo_int_status_t
(*show_text_glyphs) (void *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
@@ -1581,7 +1581,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
cairo_private cairo_status_t
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_surface_t *surface,
int source_x,
int source_y,
@@ -1676,12 +1676,12 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other,
cairo_private cairo_surface_t *
_cairo_surface_create_solid_pattern_surface (cairo_surface_t *other,
- cairo_solid_pattern_t *solid_pattern);
+ const cairo_solid_pattern_t *solid_pattern);
cairo_private cairo_int_status_t
_cairo_surface_repaint_solid_pattern_surface (cairo_surface_t *other,
cairo_surface_t *solid_surface,
- cairo_solid_pattern_t *solid_pattern);
+ const cairo_solid_pattern_t *solid_pattern);
cairo_private void
_cairo_surface_init (cairo_surface_t *surface,
@@ -1697,8 +1697,8 @@ _cairo_surface_get_clip_mode (cairo_surface_t *surface);
cairo_private cairo_status_t
_cairo_surface_composite (cairo_operator_t op,
- cairo_pattern_t *src,
- cairo_pattern_t *mask,
+ const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
cairo_surface_t *dst,
int src_x,
int src_y,
@@ -1734,24 +1734,24 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_paint (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source);
+ const cairo_pattern_t *source);
cairo_private cairo_status_t
_cairo_surface_mask (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask);
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask);
cairo_private cairo_status_t
_cairo_surface_fill_stroke (cairo_surface_t *surface,
cairo_operator_t fill_op,
- cairo_pattern_t *fill_source,
+ const cairo_pattern_t *fill_source,
cairo_fill_rule_t fill_rule,
double fill_tolerance,
cairo_antialias_t fill_antialias,
cairo_path_fixed_t *path,
cairo_operator_t stroke_op,
- cairo_pattern_t *stroke_source,
+ const cairo_pattern_t *stroke_source,
cairo_stroke_style_t *stroke_style,
cairo_matrix_t *stroke_ctm,
cairo_matrix_t *stroke_ctm_inverse,
@@ -1761,7 +1761,7 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_stroke (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_stroke_style_t *style,
cairo_matrix_t *ctm,
@@ -1772,7 +1772,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_fill (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -1781,7 +1781,7 @@ _cairo_surface_fill (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_show_text_glyphs (cairo_surface_t *surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
@@ -1793,7 +1793,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_composite_trapezoids (cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *dst,
cairo_antialias_t antialias,
int src_x,
@@ -1885,7 +1885,7 @@ _cairo_surface_get_extents (cairo_surface_t *surface,
cairo_private cairo_status_t
_cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,
- cairo_pattern_t *pattern,
+ const cairo_pattern_t *pattern,
cairo_surface_t *surface,
int source_x,
int source_y,
@@ -2318,7 +2318,7 @@ cairo_private cairo_bool_t
_cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern);
cairo_private cairo_int_status_t
-_cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
+_cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
cairo_surface_t *dst,
int x,
int y,
@@ -2328,13 +2328,13 @@ _cairo_pattern_acquire_surface (cairo_pattern_t *pattern,
cairo_surface_attributes_t *attributes);
cairo_private void
-_cairo_pattern_release_surface (cairo_pattern_t *pattern,
+_cairo_pattern_release_surface (const cairo_pattern_t *pattern,
cairo_surface_t *surface,
cairo_surface_attributes_t *attributes);
cairo_private cairo_int_status_t
-_cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
- cairo_pattern_t *mask,
+_cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
+ const cairo_pattern_t *mask,
cairo_surface_t *dst,
int src_x,
int src_y,
@@ -2348,8 +2348,8 @@ _cairo_pattern_acquire_surfaces (cairo_pattern_t *src,
cairo_surface_attributes_t *mask_attributes);
cairo_private cairo_status_t
-_cairo_pattern_get_extents (cairo_pattern_t *pattern,
- cairo_rectangle_int_t *extents);
+_cairo_pattern_get_extents (const cairo_pattern_t *pattern,
+ cairo_rectangle_int_t *extents);
cairo_private void
_cairo_pattern_reset_static_data (void);
diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c
index 6038430..f19cbd6 100644
--- a/src/test-meta-surface.c
+++ b/src/test-meta-surface.c
@@ -194,7 +194,7 @@ _test_meta_surface_get_extents (void *abstract_surface,
static cairo_int_status_t
_test_meta_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
test_meta_surface_t *surface = abstract_surface;
@@ -206,8 +206,8 @@ _test_meta_surface_paint (void *abstract_surface,
static cairo_int_status_t
_test_meta_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
test_meta_surface_t *surface = abstract_surface;
@@ -217,15 +217,15 @@ _test_meta_surface_mask (void *abstract_surface,
}
static cairo_int_status_t
-_test_meta_surface_stroke (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_stroke_style_t *style,
- cairo_matrix_t *ctm,
- cairo_matrix_t *ctm_inverse,
- double tolerance,
- cairo_antialias_t antialias)
+_test_meta_surface_stroke (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_stroke_style_t *style,
+ cairo_matrix_t *ctm,
+ cairo_matrix_t *ctm_inverse,
+ double tolerance,
+ cairo_antialias_t antialias)
{
test_meta_surface_t *surface = abstract_surface;
@@ -240,7 +240,7 @@ _test_meta_surface_stroke (void *abstract_surface,
static cairo_int_status_t
_test_meta_surface_fill (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
@@ -266,7 +266,7 @@ _test_meta_surface_has_show_text_glyphs (void *abstract_surface)
static cairo_int_status_t
_test_meta_surface_show_text_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c
index 354f95d..ba80a10 100644
--- a/src/test-paginated-surface.c
+++ b/src/test-paginated-surface.c
@@ -169,7 +169,7 @@ _test_paginated_surface_get_extents (void *abstract_surface,
static cairo_int_status_t
_test_paginated_surface_paint (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source)
+ const cairo_pattern_t *source)
{
test_paginated_surface_t *surface = abstract_surface;
@@ -182,8 +182,8 @@ _test_paginated_surface_paint (void *abstract_surface,
static cairo_int_status_t
_test_paginated_surface_mask (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_pattern_t *mask)
+ const cairo_pattern_t *source,
+ const cairo_pattern_t *mask)
{
test_paginated_surface_t *surface = abstract_surface;
@@ -194,15 +194,15 @@ _test_paginated_surface_mask (void *abstract_surface,
}
static cairo_int_status_t
-_test_paginated_surface_stroke (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_stroke_style_t *style,
- cairo_matrix_t *ctm,
- cairo_matrix_t *ctm_inverse,
- double tolerance,
- cairo_antialias_t antialias)
+_test_paginated_surface_stroke (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_stroke_style_t *style,
+ cairo_matrix_t *ctm,
+ cairo_matrix_t *ctm_inverse,
+ double tolerance,
+ cairo_antialias_t antialias)
{
test_paginated_surface_t *surface = abstract_surface;
@@ -216,13 +216,13 @@ _test_paginated_surface_stroke (void *abstract_surface,
}
static cairo_int_status_t
-_test_paginated_surface_fill (void *abstract_surface,
- cairo_operator_t op,
- cairo_pattern_t *source,
- cairo_path_fixed_t *path,
- cairo_fill_rule_t fill_rule,
- double tolerance,
- cairo_antialias_t antialias)
+_test_paginated_surface_fill (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias)
{
test_paginated_surface_t *surface = abstract_surface;
@@ -245,7 +245,7 @@ _test_paginated_surface_has_show_text_glyphs (void *abstract_surface)
static cairo_int_status_t
_test_paginated_surface_show_text_glyphs (void *abstract_surface,
cairo_operator_t op,
- cairo_pattern_t *source,
+ const cairo_pattern_t *source,
const char *utf8,
int utf8_len,
cairo_glyph_t *glyphs,
commit 9d2189afbd2aa1413f620a4d35016ef3be3fc0e9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 22 18:29:02 2008 +0100
[pattern] Do not recompute the inverse if setting an identical matrix.
More micro-optimisation.
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 81fa62a..064eeb6 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1055,6 +1055,9 @@ cairo_pattern_set_matrix (cairo_pattern_t *pattern,
if (pattern->status)
return;
+ if (memcmp (&pattern->matrix, matrix, sizeof (cairo_matrix_t)) == 0)
+ return;
+
pattern->matrix = *matrix;
inverse = *matrix;
commit 2c277ddbea42222130b8b1c2a2b4934503b40188
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 22 18:17:49 2008 +0100
[matrix] Avoid error correction overhead for translation matrices.
We can only correct rounding errors between cairo and pixman matrices for
scaled matrices - so skip the inversion and point transformation overhead
for simple translation matrices.
diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c
index ca18323..f01353e 100644
--- a/src/cairo-matrix.c
+++ b/src/cairo-matrix.c
@@ -813,8 +813,8 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
*pixman_transform = pixman_identity_transform;
}
else {
- cairo_matrix_t inv = *matrix;
- double x = 0, y = 0;
+ cairo_matrix_t inv;
+ double x,y;
pixman_vector_t vector;
pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx);
@@ -839,11 +839,16 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
* space and adjust pixman's transform to agree with cairo's at
* that point. */
+ if (_cairo_matrix_is_translation (matrix))
+ return;
+
/* Note: If we can't invert the transformation, skip the adjustment. */
+ inv = *matrix;
if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS)
return;
/* find the device space coordinate that maps to (0, 0) */
+ x = 0, y = 0;
cairo_matrix_transform_point (&inv, &x, &y);
/* transform the resulting device space coordinate back
@@ -852,7 +857,7 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
vector.vector[1] = _cairo_fixed_16_16_from_double (y);
vector.vector[2] = 1 << 16;
- if (!pixman_transform_point_3d (pixman_transform, &vector))
+ if (! pixman_transform_point_3d (pixman_transform, &vector))
return;
/* Ideally, the vector should now be (0, 0). We can now compensate
commit 57a1d932f3e9d79f3259a536ec2f45f020d46de5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 22 18:12:10 2008 +0100
[array] Rearrange user_data_fini() to optimize common case.
Micro-optimisation to avoid the _cairo_array_index() for the common case
of 0 elements.
diff --git a/src/cairo-array.c b/src/cairo-array.c
index b2790c8..f38cfe3 100644
--- a/src/cairo-array.c
+++ b/src/cairo-array.c
@@ -382,14 +382,18 @@ _cairo_user_data_array_init (cairo_user_data_array_t *array)
void
_cairo_user_data_array_fini (cairo_user_data_array_t *array)
{
- int i, num_slots;
- cairo_user_data_slot_t *slots;
+ unsigned int num_slots;
num_slots = array->num_elements;
- slots = _cairo_array_index (array, 0);
- for (i = 0; i < num_slots; i++) {
- if (slots[i].user_data != NULL && slots[i].destroy != NULL)
- slots[i].destroy (slots[i].user_data);
+ if (num_slots) {
+ cairo_user_data_slot_t *slots;
+
+ slots = _cairo_array_index (array, 0);
+ do {
+ if (slots->user_data != NULL && slots->destroy != NULL)
+ slots->destroy (slots->user_data);
+ slots++;
+ } while (--num_slots);
}
_cairo_array_fini (array);
commit 2852127c72fa6cfe246e6ece0433be6c3f2a93ab
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 22 18:04:30 2008 +0100
[cairoint] Add a few cairo_pure.
Start marking up the prototypes with function attributes - first the
obvious pure functions.
diff --git a/src/cairoint.h b/src/cairoint.h
index 43c5ae8..baa0cb5 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -1274,10 +1274,10 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
cairo_path_fixed_t *path);
cairo_private cairo_bool_t
-_cairo_operator_bounded_by_mask (cairo_operator_t op);
+_cairo_operator_bounded_by_mask (cairo_operator_t op) cairo_pure;
cairo_private cairo_bool_t
-_cairo_operator_bounded_by_source (cairo_operator_t op);
+_cairo_operator_bounded_by_source (cairo_operator_t op) cairo_pure;
/* cairo-color.c */
cairo_private const cairo_color_t *
@@ -1288,7 +1288,7 @@ _cairo_stock_color (cairo_stock_t stock);
#define CAIRO_COLOR_TRANSPARENT _cairo_stock_color (CAIRO_STOCK_TRANSPARENT)
cairo_private uint16_t
-_cairo_color_double_to_short (double d);
+_cairo_color_double_to_short (double d) cairo_pure;
cairo_private void
_cairo_color_init (cairo_color_t *color);
@@ -1987,13 +1987,13 @@ _cairo_surface_has_device_transform (cairo_surface_t *surface);
== 0))
cairo_private int
-_cairo_format_bits_per_pixel (cairo_format_t format);
+_cairo_format_bits_per_pixel (cairo_format_t format) cairo_pure;
cairo_private cairo_format_t
-_cairo_format_from_content (cairo_content_t content);
+_cairo_format_from_content (cairo_content_t content) cairo_pure;
cairo_private cairo_content_t
-_cairo_content_from_format (cairo_format_t format);
+_cairo_content_from_format (cairo_format_t format) cairo_pure;
cairo_private cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
More information about the cairo-commit
mailing list