2007-06-18 18:33:29 -07:00
|
|
|
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
2004-08-02 13:13:28 +00:00
|
|
|
/* cairo - a vector graphics library with display and print output
|
|
|
|
|
*
|
2004-10-21 18:40:50 +00:00
|
|
|
* Copyright © 2002 University of Southern California
|
2005-04-14 14:42:26 +00:00
|
|
|
* Copyright © 2005 Red Hat, Inc.
|
2003-07-18 11:34:19 +00:00
|
|
|
*
|
2004-08-02 13:13:28 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
2004-09-04 06:38:34 +00:00
|
|
|
* modify it either under the terms of the GNU Lesser General Public
|
|
|
|
|
* License version 2.1 as published by the Free Software Foundation
|
|
|
|
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
|
|
|
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
|
|
|
|
* notice, a recipient may use your version of this file under either
|
|
|
|
|
* the MPL or the LGPL.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the LGPL along with this library
|
|
|
|
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
2010-04-27 10:17:23 +02:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
|
2004-09-04 06:38:34 +00:00
|
|
|
* You should have received a copy of the MPL along with this library
|
|
|
|
|
* in the file COPYING-MPL-1.1
|
|
|
|
|
*
|
|
|
|
|
* The contents of this file are subject to the Mozilla Public License
|
|
|
|
|
* Version 1.1 (the "License"); you may not use this file except in
|
|
|
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
|
*
|
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
|
|
|
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
|
|
|
|
* the specific language governing rights and limitations.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is the cairo graphics library.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is University of Southern
|
|
|
|
|
* California.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s):
|
2005-02-22 11:35:03 +00:00
|
|
|
* Carl D. Worth <cworth@cworth.org>
|
2003-07-18 11:34:19 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "cairoint.h"
|
2007-04-03 20:25:30 -04:00
|
|
|
|
2005-12-19 22:45:41 +00:00
|
|
|
#include "cairo-surface-fallback-private.h"
|
2005-10-31 16:55:21 +00:00
|
|
|
#include "cairo-clip-private.h"
|
2010-01-18 21:53:42 +00:00
|
|
|
#include "cairo-device-private.h"
|
2010-01-18 16:58:40 +00:00
|
|
|
#include "cairo-error-private.h"
|
2009-10-22 02:13:36 +03:00
|
|
|
#include "cairo-recording-surface-private.h"
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
#include "cairo-region-private.h"
|
2009-08-16 18:04:54 +01:00
|
|
|
#include "cairo-tee-surface-private.h"
|
2005-05-02 13:39:30 +00:00
|
|
|
|
2010-07-08 13:05:18 +02:00
|
|
|
/**
|
|
|
|
|
* SECTION:cairo-surface
|
|
|
|
|
* @Title: cairo_surface_t
|
|
|
|
|
* @Short_Description: Base class for surfaces
|
|
|
|
|
* @See_Also: #cairo_t, #cairo_pattern_t
|
|
|
|
|
*
|
|
|
|
|
* #cairo_surface_t is the abstract type representing all different drawing
|
|
|
|
|
* targets that cairo can render to. The actual drawings are
|
|
|
|
|
* performed using a cairo <firstterm>context</firstterm>.
|
|
|
|
|
*
|
|
|
|
|
* A cairo surface is created by using <firstterm>backend</firstterm>-specific
|
|
|
|
|
* constructors, typically of the form
|
2010-12-28 13:32:27 +01:00
|
|
|
* <function>cairo_<emphasis>backend</emphasis>_surface_create(<!-- -->)</function>.
|
2010-07-11 20:44:40 +02:00
|
|
|
*
|
|
|
|
|
* Most surface types allow accessing the surface without using Cairo
|
|
|
|
|
* functions. If you do this, keep in mind that it is mandatory that you call
|
|
|
|
|
* cairo_surface_flush() before reading from or writing to the surface and that
|
|
|
|
|
* you must use cairo_surface_mark_dirty() after modifying it.
|
|
|
|
|
* <example>
|
|
|
|
|
* <title>Directly modifying an image surface</title>
|
|
|
|
|
* <programlisting>
|
|
|
|
|
* void
|
|
|
|
|
* modify_image_surface (cairo_surface_t *surface)
|
|
|
|
|
* {
|
|
|
|
|
* unsigned char *data;
|
|
|
|
|
* int width, height, stride;
|
|
|
|
|
*
|
|
|
|
|
* // flush to ensure all writing to the image was done
|
|
|
|
|
* cairo_surface_flush (surface);
|
|
|
|
|
*
|
|
|
|
|
* // modify the image
|
|
|
|
|
* data = cairo_image_surface_get_data (surface);
|
|
|
|
|
* width = cairo_image_surface_get_width (surface);
|
|
|
|
|
* height = cairo_image_surface_get_height (surface);
|
|
|
|
|
* stride = cairo_image_surface_get_stride (surface);
|
|
|
|
|
* modify_image_data (data, width, height, stride);
|
|
|
|
|
*
|
|
|
|
|
* // mark the image dirty so Cairo clears its caches.
|
|
|
|
|
* cairo_surface_mark_dirty (surface);
|
|
|
|
|
* }
|
|
|
|
|
* </programlisting>
|
|
|
|
|
* </example>
|
|
|
|
|
* Note that for other surface types it might be necessary to acquire the
|
|
|
|
|
* surface's device first. See cairo_device_acquire() for a discussion of
|
|
|
|
|
* devices.
|
2010-07-08 13:05:18 +02:00
|
|
|
*/
|
|
|
|
|
|
2007-02-08 15:28:14 -08:00
|
|
|
#define DEFINE_NIL_SURFACE(status, name) \
|
|
|
|
|
const cairo_surface_t name = { \
|
2008-11-20 09:40:25 +00:00
|
|
|
NULL, /* backend */ \
|
2010-01-18 21:53:42 +00:00
|
|
|
NULL, /* device */ \
|
2008-11-20 09:40:25 +00:00
|
|
|
CAIRO_SURFACE_TYPE_IMAGE, /* type */ \
|
|
|
|
|
CAIRO_CONTENT_COLOR, /* content */ \
|
2007-09-23 21:08:09 +01:00
|
|
|
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \
|
2007-02-08 15:28:14 -08:00
|
|
|
status, /* status */ \
|
2009-05-27 16:45:20 +01:00
|
|
|
0, /* unique id */ \
|
2009-10-21 09:04:30 +01:00
|
|
|
FALSE, /* finished */ \
|
|
|
|
|
TRUE, /* is_clear */ \
|
|
|
|
|
FALSE, /* has_font_options */ \
|
2010-05-18 12:02:54 +02:00
|
|
|
FALSE, /* owns_device */ \
|
2008-11-20 09:40:25 +00:00
|
|
|
{ 0, 0, 0, NULL, }, /* user_data */ \
|
2009-02-13 12:56:46 +00:00
|
|
|
{ 0, 0, 0, NULL, }, /* mime_data */ \
|
2008-11-20 09:40:25 +00:00
|
|
|
{ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ \
|
|
|
|
|
{ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform_inverse */ \
|
2010-06-11 16:04:41 +01:00
|
|
|
{ NULL, NULL }, /* device_transform_observers */ \
|
2007-08-29 15:34:04 -07:00
|
|
|
0.0, /* x_resolution */ \
|
|
|
|
|
0.0, /* y_resolution */ \
|
2007-02-08 15:28:14 -08:00
|
|
|
0.0, /* x_fallback_resolution */ \
|
|
|
|
|
0.0, /* y_fallback_resolution */ \
|
2009-05-26 21:07:07 +01:00
|
|
|
NULL, /* snapshot_of */ \
|
|
|
|
|
NULL, /* snapshot_detach */ \
|
2010-04-29 15:19:18 +01:00
|
|
|
{ NULL, NULL }, /* snapshots */ \
|
2010-04-28 14:26:21 +01:00
|
|
|
{ NULL, NULL }, /* snapshot */ \
|
2008-08-17 14:03:33 +01:00
|
|
|
{ CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \
|
|
|
|
|
CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \
|
2010-06-17 08:56:30 +01:00
|
|
|
CAIRO_LCD_FILTER_DEFAULT, /* lcd_filter */ \
|
2008-08-17 14:03:33 +01:00
|
|
|
CAIRO_HINT_STYLE_DEFAULT, /* hint_style */ \
|
2010-10-21 13:52:33 +02:00
|
|
|
CAIRO_HINT_METRICS_DEFAULT, /* hint_metrics */ \
|
|
|
|
|
CAIRO_ROUND_GLYPH_POS_DEFAULT /* round_glyph_positions */ \
|
2007-02-08 15:28:14 -08:00
|
|
|
} /* font_options */ \
|
|
|
|
|
}
|
2005-07-28 10:41:08 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
/* XXX error object! */
|
|
|
|
|
|
2008-01-16 16:23:23 +00:00
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil);
|
2009-07-01 19:41:42 +01:00
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_SURFACE_TYPE_MISMATCH, _cairo_surface_nil_surface_type_mismatch);
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STATUS, _cairo_surface_nil_invalid_status);
|
2008-01-16 16:23:23 +00:00
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content);
|
|
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format);
|
|
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_VISUAL, _cairo_surface_nil_invalid_visual);
|
|
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_found);
|
|
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_TEMP_FILE_ERROR, _cairo_surface_nil_temp_file_error);
|
|
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error);
|
|
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error);
|
2008-01-26 23:12:14 -08:00
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride);
|
2009-05-22 12:52:43 +01:00
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size);
|
2010-01-18 21:53:42 +00:00
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch);
|
|
|
|
|
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error);
|
2005-07-27 15:39:34 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* _cairo_surface_set_error:
|
|
|
|
|
* @surface: a surface
|
2008-06-24 15:07:07 -04:00
|
|
|
* @status: a status value indicating an error
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2007-10-04 11:13:33 +01:00
|
|
|
* Atomically sets surface->status to @status and calls _cairo_error;
|
2008-06-24 15:07:07 -04:00
|
|
|
* Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal
|
|
|
|
|
* status values.
|
2005-07-27 15:39:34 +00:00
|
|
|
*
|
|
|
|
|
* All assignments of an error status to surface->status should happen
|
2007-10-04 11:13:33 +01:00
|
|
|
* through _cairo_surface_set_error(). Note that due to the nature of
|
|
|
|
|
* the atomic operation, it is not safe to call this function on the
|
|
|
|
|
* nil objects.
|
2005-07-27 15:39:34 +00:00
|
|
|
*
|
|
|
|
|
* The purpose of this function is to allow the user to set a
|
|
|
|
|
* breakpoint in _cairo_error() to generate a stack trace for when the
|
|
|
|
|
* user causes cairo to detect an error.
|
2007-10-04 13:15:46 +01:00
|
|
|
*
|
|
|
|
|
* Return value: the error status.
|
2005-07-27 15:39:34 +00:00
|
|
|
**/
|
2007-10-04 13:15:46 +01:00
|
|
|
cairo_status_t
|
2005-07-27 15:39:34 +00:00
|
|
|
_cairo_surface_set_error (cairo_surface_t *surface,
|
|
|
|
|
cairo_status_t status)
|
|
|
|
|
{
|
2011-02-18 18:52:11 +01:00
|
|
|
if (status == CAIRO_STATUS_SUCCESS ||
|
|
|
|
|
status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
2011-02-18 19:06:16 +01:00
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2011-02-18 18:52:11 +01:00
|
|
|
|
2005-08-19 12:08:42 +00:00
|
|
|
/* Don't overwrite an existing error. This preserves the first
|
2007-10-04 11:13:33 +01:00
|
|
|
* error, which is the most significant. */
|
|
|
|
|
_cairo_status_set_error (&surface->status, status);
|
2005-07-27 15:39:34 +00:00
|
|
|
|
2007-10-04 13:15:46 +01:00
|
|
|
return _cairo_error (status);
|
2005-07-27 15:39:34 +00:00
|
|
|
}
|
|
|
|
|
|
2006-02-27 23:15:45 -08:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_type:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2006-08-07 22:27:15 -04:00
|
|
|
* This function returns the type of the backend used to create
|
|
|
|
|
* a surface. See #cairo_surface_type_t for available types.
|
|
|
|
|
*
|
|
|
|
|
* Return value: The type of @surface.
|
2006-06-29 18:36:53 +02:00
|
|
|
*
|
|
|
|
|
* Since: 1.2
|
2006-02-27 23:15:45 -08:00
|
|
|
**/
|
2006-02-27 23:11:32 -08:00
|
|
|
cairo_surface_type_t
|
|
|
|
|
cairo_surface_get_type (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
/* We don't use surface->backend->type here so that some of the
|
|
|
|
|
* special "wrapper" surfaces such as cairo_paginated_surface_t
|
|
|
|
|
* can override surface->type with the type of the "child"
|
|
|
|
|
* surface. */
|
|
|
|
|
return surface->type;
|
|
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_get_type);
|
2006-02-27 23:11:32 -08:00
|
|
|
|
2006-05-24 17:05:51 -07:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_content:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2007-03-02 22:01:15 -05:00
|
|
|
* This function returns the content type of @surface which indicates
|
|
|
|
|
* whether the surface contains color and/or alpha information. See
|
2006-05-24 17:05:51 -07:00
|
|
|
* #cairo_content_t.
|
2006-06-29 18:36:53 +02:00
|
|
|
*
|
2007-03-02 22:01:15 -05:00
|
|
|
* Return value: The content type of @surface.
|
|
|
|
|
*
|
2006-06-29 18:36:53 +02:00
|
|
|
* Since: 1.2
|
2006-05-24 17:05:51 -07:00
|
|
|
**/
|
|
|
|
|
cairo_content_t
|
|
|
|
|
cairo_surface_get_content (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
return surface->content;
|
|
|
|
|
}
|
2006-06-15 15:33:45 -07:00
|
|
|
slim_hidden_def(cairo_surface_get_content);
|
2006-05-24 17:05:51 -07:00
|
|
|
|
2005-07-27 15:39:34 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_status:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-07-27 15:39:34 +00:00
|
|
|
* Checks whether an error has previously occurred for this
|
|
|
|
|
* surface.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-07-27 15:39:34 +00:00
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
|
|
|
|
|
* %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
|
2007-10-30 11:13:44 +00:00
|
|
|
* %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or
|
2005-07-27 15:39:34 +00:00
|
|
|
* %CAIRO_STATUS_INVALID_VISUAL.
|
|
|
|
|
**/
|
|
|
|
|
cairo_status_t
|
|
|
|
|
cairo_surface_status (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
return surface->status;
|
|
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_status);
|
2005-07-27 15:39:34 +00:00
|
|
|
|
2009-06-05 18:34:29 +01:00
|
|
|
static unsigned int
|
2009-05-27 16:45:20 +01:00
|
|
|
_cairo_surface_allocate_unique_id (void)
|
|
|
|
|
{
|
2009-10-13 16:10:39 +01:00
|
|
|
static cairo_atomic_int_t unique_id;
|
2009-05-27 16:45:20 +01:00
|
|
|
|
|
|
|
|
#if CAIRO_NO_MUTEX
|
|
|
|
|
if (++unique_id == 0)
|
|
|
|
|
unique_id = 1;
|
|
|
|
|
return unique_id;
|
|
|
|
|
#else
|
2009-10-13 16:10:39 +01:00
|
|
|
cairo_atomic_int_t old, id;
|
2009-05-27 16:45:20 +01:00
|
|
|
|
|
|
|
|
do {
|
2009-06-05 18:34:29 +01:00
|
|
|
old = _cairo_atomic_uint_get (&unique_id);
|
2009-05-27 16:45:20 +01:00
|
|
|
id = old + 1;
|
|
|
|
|
if (id == 0)
|
|
|
|
|
id = 1;
|
2009-06-05 18:34:29 +01:00
|
|
|
} while (! _cairo_atomic_uint_cmpxchg (&unique_id, old, id));
|
2009-05-27 16:45:20 +01:00
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-18 21:53:42 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_device:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
*
|
|
|
|
|
* This function returns the device for a @surface.
|
|
|
|
|
* See #cairo_device_t.
|
|
|
|
|
*
|
2010-07-09 03:04:27 +02:00
|
|
|
* Return value: The device for @surface or %NULL if the surface does
|
|
|
|
|
* not have an associated device.
|
2010-01-18 21:53:42 +00:00
|
|
|
*
|
|
|
|
|
* Since: 1.10
|
|
|
|
|
**/
|
|
|
|
|
cairo_device_t *
|
|
|
|
|
cairo_surface_get_device (cairo_surface_t *surface)
|
|
|
|
|
{
|
2010-04-14 19:11:15 +01:00
|
|
|
if (unlikely (surface->status))
|
|
|
|
|
return _cairo_device_create_in_error (surface->status);
|
|
|
|
|
|
2010-01-18 21:53:42 +00:00
|
|
|
return surface->device;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
static cairo_bool_t
|
|
|
|
|
_cairo_surface_has_snapshots (cairo_surface_t *surface)
|
|
|
|
|
{
|
2010-04-29 15:19:18 +01:00
|
|
|
return ! cairo_list_is_empty (&surface->snapshots);
|
2009-05-26 21:07:07 +01:00
|
|
|
}
|
|
|
|
|
|
2010-01-25 18:17:28 +00:00
|
|
|
static cairo_bool_t
|
|
|
|
|
_cairo_surface_has_mime_data (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
return surface->mime_data.num_elements != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_surface_detach_mime_data (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
if (! _cairo_surface_has_mime_data (surface))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_cairo_user_data_array_fini (&surface->mime_data);
|
2010-01-29 09:17:01 +00:00
|
|
|
_cairo_user_data_array_init (&surface->mime_data);
|
2010-01-25 18:17:28 +00:00
|
|
|
}
|
|
|
|
|
|
2010-04-29 15:19:18 +01:00
|
|
|
static void
|
|
|
|
|
_cairo_surface_detach_snapshots (cairo_surface_t *surface)
|
2009-05-26 21:07:07 +01:00
|
|
|
{
|
2010-04-29 15:19:18 +01:00
|
|
|
while (_cairo_surface_has_snapshots (surface)) {
|
|
|
|
|
_cairo_surface_detach_snapshot (cairo_list_first_entry (&surface->snapshots,
|
|
|
|
|
cairo_surface_t,
|
2010-04-28 14:26:21 +01:00
|
|
|
snapshot));
|
2010-04-29 15:19:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
_cairo_surface_detach_snapshot (cairo_surface_t *snapshot)
|
|
|
|
|
{
|
|
|
|
|
assert (snapshot->snapshot_of != NULL);
|
|
|
|
|
|
|
|
|
|
snapshot->snapshot_of = NULL;
|
2010-04-28 14:26:21 +01:00
|
|
|
cairo_list_del (&snapshot->snapshot);
|
2010-04-29 15:19:18 +01:00
|
|
|
|
|
|
|
|
if (snapshot->snapshot_detach != NULL)
|
|
|
|
|
snapshot->snapshot_detach (snapshot);
|
|
|
|
|
|
|
|
|
|
cairo_surface_destroy (snapshot);
|
|
|
|
|
}
|
2009-06-13 17:16:20 +01:00
|
|
|
|
2010-04-29 15:19:18 +01:00
|
|
|
void
|
|
|
|
|
_cairo_surface_attach_snapshot (cairo_surface_t *surface,
|
|
|
|
|
cairo_surface_t *snapshot,
|
|
|
|
|
cairo_surface_func_t detach_func)
|
|
|
|
|
{
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (surface != snapshot);
|
2010-04-29 15:19:18 +01:00
|
|
|
assert (snapshot->snapshot_of != surface);
|
|
|
|
|
|
|
|
|
|
cairo_surface_reference (snapshot);
|
2009-05-26 21:07:07 +01:00
|
|
|
|
|
|
|
|
if (snapshot->snapshot_of != NULL)
|
|
|
|
|
_cairo_surface_detach_snapshot (snapshot);
|
|
|
|
|
|
|
|
|
|
snapshot->snapshot_of = surface;
|
|
|
|
|
snapshot->snapshot_detach = detach_func;
|
|
|
|
|
|
2010-04-28 14:26:21 +01:00
|
|
|
cairo_list_add (&snapshot->snapshot, &surface->snapshots);
|
2009-06-13 17:16:20 +01:00
|
|
|
|
2010-04-29 15:19:18 +01:00
|
|
|
assert (_cairo_surface_has_snapshot (surface, snapshot->backend) == snapshot);
|
2009-05-26 21:07:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_surface_t *
|
|
|
|
|
_cairo_surface_has_snapshot (cairo_surface_t *surface,
|
2010-01-18 19:12:25 +00:00
|
|
|
const cairo_surface_backend_t *backend)
|
2009-05-26 21:07:07 +01:00
|
|
|
{
|
2010-04-29 15:19:18 +01:00
|
|
|
cairo_surface_t *snapshot;
|
2009-05-26 21:07:07 +01:00
|
|
|
|
2010-04-29 15:19:18 +01:00
|
|
|
cairo_list_foreach_entry (snapshot, cairo_surface_t,
|
2010-04-28 14:26:21 +01:00
|
|
|
&surface->snapshots, snapshot)
|
2010-04-29 15:19:18 +01:00
|
|
|
{
|
|
|
|
|
/* XXX is_similar? */
|
|
|
|
|
if (snapshot->backend == backend)
|
|
|
|
|
return snapshot;
|
2009-05-26 21:07:07 +01:00
|
|
|
}
|
|
|
|
|
|
2010-04-29 15:19:18 +01:00
|
|
|
return NULL;
|
2009-05-26 21:07:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static cairo_bool_t
|
|
|
|
|
_cairo_surface_is_writable (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
return ! surface->finished &&
|
|
|
|
|
surface->snapshot_of == NULL &&
|
2010-01-25 18:17:28 +00:00
|
|
|
! _cairo_surface_has_snapshots (surface) &&
|
|
|
|
|
! _cairo_surface_has_mime_data (surface);
|
2009-05-26 21:07:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_surface_begin_modification (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
assert (surface->status == CAIRO_STATUS_SUCCESS);
|
|
|
|
|
assert (! surface->finished);
|
|
|
|
|
assert (surface->snapshot_of == NULL);
|
|
|
|
|
|
|
|
|
|
_cairo_surface_detach_snapshots (surface);
|
2010-01-25 18:17:28 +00:00
|
|
|
_cairo_surface_detach_mime_data (surface);
|
2009-05-26 21:07:07 +01:00
|
|
|
}
|
|
|
|
|
|
2003-09-30 18:56:22 +00:00
|
|
|
void
|
|
|
|
|
_cairo_surface_init (cairo_surface_t *surface,
|
2006-05-24 17:05:51 -07:00
|
|
|
const cairo_surface_backend_t *backend,
|
2010-01-18 21:53:42 +00:00
|
|
|
cairo_device_t *device,
|
2006-05-24 17:05:51 -07:00
|
|
|
cairo_content_t content)
|
2003-07-18 11:34:19 +00:00
|
|
|
{
|
2007-03-20 10:11:14 +01:00
|
|
|
CAIRO_MUTEX_INITIALIZE ();
|
2006-05-24 17:05:51 -07:00
|
|
|
|
2007-03-20 10:11:14 +01:00
|
|
|
surface->backend = backend;
|
2010-01-18 21:53:42 +00:00
|
|
|
surface->device = cairo_device_reference (device);
|
2006-05-24 17:05:51 -07:00
|
|
|
surface->content = content;
|
2006-02-27 23:11:32 -08:00
|
|
|
surface->type = backend->type;
|
2003-07-18 11:34:19 +00:00
|
|
|
|
2007-09-23 21:08:09 +01:00
|
|
|
CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
|
2005-07-27 15:39:34 +00:00
|
|
|
surface->status = CAIRO_STATUS_SUCCESS;
|
2009-05-27 16:45:20 +01:00
|
|
|
surface->unique_id = _cairo_surface_allocate_unique_id ();
|
2009-10-21 09:04:30 +01:00
|
|
|
surface->finished = FALSE;
|
|
|
|
|
surface->is_clear = FALSE;
|
2010-05-18 12:02:54 +02:00
|
|
|
surface->owns_device = (device != NULL);
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2005-04-08 13:14:17 +00:00
|
|
|
_cairo_user_data_array_init (&surface->user_data);
|
2009-02-13 12:56:46 +00:00
|
|
|
_cairo_user_data_array_init (&surface->mime_data);
|
2003-07-30 08:30:50 +00:00
|
|
|
|
2006-06-10 00:12:51 -07:00
|
|
|
cairo_matrix_init_identity (&surface->device_transform);
|
2006-06-29 19:47:26 +02:00
|
|
|
cairo_matrix_init_identity (&surface->device_transform_inverse);
|
2010-06-11 16:04:41 +01:00
|
|
|
cairo_list_init (&surface->device_transform_observers);
|
2005-04-19 16:29:04 +00:00
|
|
|
|
2007-09-18 09:26:05 -07:00
|
|
|
surface->x_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
|
|
|
|
|
surface->y_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
|
2007-08-29 15:34:04 -07:00
|
|
|
|
2006-06-09 16:52:17 -07:00
|
|
|
surface->x_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
|
|
|
|
|
surface->y_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
|
|
|
|
|
|
2010-04-29 15:19:18 +01:00
|
|
|
cairo_list_init (&surface->snapshots);
|
2009-05-26 21:07:07 +01:00
|
|
|
surface->snapshot_of = NULL;
|
2006-07-31 14:44:42 -04:00
|
|
|
|
|
|
|
|
surface->has_font_options = FALSE;
|
2003-07-18 11:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
static void
|
|
|
|
|
_cairo_surface_copy_similar_properties (cairo_surface_t *surface,
|
|
|
|
|
cairo_surface_t *other)
|
|
|
|
|
{
|
|
|
|
|
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,
|
|
|
|
|
other->y_fallback_resolution);
|
|
|
|
|
}
|
|
|
|
|
|
2004-05-24 02:28:05 +00:00
|
|
|
cairo_surface_t *
|
2005-07-08 10:12:28 +00:00
|
|
|
_cairo_surface_create_similar_scratch (cairo_surface_t *other,
|
|
|
|
|
cairo_content_t content,
|
2004-05-24 02:28:05 +00:00
|
|
|
int width,
|
|
|
|
|
int height)
|
|
|
|
|
{
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_surface_t *surface;
|
2004-05-24 02:28:05 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (other->status))
|
2008-01-16 16:23:23 +00:00
|
|
|
return _cairo_surface_create_in_error (other->status);
|
2005-07-27 15:39:34 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (other->backend->create_similar == NULL)
|
|
|
|
|
return NULL;
|
2006-07-31 14:44:42 -04:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
surface = other->backend->create_similar (other,
|
|
|
|
|
content, width, height);
|
|
|
|
|
if (surface == NULL || surface->status)
|
2007-03-19 16:50:55 -07:00
|
|
|
return surface;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
_cairo_surface_copy_similar_properties (surface, other);
|
2006-07-31 14:50:50 -04:00
|
|
|
|
2006-07-31 14:44:42 -04:00
|
|
|
return surface;
|
2004-05-24 02:28:05 +00:00
|
|
|
}
|
|
|
|
|
|
2005-07-08 10:12:28 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_create_similar:
|
|
|
|
|
* @other: an existing surface used to select the backend of the new surface
|
|
|
|
|
* @content: the content for the new surface
|
|
|
|
|
* @width: width of the new surface, (in device-space units)
|
|
|
|
|
* @height: height of the new surface (in device-space units)
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-07-08 10:12:28 +00:00
|
|
|
* Create a new surface that is as compatible as possible with an
|
2006-08-02 11:18:14 -04:00
|
|
|
* existing surface. For example the new surface will have the same
|
|
|
|
|
* fallback resolution and font options as @other. Generally, the new
|
|
|
|
|
* surface will also use the same backend as @other, unless that is
|
|
|
|
|
* not possible for some reason. The type of the returned surface may
|
|
|
|
|
* be examined with cairo_surface_get_type().
|
|
|
|
|
*
|
2006-06-16 18:39:36 -04:00
|
|
|
* Initially the surface contents are all 0 (transparent if contents
|
|
|
|
|
* have transparency, black otherwise.)
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-07-28 09:46:38 +00:00
|
|
|
* Return value: a pointer to the newly allocated surface. The caller
|
2008-01-28 21:49:57 -05:00
|
|
|
* owns the surface and should call cairo_surface_destroy() when done
|
2005-07-28 09:46:38 +00:00
|
|
|
* with it.
|
|
|
|
|
*
|
|
|
|
|
* This function always returns a valid pointer, but it will return a
|
|
|
|
|
* pointer to a "nil" surface if @other is already in an error state
|
|
|
|
|
* or any other error occurs.
|
2005-07-08 10:12:28 +00:00
|
|
|
**/
|
2003-07-18 11:34:19 +00:00
|
|
|
cairo_surface_t *
|
2005-07-08 10:12:28 +00:00
|
|
|
cairo_surface_create_similar (cairo_surface_t *other,
|
|
|
|
|
cairo_content_t content,
|
2003-07-18 11:34:19 +00:00
|
|
|
int width,
|
|
|
|
|
int height)
|
|
|
|
|
{
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (other->status))
|
2008-01-16 16:23:23 +00:00
|
|
|
return _cairo_surface_create_in_error (other->status);
|
2010-07-05 18:24:23 +02:00
|
|
|
if (unlikely (other->finished))
|
|
|
|
|
return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
|
2003-10-31 10:41:37 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (! CAIRO_CONTENT_VALID (content)))
|
2008-01-16 16:23:23 +00:00
|
|
|
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
|
2005-07-08 10:12:28 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
return _cairo_surface_create_similar_solid (other,
|
|
|
|
|
content, width, height,
|
|
|
|
|
CAIRO_COLOR_TRANSPARENT,
|
|
|
|
|
TRUE);
|
2003-07-18 11:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_surface_t *
|
2005-04-14 14:42:26 +00:00
|
|
|
_cairo_surface_create_similar_solid (cairo_surface_t *other,
|
2005-07-08 10:12:28 +00:00
|
|
|
cairo_content_t content,
|
2005-04-14 14:42:26 +00:00
|
|
|
int width,
|
|
|
|
|
int height,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
const cairo_color_t *color,
|
|
|
|
|
cairo_bool_t allow_fallback)
|
2003-07-18 11:34:19 +00:00
|
|
|
{
|
2003-10-31 10:41:37 +00:00
|
|
|
cairo_status_t status;
|
2004-05-24 02:28:05 +00:00
|
|
|
cairo_surface_t *surface;
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_solid_pattern_t pattern;
|
2003-07-18 11:34:19 +00:00
|
|
|
|
2005-07-08 10:12:28 +00:00
|
|
|
surface = _cairo_surface_create_similar_scratch (other, content,
|
2004-05-24 02:28:05 +00:00
|
|
|
width, height);
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface == NULL && allow_fallback)
|
|
|
|
|
surface = _cairo_image_surface_create_with_content (content,
|
|
|
|
|
width, height);
|
|
|
|
|
if (surface == NULL || surface->status)
|
2008-01-16 16:23:23 +00:00
|
|
|
return surface;
|
2005-12-19 22:01:39 +00:00
|
|
|
|
2010-04-19 09:53:00 +02:00
|
|
|
_cairo_pattern_init_solid (&pattern, color);
|
2006-06-06 15:41:31 -07:00
|
|
|
status = _cairo_surface_paint (surface,
|
|
|
|
|
color == CAIRO_COLOR_TRANSPARENT ?
|
2008-06-19 21:06:07 -04:00
|
|
|
CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
&pattern.base, NULL);
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status)) {
|
2003-10-31 10:41:37 +00:00
|
|
|
cairo_surface_destroy (surface);
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
surface = _cairo_surface_create_in_error (status);
|
2003-07-18 11:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return surface;
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-13 21:36:14 -04:00
|
|
|
cairo_surface_t *
|
|
|
|
|
_cairo_surface_create_solid_pattern_surface (cairo_surface_t *other,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_solid_pattern_t *solid_pattern)
|
2008-06-13 21:36:14 -04:00
|
|
|
{
|
2008-12-17 20:34:45 +00:00
|
|
|
if (other->backend->create_solid_pattern_surface != NULL) {
|
|
|
|
|
cairo_surface_t *surface;
|
2008-06-13 21:36:14 -04:00
|
|
|
|
2008-12-17 20:34:45 +00:00
|
|
|
surface = other->backend->create_solid_pattern_surface (other,
|
|
|
|
|
solid_pattern);
|
2008-06-13 21:36:14 -04:00
|
|
|
if (surface)
|
|
|
|
|
return surface;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-17 20:34:45 +00:00
|
|
|
return _cairo_surface_create_similar_solid (other,
|
2010-04-19 09:53:00 +02:00
|
|
|
_cairo_color_get_content (&solid_pattern->color),
|
2008-12-17 20:34:45 +00:00
|
|
|
1, 1,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
&solid_pattern->color,
|
|
|
|
|
FALSE);
|
2008-06-13 21:36:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_int_status_t
|
|
|
|
|
_cairo_surface_repaint_solid_pattern_surface (cairo_surface_t *other,
|
|
|
|
|
cairo_surface_t *solid_surface,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_solid_pattern_t *solid_pattern)
|
2008-06-13 21:36:14 -04:00
|
|
|
{
|
2008-12-17 20:34:45 +00:00
|
|
|
/* Solid pattern surface for these backends are special and not trivial
|
|
|
|
|
* to repaint. Skip repainting.
|
|
|
|
|
*
|
|
|
|
|
* This does not work optimally with things like analysis surface that
|
|
|
|
|
* are proxies. But returning UNSUPPORTED is *safe* as it only
|
|
|
|
|
* disables some caching.
|
|
|
|
|
*/
|
|
|
|
|
if (other->backend->create_solid_pattern_surface != NULL &&
|
|
|
|
|
! other->backend->can_repaint_solid_pattern_surface (solid_surface,
|
|
|
|
|
solid_pattern))
|
|
|
|
|
{
|
2008-06-13 21:36:14 -04:00
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
2008-12-17 20:34:45 +00:00
|
|
|
}
|
2008-06-13 21:36:14 -04:00
|
|
|
|
2008-12-17 20:34:45 +00:00
|
|
|
return _cairo_surface_paint (solid_surface,
|
|
|
|
|
CAIRO_OPERATOR_SOURCE,
|
|
|
|
|
&solid_pattern->base,
|
|
|
|
|
NULL);
|
2008-06-13 21:36:14 -04:00
|
|
|
}
|
|
|
|
|
|
2005-08-04 18:44:29 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_reference:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-04 18:44:29 +00:00
|
|
|
* Increases the reference count on @surface by one. This prevents
|
|
|
|
|
* @surface from being destroyed until a matching call to
|
|
|
|
|
* cairo_surface_destroy() is made.
|
|
|
|
|
*
|
2007-03-02 22:42:17 -05:00
|
|
|
* The number of references to a #cairo_surface_t can be get using
|
|
|
|
|
* cairo_surface_get_reference_count().
|
|
|
|
|
*
|
2005-08-04 18:44:29 +00:00
|
|
|
* Return value: the referenced #cairo_surface_t.
|
|
|
|
|
**/
|
|
|
|
|
cairo_surface_t *
|
2003-09-16 06:45:19 +00:00
|
|
|
cairo_surface_reference (cairo_surface_t *surface)
|
2003-07-18 11:34:19 +00:00
|
|
|
{
|
2007-09-23 21:08:09 +01:00
|
|
|
if (surface == NULL ||
|
|
|
|
|
CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
2005-08-04 18:44:29 +00:00
|
|
|
return surface;
|
2005-07-27 15:39:34 +00:00
|
|
|
|
2007-09-23 21:08:09 +01:00
|
|
|
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
|
2005-08-23 14:04:28 +00:00
|
|
|
|
2007-09-23 21:08:09 +01:00
|
|
|
_cairo_reference_count_inc (&surface->ref_count);
|
2005-08-04 18:44:29 +00:00
|
|
|
|
|
|
|
|
return surface;
|
2003-07-18 11:34:19 +00:00
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_reference);
|
2003-07-18 11:34:19 +00:00
|
|
|
|
2005-08-04 18:44:29 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_destroy:
|
2007-05-01 11:28:45 +01:00
|
|
|
* @surface: a #cairo_surface_t
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-04 18:44:29 +00:00
|
|
|
* Decreases the reference count on @surface by one. If the result is
|
|
|
|
|
* zero, then @surface and all associated resources are freed. See
|
|
|
|
|
* cairo_surface_reference().
|
|
|
|
|
**/
|
2003-07-18 11:34:19 +00:00
|
|
|
void
|
|
|
|
|
cairo_surface_destroy (cairo_surface_t *surface)
|
|
|
|
|
{
|
2007-09-23 21:08:09 +01:00
|
|
|
if (surface == NULL ||
|
|
|
|
|
CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
2005-07-27 15:39:34 +00:00
|
|
|
return;
|
|
|
|
|
|
2007-09-23 21:08:09 +01:00
|
|
|
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
|
2005-08-23 14:04:28 +00:00
|
|
|
|
2007-09-23 21:08:09 +01:00
|
|
|
if (! _cairo_reference_count_dec_and_test (&surface->ref_count))
|
2003-07-18 11:34:19 +00:00
|
|
|
return;
|
|
|
|
|
|
2009-06-13 17:16:20 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
|
|
|
|
|
2007-02-01 16:05:59 -08:00
|
|
|
if (! surface->finished)
|
|
|
|
|
cairo_surface_finish (surface);
|
2005-03-10 09:28:50 +00:00
|
|
|
|
2010-01-18 19:05:34 +00:00
|
|
|
/* paranoid check that nobody took a reference whilst finishing */
|
|
|
|
|
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
|
|
|
|
|
|
2005-06-03 16:16:44 +00:00
|
|
|
_cairo_user_data_array_fini (&surface->user_data);
|
2009-02-13 12:56:46 +00:00
|
|
|
_cairo_user_data_array_fini (&surface->mime_data);
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2010-05-18 12:02:54 +02:00
|
|
|
if (surface->owns_device)
|
|
|
|
|
cairo_device_destroy (surface->device);
|
2010-05-06 17:03:56 +01:00
|
|
|
|
2010-12-25 23:39:21 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
|
|
|
|
assert (!_cairo_surface_has_snapshots (surface));
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
free (surface);
|
2003-07-18 11:34:19 +00:00
|
|
|
}
|
2003-09-09 17:38:10 +00:00
|
|
|
slim_hidden_def(cairo_surface_destroy);
|
2003-07-18 11:34:19 +00:00
|
|
|
|
2007-02-23 13:05:18 -08:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_reference_count:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
*
|
|
|
|
|
* Returns the current reference count of @surface.
|
|
|
|
|
*
|
|
|
|
|
* Return value: the current reference count of @surface. If the
|
|
|
|
|
* object is a nil object, 0 will be returned.
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.4
|
|
|
|
|
**/
|
|
|
|
|
unsigned int
|
|
|
|
|
cairo_surface_get_reference_count (cairo_surface_t *surface)
|
|
|
|
|
{
|
2007-09-23 21:08:09 +01:00
|
|
|
if (surface == NULL ||
|
|
|
|
|
CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
2007-02-23 14:24:04 -08:00
|
|
|
return 0;
|
|
|
|
|
|
2007-09-23 21:08:09 +01:00
|
|
|
return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count);
|
2007-02-23 13:05:18 -08:00
|
|
|
}
|
|
|
|
|
|
2005-03-16 12:08:41 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_finish:
|
|
|
|
|
* @surface: the #cairo_surface_t to finish
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-03-16 12:08:41 +00:00
|
|
|
* This function finishes the surface and drops all references to
|
|
|
|
|
* external resources. For example, for the Xlib backend it means
|
|
|
|
|
* that cairo will no longer access the drawable, which can be freed.
|
|
|
|
|
* After calling cairo_surface_finish() the only valid operations on a
|
2008-05-16 21:59:45 -04:00
|
|
|
* surface are getting and setting user, referencing and
|
|
|
|
|
* destroying, and flushing and finishing it.
|
|
|
|
|
* Further drawing to the surface will not affect the
|
2008-05-09 09:53:40 -04:00
|
|
|
* surface but will instead trigger a %CAIRO_STATUS_SURFACE_FINISHED
|
2005-07-27 15:39:34 +00:00
|
|
|
* error.
|
2005-03-16 12:08:41 +00:00
|
|
|
*
|
|
|
|
|
* When the last call to cairo_surface_destroy() decreases the
|
|
|
|
|
* reference count to zero, cairo will call cairo_surface_finish() if
|
|
|
|
|
* it hasn't been called already, before freeing the resources
|
|
|
|
|
* associated with the surface.
|
|
|
|
|
**/
|
2005-07-27 15:39:34 +00:00
|
|
|
void
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_surface_finish (cairo_surface_t *surface)
|
|
|
|
|
{
|
2005-04-13 14:51:59 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2007-02-01 15:22:27 -08:00
|
|
|
if (surface == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2007-09-23 21:08:09 +01:00
|
|
|
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
2007-02-01 15:22:27 -08:00
|
|
|
return;
|
|
|
|
|
|
2008-05-16 21:59:45 -04:00
|
|
|
if (surface->finished)
|
2005-07-27 15:39:34 +00:00
|
|
|
return;
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2010-12-26 11:04:30 +01:00
|
|
|
cairo_surface_flush (surface);
|
|
|
|
|
|
2010-01-18 19:05:34 +00:00
|
|
|
/* update the snapshots *before* we declare the surface as finished */
|
|
|
|
|
_cairo_surface_detach_snapshots (surface);
|
|
|
|
|
if (surface->snapshot_of != NULL)
|
|
|
|
|
_cairo_surface_detach_snapshot (surface);
|
|
|
|
|
|
2010-05-30 20:12:31 +02:00
|
|
|
surface->finished = TRUE;
|
2005-08-01 11:45:42 +00:00
|
|
|
|
2008-05-16 21:59:45 -04:00
|
|
|
/* call finish even if in error mode */
|
|
|
|
|
if (surface->backend->finish) {
|
|
|
|
|
status = surface->backend->finish (surface);
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2008-05-16 21:59:45 -04:00
|
|
|
status = _cairo_surface_set_error (surface, status);
|
2008-05-09 13:28:31 +02:00
|
|
|
}
|
2010-12-25 23:39:21 +01:00
|
|
|
|
|
|
|
|
assert (surface->snapshot_of == NULL);
|
|
|
|
|
assert (!_cairo_surface_has_snapshots (surface));
|
2005-03-16 12:08:41 +00:00
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_finish);
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2010-05-18 12:02:54 +02:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_release_device_reference:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
*
|
|
|
|
|
* This function makes @surface release the reference to its device. The
|
|
|
|
|
* function is intended to be used for avoiding cycling references for
|
|
|
|
|
* surfaces that are owned by their device, for example cache surfaces.
|
|
|
|
|
* Note that the @surface will still assume that the device is available.
|
|
|
|
|
* So it is the caller's responsibility to ensure the device stays around
|
|
|
|
|
* until the @surface is destroyed. Just calling cairo_surface_finish() is
|
|
|
|
|
* not enough.
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
_cairo_surface_release_device_reference (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
assert (surface->owns_device);
|
|
|
|
|
|
|
|
|
|
cairo_device_destroy (surface->device);
|
|
|
|
|
surface->owns_device = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-10 08:59:11 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_user_data:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @key: the address of the #cairo_user_data_key_t the user data was
|
|
|
|
|
* attached to
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-03-10 08:59:11 +00:00
|
|
|
* Return user data previously attached to @surface using the specified
|
|
|
|
|
* key. If no user data has been attached with the given key this
|
|
|
|
|
* function returns %NULL.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-03-10 08:59:11 +00:00
|
|
|
* Return value: the user data previously attached or %NULL.
|
|
|
|
|
**/
|
|
|
|
|
void *
|
|
|
|
|
cairo_surface_get_user_data (cairo_surface_t *surface,
|
|
|
|
|
const cairo_user_data_key_t *key)
|
|
|
|
|
{
|
2005-04-08 13:14:17 +00:00
|
|
|
return _cairo_user_data_array_get_data (&surface->user_data,
|
|
|
|
|
key);
|
2005-03-10 08:59:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* cairo_surface_set_user_data:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @key: the address of a #cairo_user_data_key_t to attach the user data to
|
|
|
|
|
* @user_data: the user data to attach to the surface
|
|
|
|
|
* @destroy: a #cairo_destroy_func_t which will be called when the
|
|
|
|
|
* surface is destroyed or when new user data is attached using the
|
|
|
|
|
* same key.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-03-10 08:59:11 +00:00
|
|
|
* Attach user data to @surface. To remove user data from a surface,
|
|
|
|
|
* call this function with the key that was used to set it and %NULL
|
|
|
|
|
* for @data.
|
|
|
|
|
*
|
|
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
|
|
|
|
|
* slot could not be allocated for the user data.
|
|
|
|
|
**/
|
|
|
|
|
cairo_status_t
|
|
|
|
|
cairo_surface_set_user_data (cairo_surface_t *surface,
|
|
|
|
|
const cairo_user_data_key_t *key,
|
|
|
|
|
void *user_data,
|
|
|
|
|
cairo_destroy_func_t destroy)
|
|
|
|
|
{
|
2007-09-23 21:08:09 +01:00
|
|
|
if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
|
2008-09-23 10:51:13 +01:00
|
|
|
return surface->status;
|
2006-06-06 15:25:49 -07:00
|
|
|
|
2005-04-08 13:14:17 +00:00
|
|
|
return _cairo_user_data_array_set_data (&surface->user_data,
|
|
|
|
|
key, user_data, destroy);
|
2005-03-10 08:59:11 +00:00
|
|
|
}
|
|
|
|
|
|
2008-09-07 20:46:20 +09:30
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_mime_data:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @mime_type: the mime type of the image data
|
|
|
|
|
* @data: the image data to attached to the surface
|
|
|
|
|
* @length: the length of the image data
|
|
|
|
|
*
|
|
|
|
|
* Return mime data previously attached to @surface using the
|
|
|
|
|
* specified mime type. If no data has been attached with the given
|
2008-11-03 09:40:35 +00:00
|
|
|
* mime type, @data is set %NULL.
|
2008-09-07 20:46:20 +09:30
|
|
|
*
|
|
|
|
|
* Since: 1.10
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_get_mime_data (cairo_surface_t *surface,
|
2008-11-03 09:40:35 +00:00
|
|
|
const char *mime_type,
|
2008-09-07 20:46:20 +09:30
|
|
|
const unsigned char **data,
|
2010-07-10 11:13:07 +01:00
|
|
|
unsigned long *length)
|
2008-09-07 20:46:20 +09:30
|
|
|
{
|
2009-05-25 23:25:38 +01:00
|
|
|
cairo_user_data_slot_t *slots;
|
|
|
|
|
int i, num_slots;
|
2008-11-03 11:01:22 +00:00
|
|
|
|
|
|
|
|
*data = NULL;
|
|
|
|
|
*length = 0;
|
2009-05-25 23:25:38 +01:00
|
|
|
if (unlikely (surface->status))
|
2008-11-03 11:01:22 +00:00
|
|
|
return;
|
|
|
|
|
|
2009-05-25 23:25:38 +01:00
|
|
|
/* The number of mime-types attached to a surface is usually small,
|
|
|
|
|
* typically zero. Therefore it is quicker to do a strcmp() against
|
|
|
|
|
* each key than it is to intern the string (i.e. compute a hash,
|
|
|
|
|
* search the hash table, and do a final strcmp).
|
|
|
|
|
*/
|
|
|
|
|
num_slots = surface->mime_data.num_elements;
|
|
|
|
|
slots = _cairo_array_index (&surface->mime_data, 0);
|
|
|
|
|
for (i = 0; i < num_slots; i++) {
|
|
|
|
|
if (strcmp ((char *) slots[i].key, mime_type) == 0) {
|
|
|
|
|
cairo_mime_data_t *mime_data = slots[i].user_data;
|
|
|
|
|
|
|
|
|
|
*data = mime_data->data;
|
|
|
|
|
*length = mime_data->length;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2008-09-07 20:46:20 +09:30
|
|
|
}
|
2008-11-03 11:01:22 +00:00
|
|
|
}
|
|
|
|
|
slim_hidden_def (cairo_surface_get_mime_data);
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
_cairo_mime_data_destroy (void *ptr)
|
|
|
|
|
{
|
|
|
|
|
cairo_mime_data_t *mime_data = ptr;
|
|
|
|
|
|
2008-11-03 23:45:12 +00:00
|
|
|
if (! _cairo_reference_count_dec_and_test (&mime_data->ref_count))
|
|
|
|
|
return;
|
|
|
|
|
|
2008-11-07 13:26:46 +00:00
|
|
|
if (mime_data->destroy && mime_data->closure)
|
|
|
|
|
mime_data->destroy (mime_data->closure);
|
2008-11-03 11:01:22 +00:00
|
|
|
|
|
|
|
|
free (mime_data);
|
2008-09-07 20:46:20 +09:30
|
|
|
}
|
|
|
|
|
|
2010-07-08 13:05:18 +02:00
|
|
|
/**
|
|
|
|
|
* CAIRO_MIME_TYPE_JP2:
|
|
|
|
|
*
|
|
|
|
|
* The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1).
|
|
|
|
|
*
|
|
|
|
|
* @Since: 1.10
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* CAIRO_MIME_TYPE_JPEG:
|
|
|
|
|
*
|
|
|
|
|
* The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1).
|
|
|
|
|
*
|
|
|
|
|
* @Since: 1.10
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* CAIRO_MIME_TYPE_PNG:
|
|
|
|
|
*
|
|
|
|
|
* The Portable Network Graphics image file format (ISO/IEC 15948).
|
|
|
|
|
*
|
|
|
|
|
* @Since: 1.10
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* CAIRO_MIME_TYPE_URI:
|
|
|
|
|
*
|
|
|
|
|
* URI for an image file (unofficial MIME type).
|
|
|
|
|
*
|
|
|
|
|
* @Since: 1.10
|
|
|
|
|
*/
|
|
|
|
|
|
2010-11-02 22:39:57 +10:30
|
|
|
/**
|
|
|
|
|
* CAIRO_MIME_TYPE_UNIQUE_ID:
|
|
|
|
|
*
|
|
|
|
|
* Unique identifier for a surface (cairo specific MIME type).
|
|
|
|
|
*
|
|
|
|
|
* @Since: 1.12
|
|
|
|
|
*/
|
|
|
|
|
|
2008-09-07 20:46:20 +09:30
|
|
|
/**
|
|
|
|
|
* cairo_surface_set_mime_data:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2010-02-20 20:59:32 +02:00
|
|
|
* @mime_type: the MIME type of the image data
|
2008-09-07 20:46:20 +09:30
|
|
|
* @data: the image data to attach to the surface
|
|
|
|
|
* @length: the length of the image data
|
|
|
|
|
* @destroy: a #cairo_destroy_func_t which will be called when the
|
|
|
|
|
* surface is destroyed or when new image data is attached using the
|
|
|
|
|
* same mime type.
|
2008-11-07 13:26:46 +00:00
|
|
|
* @closure: the data to be passed to the @destroy notifier
|
2008-09-07 20:46:20 +09:30
|
|
|
*
|
|
|
|
|
* Attach an image in the format @mime_type to @surface. To remove
|
|
|
|
|
* the data from a surface, call this function with same mime type
|
|
|
|
|
* and %NULL for @data.
|
|
|
|
|
*
|
2010-02-20 20:59:32 +02:00
|
|
|
* The attached image (or filename) data can later be used by backends
|
|
|
|
|
* which support it (currently: PDF, PS, SVG and Win32 Printing
|
|
|
|
|
* surfaces) to emit this data instead of making a snapshot of the
|
|
|
|
|
* @surface. This approach tends to be faster and requires less
|
|
|
|
|
* memory and disk space.
|
|
|
|
|
*
|
2010-03-28 19:40:54 +01:00
|
|
|
* The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG,
|
|
|
|
|
* %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI.
|
2010-02-20 20:59:32 +02:00
|
|
|
*
|
|
|
|
|
* See corresponding backend surface docs for details about which MIME
|
|
|
|
|
* types it can handle. Caution: the associated MIME data will be
|
|
|
|
|
* discarded if you draw on the surface afterwards. Use this function
|
|
|
|
|
* with care.
|
|
|
|
|
*
|
2008-09-07 20:46:20 +09:30
|
|
|
* Since: 1.10
|
2008-11-03 11:01:22 +00:00
|
|
|
*
|
|
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
|
|
|
|
|
* slot could not be allocated for the user data.
|
2008-09-07 20:46:20 +09:30
|
|
|
**/
|
2008-11-03 11:01:22 +00:00
|
|
|
cairo_status_t
|
2008-09-07 20:46:20 +09:30
|
|
|
cairo_surface_set_mime_data (cairo_surface_t *surface,
|
|
|
|
|
const char *mime_type,
|
|
|
|
|
const unsigned char *data,
|
2010-07-10 11:13:07 +01:00
|
|
|
unsigned long length,
|
2008-11-07 13:26:46 +00:00
|
|
|
cairo_destroy_func_t destroy,
|
|
|
|
|
void *closure)
|
2008-09-07 20:46:20 +09:30
|
|
|
{
|
2008-11-03 11:01:22 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
cairo_mime_data_t *mime_data;
|
2008-09-07 20:46:20 +09:30
|
|
|
|
2009-01-26 20:51:02 +00:00
|
|
|
if (unlikely (surface->status))
|
2008-11-03 11:01:22 +00:00
|
|
|
return surface->status;
|
2010-07-05 18:25:16 +02:00
|
|
|
if (surface->finished)
|
2010-07-05 22:41:43 +02:00
|
|
|
return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
|
2008-11-03 11:01:22 +00:00
|
|
|
|
|
|
|
|
status = _cairo_intern_string (&mime_type, -1);
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2008-11-03 11:01:22 +00:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
|
|
|
|
|
2008-11-05 16:41:13 +00:00
|
|
|
if (data != NULL) {
|
|
|
|
|
mime_data = malloc (sizeof (cairo_mime_data_t));
|
2008-11-18 17:26:55 +00:00
|
|
|
if (unlikely (mime_data == NULL))
|
2008-11-05 16:41:13 +00:00
|
|
|
return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_NO_MEMORY));
|
|
|
|
|
|
|
|
|
|
CAIRO_REFERENCE_COUNT_INIT (&mime_data->ref_count, 1);
|
|
|
|
|
|
|
|
|
|
mime_data->data = (unsigned char *) data;
|
|
|
|
|
mime_data->length = length;
|
|
|
|
|
mime_data->destroy = destroy;
|
2008-11-07 13:26:46 +00:00
|
|
|
mime_data->closure = closure;
|
2008-11-05 16:41:13 +00:00
|
|
|
} else
|
|
|
|
|
mime_data = NULL;
|
2008-11-03 23:45:12 +00:00
|
|
|
|
2009-02-13 12:56:46 +00:00
|
|
|
status = _cairo_user_data_array_set_data (&surface->mime_data,
|
2008-11-03 23:45:12 +00:00
|
|
|
(cairo_user_data_key_t *) mime_type,
|
|
|
|
|
mime_data,
|
|
|
|
|
_cairo_mime_data_destroy);
|
2009-01-26 20:51:02 +00:00
|
|
|
if (unlikely (status)) {
|
|
|
|
|
if (mime_data != NULL)
|
|
|
|
|
free (mime_data);
|
|
|
|
|
|
2008-11-03 23:45:12 +00:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2009-01-26 20:51:02 +00:00
|
|
|
}
|
2008-11-03 23:45:12 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
slim_hidden_def (cairo_surface_set_mime_data);
|
|
|
|
|
|
2009-02-13 12:56:46 +00:00
|
|
|
static void
|
2009-02-18 18:43:29 -05:00
|
|
|
_cairo_mime_data_reference (const void *key, void *elt, void *closure)
|
2009-02-13 12:56:46 +00:00
|
|
|
{
|
|
|
|
|
cairo_mime_data_t *mime_data = elt;
|
|
|
|
|
|
|
|
|
|
_cairo_reference_count_inc (&mime_data->ref_count);
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-03 23:45:12 +00:00
|
|
|
cairo_status_t
|
|
|
|
|
_cairo_surface_copy_mime_data (cairo_surface_t *dst,
|
2009-02-13 12:56:46 +00:00
|
|
|
cairo_surface_t *src)
|
2008-11-03 23:45:12 +00:00
|
|
|
{
|
|
|
|
|
cairo_status_t status;
|
|
|
|
|
|
|
|
|
|
if (dst->status)
|
|
|
|
|
return dst->status;
|
|
|
|
|
|
|
|
|
|
if (src->status)
|
|
|
|
|
return _cairo_surface_set_error (dst, src->status);
|
|
|
|
|
|
2009-02-13 12:56:46 +00:00
|
|
|
/* first copy the mime-data, discarding any already set on dst */
|
|
|
|
|
status = _cairo_user_data_array_copy (&dst->mime_data, &src->mime_data);
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2008-11-03 23:45:12 +00:00
|
|
|
return _cairo_surface_set_error (dst, status);
|
|
|
|
|
|
2009-02-13 12:56:46 +00:00
|
|
|
/* now increment the reference counters for the copies */
|
|
|
|
|
_cairo_user_data_array_foreach (&dst->mime_data,
|
|
|
|
|
_cairo_mime_data_reference,
|
|
|
|
|
NULL);
|
2008-11-03 11:01:22 +00:00
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2008-09-07 20:46:20 +09:30
|
|
|
}
|
|
|
|
|
|
2006-07-31 14:44:42 -04:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_set_font_options:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @options: a #cairo_font_options_t object that contains the
|
|
|
|
|
* options to use for this surface instead of backend's default
|
|
|
|
|
* font options.
|
|
|
|
|
*
|
|
|
|
|
* Sets the default font rendering options for the surface.
|
|
|
|
|
* This is useful to correctly propagate default font options when
|
|
|
|
|
* falling back to an image surface in a backend implementation.
|
|
|
|
|
* This affects the options returned in cairo_surface_get_font_options().
|
|
|
|
|
*
|
|
|
|
|
* If @options is %NULL the surface options are reset to those of
|
|
|
|
|
* the backend default.
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
_cairo_surface_set_font_options (cairo_surface_t *surface,
|
|
|
|
|
cairo_font_options_t *options)
|
|
|
|
|
{
|
2007-10-29 12:04:33 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
|
|
|
|
if (surface->status)
|
|
|
|
|
return;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2007-10-29 12:04:33 +00:00
|
|
|
if (surface->finished) {
|
|
|
|
|
status = _cairo_surface_set_error (surface,
|
2010-07-05 22:41:43 +02:00
|
|
|
_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
|
2007-10-29 12:04:33 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2006-07-31 14:44:42 -04:00
|
|
|
if (options) {
|
|
|
|
|
surface->has_font_options = TRUE;
|
|
|
|
|
_cairo_font_options_init_copy (&surface->font_options, options);
|
|
|
|
|
} else {
|
|
|
|
|
surface->has_font_options = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-07-21 06:52:13 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_font_options:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @options: a #cairo_font_options_t object into which to store
|
|
|
|
|
* the retrieved options. All existing values are overwritten
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-07-21 06:52:13 +00:00
|
|
|
* Retrieves the default font rendering options for the surface.
|
|
|
|
|
* This allows display surfaces to report the correct subpixel order
|
|
|
|
|
* for rendering on them, print surfaces to disable hinting of
|
|
|
|
|
* metrics and so forth. The result can then be used with
|
|
|
|
|
* cairo_scaled_font_create().
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_get_font_options (cairo_surface_t *surface,
|
|
|
|
|
cairo_font_options_t *options)
|
|
|
|
|
{
|
2007-05-08 17:26:22 +01:00
|
|
|
if (cairo_font_options_status (options))
|
|
|
|
|
return;
|
|
|
|
|
|
2008-08-12 21:21:20 +01:00
|
|
|
if (surface->status) {
|
|
|
|
|
_cairo_font_options_init_default (options);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! surface->has_font_options) {
|
2006-07-31 14:44:42 -04:00
|
|
|
surface->has_font_options = TRUE;
|
|
|
|
|
|
2007-04-12 20:14:23 -04:00
|
|
|
_cairo_font_options_init_default (&surface->font_options);
|
|
|
|
|
|
2006-07-31 14:44:42 -04:00
|
|
|
if (!surface->finished && surface->backend->get_font_options) {
|
|
|
|
|
surface->backend->get_font_options (surface, &surface->font_options);
|
|
|
|
|
}
|
2005-07-21 06:52:13 +00:00
|
|
|
}
|
2006-07-31 14:44:42 -04:00
|
|
|
|
|
|
|
|
_cairo_font_options_init_copy (options, &surface->font_options);
|
2005-07-21 06:52:13 +00:00
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_get_font_options);
|
2005-07-21 06:52:13 +00:00
|
|
|
|
2005-08-01 11:45:42 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_flush:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-01 11:45:42 +00:00
|
|
|
* Do any pending drawing for the surface and also restore any
|
2010-05-28 17:19:45 +02:00
|
|
|
* temporary modifications cairo has made to the surface's
|
2005-08-01 11:45:42 +00:00
|
|
|
* state. This function must be called before switching from
|
|
|
|
|
* drawing on the surface with cairo to drawing on it directly
|
|
|
|
|
* with native APIs. If the surface doesn't support direct access,
|
|
|
|
|
* then this function does nothing.
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_flush (cairo_surface_t *surface)
|
|
|
|
|
{
|
2007-10-04 13:15:46 +01:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2005-08-19 12:08:42 +00:00
|
|
|
if (surface->status)
|
2005-08-01 11:45:42 +00:00
|
|
|
return;
|
|
|
|
|
|
2008-05-16 21:59:45 -04:00
|
|
|
if (surface->finished)
|
2005-08-01 11:45:42 +00:00
|
|
|
return;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
/* update the current snapshots *before* the user updates the surface */
|
|
|
|
|
_cairo_surface_detach_snapshots (surface);
|
|
|
|
|
|
2005-08-01 11:45:42 +00:00
|
|
|
if (surface->backend->flush) {
|
|
|
|
|
status = surface->backend->flush (surface);
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2007-10-04 13:15:46 +01:00
|
|
|
status = _cairo_surface_set_error (surface, status);
|
2005-08-01 11:45:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
2008-05-24 20:31:24 -04:00
|
|
|
slim_hidden_def (cairo_surface_flush);
|
2005-08-01 11:45:42 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* cairo_surface_mark_dirty:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
*
|
|
|
|
|
* Tells cairo that drawing has been done to surface using means other
|
|
|
|
|
* than cairo, and that cairo should reread any cached areas. Note
|
|
|
|
|
* that you must call cairo_surface_flush() before doing such drawing.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_mark_dirty (cairo_surface_t *surface)
|
|
|
|
|
{
|
|
|
|
|
cairo_surface_mark_dirty_rectangle (surface, 0, 0, -1, -1);
|
|
|
|
|
}
|
2010-01-15 13:44:04 +01:00
|
|
|
slim_hidden_def (cairo_surface_mark_dirty);
|
2005-08-01 11:45:42 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* cairo_surface_mark_dirty_rectangle:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @x: X coordinate of dirty rectangle
|
|
|
|
|
* @y: Y coordinate of dirty rectangle
|
|
|
|
|
* @width: width of dirty rectangle
|
|
|
|
|
* @height: height of dirty rectangle
|
|
|
|
|
*
|
|
|
|
|
* Like cairo_surface_mark_dirty(), but drawing has been done only to
|
|
|
|
|
* the specified rectangle, so that cairo can retain cached contents
|
|
|
|
|
* for other parts of the surface.
|
2006-02-15 13:14:52 -08:00
|
|
|
*
|
|
|
|
|
* Any cached clip set on the surface will be reset by this function,
|
|
|
|
|
* to make sure that future cairo calls have the clip set that they
|
|
|
|
|
* expect.
|
2005-08-01 11:45:42 +00:00
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
|
|
|
|
int x,
|
|
|
|
|
int y,
|
|
|
|
|
int width,
|
|
|
|
|
int height)
|
|
|
|
|
{
|
2007-10-04 13:15:46 +01:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2005-08-19 12:08:42 +00:00
|
|
|
if (surface->status)
|
2005-08-01 11:45:42 +00:00
|
|
|
return;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2005-08-01 11:45:42 +00:00
|
|
|
if (surface->finished) {
|
2010-07-05 22:41:43 +02:00
|
|
|
status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
|
2005-08-01 11:45:42 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
/* The application *should* have called cairo_surface_flush() before
|
|
|
|
|
* modifying the surface independently of cairo (and thus having to
|
|
|
|
|
* call mark_dirty()). */
|
|
|
|
|
assert (! _cairo_surface_has_snapshots (surface));
|
2010-01-25 18:17:28 +00:00
|
|
|
assert (! _cairo_surface_has_mime_data (surface));
|
2009-05-26 21:07:07 +01:00
|
|
|
|
2009-10-21 09:04:30 +01:00
|
|
|
surface->is_clear = FALSE;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->mark_dirty_rectangle != NULL) {
|
2006-06-10 00:12:51 -07:00
|
|
|
/* XXX: FRAGILE: We're ignoring the scaling component of
|
|
|
|
|
* device_transform here. I don't know what the right thing to
|
|
|
|
|
* do would actually be if there were some scaling here, but
|
|
|
|
|
* we avoid this since device_transfom scaling is not exported
|
|
|
|
|
* publicly and mark_dirty is not used internally. */
|
2006-05-04 01:45:41 -07:00
|
|
|
status = surface->backend->mark_dirty_rectangle (surface,
|
2006-06-10 00:12:51 -07:00
|
|
|
x + surface->device_transform.x0,
|
|
|
|
|
y + surface->device_transform.y0,
|
2006-05-04 01:45:41 -07:00
|
|
|
width, height);
|
2006-06-06 15:25:49 -07:00
|
|
|
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2007-10-04 13:15:46 +01:00
|
|
|
status = _cairo_surface_set_error (surface, status);
|
2005-08-01 11:45:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_mark_dirty_rectangle);
|
2005-08-01 11:45:42 +00:00
|
|
|
|
2006-06-10 08:19:41 -07:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_set_device_scale:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @sx: a scale factor in the X direction
|
|
|
|
|
* @sy: a scale factor in the Y direction
|
|
|
|
|
*
|
|
|
|
|
* Private function for setting an extra scale factor to affect all
|
|
|
|
|
* drawing to a surface. This is used, for example, when replaying a
|
2009-10-22 02:13:36 +03:00
|
|
|
* recording surface to an image fallback intended for an eventual
|
|
|
|
|
* vector-oriented backend. Since the recording surface will record
|
2006-06-10 08:19:41 -07:00
|
|
|
* coordinates in one backend space, but the image fallback uses a
|
|
|
|
|
* different backend space, (differing by the fallback resolution
|
|
|
|
|
* scale factors), we need a scale factor correction.
|
|
|
|
|
*
|
2008-05-09 12:59:07 +02:00
|
|
|
* Caution: Not all places we use device transform correctly handle
|
|
|
|
|
* both a translate and a scale. An audit would be nice.
|
2006-06-10 08:19:41 -07:00
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
_cairo_surface_set_device_scale (cairo_surface_t *surface,
|
|
|
|
|
double sx,
|
|
|
|
|
double sy)
|
|
|
|
|
{
|
2007-10-04 13:15:46 +01:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2006-06-10 08:19:41 -07:00
|
|
|
if (surface->status)
|
|
|
|
|
return;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2006-06-10 08:19:41 -07:00
|
|
|
if (surface->finished) {
|
2010-07-05 22:41:43 +02:00
|
|
|
status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
|
2006-06-10 08:19:41 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
|
|
|
|
|
2006-06-10 08:19:41 -07:00
|
|
|
surface->device_transform.xx = sx;
|
|
|
|
|
surface->device_transform.yy = sy;
|
2008-05-09 13:00:28 +02:00
|
|
|
surface->device_transform.xy = 0.0;
|
|
|
|
|
surface->device_transform.yx = 0.0;
|
2006-06-29 19:47:26 +02:00
|
|
|
|
2008-09-28 15:57:37 +01:00
|
|
|
surface->device_transform_inverse = surface->device_transform;
|
2008-09-29 16:37:35 +01:00
|
|
|
status = cairo_matrix_invert (&surface->device_transform_inverse);
|
|
|
|
|
/* should always be invertible unless given pathological input */
|
|
|
|
|
assert (status == CAIRO_STATUS_SUCCESS);
|
2010-06-11 16:04:41 +01:00
|
|
|
|
|
|
|
|
_cairo_observers_notify (&surface->device_transform_observers, surface);
|
2006-06-10 08:19:41 -07:00
|
|
|
}
|
|
|
|
|
|
2005-03-17 12:57:42 +00:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_set_device_offset:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @x_offset: the offset in the X direction, in device units
|
|
|
|
|
* @y_offset: the offset in the Y direction, in device units
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-03-17 12:57:42 +00:00
|
|
|
* Sets an offset that is added to the device coordinates determined
|
|
|
|
|
* by the CTM when drawing to @surface. One use case for this function
|
|
|
|
|
* is when we want to create a #cairo_surface_t that redirects drawing
|
|
|
|
|
* for a portion of an onscreen surface to an offscreen surface in a
|
|
|
|
|
* way that is completely invisible to the user of the cairo
|
|
|
|
|
* API. Setting a transformation via cairo_translate() isn't
|
|
|
|
|
* sufficient to do this, since functions like
|
2005-05-06 21:19:49 +00:00
|
|
|
* cairo_device_to_user() will expose the hidden offset.
|
2005-03-17 12:57:42 +00:00
|
|
|
*
|
2006-05-24 17:24:52 -07:00
|
|
|
* Note that the offset affects drawing to the surface as well as
|
|
|
|
|
* using the surface in a source pattern.
|
2005-03-17 12:57:42 +00:00
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_set_device_offset (cairo_surface_t *surface,
|
|
|
|
|
double x_offset,
|
|
|
|
|
double y_offset)
|
|
|
|
|
{
|
2007-10-04 13:15:46 +01:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2005-08-19 12:08:42 +00:00
|
|
|
if (surface->status)
|
2005-07-27 15:39:34 +00:00
|
|
|
return;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2005-07-27 15:39:34 +00:00
|
|
|
if (surface->finished) {
|
2010-07-05 22:41:43 +02:00
|
|
|
status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
|
2005-07-27 15:39:34 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
|
|
|
|
|
2006-06-10 00:12:51 -07:00
|
|
|
surface->device_transform.x0 = x_offset;
|
|
|
|
|
surface->device_transform.y0 = y_offset;
|
2006-06-29 19:47:26 +02:00
|
|
|
|
2008-09-28 15:57:37 +01:00
|
|
|
surface->device_transform_inverse = surface->device_transform;
|
2008-09-29 16:37:35 +01:00
|
|
|
status = cairo_matrix_invert (&surface->device_transform_inverse);
|
|
|
|
|
/* should always be invertible unless given pathological input */
|
|
|
|
|
assert (status == CAIRO_STATUS_SUCCESS);
|
2010-06-11 16:04:41 +01:00
|
|
|
|
|
|
|
|
_cairo_observers_notify (&surface->device_transform_observers, surface);
|
2006-05-04 01:45:41 -07:00
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_set_device_offset);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_device_offset:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @x_offset: the offset in the X direction, in device units
|
|
|
|
|
* @y_offset: the offset in the Y direction, in device units
|
|
|
|
|
*
|
2006-06-30 01:33:14 +02:00
|
|
|
* This function returns the previous device offset set by
|
2006-05-04 01:45:41 -07:00
|
|
|
* cairo_surface_set_device_offset().
|
|
|
|
|
*
|
2006-06-29 18:36:53 +02:00
|
|
|
* Since: 1.2
|
2006-05-04 01:45:41 -07:00
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_get_device_offset (cairo_surface_t *surface,
|
|
|
|
|
double *x_offset,
|
|
|
|
|
double *y_offset)
|
|
|
|
|
{
|
2007-03-15 22:38:42 -07:00
|
|
|
if (x_offset)
|
|
|
|
|
*x_offset = surface->device_transform.x0;
|
|
|
|
|
if (y_offset)
|
|
|
|
|
*y_offset = surface->device_transform.y0;
|
2006-05-04 01:45:41 -07:00
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_get_device_offset);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2006-06-09 16:52:17 -07:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_set_fallback_resolution:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @x_pixels_per_inch: horizontal setting for pixels per inch
|
|
|
|
|
* @y_pixels_per_inch: vertical setting for pixels per inch
|
|
|
|
|
*
|
|
|
|
|
* Set the horizontal and vertical resolution for image fallbacks.
|
|
|
|
|
*
|
|
|
|
|
* When certain operations aren't supported natively by a backend,
|
|
|
|
|
* cairo will fallback by rendering operations to an image and then
|
|
|
|
|
* overlaying that image onto the output. For backends that are
|
|
|
|
|
* natively vector-oriented, this function can be used to set the
|
|
|
|
|
* resolution used for these image fallbacks, (larger values will
|
|
|
|
|
* result in more detailed images, but also larger file sizes).
|
|
|
|
|
*
|
|
|
|
|
* Some examples of natively vector-oriented backends are the ps, pdf,
|
|
|
|
|
* and svg backends.
|
|
|
|
|
*
|
|
|
|
|
* For backends that are natively raster-oriented, image fallbacks are
|
|
|
|
|
* still possible, but they are always performed at the native
|
|
|
|
|
* device resolution. So this function has no effect on those
|
|
|
|
|
* backends.
|
2006-06-10 09:44:30 -07:00
|
|
|
*
|
2008-01-28 21:53:44 -05:00
|
|
|
* Note: The fallback resolution only takes effect at the time of
|
2006-06-10 09:44:30 -07:00
|
|
|
* completing a page (with cairo_show_page() or cairo_copy_page()) so
|
|
|
|
|
* there is currently no way to have more than one fallback resolution
|
|
|
|
|
* in effect on a single page.
|
2006-06-29 18:36:53 +02:00
|
|
|
*
|
2008-04-06 02:47:32 -07:00
|
|
|
* The default fallback resoultion is 300 pixels per inch in both
|
|
|
|
|
* dimensions.
|
|
|
|
|
*
|
2006-06-29 18:36:53 +02:00
|
|
|
* Since: 1.2
|
2006-06-09 16:52:17 -07:00
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_set_fallback_resolution (cairo_surface_t *surface,
|
|
|
|
|
double x_pixels_per_inch,
|
|
|
|
|
double y_pixels_per_inch)
|
|
|
|
|
{
|
2007-10-05 09:44:29 +01:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
|
|
|
|
if (surface->status)
|
|
|
|
|
return;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2007-10-05 09:44:29 +01:00
|
|
|
if (surface->finished) {
|
2010-07-05 22:41:43 +02:00
|
|
|
status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
|
2007-10-05 09:44:29 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-05 15:11:00 +01:00
|
|
|
if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) {
|
|
|
|
|
/* XXX Could delay raising the error until we fallback, but throwing
|
|
|
|
|
* the error here means that we can catch the real culprit.
|
|
|
|
|
*/
|
|
|
|
|
status = _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
|
|
|
|
|
2006-06-09 16:52:17 -07:00
|
|
|
surface->x_fallback_resolution = x_pixels_per_inch;
|
|
|
|
|
surface->y_fallback_resolution = y_pixels_per_inch;
|
|
|
|
|
}
|
2006-09-05 16:48:49 -07:00
|
|
|
slim_hidden_def (cairo_surface_set_fallback_resolution);
|
2006-06-09 16:52:17 -07:00
|
|
|
|
2008-05-15 17:19:53 -04:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_get_fallback_resolution:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @x_pixels_per_inch: horizontal pixels per inch
|
|
|
|
|
* @y_pixels_per_inch: vertical pixels per inch
|
|
|
|
|
*
|
|
|
|
|
* This function returns the previous fallback resolution set by
|
|
|
|
|
* cairo_surface_set_fallback_resolution(), or default fallback
|
|
|
|
|
* resolution if never set.
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.8
|
|
|
|
|
**/
|
|
|
|
|
void
|
|
|
|
|
cairo_surface_get_fallback_resolution (cairo_surface_t *surface,
|
|
|
|
|
double *x_pixels_per_inch,
|
|
|
|
|
double *y_pixels_per_inch)
|
|
|
|
|
{
|
|
|
|
|
if (x_pixels_per_inch)
|
|
|
|
|
*x_pixels_per_inch = surface->x_fallback_resolution;
|
|
|
|
|
if (y_pixels_per_inch)
|
|
|
|
|
*y_pixels_per_inch = surface->y_fallback_resolution;
|
|
|
|
|
}
|
|
|
|
|
|
2006-05-04 01:45:41 -07:00
|
|
|
cairo_bool_t
|
2006-06-10 00:12:51 -07:00
|
|
|
_cairo_surface_has_device_transform (cairo_surface_t *surface)
|
2006-05-04 01:45:41 -07:00
|
|
|
{
|
2006-06-10 00:12:51 -07:00
|
|
|
return ! _cairo_matrix_is_identity (&surface->device_transform);
|
2005-03-17 12:57:42 +00:00
|
|
|
}
|
|
|
|
|
|
2005-01-31 08:50:22 +00:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_acquire_source_image:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2005-08-21 08:24:41 +00:00
|
|
|
* @image_out: location to store a pointer to an image surface that
|
|
|
|
|
* has identical contents to @surface. This surface could be @surface
|
|
|
|
|
* itself, a surface held internal to @surface, or it could be a new
|
|
|
|
|
* surface with a copy of the relevant portion of @surface.
|
2005-01-31 08:50:22 +00:00
|
|
|
* @image_extra: location to store image specific backend data
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-01-31 08:50:22 +00:00
|
|
|
* Gets an image surface to use when drawing as a fallback when drawing with
|
|
|
|
|
* @surface as a source. _cairo_surface_release_source_image() must be called
|
|
|
|
|
* when finished.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2007-12-20 17:51:48 +00:00
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS if an image was stored in @image_out.
|
2005-01-31 08:50:22 +00:00
|
|
|
* %CAIRO_INT_STATUS_UNSUPPORTED if an image cannot be retrieved for the specified
|
|
|
|
|
* surface. Or %CAIRO_STATUS_NO_MEMORY.
|
|
|
|
|
**/
|
2005-07-15 13:59:47 +00:00
|
|
|
cairo_status_t
|
2005-01-31 08:50:22 +00:00
|
|
|
_cairo_surface_acquire_source_image (cairo_surface_t *surface,
|
|
|
|
|
cairo_image_surface_t **image_out,
|
|
|
|
|
void **image_extra)
|
2003-07-30 08:30:50 +00:00
|
|
|
{
|
2009-05-15 17:40:26 +01:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2008-02-19 15:14:37 +00:00
|
|
|
if (surface->status)
|
|
|
|
|
return surface->status;
|
|
|
|
|
|
2008-10-17 10:35:38 +01:00
|
|
|
assert (!surface->finished);
|
|
|
|
|
|
2007-12-20 17:51:48 +00:00
|
|
|
if (surface->backend->acquire_source_image == NULL)
|
|
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
|
|
|
|
2009-05-15 17:40:26 +01:00
|
|
|
status = surface->backend->acquire_source_image (surface,
|
|
|
|
|
image_out, image_extra);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return _cairo_surface_set_error (surface, status);
|
|
|
|
|
|
|
|
|
|
_cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2003-07-30 08:30:50 +00:00
|
|
|
}
|
|
|
|
|
|
2010-11-21 23:25:21 +10:30
|
|
|
cairo_status_t
|
|
|
|
|
_cairo_surface_acquire_source_image_transformed (cairo_surface_t *surface,
|
|
|
|
|
cairo_matrix_t *device_transform,
|
|
|
|
|
cairo_image_surface_t **image_out,
|
|
|
|
|
void **image_extra)
|
|
|
|
|
{
|
|
|
|
|
cairo_status_t status;
|
|
|
|
|
|
|
|
|
|
if (surface->status)
|
|
|
|
|
return surface->status;
|
|
|
|
|
|
|
|
|
|
assert (!surface->finished);
|
|
|
|
|
|
|
|
|
|
if (surface->backend->acquire_source_image_transformed == NULL)
|
|
|
|
|
return _cairo_surface_acquire_source_image (surface,
|
|
|
|
|
image_out, image_extra);
|
|
|
|
|
|
|
|
|
|
status = surface->backend->acquire_source_image_transformed (surface, device_transform,
|
|
|
|
|
image_out, image_extra);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return _cairo_surface_set_error (surface, status);
|
|
|
|
|
|
|
|
|
|
_cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-31 08:50:22 +00:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_release_source_image:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2005-08-21 08:24:41 +00:00
|
|
|
* @image_extra: same as return from the matching _cairo_surface_acquire_source_image()
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-01-31 08:50:22 +00:00
|
|
|
* Releases any resources obtained with _cairo_surface_acquire_source_image()
|
|
|
|
|
**/
|
2005-07-15 13:59:47 +00:00
|
|
|
void
|
2005-01-31 08:50:22 +00:00
|
|
|
_cairo_surface_release_source_image (cairo_surface_t *surface,
|
|
|
|
|
cairo_image_surface_t *image,
|
|
|
|
|
void *image_extra)
|
|
|
|
|
{
|
2005-03-16 12:08:41 +00:00
|
|
|
assert (!surface->finished);
|
|
|
|
|
|
2005-04-07 14:25:00 +00:00
|
|
|
if (surface->backend->release_source_image)
|
|
|
|
|
surface->backend->release_source_image (surface, image, image_extra);
|
2005-01-31 08:50:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* _cairo_surface_acquire_dest_image:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @interest_rect: area of @surface for which fallback drawing is being done.
|
|
|
|
|
* A value of %NULL indicates that the entire surface is desired.
|
2008-01-28 20:48:48 -05:00
|
|
|
* XXXX I'd like to get rid of being able to pass %NULL here (nothing seems to)
|
2005-01-31 08:50:22 +00:00
|
|
|
* @image_out: location to store a pointer to an image surface that includes at least
|
|
|
|
|
* the intersection of @interest_rect with the visible area of @surface.
|
|
|
|
|
* This surface could be @surface itself, a surface held internal to @surface,
|
|
|
|
|
* or it could be a new surface with a copy of the relevant portion of @surface.
|
2005-08-21 08:24:41 +00:00
|
|
|
* If a new surface is created, it should have the same channels and depth
|
|
|
|
|
* as @surface so that copying to and from it is exact.
|
2006-06-06 15:35:48 -07:00
|
|
|
* @image_rect: location to store area of the original surface occupied
|
2005-01-31 08:50:22 +00:00
|
|
|
* by the surface stored in @image.
|
|
|
|
|
* @image_extra: location to store image specific backend data
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-01-31 08:50:22 +00:00
|
|
|
* Retrieves a local image for a surface for implementing a fallback drawing
|
|
|
|
|
* operation. After calling this function, the implementation of the fallback
|
|
|
|
|
* drawing operation draws the primitive to the surface stored in @image_out
|
2005-08-21 08:24:41 +00:00
|
|
|
* then calls _cairo_surface_release_dest_image(),
|
2005-01-31 08:50:22 +00:00
|
|
|
* which, if a temporary surface was created, copies the bits back to the
|
|
|
|
|
* main surface and frees the temporary surface.
|
2005-08-21 08:24:41 +00:00
|
|
|
*
|
2005-01-31 08:50:22 +00:00
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY.
|
|
|
|
|
* %CAIRO_INT_STATUS_UNSUPPORTED can be returned but this will mean that
|
|
|
|
|
* the backend can't draw with fallbacks. It's possible for the routine
|
2008-01-28 20:48:48 -05:00
|
|
|
* to store %NULL in @local_out and return %CAIRO_STATUS_SUCCESS;
|
2005-01-31 08:50:22 +00:00
|
|
|
* that indicates that no part of @interest_rect is visible, so no drawing
|
2005-08-21 08:24:41 +00:00
|
|
|
* is necessary. _cairo_surface_release_dest_image() should not be called in that
|
2005-01-31 08:50:22 +00:00
|
|
|
* case.
|
|
|
|
|
**/
|
2003-10-31 10:41:37 +00:00
|
|
|
cairo_status_t
|
2005-01-31 08:50:22 +00:00
|
|
|
_cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t *interest_rect,
|
2005-01-31 08:50:22 +00:00
|
|
|
cairo_image_surface_t **image_out,
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t *image_rect,
|
2005-01-31 08:50:22 +00:00
|
|
|
void **image_extra)
|
|
|
|
|
{
|
2009-05-15 17:40:26 +01:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2008-02-19 15:14:37 +00:00
|
|
|
if (surface->status)
|
|
|
|
|
return surface->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (surface));
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2007-12-20 17:51:48 +00:00
|
|
|
if (surface->backend->acquire_dest_image == NULL)
|
|
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
|
|
|
|
2009-05-15 17:40:26 +01:00
|
|
|
status = surface->backend->acquire_dest_image (surface,
|
|
|
|
|
interest_rect,
|
|
|
|
|
image_out,
|
|
|
|
|
image_rect,
|
|
|
|
|
image_extra);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return _cairo_surface_set_error (surface, status);
|
|
|
|
|
|
|
|
|
|
_cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2005-01-31 08:50:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2005-08-21 08:24:41 +00:00
|
|
|
* _cairo_surface_release_dest_image:
|
2005-01-31 08:50:22 +00:00
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @interest_rect: same as passed to the matching _cairo_surface_acquire_dest_image()
|
|
|
|
|
* @image: same as returned from the matching _cairo_surface_acquire_dest_image()
|
|
|
|
|
* @image_rect: same as returned from the matching _cairo_surface_acquire_dest_image()
|
|
|
|
|
* @image_extra: same as return from the matching _cairo_surface_acquire_dest_image()
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-01-31 08:50:22 +00:00
|
|
|
* Finishes the operation started with _cairo_surface_acquire_dest_image(), by, if
|
|
|
|
|
* necessary, copying the image from @image back to @surface and freeing any
|
|
|
|
|
* resources that were allocated.
|
|
|
|
|
**/
|
|
|
|
|
void
|
2006-05-04 03:43:34 -07:00
|
|
|
_cairo_surface_release_dest_image (cairo_surface_t *surface,
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t *interest_rect,
|
2006-05-04 03:43:34 -07:00
|
|
|
cairo_image_surface_t *image,
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t *image_rect,
|
2006-05-04 03:43:34 -07:00
|
|
|
void *image_extra)
|
2003-07-30 08:30:50 +00:00
|
|
|
{
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (surface));
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2005-04-07 14:25:00 +00:00
|
|
|
if (surface->backend->release_dest_image)
|
|
|
|
|
surface->backend->release_dest_image (surface, interest_rect,
|
|
|
|
|
image, image_rect, image_extra);
|
2005-01-31 08:50:22 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-04 14:07:16 +01:00
|
|
|
static cairo_status_t
|
2009-10-22 02:13:36 +03:00
|
|
|
_cairo_recording_surface_clone_similar (cairo_surface_t *surface,
|
|
|
|
|
cairo_surface_t *src,
|
|
|
|
|
int src_x,
|
|
|
|
|
int src_y,
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
|
|
|
|
int *clone_offset_x,
|
|
|
|
|
int *clone_offset_y,
|
|
|
|
|
cairo_surface_t **clone_out)
|
|
|
|
|
{
|
|
|
|
|
cairo_recording_surface_t *recorder = (cairo_recording_surface_t *) src;
|
2009-07-04 14:07:16 +01:00
|
|
|
cairo_surface_t *similar;
|
|
|
|
|
cairo_status_t status;
|
|
|
|
|
|
2010-01-18 19:12:25 +00:00
|
|
|
similar = _cairo_surface_has_snapshot (src, surface->backend);
|
2009-07-04 14:07:16 +01:00
|
|
|
if (similar != NULL) {
|
|
|
|
|
*clone_out = cairo_surface_reference (similar);
|
|
|
|
|
*clone_offset_x = 0;
|
|
|
|
|
*clone_offset_y = 0;
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-22 02:13:36 +03:00
|
|
|
if (recorder->unbounded ||
|
|
|
|
|
width*height*8 < recorder->extents.width*recorder->extents.height)
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
{
|
2010-04-30 20:14:54 +02:00
|
|
|
similar = _cairo_surface_create_similar_solid (surface,
|
|
|
|
|
src->content,
|
|
|
|
|
width, height,
|
|
|
|
|
CAIRO_COLOR_TRANSPARENT,
|
|
|
|
|
FALSE);
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (similar == NULL)
|
|
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
|
|
|
if (unlikely (similar->status))
|
|
|
|
|
return similar->status;
|
2009-07-04 14:07:16 +01:00
|
|
|
|
|
|
|
|
cairo_surface_set_device_offset (similar, -src_x, -src_y);
|
|
|
|
|
|
2009-10-22 02:13:36 +03:00
|
|
|
status = _cairo_recording_surface_replay (src, similar);
|
2009-07-04 14:07:16 +01:00
|
|
|
if (unlikely (status)) {
|
|
|
|
|
cairo_surface_destroy (similar);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
similar = _cairo_surface_create_similar_scratch (surface,
|
2009-10-16 10:11:41 +01:00
|
|
|
src->content,
|
2009-10-22 02:13:36 +03:00
|
|
|
recorder->extents.width,
|
|
|
|
|
recorder->extents.height);
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (similar == NULL)
|
|
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
|
|
|
if (unlikely (similar->status))
|
|
|
|
|
return similar->status;
|
2009-07-04 14:07:16 +01:00
|
|
|
|
2009-10-22 02:13:36 +03:00
|
|
|
status = _cairo_recording_surface_replay (src, similar);
|
2009-07-04 14:07:16 +01:00
|
|
|
if (unlikely (status)) {
|
|
|
|
|
cairo_surface_destroy (similar);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2010-04-29 15:19:18 +01:00
|
|
|
_cairo_surface_attach_snapshot (src, similar, NULL);
|
2009-07-04 14:07:16 +01:00
|
|
|
|
|
|
|
|
src_x = src_y = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*clone_out = similar;
|
|
|
|
|
*clone_offset_x = src_x;
|
|
|
|
|
*clone_offset_y = src_y;
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-31 08:50:22 +00:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_clone_similar:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
* @src: the source image
|
2009-05-09 10:10:14 +01:00
|
|
|
* @content: target content mask
|
2006-10-18 17:06:23 -07:00
|
|
|
* @src_x: extent for the rectangle in src we actually care about
|
|
|
|
|
* @src_y: extent for the rectangle in src we actually care about
|
|
|
|
|
* @width: extent for the rectangle in src we actually care about
|
|
|
|
|
* @height: extent for the rectangle in src we actually care about
|
2005-01-31 08:50:22 +00:00
|
|
|
* @clone_out: location to store a surface compatible with @surface
|
|
|
|
|
* and with contents identical to @src. The caller must call
|
|
|
|
|
* cairo_surface_destroy() on the result.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-01-31 08:50:22 +00:00
|
|
|
* Creates a surface with contents identical to @src but that
|
|
|
|
|
* can be used efficiently with @surface. If @surface and @src are
|
|
|
|
|
* already compatible then it may return a new reference to @src.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-01-31 08:50:22 +00:00
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS if a surface was created and stored
|
|
|
|
|
* in @clone_out. Otherwise %CAIRO_INT_STATUS_UNSUPPORTED or another
|
|
|
|
|
* error like %CAIRO_STATUS_NO_MEMORY.
|
|
|
|
|
**/
|
|
|
|
|
cairo_status_t
|
|
|
|
|
_cairo_surface_clone_similar (cairo_surface_t *surface,
|
|
|
|
|
cairo_surface_t *src,
|
2006-10-18 17:06:23 -07:00
|
|
|
int src_x,
|
|
|
|
|
int src_y,
|
|
|
|
|
int width,
|
|
|
|
|
int height,
|
2008-09-27 17:24:57 +01:00
|
|
|
int *clone_offset_x,
|
|
|
|
|
int *clone_offset_y,
|
2005-01-31 08:50:22 +00:00
|
|
|
cairo_surface_t **clone_out)
|
|
|
|
|
{
|
2007-08-28 16:47:24 -07:00
|
|
|
cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
|
2005-01-31 08:50:22 +00:00
|
|
|
cairo_image_surface_t *image;
|
|
|
|
|
void *image_extra;
|
2006-06-06 15:25:49 -07:00
|
|
|
|
2008-11-19 14:04:01 +00:00
|
|
|
if (unlikely (surface->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return surface->status;
|
|
|
|
|
|
2008-11-19 14:04:01 +00:00
|
|
|
if (unlikely (surface->finished))
|
2007-10-04 13:15:46 +01:00
|
|
|
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2010-07-30 21:48:14 +02:00
|
|
|
#if CAIRO_HAS_TEE_SURFACE
|
|
|
|
|
|
2009-08-16 18:04:54 +01:00
|
|
|
if (src->type == CAIRO_SURFACE_TYPE_TEE) {
|
|
|
|
|
cairo_surface_t *match;
|
|
|
|
|
|
|
|
|
|
match = _cairo_tee_surface_find_match (src,
|
|
|
|
|
surface->backend,
|
2009-10-16 10:11:41 +01:00
|
|
|
src->content);
|
2009-08-16 18:04:54 +01:00
|
|
|
if (match != NULL)
|
|
|
|
|
src = match;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-30 21:48:14 +02:00
|
|
|
#endif
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->clone_similar != NULL) {
|
2008-09-27 00:18:07 +01:00
|
|
|
status = surface->backend->clone_similar (surface, src,
|
|
|
|
|
src_x, src_y,
|
|
|
|
|
width, height,
|
2008-09-27 17:24:57 +01:00
|
|
|
clone_offset_x,
|
|
|
|
|
clone_offset_y,
|
2008-09-27 00:18:07 +01:00
|
|
|
clone_out);
|
2007-08-28 16:47:24 -07:00
|
|
|
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
2009-05-20 18:46:35 +01:00
|
|
|
if (_cairo_surface_is_image (src))
|
|
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
|
|
|
|
2008-11-19 14:04:01 +00:00
|
|
|
/* First check to see if we can replay to a similar surface */
|
2009-10-22 02:13:36 +03:00
|
|
|
if (_cairo_surface_is_recording (src)) {
|
|
|
|
|
return _cairo_recording_surface_clone_similar (surface, src,
|
|
|
|
|
src_x, src_y,
|
|
|
|
|
width, height,
|
|
|
|
|
clone_offset_x,
|
|
|
|
|
clone_offset_y,
|
|
|
|
|
clone_out);
|
2008-11-19 14:04:01 +00:00
|
|
|
}
|
|
|
|
|
|
2007-08-28 16:47:24 -07:00
|
|
|
/* If we failed, try again with an image surface */
|
|
|
|
|
status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
|
|
|
|
|
if (status == CAIRO_STATUS_SUCCESS) {
|
|
|
|
|
status =
|
|
|
|
|
surface->backend->clone_similar (surface, &image->base,
|
|
|
|
|
src_x, src_y,
|
|
|
|
|
width, height,
|
2008-09-27 17:24:57 +01:00
|
|
|
clone_offset_x,
|
|
|
|
|
clone_offset_y,
|
2007-08-28 16:47:24 -07:00
|
|
|
clone_out);
|
|
|
|
|
|
|
|
|
|
_cairo_surface_release_source_image (src, image, image_extra);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2007-08-28 16:47:24 -07:00
|
|
|
/* If we're still unsupported, hit our fallback path to get a clone */
|
2009-05-20 18:46:35 +01:00
|
|
|
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
2007-08-28 16:47:24 -07:00
|
|
|
status =
|
2008-09-27 00:18:07 +01:00
|
|
|
_cairo_surface_fallback_clone_similar (surface, src,
|
|
|
|
|
src_x, src_y,
|
|
|
|
|
width, height,
|
2008-09-27 17:24:57 +01:00
|
|
|
clone_offset_x,
|
|
|
|
|
clone_offset_y,
|
2008-09-27 00:18:07 +01:00
|
|
|
clone_out);
|
2009-05-20 18:46:35 +01:00
|
|
|
}
|
2005-01-31 08:50:22 +00:00
|
|
|
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2005-01-31 08:50:22 +00:00
|
|
|
return status;
|
2005-10-13 21:00:52 +00:00
|
|
|
|
2007-08-28 16:47:24 -07:00
|
|
|
/* Update the clone's device_transform (which the underlying surface
|
|
|
|
|
* backend knows nothing about) */
|
|
|
|
|
if (*clone_out != src) {
|
2008-09-27 00:18:07 +01:00
|
|
|
(*clone_out)->device_transform = src->device_transform;
|
|
|
|
|
(*clone_out)->device_transform_inverse = src->device_transform_inverse;
|
2008-02-19 15:14:37 +00:00
|
|
|
}
|
2006-06-06 15:25:49 -07:00
|
|
|
|
2011-03-02 18:30:47 +00:00
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2003-07-30 08:30:50 +00:00
|
|
|
}
|
2003-07-18 11:34:19 +00:00
|
|
|
|
2007-05-02 10:00:22 +01:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_is_similar
|
|
|
|
|
* @surface_a: a #cairo_surface_t
|
|
|
|
|
* @surface_b: a #cairo_surface_t
|
|
|
|
|
* @content: a #cairo_content_t
|
|
|
|
|
*
|
|
|
|
|
* Find out whether the given surfaces share the same backend,
|
|
|
|
|
* and if so, whether they can be considered similar.
|
|
|
|
|
*
|
|
|
|
|
* The definition of "similar" depends on the backend. In
|
|
|
|
|
* general, it means that the surface is equivalent to one
|
2008-01-28 21:49:57 -05:00
|
|
|
* that would have been generated by a call to cairo_surface_create_similar().
|
2007-05-02 10:00:22 +01:00
|
|
|
*
|
2008-01-28 20:48:48 -05:00
|
|
|
* Return value: %TRUE if the surfaces are similar.
|
2007-05-02 10:00:22 +01:00
|
|
|
**/
|
|
|
|
|
cairo_bool_t
|
|
|
|
|
_cairo_surface_is_similar (cairo_surface_t *surface_a,
|
2010-04-19 09:51:26 +02:00
|
|
|
cairo_surface_t *surface_b)
|
2007-05-02 10:00:22 +01:00
|
|
|
{
|
|
|
|
|
if (surface_a->backend != surface_b->backend)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (surface_a->backend->is_similar != NULL)
|
2010-04-19 09:51:26 +02:00
|
|
|
return surface_a->backend->is_similar (surface_a, surface_b);
|
2007-05-02 10:00:22 +01:00
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-23 10:08:53 +00:00
|
|
|
cairo_status_t
|
2005-12-16 03:02:35 +00:00
|
|
|
_cairo_surface_composite (cairo_operator_t op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *src,
|
|
|
|
|
const cairo_pattern_t *mask,
|
2003-07-30 08:30:50 +00:00
|
|
|
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,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
unsigned int height,
|
|
|
|
|
cairo_region_t *clip_region)
|
2003-07-18 11:34:19 +00:00
|
|
|
{
|
2003-10-27 18:40:55 +00:00
|
|
|
cairo_int_status_t status;
|
2003-10-31 10:41:37 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (dst->status))
|
2009-05-26 21:07:07 +01:00
|
|
|
return dst->status;
|
|
|
|
|
|
|
|
|
|
assert (_cairo_surface_is_writable (dst));
|
|
|
|
|
|
2005-08-18 15:50:36 +00:00
|
|
|
if (mask) {
|
|
|
|
|
/* These operators aren't interpreted the same way by the backends;
|
|
|
|
|
* they are implemented in terms of other operators in cairo-gstate.c
|
|
|
|
|
*/
|
2005-12-16 03:02:35 +00:00
|
|
|
assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
|
2005-08-18 15:50:36 +00:00
|
|
|
}
|
|
|
|
|
|
2005-04-07 14:25:00 +00:00
|
|
|
if (dst->backend->composite) {
|
2005-12-16 03:02:35 +00:00
|
|
|
status = dst->backend->composite (op,
|
2005-04-07 14:25:00 +00:00
|
|
|
src, mask, dst,
|
2006-05-04 01:45:41 -07:00
|
|
|
src_x, src_y,
|
|
|
|
|
mask_x, mask_y,
|
|
|
|
|
dst_x, dst_y,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
width, height,
|
|
|
|
|
clip_region);
|
2005-04-07 14:25:00 +00:00
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (dst, status);
|
2005-04-07 14:25:00 +00:00
|
|
|
}
|
2003-10-31 10:41:37 +00:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (dst,
|
|
|
|
|
_cairo_surface_fallback_composite (op,
|
2005-12-19 22:45:41 +00:00
|
|
|
src, mask, dst,
|
|
|
|
|
src_x, src_y,
|
|
|
|
|
mask_x, mask_y,
|
|
|
|
|
dst_x, dst_y,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
width, height,
|
|
|
|
|
clip_region));
|
2003-07-18 11:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
2005-08-16 18:22:16 +00:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_fill_region:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2005-12-16 03:02:35 +00:00
|
|
|
* @op: the operator to apply to the region
|
2005-08-16 18:22:16 +00:00
|
|
|
* @color: the source color
|
|
|
|
|
* @region: the region to modify, in backend coordinates
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-16 18:22:16 +00:00
|
|
|
* Applies an operator to a set of rectangles specified as a
|
2007-06-18 18:33:29 -07:00
|
|
|
* #cairo_region_t using a solid color as the source.
|
2005-08-16 18:22:16 +00:00
|
|
|
* See _cairo_surface_fill_rectangles() for full details.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-16 18:22:16 +00:00
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
|
|
|
|
|
**/
|
|
|
|
|
cairo_status_t
|
|
|
|
|
_cairo_surface_fill_region (cairo_surface_t *surface,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
2005-08-16 18:22:16 +00:00
|
|
|
const cairo_color_t *color,
|
2007-06-18 18:33:29 -07:00
|
|
|
cairo_region_t *region)
|
2005-08-16 18:22:16 +00:00
|
|
|
{
|
2009-02-16 05:41:31 -05:00
|
|
|
int num_rects;
|
2007-12-17 13:42:07 +00:00
|
|
|
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
|
2007-11-03 10:41:55 +00:00
|
|
|
cairo_rectangle_int_t *rects = stack_rects;
|
2005-08-16 18:22:16 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
int i;
|
|
|
|
|
|
2008-02-19 15:14:37 +00:00
|
|
|
if (surface->status)
|
|
|
|
|
return surface->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (surface));
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2009-02-17 23:52:18 -05:00
|
|
|
num_rects = cairo_region_num_rectangles (region);
|
2009-02-16 05:41:31 -05:00
|
|
|
if (num_rects == 0)
|
2005-08-16 18:22:16 +00:00
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2006-06-06 15:25:49 -07:00
|
|
|
|
2009-09-10 19:25:14 +01:00
|
|
|
/* catch a common reduction of _cairo_clip_combine_with_surface() */
|
|
|
|
|
if (op == CAIRO_OPERATOR_IN &&
|
2011-01-17 10:25:30 +01:00
|
|
|
surface->content == CAIRO_CONTENT_ALPHA &&
|
|
|
|
|
CAIRO_COLOR_IS_OPAQUE (color))
|
2009-09-10 19:25:14 +01:00
|
|
|
{
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-16 05:41:31 -05:00
|
|
|
if (num_rects > ARRAY_LENGTH (stack_rects)) {
|
|
|
|
|
rects = _cairo_malloc_ab (num_rects,
|
2009-02-15 18:55:17 -05:00
|
|
|
sizeof (cairo_rectangle_int_t));
|
|
|
|
|
if (rects == NULL) {
|
|
|
|
|
return _cairo_surface_set_error (surface,
|
|
|
|
|
_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
2007-11-03 10:41:55 +00:00
|
|
|
}
|
2009-02-15 18:55:17 -05:00
|
|
|
}
|
2005-08-16 18:22:16 +00:00
|
|
|
|
2009-02-16 05:41:31 -05:00
|
|
|
for (i = 0; i < num_rects; i++)
|
2009-02-17 23:52:18 -05:00
|
|
|
cairo_region_get_rectangle (region, i, &rects[i]);
|
2005-08-16 18:22:16 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
status = _cairo_surface_fill_rectangles (surface,
|
|
|
|
|
op, color, rects, num_rects);
|
2007-06-18 18:33:29 -07:00
|
|
|
|
2007-03-14 01:31:58 +00:00
|
|
|
if (rects != stack_rects)
|
|
|
|
|
free (rects);
|
2005-08-16 18:22:16 +00:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2005-08-16 18:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* _cairo_surface_fill_rectangles:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
2005-12-16 03:02:35 +00:00
|
|
|
* @op: the operator to apply to the region
|
2005-08-16 18:22:16 +00:00
|
|
|
* @color: the source color
|
|
|
|
|
* @rects: the rectangles to modify, in backend coordinates
|
|
|
|
|
* @num_rects: the number of rectangles in @rects
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-16 18:22:16 +00:00
|
|
|
* Applies an operator to a set of rectangles using a solid color
|
|
|
|
|
* as the source. Note that even if the operator is an unbounded operator
|
2005-08-18 15:50:36 +00:00
|
|
|
* such as %CAIRO_OPERATOR_IN, only the given set of rectangles
|
2005-08-16 18:22:16 +00:00
|
|
|
* is affected. This differs from _cairo_surface_composite_trapezoids()
|
|
|
|
|
* where the entire destination rectangle is cleared.
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-16 18:22:16 +00:00
|
|
|
* Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
|
|
|
|
|
**/
|
2003-10-31 10:41:37 +00:00
|
|
|
cairo_status_t
|
2003-07-30 08:30:50 +00:00
|
|
|
_cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
2006-05-04 03:43:34 -07:00
|
|
|
cairo_operator_t op,
|
2003-07-30 08:30:50 +00:00
|
|
|
const cairo_color_t *color,
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t *rects,
|
2006-05-04 03:43:34 -07:00
|
|
|
int num_rects)
|
2003-07-30 08:30:50 +00:00
|
|
|
{
|
2003-10-27 18:40:55 +00:00
|
|
|
cairo_int_status_t status;
|
2003-09-30 18:56:22 +00:00
|
|
|
|
2005-07-27 15:39:34 +00:00
|
|
|
if (surface->status)
|
|
|
|
|
return surface->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (surface));
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2003-09-05 15:29:49 +00:00
|
|
|
if (num_rects == 0)
|
2003-10-31 10:41:37 +00:00
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2003-09-05 15:29:49 +00:00
|
|
|
|
2005-04-07 14:25:00 +00:00
|
|
|
if (surface->backend->fill_rectangles) {
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
status = surface->backend->fill_rectangles (surface,
|
|
|
|
|
op, color,
|
2005-04-07 14:25:00 +00:00
|
|
|
rects, num_rects);
|
|
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2005-04-07 14:25:00 +00:00
|
|
|
}
|
2003-10-31 10:41:37 +00:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
_cairo_surface_fallback_fill_rectangles (surface,
|
|
|
|
|
op, color,
|
2007-10-04 20:05:58 +01:00
|
|
|
rects, num_rects));
|
2005-10-27 15:06:53 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
static cairo_status_t
|
|
|
|
|
_pattern_has_error (const cairo_pattern_t *pattern)
|
|
|
|
|
{
|
|
|
|
|
const cairo_surface_pattern_t *spattern;
|
|
|
|
|
|
|
|
|
|
if (unlikely (pattern->status))
|
|
|
|
|
return pattern->status;
|
|
|
|
|
|
|
|
|
|
if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
|
|
spattern = (const cairo_surface_pattern_t *) pattern;
|
|
|
|
|
if (unlikely (spattern->surface->status))
|
|
|
|
|
return spattern->surface->status;
|
|
|
|
|
|
|
|
|
|
if (unlikely (spattern->surface->finished))
|
|
|
|
|
return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
|
|
|
|
|
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2005-10-27 15:06:53 +00:00
|
|
|
cairo_status_t
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
_cairo_surface_paint (cairo_surface_t *surface,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
2008-10-01 20:50:53 +09:30
|
|
|
const cairo_pattern_t *source,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_clip_t *clip)
|
2005-10-27 15:06:53 +00:00
|
|
|
{
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
cairo_status_t status;
|
2005-10-27 15:06:53 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (surface->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return surface->status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (clip && clip->all_clipped)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2010-03-03 20:25:54 +00:00
|
|
|
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2009-10-21 09:04:30 +01:00
|
|
|
|
2010-04-27 18:56:23 +01:00
|
|
|
if (op == CAIRO_OPERATOR_OVER &&
|
|
|
|
|
_cairo_pattern_is_clear (source))
|
|
|
|
|
{
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
status = _pattern_has_error (source);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->paint != NULL) {
|
|
|
|
|
status = surface->backend->paint (surface, op, source, clip);
|
2005-10-27 15:06:53 +00:00
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
2006-05-04 01:45:41 -07:00
|
|
|
goto FINISH;
|
2005-10-27 15:06:53 +00:00
|
|
|
}
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
status = _cairo_surface_fallback_paint (surface, op, source, clip);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2006-06-10 00:12:51 -07:00
|
|
|
FINISH:
|
2010-11-17 18:25:27 +01:00
|
|
|
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
|
|
|
|
|
surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL;
|
2009-10-21 09:04:30 +01:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2005-10-27 17:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_status_t
|
2008-10-22 19:24:44 +01:00
|
|
|
_cairo_surface_mask (cairo_surface_t *surface,
|
|
|
|
|
cairo_operator_t op,
|
|
|
|
|
const cairo_pattern_t *source,
|
2008-10-01 20:50:53 +09:30
|
|
|
const cairo_pattern_t *mask,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_clip_t *clip)
|
2005-10-27 17:16:46 +00:00
|
|
|
{
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
cairo_status_t status;
|
2005-10-27 17:16:46 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (surface->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return surface->status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (clip && clip->all_clipped)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2009-10-21 09:04:30 +01:00
|
|
|
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
|
|
/* If the mask is blank, this is just an expensive no-op */
|
2010-04-03 22:54:57 +02:00
|
|
|
if (_cairo_pattern_is_clear (mask) &&
|
|
|
|
|
_cairo_operator_bounded_by_mask (op))
|
|
|
|
|
{
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2009-10-21 09:04:30 +01:00
|
|
|
}
|
|
|
|
|
|
2010-04-27 18:56:23 +01:00
|
|
|
if (op == CAIRO_OPERATOR_OVER &&
|
|
|
|
|
_cairo_pattern_is_clear (source))
|
|
|
|
|
{
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
status = _pattern_has_error (source);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
status = _pattern_has_error (mask);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
2007-10-04 20:05:58 +01:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->mask != NULL) {
|
|
|
|
|
status = surface->backend->mask (surface, op, source, mask, clip);
|
2005-10-27 17:16:46 +00:00
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
goto FINISH;
|
2005-10-27 17:16:46 +00:00
|
|
|
}
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
status = _cairo_surface_fallback_mask (surface, op, source, mask, clip);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2007-05-08 16:13:08 +01:00
|
|
|
FINISH:
|
2010-11-17 18:25:27 +01:00
|
|
|
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
|
|
|
|
|
surface->is_clear = FALSE;
|
2009-10-21 09:04:30 +01:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2005-10-31 16:55:21 +00:00
|
|
|
}
|
|
|
|
|
|
2007-08-25 20:49:50 +02:00
|
|
|
cairo_status_t
|
|
|
|
|
_cairo_surface_fill_stroke (cairo_surface_t *surface,
|
|
|
|
|
cairo_operator_t fill_op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *fill_source,
|
2007-08-25 20:49:50 +02:00
|
|
|
cairo_fill_rule_t fill_rule,
|
|
|
|
|
double fill_tolerance,
|
|
|
|
|
cairo_antialias_t fill_antialias,
|
|
|
|
|
cairo_path_fixed_t *path,
|
|
|
|
|
cairo_operator_t stroke_op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *stroke_source,
|
2010-01-18 18:20:16 +00:00
|
|
|
const cairo_stroke_style_t *stroke_style,
|
|
|
|
|
const cairo_matrix_t *stroke_ctm,
|
|
|
|
|
const cairo_matrix_t *stroke_ctm_inverse,
|
2007-08-25 20:49:50 +02:00
|
|
|
double stroke_tolerance,
|
2008-10-01 20:50:53 +09:30
|
|
|
cairo_antialias_t stroke_antialias,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_clip_t *clip)
|
2007-08-25 20:49:50 +02:00
|
|
|
{
|
|
|
|
|
cairo_status_t status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (surface->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return surface->status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (clip && clip->all_clipped)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2009-10-21 09:04:30 +01:00
|
|
|
if (surface->is_clear &&
|
|
|
|
|
fill_op == CAIRO_OPERATOR_CLEAR &&
|
|
|
|
|
stroke_op == CAIRO_OPERATOR_CLEAR)
|
|
|
|
|
{
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
status = _pattern_has_error (fill_source);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
|
|
|
|
status = _pattern_has_error (stroke_source);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
|
|
|
|
|
2007-08-25 20:49:50 +02:00
|
|
|
if (surface->backend->fill_stroke) {
|
|
|
|
|
cairo_matrix_t dev_ctm = *stroke_ctm;
|
|
|
|
|
cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
|
|
|
|
|
|
2008-10-22 19:24:44 +01:00
|
|
|
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,
|
2008-10-01 20:50:53 +09:30
|
|
|
stroke_tolerance, stroke_antialias,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
clip);
|
2007-08-25 20:49:50 +02:00
|
|
|
|
|
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
2009-10-21 09:04:30 +01:00
|
|
|
goto FINISH;
|
2007-08-25 20:49:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status = _cairo_surface_fill (surface, fill_op, fill_source, path,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
fill_rule, fill_tolerance, fill_antialias,
|
|
|
|
|
clip);
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2009-10-21 09:04:30 +01:00
|
|
|
goto FINISH;
|
2007-08-25 20:49:50 +02:00
|
|
|
|
|
|
|
|
status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path,
|
|
|
|
|
stroke_style, stroke_ctm, stroke_ctm_inverse,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
stroke_tolerance, stroke_antialias,
|
|
|
|
|
clip);
|
2008-11-18 15:38:37 +00:00
|
|
|
if (unlikely (status))
|
2009-10-21 09:04:30 +01:00
|
|
|
goto FINISH;
|
2007-08-25 20:49:50 +02:00
|
|
|
|
2009-10-21 09:04:30 +01:00
|
|
|
FINISH:
|
2010-11-17 18:25:27 +01:00
|
|
|
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
|
|
|
|
|
surface->is_clear = FALSE;
|
2009-10-21 09:04:30 +01:00
|
|
|
|
|
|
|
|
return _cairo_surface_set_error (surface, status);
|
2007-08-25 20:49:50 +02:00
|
|
|
}
|
|
|
|
|
|
2005-10-31 16:55:21 +00:00
|
|
|
cairo_status_t
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
_cairo_surface_stroke (cairo_surface_t *surface,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *source,
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
cairo_path_fixed_t *path,
|
2010-01-18 18:20:16 +00:00
|
|
|
const cairo_stroke_style_t *stroke_style,
|
|
|
|
|
const cairo_matrix_t *ctm,
|
|
|
|
|
const cairo_matrix_t *ctm_inverse,
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
double tolerance,
|
2008-10-01 20:50:53 +09:30
|
|
|
cairo_antialias_t antialias,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_clip_t *clip)
|
2005-10-31 16:55:21 +00:00
|
|
|
{
|
2006-05-04 01:45:41 -07:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (surface->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return surface->status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (clip && clip->all_clipped)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2009-10-21 09:04:30 +01:00
|
|
|
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2010-04-27 18:56:23 +01:00
|
|
|
if (op == CAIRO_OPERATOR_OVER &&
|
|
|
|
|
_cairo_pattern_is_clear (source))
|
|
|
|
|
{
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
status = _pattern_has_error (source);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->stroke != NULL) {
|
2008-10-22 19:24:44 +01:00
|
|
|
status = surface->backend->stroke (surface, op, source,
|
2006-06-29 19:47:26 +02:00
|
|
|
path, stroke_style,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
ctm, ctm_inverse,
|
|
|
|
|
tolerance, antialias,
|
|
|
|
|
clip);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2005-10-31 16:55:21 +00:00
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
2006-05-04 01:45:41 -07:00
|
|
|
goto FINISH;
|
2005-10-31 16:55:21 +00:00
|
|
|
}
|
|
|
|
|
|
2008-10-22 19:24:44 +01:00
|
|
|
status = _cairo_surface_fallback_stroke (surface, op, source,
|
2006-06-29 19:47:26 +02:00
|
|
|
path, stroke_style,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
ctm, ctm_inverse,
|
|
|
|
|
tolerance, antialias,
|
|
|
|
|
clip);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2006-06-10 00:12:51 -07:00
|
|
|
FINISH:
|
2010-11-17 18:25:27 +01:00
|
|
|
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
|
|
|
|
|
surface->is_clear = FALSE;
|
2009-10-21 09:04:30 +01:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2005-10-13 16:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_status_t
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
_cairo_surface_fill (cairo_surface_t *surface,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *source,
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
cairo_path_fixed_t *path,
|
|
|
|
|
cairo_fill_rule_t fill_rule,
|
|
|
|
|
double tolerance,
|
2008-10-01 20:50:53 +09:30
|
|
|
cairo_antialias_t antialias,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_clip_t *clip)
|
2005-05-03 14:28:50 +00:00
|
|
|
{
|
2005-10-13 16:55:14 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (surface->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return surface->status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (clip && clip->all_clipped)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2009-10-21 09:04:30 +01:00
|
|
|
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2010-04-27 18:56:23 +01:00
|
|
|
if (op == CAIRO_OPERATOR_OVER &&
|
|
|
|
|
_cairo_pattern_is_clear (source))
|
|
|
|
|
{
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
status = _pattern_has_error (source);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->fill != NULL) {
|
2008-10-22 19:24:44 +01:00
|
|
|
status = surface->backend->fill (surface, op, source,
|
2006-06-29 19:47:26 +02:00
|
|
|
path, fill_rule,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
tolerance, antialias,
|
|
|
|
|
clip);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2005-10-13 16:55:14 +00:00
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
2006-05-04 01:45:41 -07:00
|
|
|
goto FINISH;
|
2005-10-13 16:55:14 +00:00
|
|
|
}
|
2005-05-03 14:28:50 +00:00
|
|
|
|
2008-10-22 19:24:44 +01:00
|
|
|
status = _cairo_surface_fallback_fill (surface, op, source,
|
2006-06-29 19:47:26 +02:00
|
|
|
path, fill_rule,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
tolerance, antialias,
|
|
|
|
|
clip);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2006-06-10 00:12:51 -07:00
|
|
|
FINISH:
|
2010-11-17 18:25:27 +01:00
|
|
|
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
|
|
|
|
|
surface->is_clear = FALSE;
|
2009-10-21 09:04:30 +01:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2005-10-13 16:55:14 +00:00
|
|
|
}
|
2006-06-06 15:25:49 -07:00
|
|
|
|
2003-10-31 10:41:37 +00:00
|
|
|
cairo_status_t
|
2005-12-16 03:02:35 +00:00
|
|
|
_cairo_surface_composite_trapezoids (cairo_operator_t op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *pattern,
|
2003-07-30 08:30:50 +00:00
|
|
|
cairo_surface_t *dst,
|
2005-08-08 18:35:22 +00:00
|
|
|
cairo_antialias_t antialias,
|
2005-01-27 10:46:20 +00:00
|
|
|
int src_x,
|
|
|
|
|
int src_y,
|
|
|
|
|
int dst_x,
|
|
|
|
|
int dst_y,
|
|
|
|
|
unsigned int width,
|
|
|
|
|
unsigned int height,
|
2003-09-05 15:29:49 +00:00
|
|
|
cairo_trapezoid_t *traps,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
int num_traps,
|
|
|
|
|
cairo_region_t *clip_region)
|
2003-07-30 08:30:50 +00:00
|
|
|
{
|
2003-10-27 18:40:55 +00:00
|
|
|
cairo_int_status_t status;
|
|
|
|
|
|
2005-07-27 15:39:34 +00:00
|
|
|
if (dst->status)
|
|
|
|
|
return dst->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (dst));
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
/* These operators aren't interpreted the same way by the backends;
|
|
|
|
|
* they are implemented in terms of other operators in cairo-gstate.c
|
|
|
|
|
*/
|
|
|
|
|
assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2005-04-07 14:25:00 +00:00
|
|
|
if (dst->backend->composite_trapezoids) {
|
2005-12-16 03:02:35 +00:00
|
|
|
status = dst->backend->composite_trapezoids (op,
|
2005-04-07 14:25:00 +00:00
|
|
|
pattern, dst,
|
2005-08-08 18:35:22 +00:00
|
|
|
antialias,
|
2005-04-07 14:25:00 +00:00
|
|
|
src_x, src_y,
|
2006-05-04 01:45:41 -07:00
|
|
|
dst_x, dst_y,
|
2005-04-07 14:25:00 +00:00
|
|
|
width, height,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
traps, num_traps,
|
|
|
|
|
clip_region);
|
2005-04-07 14:25:00 +00:00
|
|
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (dst, status);
|
2005-04-07 14:25:00 +00:00
|
|
|
}
|
2003-10-31 10:41:37 +00:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (dst,
|
|
|
|
|
_cairo_surface_fallback_composite_trapezoids (op, pattern, dst,
|
2005-12-19 22:45:41 +00:00
|
|
|
antialias,
|
|
|
|
|
src_x, src_y,
|
|
|
|
|
dst_x, dst_y,
|
|
|
|
|
width, height,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
traps, num_traps,
|
|
|
|
|
clip_region));
|
2003-07-18 11:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
2008-07-11 00:59:47 +03:00
|
|
|
cairo_span_renderer_t *
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
_cairo_surface_create_span_renderer (cairo_operator_t op,
|
|
|
|
|
const cairo_pattern_t *pattern,
|
2008-07-11 00:59:47 +03:00
|
|
|
cairo_surface_t *dst,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_antialias_t antialias,
|
|
|
|
|
const cairo_composite_rectangles_t *rects,
|
|
|
|
|
cairo_region_t *clip_region)
|
2008-07-11 00:59:47 +03:00
|
|
|
{
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (dst->snapshot_of == NULL);
|
2008-07-11 00:59:47 +03:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (dst->status))
|
2008-07-11 00:59:47 +03:00
|
|
|
return _cairo_span_renderer_create_in_error (dst->status);
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (dst->finished))
|
2008-07-11 00:59:47 +03:00
|
|
|
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
|
|
|
|
|
|
|
|
|
|
if (dst->backend->create_span_renderer) {
|
|
|
|
|
return dst->backend->create_span_renderer (op,
|
|
|
|
|
pattern, dst,
|
|
|
|
|
antialias,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
rects,
|
|
|
|
|
clip_region);
|
2008-07-11 00:59:47 +03:00
|
|
|
}
|
|
|
|
|
ASSERT_NOT_REACHED;
|
|
|
|
|
return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_bool_t
|
2009-08-21 15:51:12 +01:00
|
|
|
_cairo_surface_check_span_renderer (cairo_operator_t op,
|
|
|
|
|
const cairo_pattern_t *pattern,
|
|
|
|
|
cairo_surface_t *dst,
|
|
|
|
|
cairo_antialias_t antialias)
|
2008-07-11 00:59:47 +03:00
|
|
|
{
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (dst->snapshot_of == NULL);
|
2009-08-21 15:51:12 +01:00
|
|
|
assert (dst->status == CAIRO_STATUS_SUCCESS);
|
|
|
|
|
assert (! dst->finished);
|
2008-07-11 00:59:47 +03:00
|
|
|
|
2009-08-21 15:51:12 +01:00
|
|
|
/* XXX: Currently we have no mono span renderer */
|
|
|
|
|
if (antialias == CAIRO_ANTIALIAS_NONE)
|
2008-07-11 00:59:47 +03:00
|
|
|
return FALSE;
|
|
|
|
|
|
2009-08-21 15:51:12 +01:00
|
|
|
if (dst->backend->check_span_renderer != NULL)
|
|
|
|
|
return dst->backend->check_span_renderer (op, pattern, dst, antialias);
|
2008-07-11 00:59:47 +03:00
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-11 13:30:35 -07:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_copy_page:
|
2008-01-25 19:13:13 -05:00
|
|
|
* @surface: a #cairo_surface_t
|
2007-09-11 13:30:35 -07:00
|
|
|
*
|
|
|
|
|
* Emits the current page for backends that support multiple pages,
|
|
|
|
|
* but doesn't clear it, so that the contents of the current page will
|
|
|
|
|
* be retained for the next page. Use cairo_surface_show_page() if you
|
|
|
|
|
* want to get an empty page after the emission.
|
|
|
|
|
*
|
2008-08-18 14:52:43 -04:00
|
|
|
* There is a convenience function for this that takes a #cairo_t,
|
|
|
|
|
* namely cairo_copy_page().
|
|
|
|
|
*
|
2007-09-11 13:30:35 -07:00
|
|
|
* Since: 1.6
|
|
|
|
|
*/
|
2008-01-25 19:38:27 -05:00
|
|
|
void
|
2007-09-11 13:30:35 -07:00
|
|
|
cairo_surface_copy_page (cairo_surface_t *surface)
|
2003-11-03 19:17:31 +00:00
|
|
|
{
|
2008-01-29 09:07:14 +00:00
|
|
|
cairo_status_t status_ignored;
|
|
|
|
|
|
2005-07-27 15:39:34 +00:00
|
|
|
if (surface->status)
|
2008-01-25 19:38:27 -05:00
|
|
|
return;
|
2005-07-27 15:39:34 +00:00
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (surface->snapshot_of == NULL);
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2008-01-25 19:38:27 -05:00
|
|
|
if (surface->finished) {
|
2008-01-29 09:07:14 +00:00
|
|
|
status_ignored = _cairo_surface_set_error (surface,
|
|
|
|
|
CAIRO_STATUS_SURFACE_FINISHED);
|
2008-01-25 19:38:27 -05:00
|
|
|
return;
|
|
|
|
|
}
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2007-04-10 23:01:55 -07:00
|
|
|
/* It's fine if some backends don't implement copy_page */
|
2005-04-07 14:25:00 +00:00
|
|
|
if (surface->backend->copy_page == NULL)
|
2008-01-25 19:38:27 -05:00
|
|
|
return;
|
2003-11-03 19:17:31 +00:00
|
|
|
|
2008-01-29 09:07:14 +00:00
|
|
|
status_ignored = _cairo_surface_set_error (surface,
|
|
|
|
|
surface->backend->copy_page (surface));
|
2003-11-03 19:17:31 +00:00
|
|
|
}
|
2007-09-11 13:30:35 -07:00
|
|
|
slim_hidden_def (cairo_surface_copy_page);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* cairo_surface_show_page:
|
|
|
|
|
* @surface: a #cairo_Surface_t
|
|
|
|
|
*
|
|
|
|
|
* Emits and clears the current page for backends that support multiple
|
|
|
|
|
* pages. Use cairo_surface_copy_page() if you don't want to clear the page.
|
|
|
|
|
*
|
2008-08-18 14:52:43 -04:00
|
|
|
* There is a convenience function for this that takes a #cairo_t,
|
|
|
|
|
* namely cairo_show_page().
|
|
|
|
|
*
|
2007-09-11 13:30:35 -07:00
|
|
|
* Since: 1.6
|
|
|
|
|
**/
|
2008-01-25 19:38:27 -05:00
|
|
|
void
|
2007-09-11 13:30:35 -07:00
|
|
|
cairo_surface_show_page (cairo_surface_t *surface)
|
2003-10-31 21:30:35 +00:00
|
|
|
{
|
2008-01-29 09:07:14 +00:00
|
|
|
cairo_status_t status_ignored;
|
|
|
|
|
|
2005-07-27 15:39:34 +00:00
|
|
|
if (surface->status)
|
2008-01-25 19:38:27 -05:00
|
|
|
return;
|
2005-07-27 15:39:34 +00:00
|
|
|
|
2008-01-25 19:38:27 -05:00
|
|
|
if (surface->finished) {
|
2008-01-29 09:07:14 +00:00
|
|
|
status_ignored = _cairo_surface_set_error (surface,
|
|
|
|
|
CAIRO_STATUS_SURFACE_FINISHED);
|
2008-01-25 19:38:27 -05:00
|
|
|
return;
|
|
|
|
|
}
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2010-07-05 18:23:37 +02:00
|
|
|
_cairo_surface_begin_modification (surface);
|
|
|
|
|
|
2007-04-10 23:01:55 -07:00
|
|
|
/* It's fine if some backends don't implement show_page */
|
2005-04-07 14:25:00 +00:00
|
|
|
if (surface->backend->show_page == NULL)
|
2008-01-25 19:38:27 -05:00
|
|
|
return;
|
2003-10-31 21:30:35 +00:00
|
|
|
|
2008-01-29 09:07:14 +00:00
|
|
|
status_ignored = _cairo_surface_set_error (surface,
|
|
|
|
|
surface->backend->show_page (surface));
|
2003-10-31 21:30:35 +00:00
|
|
|
}
|
2007-09-11 13:30:35 -07:00
|
|
|
slim_hidden_def (cairo_surface_show_page);
|
2003-10-31 21:30:35 +00:00
|
|
|
|
2005-05-26 11:35:44 +00:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_get_extents:
|
|
|
|
|
* @surface: the #cairo_surface_t to fetch extents for
|
|
|
|
|
*
|
2006-06-10 11:20:21 -07:00
|
|
|
* This function returns a bounding box for the surface. The surface
|
|
|
|
|
* bounds are defined as a region beyond which no rendering will
|
2007-01-07 02:08:15 -05:00
|
|
|
* possibly be recorded, in other words, it is the maximum extent of
|
2006-06-10 11:20:21 -07:00
|
|
|
* potentially usable coordinates.
|
|
|
|
|
*
|
2009-10-22 02:13:36 +03:00
|
|
|
* For vector surfaces, (PDF, PS, SVG and recording-surfaces), the surface
|
2006-06-10 11:20:21 -07:00
|
|
|
* might be conceived as unbounded, but we force the user to provide a
|
2006-06-25 10:02:10 +02:00
|
|
|
* maximum size at the time of surface_create. So get_extents uses
|
|
|
|
|
* that size.
|
|
|
|
|
*
|
2008-01-28 21:53:44 -05:00
|
|
|
* Note: The coordinates returned are in "backend" space rather than
|
2006-06-25 10:02:10 +02:00
|
|
|
* "surface" space. That is, they are relative to the true (0,0)
|
|
|
|
|
* origin rather than the device_transform origin. This might seem a
|
2008-01-28 21:49:57 -05:00
|
|
|
* bit inconsistent with other #cairo_surface_t interfaces, but all
|
2006-06-25 10:02:10 +02:00
|
|
|
* current callers are within the surface layer where backend space is
|
|
|
|
|
* desired.
|
|
|
|
|
*
|
|
|
|
|
* This behavior would have to be changed is we ever exported a public
|
|
|
|
|
* variant of this function.
|
2005-05-26 11:35:44 +00:00
|
|
|
*/
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_bool_t
|
2006-05-04 03:43:34 -07:00
|
|
|
_cairo_surface_get_extents (cairo_surface_t *surface,
|
2008-05-09 14:46:22 +02:00
|
|
|
cairo_rectangle_int_t *extents)
|
2005-04-19 16:29:04 +00:00
|
|
|
{
|
2010-03-22 10:37:18 +00:00
|
|
|
cairo_bool_t bounded;
|
2005-07-27 15:39:34 +00:00
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
bounded = FALSE;
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->get_extents != NULL)
|
|
|
|
|
bounded = surface->backend->get_extents (surface, extents);
|
2005-04-19 16:29:04 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (! bounded)
|
|
|
|
|
_cairo_unbounded_rectangle_init (extents);
|
2008-05-09 14:46:22 +02:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
return bounded;
|
2005-04-19 16:29:04 +00:00
|
|
|
}
|
|
|
|
|
|
2008-08-18 14:52:43 -04:00
|
|
|
/**
|
|
|
|
|
* cairo_surface_has_show_text_glyphs:
|
|
|
|
|
* @surface: a #cairo_surface_t
|
|
|
|
|
*
|
|
|
|
|
* Returns whether the surface supports
|
|
|
|
|
* sophisticated cairo_show_text_glyphs() operations. That is,
|
|
|
|
|
* whether it actually uses the provided text and cluster data
|
|
|
|
|
* to a cairo_show_text_glyphs() call.
|
|
|
|
|
*
|
|
|
|
|
* Note: Even if this function returns %FALSE, a
|
|
|
|
|
* cairo_show_text_glyphs() operation targeted at @surface will
|
|
|
|
|
* still succeed. It just will
|
|
|
|
|
* act like a cairo_show_glyphs() operation. Users can use this
|
|
|
|
|
* function to avoid computing UTF-8 text and cluster mapping if the
|
|
|
|
|
* target surface does not use it.
|
|
|
|
|
*
|
|
|
|
|
* Return value: %TRUE if @surface supports
|
|
|
|
|
* cairo_show_text_glyphs(), %FALSE otherwise
|
|
|
|
|
*
|
|
|
|
|
* Since: 1.8
|
|
|
|
|
**/
|
2008-06-26 16:15:12 -04:00
|
|
|
cairo_bool_t
|
2008-08-18 14:52:43 -04:00
|
|
|
cairo_surface_has_show_text_glyphs (cairo_surface_t *surface)
|
2008-06-26 16:15:12 -04:00
|
|
|
{
|
2008-08-18 14:52:43 -04:00
|
|
|
cairo_status_t status_ignored;
|
|
|
|
|
|
|
|
|
|
if (surface->status)
|
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
|
|
if (surface->finished) {
|
|
|
|
|
status_ignored = _cairo_surface_set_error (surface,
|
|
|
|
|
CAIRO_STATUS_SURFACE_FINISHED);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-26 16:15:12 -04:00
|
|
|
if (surface->backend->has_show_text_glyphs)
|
|
|
|
|
return surface->backend->has_show_text_glyphs (surface);
|
|
|
|
|
else
|
|
|
|
|
return surface->backend->show_text_glyphs != NULL;
|
|
|
|
|
}
|
2008-08-18 14:52:43 -04:00
|
|
|
slim_hidden_def (cairo_surface_has_show_text_glyphs);
|
2008-06-26 16:15:12 -04:00
|
|
|
|
2007-08-31 17:20:54 +01:00
|
|
|
/* Note: the backends may modify the contents of the glyph array as long as
|
2008-05-09 09:53:40 -04:00
|
|
|
* they do not return %CAIRO_INT_STATUS_UNSUPPORTED. This makes it possible to
|
2007-08-31 17:20:54 +01:00
|
|
|
* avoid copying the array again and again, and edit it in-place.
|
|
|
|
|
* Backends are in fact free to use the array as a generic buffer as they
|
|
|
|
|
* see fit.
|
2008-05-23 19:57:48 -04:00
|
|
|
*
|
2008-06-26 16:15:12 -04:00
|
|
|
* For show_glyphs backend method, and NOT for show_text_glyphs method,
|
|
|
|
|
* when they do return UNSUPPORTED, they may adjust remaining_glyphs to notify
|
2008-05-23 19:57:48 -04:00
|
|
|
* that they have successfully rendered some of the glyphs (from the beginning
|
|
|
|
|
* of the array), but not all. If they don't touch remaining_glyphs, it
|
|
|
|
|
* defaults to all glyphs.
|
|
|
|
|
*
|
2007-08-31 17:20:54 +01:00
|
|
|
* See commits 5a9642c5746fd677aed35ce620ce90b1029b1a0c and
|
|
|
|
|
* 1781e6018c17909311295a9cc74b70500c6b4d0a for the rationale.
|
|
|
|
|
*/
|
2005-03-16 12:08:41 +00:00
|
|
|
cairo_status_t
|
2008-06-26 16:15:12 -04:00
|
|
|
_cairo_surface_show_text_glyphs (cairo_surface_t *surface,
|
|
|
|
|
cairo_operator_t op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *source,
|
2008-06-26 16:15:12 -04:00
|
|
|
const char *utf8,
|
|
|
|
|
int utf8_len,
|
|
|
|
|
cairo_glyph_t *glyphs,
|
|
|
|
|
int num_glyphs,
|
|
|
|
|
const cairo_text_cluster_t *clusters,
|
|
|
|
|
int num_clusters,
|
2008-09-18 00:26:07 -04:00
|
|
|
cairo_text_cluster_flags_t cluster_flags,
|
2008-10-01 20:50:53 +09:30
|
|
|
cairo_scaled_font_t *scaled_font,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
cairo_clip_t *clip)
|
2005-11-01 16:40:37 +00:00
|
|
|
{
|
Rework support in the surface backend for the five basic drawing operations (paint, mask, stroke, fill, and show_glyphs). Now, all 5 operations have backend functions, and all use a consistent convention for argument naming and ordering. The old fill_path has been replaced with a new fill. The old show_glyphs function was recently renamed to old_show_glyphs and has not yet been ported to the new show_glyphs, (so all backends have a NULL show_glyphs function). In fact, of the 5 new backend functions, fill is the only one that has an implementation in any backend. As part of this cleanup a new cairo_stroke_style_t object is introduced to capture the many settings unique to the stroke operation, (line_width, line_cap, line_join, miter_limit, dash, num_dashes, and dash_offset).
Track changes in surface backend from fill_path to fill.
Track the new canonical argument naming and ordering for the 5 drawing operations.
Move various stroke style settings into new cairo_stroke_style_t.
Drop NULL fill_path backend function which no longer exists.
2005-11-04 11:16:38 +00:00
|
|
|
cairo_status_t status;
|
2006-06-10 08:35:01 -07:00
|
|
|
cairo_scaled_font_t *dev_scaled_font = scaled_font;
|
2005-11-01 16:40:37 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (surface->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return surface->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
if (num_glyphs == 0 && utf8_len == 0)
|
2006-12-23 17:08:04 -05:00
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (clip && clip->all_clipped)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2009-10-21 09:04:30 +01:00
|
|
|
if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
|
|
|
|
|
return CAIRO_STATUS_SUCCESS;
|
|
|
|
|
|
2010-03-22 10:37:18 +00:00
|
|
|
status = _pattern_has_error (source);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
return status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
_cairo_surface_begin_modification (surface);
|
|
|
|
|
|
2006-07-28 15:12:10 -04:00
|
|
|
if (_cairo_surface_has_device_transform (surface) &&
|
|
|
|
|
! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL))
|
2006-05-04 01:45:41 -07:00
|
|
|
{
|
2008-03-31 15:48:51 +01:00
|
|
|
cairo_font_options_t font_options;
|
2008-05-24 13:17:31 -04:00
|
|
|
cairo_matrix_t dev_ctm, font_matrix;
|
2006-07-28 15:12:10 -04:00
|
|
|
|
2008-05-24 13:17:31 -04:00
|
|
|
cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
|
2006-07-28 15:12:10 -04:00
|
|
|
cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
|
|
|
|
|
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
|
2008-03-31 15:48:51 +01:00
|
|
|
cairo_scaled_font_get_font_options (scaled_font, &font_options);
|
2006-07-28 15:12:10 -04:00
|
|
|
dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
|
|
|
|
|
&font_matrix,
|
|
|
|
|
&dev_ctm,
|
2008-03-31 15:48:51 +01:00
|
|
|
&font_options);
|
2006-05-04 01:45:41 -07:00
|
|
|
}
|
2007-05-08 21:28:48 +01:00
|
|
|
status = cairo_scaled_font_status (dev_scaled_font);
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (status))
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2006-05-04 01:45:41 -07:00
|
|
|
|
2007-02-05 16:45:25 -08:00
|
|
|
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
|
|
|
|
|
2008-07-02 19:21:50 -04:00
|
|
|
/* The logic here is duplicated in _cairo_analysis_surface show_glyphs and
|
|
|
|
|
* show_text_glyphs. Keep in synch. */
|
2008-06-26 16:15:12 -04:00
|
|
|
if (clusters) {
|
|
|
|
|
/* A real show_text_glyphs call. Try show_text_glyphs backend
|
|
|
|
|
* method first */
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->show_text_glyphs != NULL) {
|
2008-10-22 19:24:44 +01:00
|
|
|
status = surface->backend->show_text_glyphs (surface, op,
|
|
|
|
|
source,
|
2008-06-26 16:15:12 -04:00
|
|
|
utf8, utf8_len,
|
|
|
|
|
glyphs, num_glyphs,
|
2008-09-18 00:26:07 -04:00
|
|
|
clusters, num_clusters, cluster_flags,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
dev_scaled_font,
|
|
|
|
|
clip);
|
2008-06-26 16:15:12 -04:00
|
|
|
}
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
|
|
|
|
|
surface->backend->show_glyphs)
|
|
|
|
|
{
|
2008-06-26 16:15:12 -04:00
|
|
|
int remaining_glyphs = num_glyphs;
|
2008-10-22 19:24:44 +01:00
|
|
|
status = surface->backend->show_glyphs (surface, op,
|
|
|
|
|
source,
|
2008-06-26 16:15:12 -04:00
|
|
|
glyphs, num_glyphs,
|
|
|
|
|
dev_scaled_font,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
clip,
|
|
|
|
|
&remaining_glyphs);
|
2008-06-26 16:15:12 -04:00
|
|
|
glyphs += num_glyphs - remaining_glyphs;
|
|
|
|
|
num_glyphs = remaining_glyphs;
|
2008-07-02 19:21:50 -04:00
|
|
|
if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0)
|
2008-06-26 16:15:12 -04:00
|
|
|
status = CAIRO_STATUS_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* A mere show_glyphs call. Try show_glyphs backend method first */
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (surface->backend->show_glyphs != NULL) {
|
2008-06-26 16:15:12 -04:00
|
|
|
int remaining_glyphs = num_glyphs;
|
2008-10-22 19:24:44 +01:00
|
|
|
status = surface->backend->show_glyphs (surface, op,
|
|
|
|
|
source,
|
2008-06-26 16:15:12 -04:00
|
|
|
glyphs, num_glyphs,
|
|
|
|
|
dev_scaled_font,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
clip,
|
|
|
|
|
&remaining_glyphs);
|
2008-06-26 16:15:12 -04:00
|
|
|
glyphs += num_glyphs - remaining_glyphs;
|
|
|
|
|
num_glyphs = remaining_glyphs;
|
2008-07-02 19:21:50 -04:00
|
|
|
if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0)
|
2008-06-26 16:15:12 -04:00
|
|
|
status = CAIRO_STATUS_SUCCESS;
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
} else if (surface->backend->show_text_glyphs != NULL) {
|
2008-06-26 16:15:12 -04:00
|
|
|
/* Intentionally only try show_text_glyphs method for show_glyphs
|
|
|
|
|
* calls if backend does not have show_glyphs. If backend has
|
|
|
|
|
* both methods implemented, we don't fallback from show_glyphs to
|
2008-07-02 19:21:50 -04:00
|
|
|
* show_text_glyphs, and hence the backend can assume in its
|
2008-06-26 16:15:12 -04:00
|
|
|
* show_text_glyphs call that clusters is not NULL (which also
|
|
|
|
|
* implies that UTF-8 is not NULL, unless the text is
|
|
|
|
|
* zero-length).
|
|
|
|
|
*/
|
2008-10-22 19:24:44 +01:00
|
|
|
status = surface->backend->show_text_glyphs (surface, op,
|
|
|
|
|
source,
|
2008-06-26 16:15:12 -04:00
|
|
|
utf8, utf8_len,
|
|
|
|
|
glyphs, num_glyphs,
|
2008-09-18 00:26:07 -04:00
|
|
|
clusters, num_clusters, cluster_flags,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
dev_scaled_font,
|
|
|
|
|
clip);
|
2008-06-26 16:15:12 -04:00
|
|
|
}
|
2008-05-23 19:57:48 -04:00
|
|
|
}
|
2005-11-01 16:40:37 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
2008-10-22 19:24:44 +01:00
|
|
|
status = _cairo_surface_fallback_show_glyphs (surface, op,
|
|
|
|
|
source,
|
2007-02-05 16:45:25 -08:00
|
|
|
glyphs, num_glyphs,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
dev_scaled_font,
|
|
|
|
|
clip);
|
|
|
|
|
}
|
2007-02-05 16:45:25 -08:00
|
|
|
|
2006-06-10 08:35:01 -07:00
|
|
|
if (dev_scaled_font != scaled_font)
|
|
|
|
|
cairo_scaled_font_destroy (dev_scaled_font);
|
|
|
|
|
|
2010-11-17 18:25:27 +01:00
|
|
|
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
|
|
|
|
|
surface->is_clear = FALSE;
|
2009-10-21 09:04:30 +01:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (surface, status);
|
2005-11-01 16:40:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* XXX: Previously, we had a function named _cairo_surface_show_glyphs
|
2008-06-30 22:11:48 -04:00
|
|
|
* with not-so-useful semantics. We've now got a
|
|
|
|
|
* _cairo_surface_show_text_glyphs with the proper semantics, and its
|
2005-11-01 16:40:37 +00:00
|
|
|
* fallback still uses this old function (which still needs to be
|
|
|
|
|
* cleaned up in terms of both semantics and naming). */
|
|
|
|
|
cairo_status_t
|
|
|
|
|
_cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
2005-12-16 03:02:35 +00:00
|
|
|
cairo_operator_t op,
|
2008-10-22 19:24:44 +01:00
|
|
|
const cairo_pattern_t *pattern,
|
2005-11-01 16:40:37 +00:00
|
|
|
cairo_surface_t *dst,
|
|
|
|
|
int source_x,
|
|
|
|
|
int source_y,
|
|
|
|
|
int dest_x,
|
|
|
|
|
int dest_y,
|
|
|
|
|
unsigned int width,
|
|
|
|
|
unsigned int height,
|
2007-08-31 16:53:21 +01:00
|
|
|
cairo_glyph_t *glyphs,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
int num_glyphs,
|
|
|
|
|
cairo_region_t *clip_region)
|
2005-03-16 12:08:41 +00:00
|
|
|
{
|
2011-03-02 18:30:47 +00:00
|
|
|
if (unlikely (dst->status))
|
2005-07-27 15:39:34 +00:00
|
|
|
return dst->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (dst));
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2011-03-02 18:30:47 +00:00
|
|
|
if (dst->backend->old_show_glyphs == NULL)
|
|
|
|
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
2005-03-16 12:08:41 +00:00
|
|
|
|
2011-03-02 18:30:47 +00:00
|
|
|
return _cairo_surface_set_error
|
|
|
|
|
(dst, dst->backend->old_show_glyphs (scaled_font,
|
|
|
|
|
op, pattern, dst,
|
|
|
|
|
source_x, source_y,
|
|
|
|
|
dest_x, dest_y,
|
|
|
|
|
width, height,
|
|
|
|
|
glyphs, num_glyphs,
|
|
|
|
|
clip_region));
|
2005-03-16 12:08:41 +00:00
|
|
|
}
|
2005-08-08 13:46:11 +00:00
|
|
|
|
2005-08-16 18:22:16 +00:00
|
|
|
static cairo_status_t
|
2006-05-04 03:43:34 -07:00
|
|
|
_cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t *src_rectangle,
|
|
|
|
|
cairo_rectangle_int_t *mask_rectangle,
|
2006-05-04 03:43:34 -07:00
|
|
|
int dst_x,
|
|
|
|
|
int dst_y,
|
|
|
|
|
unsigned int width,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
unsigned int height,
|
|
|
|
|
cairo_region_t *clip_region)
|
2005-08-16 18:22:16 +00:00
|
|
|
{
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t dst_rectangle;
|
2009-07-02 09:17:43 +01:00
|
|
|
cairo_region_t clear_region;
|
2007-03-14 00:28:49 +01:00
|
|
|
cairo_status_t status;
|
2005-08-16 18:22:16 +00:00
|
|
|
|
2009-03-30 10:54:26 +01:00
|
|
|
/* The area that was drawn is the area in the destination rectangle but
|
|
|
|
|
* not within the source or the mask.
|
2005-08-16 18:22:16 +00:00
|
|
|
*/
|
|
|
|
|
dst_rectangle.x = dst_x;
|
|
|
|
|
dst_rectangle.y = dst_y;
|
|
|
|
|
dst_rectangle.width = width;
|
|
|
|
|
dst_rectangle.height = height;
|
2008-12-11 15:29:23 -05:00
|
|
|
|
2009-07-02 09:17:43 +01:00
|
|
|
_cairo_region_init_rectangle (&clear_region, &dst_rectangle);
|
2005-08-16 18:22:16 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (clip_region != NULL) {
|
|
|
|
|
status = cairo_region_intersect (&clear_region, clip_region);
|
|
|
|
|
if (unlikely (status))
|
|
|
|
|
goto CLEANUP_REGIONS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (src_rectangle != NULL) {
|
2009-03-30 10:54:26 +01:00
|
|
|
if (! _cairo_rectangle_intersect (&dst_rectangle, src_rectangle))
|
2008-10-23 14:34:30 +01:00
|
|
|
goto EMPTY;
|
|
|
|
|
}
|
2005-08-16 18:22:16 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (mask_rectangle != NULL) {
|
2009-03-30 10:54:26 +01:00
|
|
|
if (! _cairo_rectangle_intersect (&dst_rectangle, mask_rectangle))
|
2008-10-23 14:34:30 +01:00
|
|
|
goto EMPTY;
|
|
|
|
|
}
|
2005-08-16 18:22:16 +00:00
|
|
|
|
2009-03-30 10:54:26 +01:00
|
|
|
/* Now compute the area that is in dst but not drawn */
|
2009-07-02 09:17:43 +01:00
|
|
|
status = cairo_region_subtract_rectangle (&clear_region, &dst_rectangle);
|
2009-09-21 13:50:00 +01:00
|
|
|
if (unlikely (status) || cairo_region_is_empty (&clear_region))
|
2007-03-14 00:28:49 +01:00
|
|
|
goto CLEANUP_REGIONS;
|
2005-08-16 18:22:16 +00:00
|
|
|
|
2008-10-23 14:34:30 +01:00
|
|
|
EMPTY:
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
|
2007-03-14 00:28:49 +01:00
|
|
|
CAIRO_COLOR_TRANSPARENT,
|
2009-07-02 09:17:43 +01:00
|
|
|
&clear_region);
|
2007-03-14 00:28:49 +01:00
|
|
|
|
2008-10-23 14:34:30 +01:00
|
|
|
CLEANUP_REGIONS:
|
2009-07-02 09:17:43 +01:00
|
|
|
_cairo_region_fini (&clear_region);
|
2005-08-16 18:22:16 +00:00
|
|
|
|
2007-10-04 20:05:58 +01:00
|
|
|
return _cairo_surface_set_error (dst, status);
|
2005-08-16 18:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
2005-08-08 13:46:11 +00:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_composite_fixup_unbounded:
|
|
|
|
|
* @dst: the destination surface
|
|
|
|
|
* @src_attr: source surface attributes (from _cairo_pattern_acquire_surface())
|
|
|
|
|
* @src_width: width of source surface
|
|
|
|
|
* @src_height: height of source surface
|
|
|
|
|
* @mask_attr: mask surface attributes or %NULL if no mask
|
|
|
|
|
* @mask_width: width of mask surface
|
|
|
|
|
* @mask_height: height of mask surface
|
|
|
|
|
* @src_x: @src_x from _cairo_surface_composite()
|
|
|
|
|
* @src_y: @src_y from _cairo_surface_composite()
|
|
|
|
|
* @mask_x: @mask_x from _cairo_surface_composite()
|
|
|
|
|
* @mask_y: @mask_y from _cairo_surface_composite()
|
|
|
|
|
* @dst_x: @dst_x from _cairo_surface_composite()
|
|
|
|
|
* @dst_y: @dst_y from _cairo_surface_composite()
|
|
|
|
|
* @width: @width from _cairo_surface_composite()
|
|
|
|
|
* @height: @height_x from _cairo_surface_composite()
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-08 13:46:11 +00:00
|
|
|
* Eeek! Too many parameters! This is a helper function to take care of fixing
|
|
|
|
|
* up for bugs in libpixman and RENDER where, when asked to composite an
|
|
|
|
|
* untransformed surface with an unbounded operator (like CLEAR or SOURCE)
|
|
|
|
|
* only the region inside both the source and the mask is affected.
|
|
|
|
|
* This function clears the region that should have been drawn but was wasn't.
|
|
|
|
|
**/
|
2005-08-16 18:22:16 +00:00
|
|
|
cairo_status_t
|
2005-08-08 13:46:11 +00:00
|
|
|
_cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
|
|
|
|
cairo_surface_attributes_t *src_attr,
|
|
|
|
|
int src_width,
|
|
|
|
|
int src_height,
|
|
|
|
|
cairo_surface_attributes_t *mask_attr,
|
|
|
|
|
int mask_width,
|
|
|
|
|
int mask_height,
|
|
|
|
|
int src_x,
|
|
|
|
|
int src_y,
|
|
|
|
|
int mask_x,
|
|
|
|
|
int mask_y,
|
|
|
|
|
int dst_x,
|
|
|
|
|
int dst_y,
|
|
|
|
|
unsigned int width,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
unsigned int height,
|
|
|
|
|
cairo_region_t *clip_region)
|
2005-08-08 13:46:11 +00:00
|
|
|
{
|
2007-06-18 16:56:24 -07:00
|
|
|
cairo_rectangle_int_t src_tmp, mask_tmp;
|
|
|
|
|
cairo_rectangle_int_t *src_rectangle = NULL;
|
|
|
|
|
cairo_rectangle_int_t *mask_rectangle = NULL;
|
2005-10-13 21:00:52 +00:00
|
|
|
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
if (unlikely (dst->status))
|
2008-02-19 15:14:37 +00:00
|
|
|
return dst->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (dst));
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2005-08-08 13:46:11 +00:00
|
|
|
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
|
|
|
|
* non-repeating sources and masks. Other sources and masks can be ignored.
|
|
|
|
|
*/
|
2005-08-16 18:22:16 +00:00
|
|
|
if (_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) &&
|
|
|
|
|
src_attr->extend == CAIRO_EXTEND_NONE)
|
|
|
|
|
{
|
|
|
|
|
src_tmp.x = (dst_x - (src_x + src_attr->x_offset));
|
|
|
|
|
src_tmp.y = (dst_y - (src_y + src_attr->y_offset));
|
|
|
|
|
src_tmp.width = src_width;
|
|
|
|
|
src_tmp.height = src_height;
|
2005-08-08 13:46:11 +00:00
|
|
|
|
2005-08-16 18:22:16 +00:00
|
|
|
src_rectangle = &src_tmp;
|
2005-08-08 13:46:11 +00:00
|
|
|
}
|
|
|
|
|
|
2005-08-16 18:22:16 +00:00
|
|
|
if (mask_attr &&
|
|
|
|
|
_cairo_matrix_is_integer_translation (&mask_attr->matrix, NULL, NULL) &&
|
|
|
|
|
mask_attr->extend == CAIRO_EXTEND_NONE)
|
|
|
|
|
{
|
|
|
|
|
mask_tmp.x = (dst_x - (mask_x + mask_attr->x_offset));
|
|
|
|
|
mask_tmp.y = (dst_y - (mask_y + mask_attr->y_offset));
|
|
|
|
|
mask_tmp.width = mask_width;
|
|
|
|
|
mask_tmp.height = mask_height;
|
2005-08-08 13:46:11 +00:00
|
|
|
|
2005-08-16 18:22:16 +00:00
|
|
|
mask_rectangle = &mask_tmp;
|
2005-08-08 13:46:11 +00:00
|
|
|
}
|
|
|
|
|
|
2005-08-16 18:22:16 +00:00
|
|
|
return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
dst_x, dst_y, width, height,
|
|
|
|
|
clip_region);
|
2005-08-16 18:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* _cairo_surface_composite_shape_fixup_unbounded:
|
|
|
|
|
* @dst: the destination surface
|
|
|
|
|
* @src_attr: source surface attributes (from _cairo_pattern_acquire_surface())
|
|
|
|
|
* @src_width: width of source surface
|
|
|
|
|
* @src_height: height of source surface
|
|
|
|
|
* @mask_width: width of mask surface
|
|
|
|
|
* @mask_height: height of mask surface
|
|
|
|
|
* @src_x: @src_x from _cairo_surface_composite()
|
|
|
|
|
* @src_y: @src_y from _cairo_surface_composite()
|
|
|
|
|
* @mask_x: @mask_x from _cairo_surface_composite()
|
|
|
|
|
* @mask_y: @mask_y from _cairo_surface_composite()
|
|
|
|
|
* @dst_x: @dst_x from _cairo_surface_composite()
|
|
|
|
|
* @dst_y: @dst_y from _cairo_surface_composite()
|
|
|
|
|
* @width: @width from _cairo_surface_composite()
|
|
|
|
|
* @height: @height_x from _cairo_surface_composite()
|
2006-06-06 15:35:48 -07:00
|
|
|
*
|
2005-08-16 18:22:16 +00:00
|
|
|
* Like _cairo_surface_composite_fixup_unbounded(), but instead of
|
|
|
|
|
* handling the case where we have a source pattern and a mask
|
|
|
|
|
* pattern, handle the case where we are compositing a source pattern
|
|
|
|
|
* using a mask we create ourselves, as in
|
|
|
|
|
* _cairo_surface_composite_glyphs() or _cairo_surface_composite_trapezoids()
|
|
|
|
|
**/
|
|
|
|
|
cairo_status_t
|
|
|
|
|
_cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
|
|
|
|
cairo_surface_attributes_t *src_attr,
|
|
|
|
|
int src_width,
|
|
|
|
|
int src_height,
|
|
|
|
|
int mask_width,
|
|
|
|
|
int mask_height,
|
|
|
|
|
int src_x,
|
|
|
|
|
int src_y,
|
|
|
|
|
int mask_x,
|
|
|
|
|
int mask_y,
|
|
|
|
|
int dst_x,
|
|
|
|
|
int dst_y,
|
|
|
|
|
unsigned int width,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
unsigned int height,
|
|
|
|
|
cairo_region_t *clip_region)
|
2005-08-16 18:22:16 +00:00
|
|
|
{
|
2009-09-21 13:50:00 +01:00
|
|
|
cairo_rectangle_int_t src_tmp, *src= NULL;
|
|
|
|
|
cairo_rectangle_int_t mask;
|
2005-10-13 21:00:52 +00:00
|
|
|
|
2008-02-19 15:14:37 +00:00
|
|
|
if (dst->status)
|
|
|
|
|
return dst->status;
|
|
|
|
|
|
2009-05-26 21:07:07 +01:00
|
|
|
assert (_cairo_surface_is_writable (dst));
|
2008-10-17 10:35:38 +01:00
|
|
|
|
2005-08-16 18:22:16 +00:00
|
|
|
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
|
|
|
|
* non-repeating sources and masks. Other sources and masks can be ignored.
|
2005-08-08 13:46:11 +00:00
|
|
|
*/
|
2005-08-16 18:22:16 +00:00
|
|
|
if (_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) &&
|
|
|
|
|
src_attr->extend == CAIRO_EXTEND_NONE)
|
2005-08-08 13:46:11 +00:00
|
|
|
{
|
2005-08-16 18:22:16 +00:00
|
|
|
src_tmp.x = (dst_x - (src_x + src_attr->x_offset));
|
|
|
|
|
src_tmp.y = (dst_y - (src_y + src_attr->y_offset));
|
2009-09-21 13:50:00 +01:00
|
|
|
src_tmp.width = src_width;
|
2005-08-16 18:22:16 +00:00
|
|
|
src_tmp.height = src_height;
|
|
|
|
|
|
2009-09-21 13:50:00 +01:00
|
|
|
src = &src_tmp;
|
2005-08-08 13:46:11 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-21 13:50:00 +01:00
|
|
|
mask.x = dst_x - mask_x;
|
|
|
|
|
mask.y = dst_y - mask_y;
|
|
|
|
|
mask.width = mask_width;
|
|
|
|
|
mask.height = mask_height;
|
2006-06-06 15:25:49 -07:00
|
|
|
|
2009-09-21 13:50:00 +01:00
|
|
|
return _cairo_surface_composite_fixup_unbounded_internal (dst, src, &mask,
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
dst_x, dst_y, width, height,
|
|
|
|
|
clip_region);
|
2005-08-16 18:22:16 +00:00
|
|
|
}
|
2006-04-14 17:25:54 -07:00
|
|
|
|
2007-08-29 15:34:04 -07:00
|
|
|
/**
|
|
|
|
|
* _cairo_surface_set_resolution
|
|
|
|
|
* @surface: the surface
|
|
|
|
|
* @x_res: x resolution, in dpi
|
|
|
|
|
* @y_res: y resolution, in dpi
|
|
|
|
|
*
|
|
|
|
|
* Set the actual surface resolution of @surface to the given x and y DPI.
|
|
|
|
|
* Mainly used for correctly computing the scale factor when fallback
|
|
|
|
|
* rendering needs to take place in the paginated surface.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
_cairo_surface_set_resolution (cairo_surface_t *surface,
|
|
|
|
|
double x_res,
|
|
|
|
|
double y_res)
|
|
|
|
|
{
|
2008-02-19 15:14:37 +00:00
|
|
|
if (surface->status)
|
|
|
|
|
return;
|
|
|
|
|
|
2007-08-29 15:34:04 -07:00
|
|
|
surface->x_resolution = x_res;
|
|
|
|
|
surface->y_resolution = y_res;
|
|
|
|
|
}
|
|
|
|
|
|
2008-01-16 16:23:23 +00:00
|
|
|
cairo_surface_t *
|
|
|
|
|
_cairo_surface_create_in_error (cairo_status_t status)
|
|
|
|
|
{
|
|
|
|
|
switch (status) {
|
|
|
|
|
case CAIRO_STATUS_NO_MEMORY:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil;
|
2009-07-01 19:41:42 +01:00
|
|
|
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_surface_type_mismatch;
|
Remove clip handling from generic surface layer.
Handling clip as part of the surface state, as opposed to being part of
the operation state, is cumbersome and a hindrance to providing true proxy
surface support. For example, the clip must be copied from the surface
onto the fallback image, but this was forgotten causing undue hassle in
each backend. Another example is the contortion the meta surface
endures to ensure the clip is correctly recorded. By contrast passing the
clip along with the operation is quite simple and enables us to write
generic handlers for providing surface wrappers. (And in the future, we
should be able to write more esoteric wrappers, e.g. automatic 2x FSAA,
trivially.)
In brief, instead of the surface automatically applying the clip before
calling the backend, the backend can call into a generic helper to apply
clipping. For raster surfaces, clip regions are handled automatically as
part of the composite interface. For vector surfaces, a clip helper is
introduced to replay and callback into an intersect_clip_path() function
as necessary.
Whilst this is not primarily a performance related change (the change
should just move the computation of the clip from the moment it is applied
by the user to the moment it is required by the backend), it is important
to track any potential regression:
ppc:
Speedups
========
image-rgba evolution-20090607-0 1026085.22 0.18% -> 672972.07 0.77%: 1.52x speedup
▌
image-rgba evolution-20090618-0 680579.98 0.12% -> 573237.66 0.16%: 1.19x speedup
▎
image-rgba swfdec-fill-rate-4xaa-0 460296.92 0.36% -> 407464.63 0.42%: 1.13x speedup
▏
image-rgba swfdec-fill-rate-2xaa-0 128431.95 0.47% -> 115051.86 0.42%: 1.12x speedup
▏
Slowdowns
=========
image-rgba firefox-periodic-table-0 56837.61 0.78% -> 66055.17 3.20%: 1.09x slowdown
▏
2009-07-23 15:32:13 +01:00
|
|
|
case CAIRO_STATUS_INVALID_STATUS:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_invalid_status;
|
2008-01-16 16:23:23 +00:00
|
|
|
case CAIRO_STATUS_INVALID_CONTENT:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_invalid_content;
|
|
|
|
|
case CAIRO_STATUS_INVALID_FORMAT:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_invalid_format;
|
|
|
|
|
case CAIRO_STATUS_INVALID_VISUAL:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_invalid_visual;
|
|
|
|
|
case CAIRO_STATUS_READ_ERROR:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_read_error;
|
|
|
|
|
case CAIRO_STATUS_WRITE_ERROR:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_write_error;
|
|
|
|
|
case CAIRO_STATUS_FILE_NOT_FOUND:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_file_not_found;
|
|
|
|
|
case CAIRO_STATUS_TEMP_FILE_ERROR:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error;
|
2008-01-26 23:12:14 -08:00
|
|
|
case CAIRO_STATUS_INVALID_STRIDE:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride;
|
2009-05-22 12:52:43 +01:00
|
|
|
case CAIRO_STATUS_INVALID_SIZE:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_invalid_size;
|
2010-01-18 21:53:42 +00:00
|
|
|
case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_device_type_mismatch;
|
|
|
|
|
case CAIRO_STATUS_DEVICE_ERROR:
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil_device_error;
|
2008-03-25 10:27:36 -07:00
|
|
|
case CAIRO_STATUS_SUCCESS:
|
2009-03-28 19:26:03 +00:00
|
|
|
case CAIRO_STATUS_LAST_STATUS:
|
2008-03-25 10:27:36 -07:00
|
|
|
ASSERT_NOT_REACHED;
|
|
|
|
|
/* fall-through */
|
|
|
|
|
case CAIRO_STATUS_INVALID_RESTORE:
|
|
|
|
|
case CAIRO_STATUS_INVALID_POP_GROUP:
|
|
|
|
|
case CAIRO_STATUS_NO_CURRENT_POINT:
|
|
|
|
|
case CAIRO_STATUS_INVALID_MATRIX:
|
|
|
|
|
case CAIRO_STATUS_NULL_POINTER:
|
|
|
|
|
case CAIRO_STATUS_INVALID_STRING:
|
|
|
|
|
case CAIRO_STATUS_INVALID_PATH_DATA:
|
|
|
|
|
case CAIRO_STATUS_SURFACE_FINISHED:
|
|
|
|
|
case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
|
|
|
|
|
case CAIRO_STATUS_INVALID_DASH:
|
|
|
|
|
case CAIRO_STATUS_INVALID_DSC_COMMENT:
|
|
|
|
|
case CAIRO_STATUS_INVALID_INDEX:
|
|
|
|
|
case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
|
2008-05-15 19:41:49 -04:00
|
|
|
case CAIRO_STATUS_FONT_TYPE_MISMATCH:
|
|
|
|
|
case CAIRO_STATUS_USER_FONT_IMMUTABLE:
|
|
|
|
|
case CAIRO_STATUS_USER_FONT_ERROR:
|
2008-06-23 17:53:25 -04:00
|
|
|
case CAIRO_STATUS_NEGATIVE_COUNT:
|
2008-06-26 16:15:12 -04:00
|
|
|
case CAIRO_STATUS_INVALID_CLUSTERS:
|
2008-08-06 21:37:36 -04:00
|
|
|
case CAIRO_STATUS_INVALID_SLANT:
|
|
|
|
|
case CAIRO_STATUS_INVALID_WEIGHT:
|
2009-04-28 15:03:53 -04:00
|
|
|
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
|
2010-12-09 10:34:31 +01:00
|
|
|
case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
|
2008-01-16 16:23:23 +00:00
|
|
|
default:
|
|
|
|
|
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
|
|
|
|
return (cairo_surface_t *) &_cairo_surface_nil;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-06-09 16:52:17 -07:00
|
|
|
/* LocalWords: rasterized
|
|
|
|
|
*/
|