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 ▏
6
NEWS
|
|
@ -9,6 +9,12 @@ API additions:
|
||||||
Finally exporting the internal meta-surface so that applications
|
Finally exporting the internal meta-surface so that applications
|
||||||
have a method to record and replay a sequence of drawing commands.
|
have a method to record and replay a sequence of drawing commands.
|
||||||
|
|
||||||
|
cairo_in_clip()
|
||||||
|
|
||||||
|
Determines whether a given point is inside the current clip.
|
||||||
|
??? Should this be called cairo_in_paint() instead? in-clip is the test
|
||||||
|
that is performed, but in-paint would be similar to in-fill and in-stroke.
|
||||||
|
|
||||||
New utilities:
|
New utilities:
|
||||||
|
|
||||||
cairo-test-trace
|
cairo-test-trace
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@
|
||||||
static const cairo_user_data_key_t glitz_closure_key;
|
static const cairo_user_data_key_t glitz_closure_key;
|
||||||
|
|
||||||
typedef struct _glitz_glx_target_closure {
|
typedef struct _glitz_glx_target_closure {
|
||||||
glitz_target_closure_base_t base;
|
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
int scr;
|
int scr;
|
||||||
Window win;
|
Window win;
|
||||||
|
|
@ -206,9 +205,6 @@ _cairo_boilerplate_glitz_glx_create_surface (const char *name,
|
||||||
if (cairo_surface_status (surface))
|
if (cairo_surface_status (surface))
|
||||||
goto FAIL_CLOSE_DISPLAY;
|
goto FAIL_CLOSE_DISPLAY;
|
||||||
|
|
||||||
gxtc->base.width = width;
|
|
||||||
gxtc->base.height = height;
|
|
||||||
gxtc->base.content = content;
|
|
||||||
status = cairo_surface_set_user_data (surface,
|
status = cairo_surface_set_user_data (surface,
|
||||||
&glitz_closure_key, gxtc, NULL);
|
&glitz_closure_key, gxtc, NULL);
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
if (status == CAIRO_STATUS_SUCCESS)
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,6 @@ _cairo_boilerplate_pdf_finish_surface (cairo_surface_t *surface)
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
cairo_surface_finish (surface);
|
|
||||||
status = cairo_surface_status (surface);
|
status = cairo_surface_status (surface);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@ _cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface)
|
||||||
|
|
||||||
if (ptc->target) {
|
if (ptc->target) {
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
|
||||||
cr = cairo_create (ptc->target);
|
cr = cairo_create (ptc->target);
|
||||||
cairo_set_source_surface (cr, surface, 0, 0);
|
cairo_set_source_surface (cr, surface, 0, 0);
|
||||||
cairo_paint (cr);
|
cairo_paint (cr);
|
||||||
|
|
@ -188,7 +189,6 @@ _cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface)
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
cairo_surface_finish (surface);
|
|
||||||
status = cairo_surface_status (surface);
|
status = cairo_surface_status (surface);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -197,11 +197,7 @@ _cairo_boilerplate_ps_finish_surface (cairo_surface_t *surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_finish (surface);
|
cairo_surface_finish (surface);
|
||||||
status = cairo_surface_status (surface);
|
return cairo_surface_status (surface);
|
||||||
if (status)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
* The Initial Developer of the Original Code is Chris Wilson.
|
* The Initial Developer of the Original Code is Chris Wilson.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cairo-boilerplate.h"
|
#include "cairo-boilerplate-private.h"
|
||||||
|
|
||||||
#include <cairo-qt.h>
|
#include <cairo-qt.h>
|
||||||
|
|
||||||
|
|
@ -108,4 +108,6 @@ static const cairo_boilerplate_target_t targets[] = {
|
||||||
_cairo_boilerplate_qt_cleanup
|
_cairo_boilerplate_qt_cleanup
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
extern "C" {
|
||||||
CAIRO_BOILERPLATE (qt, targets)
|
CAIRO_BOILERPLATE (qt, targets)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,6 @@ _cairo_boilerplate_svg_finish_surface (cairo_surface_t *surface)
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
cairo_surface_finish (surface);
|
|
||||||
status = cairo_surface_status (surface);
|
status = cairo_surface_status (surface);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include <test-paginated-surface.h>
|
#include <test-paginated-surface.h>
|
||||||
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,9,3)
|
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,9,3)
|
||||||
#include <test-null-surface.h>
|
#include <test-null-surface.h>
|
||||||
|
#include <test-wrapping-surface.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cairo-types-private.h>
|
#include <cairo-types-private.h>
|
||||||
|
|
@ -49,7 +50,8 @@ _cairo_boilerplate_test_fallback_create_surface (const char *name,
|
||||||
void **closure)
|
void **closure)
|
||||||
{
|
{
|
||||||
*closure = NULL;
|
*closure = NULL;
|
||||||
return _cairo_test_fallback_surface_create (content, width, height);
|
return _cairo_test_fallback_surface_create (content,
|
||||||
|
ceil (width), ceil (height));
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
|
|
@ -64,7 +66,8 @@ _cairo_boilerplate_test_fallback16_create_surface (const char *name,
|
||||||
void **closure)
|
void **closure)
|
||||||
{
|
{
|
||||||
*closure = NULL;
|
*closure = NULL;
|
||||||
return _cairo_test_fallback16_surface_create (content, width, height);
|
return _cairo_test_fallback16_surface_create (content,
|
||||||
|
ceil (width), ceil (height));
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
|
|
@ -89,11 +92,7 @@ _cairo_boilerplate_test_null_create_surface (const char *name,
|
||||||
static const cairo_user_data_key_t test_paginated_closure_key;
|
static const cairo_user_data_key_t test_paginated_closure_key;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char *data;
|
cairo_surface_t *target;
|
||||||
cairo_content_t content;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
int stride;
|
|
||||||
} test_paginated_closure_t;
|
} test_paginated_closure_t;
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
|
|
@ -115,18 +114,10 @@ _cairo_boilerplate_test_paginated_create_surface (const char *name,
|
||||||
*closure = tpc = xmalloc (sizeof (test_paginated_closure_t));
|
*closure = tpc = xmalloc (sizeof (test_paginated_closure_t));
|
||||||
|
|
||||||
format = cairo_boilerplate_format_from_content (content);
|
format = cairo_boilerplate_format_from_content (content);
|
||||||
|
tpc->target = cairo_image_surface_create (format,
|
||||||
|
ceil (width), ceil (height));
|
||||||
|
|
||||||
tpc->content = content;
|
surface = _cairo_test_paginated_surface_create (tpc->target);
|
||||||
tpc->width = width;
|
|
||||||
tpc->height = height;
|
|
||||||
tpc->stride = cairo_format_stride_for_width (format, width);
|
|
||||||
tpc->data = xcalloc (tpc->stride, height);
|
|
||||||
|
|
||||||
surface = _cairo_test_paginated_surface_create_for_data (tpc->data,
|
|
||||||
tpc->content,
|
|
||||||
tpc->width,
|
|
||||||
tpc->height,
|
|
||||||
tpc->stride);
|
|
||||||
if (cairo_surface_status (surface))
|
if (cairo_surface_status (surface))
|
||||||
goto CLEANUP;
|
goto CLEANUP;
|
||||||
|
|
||||||
|
|
@ -139,8 +130,9 @@ _cairo_boilerplate_test_paginated_create_surface (const char *name,
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
surface = cairo_boilerplate_surface_create_in_error (status);
|
surface = cairo_boilerplate_surface_create_in_error (status);
|
||||||
|
|
||||||
|
cairo_surface_destroy (tpc->target);
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
free (tpc->data);
|
|
||||||
free (tpc);
|
free (tpc);
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
@ -160,8 +152,6 @@ static cairo_status_t
|
||||||
_cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t *surface,
|
_cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t *surface,
|
||||||
const char *filename)
|
const char *filename)
|
||||||
{
|
{
|
||||||
cairo_surface_t *image;
|
|
||||||
cairo_format_t format;
|
|
||||||
test_paginated_closure_t *tpc;
|
test_paginated_closure_t *tpc;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
|
|
@ -172,19 +162,7 @@ _cairo_boilerplate_test_paginated_surface_write_to_png (cairo_surface_t *surface
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key);
|
tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key);
|
||||||
|
return cairo_surface_write_to_png (tpc->target, filename);
|
||||||
format = cairo_boilerplate_format_from_content (tpc->content);
|
|
||||||
|
|
||||||
image = cairo_image_surface_create_for_data (tpc->data,
|
|
||||||
format,
|
|
||||||
tpc->width,
|
|
||||||
tpc->height,
|
|
||||||
tpc->stride);
|
|
||||||
|
|
||||||
status = cairo_surface_write_to_png (image, filename);
|
|
||||||
cairo_surface_destroy (image);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
|
|
@ -193,7 +171,6 @@ _cairo_boilerplate_test_paginated_get_image_surface (cairo_surface_t *surface,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
cairo_format_t format;
|
|
||||||
test_paginated_closure_t *tpc;
|
test_paginated_closure_t *tpc;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
|
|
@ -208,30 +185,7 @@ _cairo_boilerplate_test_paginated_get_image_surface (cairo_surface_t *surface,
|
||||||
return cairo_boilerplate_surface_create_in_error (status);
|
return cairo_boilerplate_surface_create_in_error (status);
|
||||||
|
|
||||||
tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key);
|
tpc = cairo_surface_get_user_data (surface, &test_paginated_closure_key);
|
||||||
|
return _cairo_boilerplate_get_image_surface (tpc->target, 0, width, height);
|
||||||
format = cairo_boilerplate_format_from_content (tpc->content);
|
|
||||||
|
|
||||||
if (0) {
|
|
||||||
return cairo_image_surface_create_for_data (tpc->data + tpc->stride * (tpc->height - height) + 4 * (tpc->width - width), /* hide the device offset */
|
|
||||||
format,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
tpc->stride);
|
|
||||||
} else {
|
|
||||||
cairo_surface_t *image, *surface;
|
|
||||||
|
|
||||||
image = cairo_image_surface_create_for_data (tpc->data,
|
|
||||||
format,
|
|
||||||
tpc->width,
|
|
||||||
tpc->height,
|
|
||||||
tpc->stride);
|
|
||||||
cairo_surface_set_device_offset (image,
|
|
||||||
tpc->width - width,
|
|
||||||
tpc->height - height);
|
|
||||||
surface = _cairo_boilerplate_get_image_surface (image, 0, width, height);
|
|
||||||
cairo_surface_destroy (image);
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -239,10 +193,40 @@ _cairo_boilerplate_test_paginated_cleanup (void *closure)
|
||||||
{
|
{
|
||||||
test_paginated_closure_t *tpc = closure;
|
test_paginated_closure_t *tpc = closure;
|
||||||
|
|
||||||
free (tpc->data);
|
cairo_surface_destroy (tpc->target);
|
||||||
free (tpc);
|
free (tpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
_cairo_boilerplate_test_wrapping_create_surface (const char *name,
|
||||||
|
cairo_content_t content,
|
||||||
|
double width,
|
||||||
|
double height,
|
||||||
|
double max_width,
|
||||||
|
double max_height,
|
||||||
|
cairo_boilerplate_mode_t mode,
|
||||||
|
int id,
|
||||||
|
void **closure)
|
||||||
|
{
|
||||||
|
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,9,3)
|
||||||
|
cairo_surface_t *target;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_format_t format;
|
||||||
|
|
||||||
|
*closure = NULL;
|
||||||
|
|
||||||
|
format = cairo_boilerplate_format_from_content (content);
|
||||||
|
target = cairo_image_surface_create (format, ceil (width), ceil (height));
|
||||||
|
surface = _cairo_test_wrapping_surface_create (target);
|
||||||
|
cairo_surface_destroy (target);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
#else
|
||||||
|
*closure = NULL;
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static const cairo_boilerplate_target_t targets[] = {
|
static const cairo_boilerplate_target_t targets[] = {
|
||||||
{
|
{
|
||||||
"test-fallback", "image", NULL, NULL,
|
"test-fallback", "image", NULL, NULL,
|
||||||
|
|
@ -304,6 +288,15 @@ static const cairo_boilerplate_target_t targets[] = {
|
||||||
NULL,
|
NULL,
|
||||||
FALSE, TRUE
|
FALSE, TRUE
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"test-wrapping", "image", NULL, NULL,
|
||||||
|
CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING,
|
||||||
|
CAIRO_CONTENT_COLOR_ALPHA, 0,
|
||||||
|
_cairo_boilerplate_test_wrapping_create_surface,
|
||||||
|
NULL, NULL,
|
||||||
|
_cairo_boilerplate_get_image_surface,
|
||||||
|
cairo_surface_write_to_png,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"null", "image", NULL, NULL,
|
"null", "image", NULL, NULL,
|
||||||
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
|
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@
|
||||||
#include <cairo-types-private.h>
|
#include <cairo-types-private.h>
|
||||||
#include <cairo-scaled-font-private.h>
|
#include <cairo-scaled-font-private.h>
|
||||||
|
|
||||||
|
#if CAIRO_HAS_SCRIPT_SURFACE
|
||||||
|
#include <cairo-script.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* get the "real" version info instead of dummy cairo-version.h */
|
/* get the "real" version info instead of dummy cairo-version.h */
|
||||||
#undef CAIRO_VERSION_H
|
#undef CAIRO_VERSION_H
|
||||||
#include "../cairo-version.h"
|
#include "../cairo-version.h"
|
||||||
|
|
@ -136,48 +140,74 @@ _cairo_boilerplate_meta_create_surface (const char *name,
|
||||||
int id,
|
int id,
|
||||||
void **closure)
|
void **closure)
|
||||||
{
|
{
|
||||||
|
cairo_rectangle_t extents;
|
||||||
|
|
||||||
*closure = NULL;
|
*closure = NULL;
|
||||||
return cairo_meta_surface_create (content, width, height);
|
|
||||||
|
extents.x = 0;
|
||||||
|
extents.y = 0;
|
||||||
|
extents.width = width;
|
||||||
|
extents.height = height;
|
||||||
|
return cairo_meta_surface_create (content, &extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cairo_user_data_key_t cairo_boilerplate_output_basename_key;
|
||||||
|
|
||||||
|
#if CAIRO_HAS_SCRIPT_SURFACE
|
||||||
|
static cairo_status_t
|
||||||
|
stdio_write (void *closure, const unsigned char *data, unsigned int len)
|
||||||
|
{
|
||||||
|
if (fwrite (data, len, 1, closure) != 1)
|
||||||
|
return CAIRO_STATUS_WRITE_ERROR;
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_boilerplate_get_image_surface (cairo_surface_t *src,
|
_cairo_boilerplate_get_image_surface (cairo_surface_t *src,
|
||||||
int page,
|
int page,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surface;
|
FILE *file = NULL;
|
||||||
|
cairo_surface_t *surface, *image;
|
||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
if (cairo_surface_status (src))
|
if (cairo_surface_status (src))
|
||||||
return cairo_surface_reference (src);
|
return cairo_surface_reference (src);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_IMAGE) {
|
|
||||||
int ww = cairo_image_surface_get_width (src);
|
|
||||||
int hh = cairo_image_surface_get_height (src);
|
|
||||||
if (width == ww && hh == height) {
|
|
||||||
return cairo_surface_reference (src);
|
|
||||||
} else {
|
|
||||||
cairo_format_t format = cairo_image_surface_get_format (src);
|
|
||||||
unsigned char *data = cairo_image_surface_get_data (src);
|
|
||||||
int stride = cairo_image_surface_get_stride (src);
|
|
||||||
|
|
||||||
data += stride * (hh - height) + 4 * (ww - width);
|
|
||||||
return cairo_image_surface_create_for_data (data,
|
|
||||||
format,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
stride);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (page != 0)
|
if (page != 0)
|
||||||
return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||||
|
|
||||||
/* extract sub-surface */
|
/* extract sub-surface */
|
||||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||||
|
image = cairo_surface_reference (surface);
|
||||||
|
|
||||||
|
/* open a logging channel (only interesting for meta surfaces) */
|
||||||
|
#if CAIRO_HAS_SCRIPT_SURFACE
|
||||||
|
if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_META) {
|
||||||
|
const char *test_name;
|
||||||
|
|
||||||
|
test_name = cairo_surface_get_user_data (src,
|
||||||
|
&cairo_boilerplate_output_basename_key);
|
||||||
|
if (test_name != NULL) {
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
xasprintf (&filename, "%s.out.trace", test_name);
|
||||||
|
file = fopen (filename, "w");
|
||||||
|
free (filename);
|
||||||
|
|
||||||
|
if (file != NULL) {
|
||||||
|
surface = cairo_script_surface_create_for_target (image,
|
||||||
|
stdio_write,
|
||||||
|
file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
cr = cairo_create (surface);
|
cr = cairo_create (surface);
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
|
|
||||||
|
|
@ -185,10 +215,17 @@ _cairo_boilerplate_get_image_surface (cairo_surface_t *src,
|
||||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||||
cairo_paint (cr);
|
cairo_paint (cr);
|
||||||
|
|
||||||
surface = cairo_surface_reference (cairo_get_target (cr));
|
status = cairo_status (cr);
|
||||||
|
if (status) {
|
||||||
|
cairo_surface_destroy (image);
|
||||||
|
image = cairo_surface_reference (cairo_get_target (cr));
|
||||||
|
}
|
||||||
cairo_destroy (cr);
|
cairo_destroy (cr);
|
||||||
|
|
||||||
return surface;
|
if (file != NULL)
|
||||||
|
fclose (file);
|
||||||
|
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
|
|
@ -705,8 +742,13 @@ cairo_boilerplate_convert_to_image (const char *filename, int page)
|
||||||
|
|
||||||
image = cairo_boilerplate_image_surface_create_from_ppm_stream (file);
|
image = cairo_boilerplate_image_surface_create_from_ppm_stream (file);
|
||||||
ret = pclose (file);
|
ret = pclose (file);
|
||||||
|
/* check for fatal errors from the interpreter */
|
||||||
|
if (ret) { /* any2pmm should never die... */
|
||||||
|
cairo_surface_destroy (image);
|
||||||
|
return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_INVALID_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
if (cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) {
|
if (ret == 0 && cairo_surface_status (image) == CAIRO_STATUS_READ_ERROR) {
|
||||||
if (flags == 0) {
|
if (flags == 0) {
|
||||||
/* Try again in a standalone process. */
|
/* Try again in a standalone process. */
|
||||||
cairo_surface_destroy (image);
|
cairo_surface_destroy (image);
|
||||||
|
|
@ -715,12 +757,6 @@ cairo_boilerplate_convert_to_image (const char *filename, int page)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cairo_surface_status (image) == CAIRO_STATUS_SUCCESS && ret != 0) {
|
|
||||||
cairo_surface_destroy (image);
|
|
||||||
image =
|
|
||||||
cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR);
|
|
||||||
};
|
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,8 @@ CAIRO_BEGIN_DECLS
|
||||||
* PDF surfaces. */
|
* PDF surfaces. */
|
||||||
#define CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED ((unsigned int) -1)
|
#define CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED ((unsigned int) -1)
|
||||||
|
|
||||||
|
extern const cairo_user_data_key_t cairo_boilerplate_output_basename_key;
|
||||||
|
|
||||||
cairo_content_t
|
cairo_content_t
|
||||||
cairo_boilerplate_content (cairo_content_t content);
|
cairo_boilerplate_content (cairo_content_t content);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ do_unaligned_clip (cairo_t *cr, int width, int height)
|
||||||
cairo_rectangle (cr, 55, 55, 35, 35);
|
cairo_rectangle (cr, 55, 55, 35, 35);
|
||||||
cairo_clip (cr);
|
cairo_clip (cr);
|
||||||
|
|
||||||
|
/* And paint something to force the clip to be evaluated. */
|
||||||
|
cairo_paint (cr);
|
||||||
|
|
||||||
cairo_perf_timer_stop ();
|
cairo_perf_timer_stop ();
|
||||||
|
|
||||||
cairo_restore (cr);
|
cairo_restore (cr);
|
||||||
|
|
|
||||||
|
|
@ -79,11 +79,14 @@ cairo_private = \
|
||||||
cairo-path-private.h \
|
cairo-path-private.h \
|
||||||
cairo-private.h \
|
cairo-private.h \
|
||||||
cairo-reference-count-private.h \
|
cairo-reference-count-private.h \
|
||||||
|
cairo-region-private.h \
|
||||||
cairo-scaled-font-private.h \
|
cairo-scaled-font-private.h \
|
||||||
cairo-skiplist-private.h \
|
cairo-skiplist-private.h \
|
||||||
cairo-spans-private.h \
|
cairo-spans-private.h \
|
||||||
cairo-surface-fallback-private.h \
|
cairo-surface-fallback-private.h \
|
||||||
cairo-surface-private.h \
|
cairo-surface-private.h \
|
||||||
|
cairo-surface-clipper-private.h \
|
||||||
|
cairo-surface-wrapper-private.h \
|
||||||
cairo-types-private.h \
|
cairo-types-private.h \
|
||||||
cairo-user-font-private.h \
|
cairo-user-font-private.h \
|
||||||
cairo-wideint-private.h \
|
cairo-wideint-private.h \
|
||||||
|
|
@ -138,6 +141,8 @@ cairo_sources = \
|
||||||
cairo-stroke-style.c \
|
cairo-stroke-style.c \
|
||||||
cairo-surface.c \
|
cairo-surface.c \
|
||||||
cairo-surface-fallback.c \
|
cairo-surface-fallback.c \
|
||||||
|
cairo-surface-clipper.c \
|
||||||
|
cairo-surface-wrapper.c \
|
||||||
cairo-tor-scan-converter.c \
|
cairo-tor-scan-converter.c \
|
||||||
cairo-system.c \
|
cairo-system.c \
|
||||||
cairo-traps.c \
|
cairo-traps.c \
|
||||||
|
|
@ -198,12 +203,14 @@ cairo_test_surfaces_private = \
|
||||||
test-fallback16-surface.h \
|
test-fallback16-surface.h \
|
||||||
test-null-surface.h \
|
test-null-surface.h \
|
||||||
test-paginated-surface.h \
|
test-paginated-surface.h \
|
||||||
|
test-wrapping-surface.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
cairo_test_surfaces_sources = \
|
cairo_test_surfaces_sources = \
|
||||||
test-fallback-surface.c \
|
test-fallback-surface.c \
|
||||||
test-fallback16-surface.c \
|
test-fallback16-surface.c \
|
||||||
test-null-surface.c \
|
test-null-surface.c \
|
||||||
test-paginated-surface.c \
|
test-paginated-surface.c \
|
||||||
|
test-wrapping-surface.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
cairo_xlib_headers = cairo-xlib.h
|
cairo_xlib_headers = cairo-xlib.h
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,11 @@
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
|
|
||||||
cairo_private cairo_surface_t *
|
cairo_private cairo_surface_t *
|
||||||
_cairo_analysis_surface_create (cairo_surface_t *target,
|
_cairo_analysis_surface_create (cairo_surface_t *target);
|
||||||
int width,
|
|
||||||
int height);
|
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_analysis_surface_set_ctm (cairo_surface_t *surface,
|
_cairo_analysis_surface_set_ctm (cairo_surface_t *surface,
|
||||||
cairo_matrix_t *ctm);
|
const cairo_matrix_t *ctm);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_analysis_surface_get_ctm (cairo_surface_t *surface,
|
_cairo_analysis_surface_get_ctm (cairo_surface_t *surface,
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,12 @@
|
||||||
#include "cairo-analysis-surface-private.h"
|
#include "cairo-analysis-surface-private.h"
|
||||||
#include "cairo-paginated-private.h"
|
#include "cairo-paginated-private.h"
|
||||||
#include "cairo-meta-surface-private.h"
|
#include "cairo-meta-surface-private.h"
|
||||||
|
#include "cairo-region-private.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
cairo_surface_t base;
|
cairo_surface_t base;
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
cairo_surface_t *target;
|
cairo_surface_t *target;
|
||||||
|
|
||||||
cairo_bool_t first_op;
|
cairo_bool_t first_op;
|
||||||
cairo_bool_t has_supported;
|
cairo_bool_t has_supported;
|
||||||
|
|
@ -53,7 +52,6 @@ typedef struct {
|
||||||
|
|
||||||
cairo_region_t supported_region;
|
cairo_region_t supported_region;
|
||||||
cairo_region_t fallback_region;
|
cairo_region_t fallback_region;
|
||||||
cairo_rectangle_int_t current_clip;
|
|
||||||
cairo_box_t page_bbox;
|
cairo_box_t page_bbox;
|
||||||
|
|
||||||
cairo_bool_t has_ctm;
|
cairo_bool_t has_ctm;
|
||||||
|
|
@ -97,61 +95,38 @@ static cairo_int_status_t
|
||||||
_analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
|
_analyze_meta_surface_pattern (cairo_analysis_surface_t *surface,
|
||||||
const cairo_pattern_t *pattern)
|
const cairo_pattern_t *pattern)
|
||||||
{
|
{
|
||||||
cairo_surface_t *analysis = &surface->base;
|
|
||||||
const cairo_surface_pattern_t *surface_pattern;
|
const cairo_surface_pattern_t *surface_pattern;
|
||||||
cairo_status_t status;
|
|
||||||
cairo_bool_t old_has_ctm;
|
cairo_bool_t old_has_ctm;
|
||||||
cairo_matrix_t old_ctm, p2d;
|
cairo_matrix_t old_ctm, p2d;
|
||||||
cairo_rectangle_int_t old_clip;
|
cairo_status_t status;
|
||||||
cairo_rectangle_int_t meta_extents;
|
|
||||||
int old_width;
|
|
||||||
int old_height;
|
|
||||||
|
|
||||||
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
|
assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
|
||||||
surface_pattern = (const cairo_surface_pattern_t *) pattern;
|
surface_pattern = (const cairo_surface_pattern_t *) pattern;
|
||||||
assert (_cairo_surface_is_meta (surface_pattern->surface));
|
assert (_cairo_surface_is_meta (surface_pattern->surface));
|
||||||
|
|
||||||
old_width = surface->width;
|
|
||||||
old_height = surface->height;
|
|
||||||
old_clip = surface->current_clip;
|
|
||||||
status = _cairo_surface_get_extents (surface_pattern->surface, &meta_extents);
|
|
||||||
if (_cairo_status_is_error (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
surface->width = meta_extents.width;
|
|
||||||
surface->height = meta_extents.height;
|
|
||||||
surface->current_clip.x = 0;
|
|
||||||
surface->current_clip.y = 0;
|
|
||||||
surface->current_clip.width = surface->width;
|
|
||||||
surface->current_clip.height = surface->height;
|
|
||||||
old_ctm = surface->ctm;
|
old_ctm = surface->ctm;
|
||||||
old_has_ctm = surface->has_ctm;
|
old_has_ctm = surface->has_ctm;
|
||||||
|
|
||||||
p2d = pattern->matrix;
|
p2d = pattern->matrix;
|
||||||
status = cairo_matrix_invert (&p2d);
|
status = cairo_matrix_invert (&p2d);
|
||||||
/* _cairo_pattern_set_matrix guarantees invertibility */
|
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm);
|
cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm);
|
||||||
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
|
surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
|
||||||
|
|
||||||
status = _cairo_meta_surface_replay_and_create_regions (surface_pattern->surface,
|
status = _cairo_meta_surface_replay_and_create_regions (surface_pattern->surface,
|
||||||
analysis);
|
&surface->base);
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
|
||||||
status = analysis->status;
|
|
||||||
|
|
||||||
surface->ctm = old_ctm;
|
surface->ctm = old_ctm;
|
||||||
surface->has_ctm = old_has_ctm;
|
surface->has_ctm = old_has_ctm;
|
||||||
surface->current_clip = old_clip;
|
|
||||||
surface->width = old_width;
|
|
||||||
surface->height = old_height;
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_add_operation (cairo_analysis_surface_t *surface,
|
_add_operation (cairo_analysis_surface_t *surface,
|
||||||
cairo_rectangle_int_t *rect,
|
cairo_rectangle_int_t *rect,
|
||||||
cairo_int_status_t backend_status)
|
cairo_int_status_t backend_status)
|
||||||
{
|
{
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
cairo_box_t bbox;
|
cairo_box_t bbox;
|
||||||
|
|
@ -174,26 +149,33 @@ _add_operation (cairo_analysis_surface_t *surface,
|
||||||
_cairo_box_from_rectangle (&bbox, rect);
|
_cairo_box_from_rectangle (&bbox, rect);
|
||||||
|
|
||||||
if (surface->has_ctm) {
|
if (surface->has_ctm) {
|
||||||
|
int tx, ty;
|
||||||
|
|
||||||
_cairo_matrix_transform_bounding_box_fixed (&surface->ctm, &bbox, NULL);
|
if (_cairo_matrix_is_integer_translation (&surface->ctm, &tx, &ty)) {
|
||||||
|
rect->x += tx;
|
||||||
|
rect->y += ty;
|
||||||
|
} else {
|
||||||
|
_cairo_matrix_transform_bounding_box_fixed (&surface->ctm,
|
||||||
|
&bbox, NULL);
|
||||||
|
|
||||||
if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
|
if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
|
||||||
/* Even though the operation is not visible we must be
|
/* Even though the operation is not visible we must be
|
||||||
* careful to not allow unsupported operations to be
|
* careful to not allow unsupported operations to be
|
||||||
* replayed to the backend during
|
* replayed to the backend during
|
||||||
* CAIRO_PAGINATED_MODE_RENDER */
|
* CAIRO_PAGINATED_MODE_RENDER */
|
||||||
if (backend_status == CAIRO_STATUS_SUCCESS ||
|
if (backend_status == CAIRO_STATUS_SUCCESS ||
|
||||||
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
|
backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
|
||||||
{
|
{
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cairo_box_round_to_rectangle (&bbox, rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_box_round_to_rectangle (&bbox, rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface->first_op) {
|
if (surface->first_op) {
|
||||||
|
|
@ -234,8 +216,7 @@ _add_operation (cairo_analysis_surface_t *surface,
|
||||||
* this region will be emitted as native operations.
|
* this region will be emitted as native operations.
|
||||||
*/
|
*/
|
||||||
surface->has_supported = TRUE;
|
surface->has_supported = TRUE;
|
||||||
status = cairo_region_union_rectangle (&surface->supported_region, rect);
|
return cairo_region_union_rectangle (&surface->supported_region, rect);
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the operation to the unsupported region. This region will
|
/* Add the operation to the unsupported region. This region will
|
||||||
|
|
@ -270,33 +251,7 @@ _cairo_analysis_surface_finish (void *abstract_surface)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_analysis_surface_intersect_clip_path (void *abstract_surface,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias)
|
|
||||||
{
|
|
||||||
cairo_analysis_surface_t *surface = abstract_surface;
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
surface->current_clip.x = 0;
|
|
||||||
surface->current_clip.y = 0;
|
|
||||||
surface->current_clip.width = surface->width;
|
|
||||||
surface->current_clip.height = surface->height;
|
|
||||||
} else {
|
|
||||||
cairo_rectangle_int_t extents;
|
|
||||||
cairo_bool_t is_empty;
|
|
||||||
|
|
||||||
_cairo_path_fixed_approximate_clip_extents (path, &extents);
|
|
||||||
is_empty = _cairo_rectangle_intersect (&surface->current_clip,
|
|
||||||
&extents);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_analysis_surface_get_extents (void *abstract_surface,
|
_cairo_analysis_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -305,66 +260,92 @@ _cairo_analysis_surface_get_extents (void *abstract_surface,
|
||||||
return _cairo_surface_get_extents (surface->target, rectangle);
|
return _cairo_surface_get_extents (surface->target, rectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static void
|
||||||
_cairo_analysis_surface_paint (void *abstract_surface,
|
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip)
|
||||||
cairo_operator_t op,
|
|
||||||
const cairo_pattern_t *source,
|
|
||||||
cairo_rectangle_int_t *paint_extents)
|
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface = abstract_surface;
|
const cairo_rectangle_int_t *clip_extents;
|
||||||
cairo_status_t status, backend_status;
|
|
||||||
cairo_rectangle_int_t extents;
|
|
||||||
cairo_bool_t is_empty;
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
if (!surface->target->backend->paint)
|
clip_extents = NULL;
|
||||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
if (clip != NULL)
|
||||||
else
|
clip_extents = _cairo_clip_get_extents (clip);
|
||||||
backend_status = (*surface->target->backend->paint) (surface->target, op,
|
|
||||||
source, NULL);
|
|
||||||
|
|
||||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
if (clip_extents != NULL)
|
||||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
is_empty = _cairo_rectangle_intersect (extents, clip_extents);
|
||||||
|
}
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
static void
|
||||||
if (_cairo_status_is_error (status))
|
_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface,
|
||||||
return status;
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_clip_t *clip,
|
||||||
|
cairo_rectangle_int_t *extents)
|
||||||
|
{
|
||||||
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
|
is_empty = _cairo_surface_get_extents (&surface->base, extents);
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_source (op)) {
|
if (_cairo_operator_bounded_by_source (op)) {
|
||||||
cairo_rectangle_int_t source_extents;
|
cairo_rectangle_int_t source_extents;
|
||||||
|
|
||||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
_cairo_pattern_get_extents (source, &source_extents);
|
||||||
if (unlikely (status))
|
is_empty = _cairo_rectangle_intersect (extents, &source_extents);
|
||||||
return status;
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
_rectangle_intersect_clip (extents, clip);
|
||||||
if (paint_extents)
|
|
||||||
*paint_extents = extents;
|
|
||||||
|
|
||||||
status = _add_operation (surface, &extents, backend_status);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_analysis_surface_mask (void *abstract_surface,
|
_cairo_analysis_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
cairo_clip_t *clip)
|
||||||
cairo_rectangle_int_t *mask_extents)
|
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface = abstract_surface;
|
cairo_analysis_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status, backend_status;
|
cairo_status_t backend_status;
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
|
if (surface->target->backend->paint == NULL) {
|
||||||
|
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
} else {
|
||||||
|
backend_status =
|
||||||
|
surface->target->backend->paint (surface->target,
|
||||||
|
op, source, clip);
|
||||||
|
if (_cairo_status_is_error (backend_status))
|
||||||
|
return backend_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||||
|
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||||
|
|
||||||
|
_cairo_analysis_surface_operation_extents (surface,
|
||||||
|
op, source, clip,
|
||||||
|
&extents);
|
||||||
|
|
||||||
|
return _add_operation (surface, &extents, backend_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_cairo_analysis_surface_mask (void *abstract_surface,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
const cairo_pattern_t *mask,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_analysis_surface_t *surface = abstract_surface;
|
||||||
|
cairo_int_status_t backend_status;
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
cairo_bool_t is_empty;
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
if (!surface->target->backend->mask)
|
if (surface->target->backend->mask == NULL) {
|
||||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
else
|
} else {
|
||||||
backend_status = (*surface->target->backend->mask) (surface->target, op,
|
backend_status =
|
||||||
source, mask, NULL);
|
surface->target->backend->mask (surface->target,
|
||||||
|
op, source, mask, clip);
|
||||||
|
if (_cairo_status_is_error (backend_status))
|
||||||
|
return backend_status;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) {
|
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN) {
|
||||||
cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
|
cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -395,37 +376,19 @@ _cairo_analysis_surface_mask (void *abstract_surface,
|
||||||
backend_mask_status);
|
backend_mask_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
_cairo_analysis_surface_operation_extents (surface,
|
||||||
if (_cairo_status_is_error (status))
|
op, source, clip,
|
||||||
return status;
|
&extents);
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_source (op)) {
|
|
||||||
cairo_rectangle_int_t source_extents;
|
|
||||||
|
|
||||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_mask (op)) {
|
if (_cairo_operator_bounded_by_mask (op)) {
|
||||||
cairo_rectangle_int_t mask_extents;
|
cairo_rectangle_int_t mask_extents;
|
||||||
|
|
||||||
status = _cairo_pattern_get_extents (mask, &mask_extents);
|
_cairo_pattern_get_extents (mask, &mask_extents);
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
|
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
return _add_operation (surface, &extents, backend_status);
|
||||||
if (mask_extents)
|
|
||||||
*mask_extents = extents;
|
|
||||||
|
|
||||||
status = _add_operation (surface, &extents, backend_status);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -438,55 +401,61 @@ _cairo_analysis_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *stroke_extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface = abstract_surface;
|
cairo_analysis_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status, backend_status;
|
cairo_status_t backend_status;
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
cairo_bool_t is_empty;
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
if (!surface->target->backend->stroke)
|
if (surface->target->backend->stroke == NULL) {
|
||||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
else
|
} else {
|
||||||
backend_status = (*surface->target->backend->stroke) (surface->target, op,
|
backend_status =
|
||||||
source, path, style,
|
surface->target->backend->stroke (surface->target, op,
|
||||||
ctm, ctm_inverse,
|
source, path, style,
|
||||||
tolerance, antialias, NULL);
|
ctm, ctm_inverse,
|
||||||
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
|
if (_cairo_status_is_error (backend_status))
|
||||||
|
return backend_status;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
_cairo_analysis_surface_operation_extents (surface,
|
||||||
if (_cairo_status_is_error (status))
|
op, source, clip,
|
||||||
return status;
|
&extents);
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_source (op)) {
|
|
||||||
cairo_rectangle_int_t source_extents;
|
|
||||||
|
|
||||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
|
||||||
}
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_mask (op)) {
|
if (_cairo_operator_bounded_by_mask (op)) {
|
||||||
cairo_rectangle_int_t mask_extents;
|
cairo_rectangle_int_t mask_extents;
|
||||||
|
|
||||||
_cairo_path_fixed_approximate_stroke_extents (path,
|
/* If the backend can handle the stroke, then mark the approximate
|
||||||
style, ctm,
|
* extents of the operation. However, if we need to fallback in order
|
||||||
&mask_extents);
|
* to draw the stroke, then ensure that the fallback is as tight as
|
||||||
|
* possible -- both to minimise output file size and to ensure good
|
||||||
|
* quality printed output for neighbouring regions.
|
||||||
|
*/
|
||||||
|
if (backend_status == CAIRO_STATUS_SUCCESS) {
|
||||||
|
_cairo_path_fixed_approximate_stroke_extents (path,
|
||||||
|
style, ctm,
|
||||||
|
&mask_extents);
|
||||||
|
} else {
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_path_fixed_stroke_extents (path, style,
|
||||||
|
ctm, ctm_inverse,
|
||||||
|
tolerance,
|
||||||
|
&mask_extents);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
|
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
|
||||||
}
|
}
|
||||||
if (stroke_extents)
|
|
||||||
*stroke_extents = extents;
|
|
||||||
|
|
||||||
status = _add_operation (surface, &extents, backend_status);
|
return _add_operation (surface, &extents, backend_status);
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -497,53 +466,49 @@ _cairo_analysis_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *fill_extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface = abstract_surface;
|
cairo_analysis_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status, backend_status;
|
cairo_status_t backend_status;
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
cairo_bool_t is_empty;
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
if (!surface->target->backend->fill)
|
if (surface->target->backend->fill == NULL) {
|
||||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
else
|
} else {
|
||||||
backend_status = (*surface->target->backend->fill) (surface->target, op,
|
backend_status =
|
||||||
source, path, fill_rule,
|
surface->target->backend->fill (surface->target, op,
|
||||||
tolerance, antialias, NULL);
|
source, path, fill_rule,
|
||||||
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
|
if (_cairo_status_is_error (backend_status))
|
||||||
|
return backend_status;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
_cairo_analysis_surface_operation_extents (surface,
|
||||||
if (_cairo_status_is_error (status))
|
op, source, clip,
|
||||||
return status;
|
&extents);
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_source (op)) {
|
|
||||||
cairo_rectangle_int_t source_extents;
|
|
||||||
|
|
||||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
|
||||||
}
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_mask (op)) {
|
if (_cairo_operator_bounded_by_mask (op)) {
|
||||||
cairo_rectangle_int_t mask_extents;
|
cairo_rectangle_int_t mask_extents;
|
||||||
|
|
||||||
_cairo_path_fixed_approximate_fill_extents (path,
|
/* We want speed for the likely case where the operation can be
|
||||||
&mask_extents);
|
* performed natively, but accuracy if we have to resort to
|
||||||
|
* using images.
|
||||||
|
*/
|
||||||
|
if (backend_status == CAIRO_STATUS_SUCCESS) {
|
||||||
|
_cairo_path_fixed_approximate_fill_extents (path, &mask_extents);
|
||||||
|
} else {
|
||||||
|
_cairo_path_fixed_fill_extents (path, fill_rule, tolerance,
|
||||||
|
&mask_extents);
|
||||||
|
}
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
|
is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
|
||||||
}
|
}
|
||||||
if (fill_extents)
|
|
||||||
*fill_extents = extents;
|
|
||||||
|
|
||||||
status = _add_operation (surface, &extents, backend_status);
|
return _add_operation (surface, &extents, backend_status);
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -553,8 +518,8 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *show_glyphs_extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface = abstract_surface;
|
cairo_analysis_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status, backend_status;
|
cairo_status_t status, backend_status;
|
||||||
|
|
@ -562,41 +527,42 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_bool_t is_empty;
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
/* Adapted from _cairo_surface_show_glyphs */
|
/* Adapted from _cairo_surface_show_glyphs */
|
||||||
if (surface->target->backend->show_glyphs)
|
if (surface->target->backend->show_glyphs != NULL) {
|
||||||
backend_status = (*surface->target->backend->show_glyphs) (surface->target, op,
|
backend_status =
|
||||||
source,
|
surface->target->backend->show_glyphs (surface->target, op,
|
||||||
glyphs, num_glyphs,
|
source,
|
||||||
scaled_font,
|
glyphs, num_glyphs,
|
||||||
remaining_glyphs, NULL);
|
scaled_font,
|
||||||
else if (surface->target->backend->show_text_glyphs)
|
clip,
|
||||||
backend_status = surface->target->backend->show_text_glyphs (surface->target, op,
|
remaining_glyphs);
|
||||||
source,
|
if (_cairo_status_is_error (backend_status))
|
||||||
NULL, 0,
|
return backend_status;
|
||||||
glyphs, num_glyphs,
|
}
|
||||||
NULL, 0,
|
else if (surface->target->backend->show_text_glyphs != NULL)
|
||||||
FALSE,
|
{
|
||||||
scaled_font, NULL);
|
backend_status =
|
||||||
|
surface->target->backend->show_text_glyphs (surface->target, op,
|
||||||
|
source,
|
||||||
|
NULL, 0,
|
||||||
|
glyphs, num_glyphs,
|
||||||
|
NULL, 0,
|
||||||
|
FALSE,
|
||||||
|
scaled_font,
|
||||||
|
clip);
|
||||||
|
if (_cairo_status_is_error (backend_status))
|
||||||
|
return backend_status;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
_cairo_analysis_surface_operation_extents (surface,
|
||||||
if (_cairo_status_is_error (status))
|
op, source, clip,
|
||||||
return status;
|
&extents);
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_source (op)) {
|
|
||||||
cairo_rectangle_int_t source_extents;
|
|
||||||
|
|
||||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
|
||||||
}
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_mask (op)) {
|
if (_cairo_operator_bounded_by_mask (op)) {
|
||||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||||
|
|
@ -608,12 +574,8 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface,
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
|
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
|
||||||
}
|
}
|
||||||
if (show_glyphs_extents)
|
|
||||||
*show_glyphs_extents = extents;
|
|
||||||
|
|
||||||
status = _add_operation (surface, &extents, backend_status);
|
return _add_operation (surface, &extents, backend_status);
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -636,7 +598,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *show_text_glyphs_extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface = abstract_surface;
|
cairo_analysis_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status, backend_status;
|
cairo_status_t status, backend_status;
|
||||||
|
|
@ -645,20 +607,33 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
|
||||||
|
|
||||||
/* Adapted from _cairo_surface_show_glyphs */
|
/* Adapted from _cairo_surface_show_glyphs */
|
||||||
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
if (surface->target->backend->show_text_glyphs)
|
if (surface->target->backend->show_text_glyphs != NULL) {
|
||||||
backend_status = surface->target->backend->show_text_glyphs (surface->target, op,
|
backend_status =
|
||||||
source,
|
surface->target->backend->show_text_glyphs (surface->target, op,
|
||||||
utf8, utf8_len,
|
source,
|
||||||
glyphs, num_glyphs,
|
utf8, utf8_len,
|
||||||
clusters, num_clusters, cluster_flags,
|
glyphs, num_glyphs,
|
||||||
scaled_font, NULL);
|
clusters, num_clusters,
|
||||||
if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED && surface->target->backend->show_glyphs) {
|
cluster_flags,
|
||||||
|
scaled_font,
|
||||||
|
clip);
|
||||||
|
if (_cairo_status_is_error (backend_status))
|
||||||
|
return backend_status;
|
||||||
|
}
|
||||||
|
if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED &&
|
||||||
|
surface->target->backend->show_glyphs != NULL)
|
||||||
|
{
|
||||||
int remaining_glyphs = num_glyphs;
|
int remaining_glyphs = num_glyphs;
|
||||||
backend_status = surface->target->backend->show_glyphs (surface->target, op,
|
backend_status =
|
||||||
source,
|
surface->target->backend->show_glyphs (surface->target, op,
|
||||||
glyphs, num_glyphs,
|
source,
|
||||||
scaled_font,
|
glyphs, num_glyphs,
|
||||||
&remaining_glyphs, NULL);
|
scaled_font,
|
||||||
|
clip,
|
||||||
|
&remaining_glyphs);
|
||||||
|
if (_cairo_status_is_error (backend_status))
|
||||||
|
return backend_status;
|
||||||
|
|
||||||
glyphs += num_glyphs - remaining_glyphs;
|
glyphs += num_glyphs - remaining_glyphs;
|
||||||
num_glyphs = remaining_glyphs;
|
num_glyphs = remaining_glyphs;
|
||||||
if (remaining_glyphs == 0)
|
if (remaining_glyphs == 0)
|
||||||
|
|
@ -668,21 +643,9 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
|
||||||
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
if (backend_status == CAIRO_INT_STATUS_ANALYZE_META_SURFACE_PATTERN)
|
||||||
backend_status = _analyze_meta_surface_pattern (surface, source);
|
backend_status = _analyze_meta_surface_pattern (surface, source);
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
_cairo_analysis_surface_operation_extents (surface,
|
||||||
if (_cairo_status_is_error (status))
|
op, source, clip,
|
||||||
return status;
|
&extents);
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_source (op)) {
|
|
||||||
cairo_rectangle_int_t source_extents;
|
|
||||||
|
|
||||||
status = _cairo_pattern_get_extents (source, &source_extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &source_extents);
|
|
||||||
}
|
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &surface->current_clip);
|
|
||||||
|
|
||||||
if (_cairo_operator_bounded_by_mask (op)) {
|
if (_cairo_operator_bounded_by_mask (op)) {
|
||||||
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
status = _cairo_scaled_font_glyph_device_extents (scaled_font,
|
||||||
|
|
@ -694,12 +657,8 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface,
|
||||||
|
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
|
is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
|
||||||
}
|
}
|
||||||
if (show_text_glyphs_extents)
|
|
||||||
*show_text_glyphs_extents = extents;
|
|
||||||
|
|
||||||
status = _add_operation (surface, &extents, backend_status);
|
return _add_operation (surface, &extents, backend_status);
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
||||||
|
|
@ -718,8 +677,6 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_analysis_surface_intersect_clip_path,
|
|
||||||
_cairo_analysis_surface_get_extents,
|
_cairo_analysis_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -734,7 +691,6 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
||||||
_cairo_analysis_surface_show_glyphs,
|
_cairo_analysis_surface_show_glyphs,
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
@ -743,9 +699,7 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = {
|
||||||
};
|
};
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_analysis_surface_create (cairo_surface_t *target,
|
_cairo_analysis_surface_create (cairo_surface_t *target)
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface;
|
cairo_analysis_surface_t *surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -763,8 +717,6 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
|
||||||
_cairo_surface_init (&surface->base, &cairo_analysis_surface_backend,
|
_cairo_surface_init (&surface->base, &cairo_analysis_surface_backend,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA);
|
CAIRO_CONTENT_COLOR_ALPHA);
|
||||||
|
|
||||||
surface->width = width;
|
|
||||||
surface->height = height;
|
|
||||||
cairo_matrix_init_identity (&surface->ctm);
|
cairo_matrix_init_identity (&surface->ctm);
|
||||||
surface->has_ctm = FALSE;
|
surface->has_ctm = FALSE;
|
||||||
|
|
||||||
|
|
@ -781,24 +733,12 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
|
||||||
surface->page_bbox.p2.x = 0;
|
surface->page_bbox.p2.x = 0;
|
||||||
surface->page_bbox.p2.y = 0;
|
surface->page_bbox.p2.y = 0;
|
||||||
|
|
||||||
if (width == -1 && height == -1) {
|
|
||||||
surface->current_clip.x = CAIRO_RECT_INT_MIN;
|
|
||||||
surface->current_clip.y = CAIRO_RECT_INT_MIN;
|
|
||||||
surface->current_clip.width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
|
||||||
surface->current_clip.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
|
||||||
} else {
|
|
||||||
surface->current_clip.x = 0;
|
|
||||||
surface->current_clip.y = 0;
|
|
||||||
surface->current_clip.width = width;
|
|
||||||
surface->current_clip.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &surface->base;
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface,
|
_cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface,
|
||||||
cairo_matrix_t *ctm)
|
const cairo_matrix_t *ctm)
|
||||||
{
|
{
|
||||||
cairo_analysis_surface_t *surface;
|
cairo_analysis_surface_t *surface;
|
||||||
|
|
||||||
|
|
@ -808,7 +748,7 @@ _cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface,
|
||||||
surface = (cairo_analysis_surface_t *) abstract_surface;
|
surface = (cairo_analysis_surface_t *) abstract_surface;
|
||||||
|
|
||||||
surface->ctm = *ctm;
|
surface->ctm = *ctm;
|
||||||
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
|
surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -871,22 +811,18 @@ _return_success (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These typedefs are just to silence the compiler... */
|
/* These typedefs are just to silence the compiler... */
|
||||||
typedef cairo_int_status_t
|
|
||||||
(*_set_clip_region_func) (void *surface,
|
|
||||||
cairo_region_t *region);
|
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_paint_func) (void *surface,
|
(*_paint_func) (void *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_mask_func) (void *surface,
|
(*_mask_func) (void *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_stroke_func) (void *surface,
|
(*_stroke_func) (void *surface,
|
||||||
|
|
@ -898,7 +834,7 @@ typedef cairo_int_status_t
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_fill_func) (void *surface,
|
(*_fill_func) (void *surface,
|
||||||
|
|
@ -908,7 +844,7 @@ typedef cairo_int_status_t
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_show_glyphs_func) (void *surface,
|
(*_show_glyphs_func) (void *surface,
|
||||||
|
|
@ -917,8 +853,8 @@ typedef cairo_int_status_t
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents);
|
int *remaining_glyphs);
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_null_surface_backend = {
|
static const cairo_surface_backend_t cairo_null_surface_backend = {
|
||||||
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
|
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
|
||||||
|
|
@ -937,8 +873,6 @@ static const cairo_surface_backend_t cairo_null_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
(_set_clip_region_func) _return_success, /* set_clip_region */
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
NULL, /* get_extents */
|
NULL, /* get_extents */
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -953,7 +887,6 @@ static const cairo_surface_backend_t cairo_null_surface_backend = {
|
||||||
(_show_glyphs_func) _return_success, /* show_glyphs */
|
(_show_glyphs_func) _return_success, /* show_glyphs */
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@
|
||||||
struct cairo_beos_surface_t {
|
struct cairo_beos_surface_t {
|
||||||
cairo_surface_t base;
|
cairo_surface_t base;
|
||||||
|
|
||||||
|
cairo_region_t *clip_region;
|
||||||
|
|
||||||
BView* view;
|
BView* view;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -70,7 +72,6 @@ struct cairo_beos_surface_t {
|
||||||
|
|
||||||
BBitmap* bitmap;
|
BBitmap* bitmap;
|
||||||
|
|
||||||
|
|
||||||
// If true, surface and view should be deleted when this surface is
|
// If true, surface and view should be deleted when this surface is
|
||||||
// destroyed
|
// destroyed
|
||||||
bool owns_bitmap_view;
|
bool owns_bitmap_view;
|
||||||
|
|
@ -101,27 +102,28 @@ _cairo_beos_surface_create_internal (BView* view,
|
||||||
BBitmap* bmp,
|
BBitmap* bmp,
|
||||||
bool owns_bitmap_view = false);
|
bool owns_bitmap_view = false);
|
||||||
|
|
||||||
static BRect
|
static inline BRect
|
||||||
_cairo_rect_to_brect (const cairo_rectangle_int16_t* rect)
|
_cairo_rectangle_to_brect (const cairo_rectangle_int_t* rect)
|
||||||
{
|
{
|
||||||
// A BRect is one pixel wider than you'd think
|
// A BRect is one pixel wider than you'd think
|
||||||
return BRect(rect->x, rect->y, rect->x + rect->width - 1,
|
return BRect (rect->x, rect->y,
|
||||||
rect->y + rect->height - 1);
|
rect->x + rect->width - 1,
|
||||||
|
rect->y + rect->height - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_rectangle_int16_t
|
static inline cairo_rectangle_int_t
|
||||||
_brect_to_cairo_rect (const BRect& rect)
|
_brect_to_cairo_rectangle (const BRect &rect)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int16_t retval;
|
cairo_rectangle_int_t retval;
|
||||||
retval.x = int(rect.left + 0.5);
|
retval.x = floor (rect.left);
|
||||||
retval.y = int(rect.top + 0.5);
|
retval.y = floor (rect.top);
|
||||||
retval.width = rect.IntegerWidth() + 1;
|
retval.width = ceil (rect.right) - retval.x + 1;
|
||||||
retval.height = rect.IntegerHeight() + 1;
|
retval.height = ceil (rect.bottom) - rectval.y + 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rgb_color
|
static inline rgb_color
|
||||||
_cairo_color_to_be_color (const cairo_color_t* color)
|
_cairo_color_to_be_color (const cairo_color_t *color)
|
||||||
{
|
{
|
||||||
// This factor ensures a uniform distribution of numbers
|
// This factor ensures a uniform distribution of numbers
|
||||||
const float factor = 256 - 1e-5;
|
const float factor = 256 - 1e-5;
|
||||||
|
|
@ -199,32 +201,8 @@ _cairo_beos_view_to_bitmap (BView* view,
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned char
|
|
||||||
unpremultiply (unsigned char color,
|
|
||||||
unsigned char alpha)
|
|
||||||
{
|
|
||||||
if (alpha == 0)
|
|
||||||
return 0;
|
|
||||||
// plus alpha/2 to round instead of truncate
|
|
||||||
return (color * 255 + alpha / 2) / alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned char
|
|
||||||
premultiply (unsigned char color,
|
|
||||||
unsigned char alpha)
|
|
||||||
{
|
|
||||||
// + 127 to round, instead of truncate
|
|
||||||
return (color * alpha + 127) / 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unpremultiply_rgba:
|
|
||||||
*
|
|
||||||
* Takes an input in ABGR premultiplied image data and unmultiplies it.
|
|
||||||
* The result is stored in retdata.
|
|
||||||
**/
|
|
||||||
static void
|
static void
|
||||||
unpremultiply_rgba (unsigned char* data,
|
unpremultiply_bgra (unsigned char* data,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int stride,
|
int stride,
|
||||||
|
|
@ -235,52 +213,108 @@ unpremultiply_rgba (unsigned char* data,
|
||||||
in < end;
|
in < end;
|
||||||
in += stride, out += stride)
|
in += stride, out += stride)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < width; ++i) {
|
for (int i = 0; i < width; i ++) {
|
||||||
// XXX for a big-endian platform this'd have to change
|
uint8_t *b = &out[4*i];
|
||||||
int idx = 4 * i;
|
uint32_t pixel;
|
||||||
unsigned char alpha = in[idx + 3];
|
uint8_t alpha;
|
||||||
out[idx + 0] = unpremultiply(in[idx + 0], alpha); // B
|
|
||||||
out[idx + 1] = unpremultiply(in[idx + 1], alpha); // G
|
memcpy (&pixel, &data[4*i], sizeof (uint32_t));
|
||||||
out[idx + 2] = unpremultiply(in[idx + 2], alpha); // R
|
alpha = pixel & 0xff;
|
||||||
out[idx + 3] = in[idx + 3]; // Alpha
|
if (alpha == 0) {
|
||||||
|
b[0] = b[1] = b[2] = b[3] = 0;
|
||||||
|
} else {
|
||||||
|
b[0] = (((pixel >> 24) & 0xff) * 255 + alpha / 2) / alpha;
|
||||||
|
b[1] = (((pixel >> 16) & 0xff) * 255 + alpha / 2) / alpha;
|
||||||
|
b[2] = (((pixel >> 8) & 0xff) * 255 + alpha / 2) / alpha;
|
||||||
|
b[3] = alpha;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static inline int
|
||||||
* premultiply_rgba:
|
multiply_alpha (int alpha, int color)
|
||||||
*
|
{
|
||||||
* Takes an input in ABGR non-premultiplied image data and premultiplies it.
|
int temp = (alpha * color) + 0x80;
|
||||||
* The returned data must be freed with free().
|
return ((temp + (temp >> 8)) >> 8);
|
||||||
**/
|
}
|
||||||
|
|
||||||
static unsigned char*
|
static unsigned char*
|
||||||
premultiply_rgba (unsigned char* data,
|
premultiply_bgra (unsigned char* data,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int stride)
|
int stride)
|
||||||
{
|
{
|
||||||
unsigned char* retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride));
|
uint8_t * retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride));
|
||||||
if (!retdata)
|
if (!retdata)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
unsigned char* end = data + stride * height;
|
uint8_t * end = data + stride * height;
|
||||||
for (unsigned char* in = data, *out = retdata;
|
for (uint8_t * in = data, *out = retdata;
|
||||||
in < end;
|
in < end;
|
||||||
in += stride, out += stride)
|
in += stride, out += stride)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < width; ++i) {
|
for (int i = 0; i < width; i ++) {
|
||||||
// XXX for a big-endian platform this'd have to change
|
uint8_t *base = &in[4*i];
|
||||||
int idx = 4 * i;
|
uint8_t alpha = base[3];
|
||||||
unsigned char alpha = in[idx + 3];
|
uint32_t p;
|
||||||
out[idx + 0] = premultiply(in[idx + 0], alpha); // B
|
|
||||||
out[idx + 1] = premultiply(in[idx + 1], alpha); // G
|
if (alpha == 0) {
|
||||||
out[idx + 2] = premultiply(in[idx + 2], alpha); // R
|
p = 0;
|
||||||
out[idx + 3] = in[idx + 3]; // Alpha
|
} else {
|
||||||
|
uint8_t blue = base[0];
|
||||||
|
uint8_t green = base[1];
|
||||||
|
uint8_t red = base[2];
|
||||||
|
|
||||||
|
if (alpha != 0xff) {
|
||||||
|
blue = multiply_alpha (alpha, blue);
|
||||||
|
green = multiply_alpha (alpha, green);
|
||||||
|
red = multiply_alpha (alpha, red);
|
||||||
|
}
|
||||||
|
p = (alpha << 0) | (red << 8) | (green << 16) | (blue << 24);
|
||||||
|
}
|
||||||
|
memcpy (&out[4*i], &p, sizeof (uint32_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retdata;
|
return retdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_cairo_beos_surface_set_clip_region (cairo_beos_surface_t *surface,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
|
abstract_surface);
|
||||||
|
AutoLockView locker(surface->view);
|
||||||
|
assert (locker);
|
||||||
|
|
||||||
|
if (region == surface->clip_region)
|
||||||
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
surface->clip_region = cairo_region_reference (region);
|
||||||
|
|
||||||
|
if (region == NULL) {
|
||||||
|
// No clipping
|
||||||
|
surface->view->ConstrainClippingRegion(NULL);
|
||||||
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = cairo_region_num_rectangles (region);
|
||||||
|
BRegion bregion;
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
cairo_region_get_rectangle (region, i, &rect);
|
||||||
|
// Have to substract one, because for pixman, the second coordinate
|
||||||
|
// lies outside the rectangle.
|
||||||
|
bregion.Include (_cairo_rectangle_to_brect (&rect));
|
||||||
|
}
|
||||||
|
surface->view->ConstrainClippingRegion(&bregion);
|
||||||
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _cairo_beos_bitmap_to_surface:
|
* _cairo_beos_bitmap_to_surface:
|
||||||
*
|
*
|
||||||
|
|
@ -309,8 +343,8 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap)
|
||||||
return imgsurf;
|
return imgsurf;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_format_t cformat = format == B_RGB32 ? CAIRO_FORMAT_RGB24
|
cairo_format_t cformat = format == B_RGB32 ?
|
||||||
: CAIRO_FORMAT_ARGB32;
|
CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32;
|
||||||
|
|
||||||
BRect bounds(bitmap->Bounds());
|
BRect bounds(bitmap->Bounds());
|
||||||
unsigned char* bits = reinterpret_cast<unsigned char*>(bitmap->Bits());
|
unsigned char* bits = reinterpret_cast<unsigned char*>(bitmap->Bits());
|
||||||
|
|
@ -318,8 +352,8 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap)
|
||||||
int height = bounds.IntegerHeight() + 1;
|
int height = bounds.IntegerHeight() + 1;
|
||||||
unsigned char* premultiplied;
|
unsigned char* premultiplied;
|
||||||
if (cformat == CAIRO_FORMAT_ARGB32) {
|
if (cformat == CAIRO_FORMAT_ARGB32) {
|
||||||
premultiplied = premultiply_rgba(bits, width, height,
|
premultiplied = premultiply_bgra (bits, width, height,
|
||||||
bitmap->BytesPerRow());
|
bitmap->BytesPerRow());
|
||||||
} else {
|
} else {
|
||||||
premultiplied = reinterpret_cast<unsigned char*>(
|
premultiplied = reinterpret_cast<unsigned char*>(
|
||||||
_cairo_malloc_ab(bitmap->BytesPerRow(), height));
|
_cairo_malloc_ab(bitmap->BytesPerRow(), height));
|
||||||
|
|
@ -327,7 +361,7 @@ _cairo_beos_bitmap_to_surface (BBitmap* bitmap)
|
||||||
memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);
|
memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);
|
||||||
}
|
}
|
||||||
if (!premultiplied)
|
if (!premultiplied)
|
||||||
return NULL;
|
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||||
|
|
||||||
cairo_image_surface_t* surf = reinterpret_cast<cairo_image_surface_t*>
|
cairo_image_surface_t* surf = reinterpret_cast<cairo_image_surface_t*>
|
||||||
(cairo_image_surface_create_for_data(premultiplied,
|
(cairo_image_surface_create_for_data(premultiplied,
|
||||||
|
|
@ -355,11 +389,11 @@ _cairo_image_surface_to_bitmap (cairo_image_surface_t* surface)
|
||||||
switch (surface->format) {
|
switch (surface->format) {
|
||||||
case CAIRO_FORMAT_ARGB32: {
|
case CAIRO_FORMAT_ARGB32: {
|
||||||
BBitmap* data = new BBitmap(size, B_RGBA32);
|
BBitmap* data = new BBitmap(size, B_RGBA32);
|
||||||
unpremultiply_rgba(surface->data,
|
unpremultiply_bgra (surface->data,
|
||||||
surface->width,
|
surface->width,
|
||||||
surface->height,
|
surface->height,
|
||||||
surface->stride,
|
surface->stride,
|
||||||
reinterpret_cast<unsigned char*>(data->Bits()));
|
reinterpret_cast<unsigned char*>(data->Bits()));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
case CAIRO_FORMAT_RGB24: {
|
case CAIRO_FORMAT_RGB24: {
|
||||||
|
|
@ -384,44 +418,44 @@ _cairo_op_to_be_op (cairo_operator_t cairo_op,
|
||||||
drawing_mode* beos_op)
|
drawing_mode* beos_op)
|
||||||
{
|
{
|
||||||
switch (cairo_op) {
|
switch (cairo_op) {
|
||||||
|
case CAIRO_OPERATOR_SOURCE:
|
||||||
|
*beos_op = B_OP_COPY;
|
||||||
|
return true;
|
||||||
|
case CAIRO_OPERATOR_OVER:
|
||||||
|
*beos_op = B_OP_ALPHA;
|
||||||
|
return true;
|
||||||
|
|
||||||
case CAIRO_OPERATOR_SOURCE:
|
case CAIRO_OPERATOR_ADD:
|
||||||
*beos_op = B_OP_COPY;
|
// Does not actually work
|
||||||
return true;
|
// XXX This is a fundamental compositing operator, it has to work!
|
||||||
case CAIRO_OPERATOR_OVER:
|
|
||||||
*beos_op = B_OP_ALPHA;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case CAIRO_OPERATOR_ADD:
|
|
||||||
// Does not actually work
|
|
||||||
#if 1
|
#if 1
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
*beos_op = B_OP_ADD;
|
*beos_op = B_OP_ADD;
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case CAIRO_OPERATOR_CLEAR:
|
case CAIRO_OPERATOR_CLEAR:
|
||||||
// Does not map to B_OP_ERASE - it replaces the dest with the low
|
// Does not map to B_OP_ERASE - it replaces the dest with the low
|
||||||
// color, instead of transparency; could be done by setting low
|
// color, instead of transparency; could be done by setting low
|
||||||
// color appropriately.
|
// color appropriately.
|
||||||
|
|
||||||
case CAIRO_OPERATOR_IN:
|
case CAIRO_OPERATOR_IN:
|
||||||
case CAIRO_OPERATOR_OUT:
|
case CAIRO_OPERATOR_OUT:
|
||||||
case CAIRO_OPERATOR_ATOP:
|
case CAIRO_OPERATOR_ATOP:
|
||||||
|
|
||||||
case CAIRO_OPERATOR_DEST:
|
case CAIRO_OPERATOR_DEST:
|
||||||
case CAIRO_OPERATOR_DEST_OVER:
|
case CAIRO_OPERATOR_DEST_OVER:
|
||||||
case CAIRO_OPERATOR_DEST_IN:
|
case CAIRO_OPERATOR_DEST_IN:
|
||||||
case CAIRO_OPERATOR_DEST_OUT:
|
case CAIRO_OPERATOR_DEST_OUT:
|
||||||
case CAIRO_OPERATOR_DEST_ATOP:
|
case CAIRO_OPERATOR_DEST_ATOP:
|
||||||
|
|
||||||
case CAIRO_OPERATOR_XOR:
|
case CAIRO_OPERATOR_XOR:
|
||||||
case CAIRO_OPERATOR_SATURATE:
|
case CAIRO_OPERATOR_SATURATE:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
|
|
@ -430,8 +464,6 @@ _cairo_beos_surface_create_similar (void *abstract_surface,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Creating similar\n");
|
|
||||||
|
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
abstract_surface);
|
abstract_surface);
|
||||||
|
|
||||||
|
|
@ -444,9 +476,7 @@ _cairo_beos_surface_create_similar (void *abstract_surface,
|
||||||
BBitmap* bmp;
|
BBitmap* bmp;
|
||||||
switch (content) {
|
switch (content) {
|
||||||
case CAIRO_CONTENT_ALPHA:
|
case CAIRO_CONTENT_ALPHA:
|
||||||
// Can't support this natively
|
return NULL;
|
||||||
return _cairo_image_surface_create_with_content(content, width,
|
|
||||||
height);
|
|
||||||
case CAIRO_CONTENT_COLOR_ALPHA:
|
case CAIRO_CONTENT_COLOR_ALPHA:
|
||||||
bmp = new BBitmap(rect, B_RGBA32, true);
|
bmp = new BBitmap(rect, B_RGBA32, true);
|
||||||
break;
|
break;
|
||||||
|
|
@ -470,10 +500,9 @@ _cairo_beos_surface_create_similar (void *abstract_surface,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
ASSERT_NOT_REACHED;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
};
|
|
||||||
BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0);
|
BView* view = new BView(rect, "Cairo bitmap view", B_FOLLOW_ALL_SIDES, 0);
|
||||||
bmp->AddChild(view);
|
bmp->AddChild(view);
|
||||||
return _cairo_beos_surface_create_internal(view, bmp, true);
|
return _cairo_beos_surface_create_internal(view, bmp, true);
|
||||||
|
|
@ -495,6 +524,8 @@ _cairo_beos_surface_finish (void *abstract_surface)
|
||||||
surface->bitmap = NULL;
|
surface->bitmap = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,7 +534,6 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa
|
||||||
cairo_image_surface_t **image_out,
|
cairo_image_surface_t **image_out,
|
||||||
void **image_extra)
|
void **image_extra)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Getting source image\n");
|
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
abstract_surface);
|
abstract_surface);
|
||||||
AutoLockView locker(surface->view);
|
AutoLockView locker(surface->view);
|
||||||
|
|
@ -514,9 +544,9 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa
|
||||||
surface->view->Sync();
|
surface->view->Sync();
|
||||||
|
|
||||||
if (surface->bitmap) {
|
if (surface->bitmap) {
|
||||||
*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
|
*image_out = _cairo_beos_bitmap_to_surface (surface->bitmap);
|
||||||
if (!*image_out)
|
if (unlikely ((*image_out)->base.status))
|
||||||
return CAIRO_STATUS_NO_MEMORY;
|
return (*image_out)->base.status;
|
||||||
|
|
||||||
*image_extra = NULL;
|
*image_extra = NULL;
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -526,10 +556,10 @@ _cairo_beos_surface_acquire_source_image (void *abstract_surfa
|
||||||
if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK)
|
if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK)
|
||||||
return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE
|
return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE
|
||||||
|
|
||||||
*image_out = _cairo_beos_bitmap_to_surface(bmp);
|
*image_out = _cairo_beos_bitmap_to_surface (bmp);
|
||||||
if (!*image_out) {
|
if (unlikely ((*image_out)->base.status)) {
|
||||||
delete bmp;
|
delete bmp;
|
||||||
return CAIRO_STATUS_NO_MEMORY;
|
return (*image_out)->base.status;
|
||||||
}
|
}
|
||||||
*image_extra = bmp;
|
*image_extra = bmp;
|
||||||
|
|
||||||
|
|
@ -543,17 +573,17 @@ _cairo_beos_surface_release_source_image (void *abstract_surfac
|
||||||
{
|
{
|
||||||
cairo_surface_destroy (&image->base);
|
cairo_surface_destroy (&image->base);
|
||||||
|
|
||||||
BBitmap* bmp = static_cast<BBitmap*>(image_extra);
|
if (image_extra != NULL) {
|
||||||
delete bmp;
|
BBitmap* bmp = static_cast<BBitmap*>(image_extra);
|
||||||
|
delete bmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
_cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
||||||
cairo_rectangle_int16_t *interest_rect,
|
cairo_rectangle_int_t *interest_rect,
|
||||||
cairo_image_surface_t **image_out,
|
cairo_image_surface_t **image_out,
|
||||||
cairo_rectangle_int16_t *image_rect,
|
cairo_rectangle_int_t *image_rect,
|
||||||
void **image_extra)
|
void **image_extra)
|
||||||
{
|
{
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
|
|
@ -563,14 +593,14 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
||||||
if (!locker) {
|
if (!locker) {
|
||||||
*image_out = NULL;
|
*image_out = NULL;
|
||||||
*image_extra = NULL;
|
*image_extra = NULL;
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return (cairo_status_t) CAIRO_INT_STATUS_NOTHING_TO_DO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface->bitmap) {
|
if (surface->bitmap) {
|
||||||
surface->view->Sync();
|
surface->view->Sync();
|
||||||
*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
|
*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
|
||||||
if (!*image_out)
|
if (unlikely ((*image_out)->base.status))
|
||||||
return CAIRO_STATUS_NO_MEMORY;
|
return (*image_out)->base.status;
|
||||||
|
|
||||||
image_rect->x = 0;
|
image_rect->x = 0;
|
||||||
image_rect->y = 0;
|
image_rect->y = 0;
|
||||||
|
|
@ -581,7 +611,7 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
BRect b_interest_rect(_cairo_rect_to_brect(interest_rect));
|
BRect b_interest_rect (_cairo_rectangle_to_brect (interest_rect));
|
||||||
|
|
||||||
BRect rect;
|
BRect rect;
|
||||||
BBitmap* bitmap;
|
BBitmap* bitmap;
|
||||||
|
|
@ -595,18 +625,11 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
||||||
if (status == ERROR)
|
if (status == ERROR)
|
||||||
return CAIRO_STATUS_NO_MEMORY;
|
return CAIRO_STATUS_NO_MEMORY;
|
||||||
|
|
||||||
*image_rect = _brect_to_cairo_rect(rect);
|
*image_rect = _brect_to_cairo_rectangle(rect);
|
||||||
|
|
||||||
#if 0
|
|
||||||
fprintf(stderr, "Requested: (cairo rects) (%ix%i) dim (%u, %u) returning (%ix%i) dim (%u, %u)\n",
|
|
||||||
interest_rect->x, interest_rect->y, interest_rect->width, interest_rect->height,
|
|
||||||
image_rect->x, image_rect->y, image_rect->width, image_rect->height);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*image_out = _cairo_beos_bitmap_to_surface(bitmap);
|
*image_out = _cairo_beos_bitmap_to_surface(bitmap);
|
||||||
delete bitmap;
|
delete bitmap;
|
||||||
if (!*image_out)
|
if (unlikely ((*image_out)->base.status))
|
||||||
return CAIRO_STATUS_NO_MEMORY;
|
return (*image_out)->base.status;
|
||||||
|
|
||||||
*image_extra = NULL;
|
*image_extra = NULL;
|
||||||
|
|
||||||
|
|
@ -616,13 +639,11 @@ _cairo_beos_surface_acquire_dest_image (void *abstract_surface,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cairo_beos_surface_release_dest_image (void *abstract_surface,
|
_cairo_beos_surface_release_dest_image (void *abstract_surface,
|
||||||
cairo_rectangle_int16_t *intersect_rect,
|
cairo_rectangle_int_t *intersect_rect,
|
||||||
cairo_image_surface_t *image,
|
cairo_image_surface_t *image,
|
||||||
cairo_rectangle_int16_t *image_rect,
|
cairo_rectangle_int_t *image_rect,
|
||||||
void *image_extra)
|
void *image_extra)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Fallback drawing\n");
|
|
||||||
|
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
abstract_surface);
|
abstract_surface);
|
||||||
|
|
||||||
|
|
@ -634,9 +655,9 @@ _cairo_beos_surface_release_dest_image (void *abstract_surface,
|
||||||
surface->view->PushState();
|
surface->view->PushState();
|
||||||
|
|
||||||
surface->view->SetDrawingMode(B_OP_COPY);
|
surface->view->SetDrawingMode(B_OP_COPY);
|
||||||
BRect rect(_cairo_rect_to_brect(image_rect));
|
|
||||||
|
|
||||||
surface->view->DrawBitmap(bitmap_to_draw, rect);
|
surface->view->DrawBitmap (bitmap_to_draw,
|
||||||
|
_cairo_rectangle_to_brect (image_rect));
|
||||||
|
|
||||||
surface->view->PopState();
|
surface->view->PopState();
|
||||||
|
|
||||||
|
|
@ -649,17 +670,19 @@ _cairo_beos_surface_composite (cairo_operator_t op,
|
||||||
cairo_pattern_t *src,
|
cairo_pattern_t *src,
|
||||||
cairo_pattern_t *mask,
|
cairo_pattern_t *mask,
|
||||||
void *dst,
|
void *dst,
|
||||||
int src_x,
|
int src_x,
|
||||||
int src_y,
|
int src_y,
|
||||||
int mask_x,
|
int mask_x,
|
||||||
int mask_y,
|
int mask_y,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
dst);
|
dst);
|
||||||
|
cairo_int_status_t status;
|
||||||
AutoLockView locker(surface->view);
|
AutoLockView locker(surface->view);
|
||||||
if (!locker)
|
if (!locker)
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
|
|
@ -684,6 +707,10 @@ _cairo_beos_surface_composite (cairo_operator_t op,
|
||||||
if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity))
|
if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_beos_surface_set_clip_region (surface, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
BRect srcRect(src_x + itx,
|
BRect srcRect(src_x + itx,
|
||||||
src_y + ity,
|
src_y + ity,
|
||||||
src_x + itx + width - 1,
|
src_x + itx + width - 1,
|
||||||
|
|
@ -731,8 +758,6 @@ _cairo_beos_surface_composite (cairo_operator_t op,
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Composite\n");
|
|
||||||
|
|
||||||
// Draw it on screen.
|
// Draw it on screen.
|
||||||
surface->view->PushState();
|
surface->view->PushState();
|
||||||
|
|
||||||
|
|
@ -767,24 +792,17 @@ _cairo_beos_surface_composite (cairo_operator_t op,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
_cairo_beos_surface_fill_rectangle (cairo_beos_surface_t *surface,
|
|
||||||
cairo_rectangle_int16_t *rect)
|
|
||||||
{
|
|
||||||
BRect brect(_cairo_rect_to_brect(rect));
|
|
||||||
surface->view->FillRect(brect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_beos_surface_fill_rectangles (void *abstract_surface,
|
_cairo_beos_surface_fill_rectangles (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_color_t *color,
|
const cairo_color_t *color,
|
||||||
cairo_rectangle_int16_t *rects,
|
cairo_rectangle_int_t *rects,
|
||||||
int num_rects)
|
int num_rects,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Drawing %i rectangles\n", num_rects);
|
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
abstract_surface);
|
abstract_surface);
|
||||||
|
cairo_int_status_t status;
|
||||||
|
|
||||||
if (num_rects <= 0)
|
if (num_rects <= 0)
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
|
|
@ -797,6 +815,10 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface,
|
||||||
if (!_cairo_op_to_be_op(op, &mode))
|
if (!_cairo_op_to_be_op(op, &mode))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_beos_surface_set_clip_region (surface, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
rgb_color be_color = _cairo_color_to_be_color(color);
|
rgb_color be_color = _cairo_color_to_be_color(color);
|
||||||
|
|
||||||
if (mode == B_OP_ALPHA && be_color.alpha == 0xFF)
|
if (mode == B_OP_ALPHA && be_color.alpha == 0xFF)
|
||||||
|
|
@ -808,9 +830,9 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface,
|
||||||
if (mode == B_OP_COPY && be_color.alpha != 0xFF &&
|
if (mode == B_OP_COPY && be_color.alpha != 0xFF &&
|
||||||
(!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32))
|
(!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32))
|
||||||
{
|
{
|
||||||
be_color.red = premultiply(be_color.red, be_color.alpha);
|
be_color.red = color->red_short >> 8;
|
||||||
be_color.green = premultiply(be_color.green, be_color.alpha);
|
be_color.green = color->green_short >> 8;
|
||||||
be_color.blue = premultiply(be_color.blue, be_color.alpha);
|
be_color.blue = color->blue_short >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->view->PushState();
|
surface->view->PushState();
|
||||||
|
|
@ -822,65 +844,26 @@ _cairo_beos_surface_fill_rectangles (void *abstract_surface,
|
||||||
else
|
else
|
||||||
surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
|
surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
|
||||||
|
|
||||||
for (int i = 0; i < num_rects; ++i) {
|
for (int i = 0; i < num_rects; ++i)
|
||||||
_cairo_beos_surface_fill_rectangle(surface, &rects[i]);
|
surface->view->FillRect (_cairo_rectangle_to_brect (&rects[i]));
|
||||||
}
|
|
||||||
|
|
||||||
surface->view->PopState();
|
surface->view->PopState();
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_beos_surface_set_clip_region (void *abstract_surface,
|
|
||||||
pixman_region16_t *region)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Setting clip region\n");
|
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
|
||||||
abstract_surface);
|
|
||||||
AutoLockView locker(surface->view);
|
|
||||||
if (!locker)
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (region == NULL) {
|
|
||||||
// No clipping
|
|
||||||
surface->view->ConstrainClippingRegion(NULL);
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = pixman_region_num_rects(region);
|
|
||||||
pixman_box16_t* rects = pixman_region_rects(region);
|
|
||||||
BRegion bregion;
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
// Have to substract one, because for pixman, the second coordinate
|
|
||||||
// lies outside the rectangle.
|
|
||||||
bregion.Include(BRect(rects[i].x1, rects[i].y1, rects[i].x2 - 1, rects[i].y2 - 1));
|
|
||||||
}
|
|
||||||
surface->view->ConstrainClippingRegion(&bregion);
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_beos_surface_get_extents (void *abstract_surface,
|
_cairo_beos_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int16_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
|
||||||
abstract_surface);
|
abstract_surface);
|
||||||
AutoLockView locker(surface->view);
|
AutoLockView locker(surface->view);
|
||||||
if (!locker)
|
if (!locker)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return FALSE;
|
||||||
|
|
||||||
BRect size = surface->view->Bounds();
|
*rectangle = _brect_to_cairo_rectangle (surface->view->Bounds());
|
||||||
|
return TRUE;
|
||||||
*rectangle = _brect_to_cairo_rect(size);
|
|
||||||
|
|
||||||
// Make sure to have our upperleft edge as (0,0)
|
|
||||||
rectangle->x = 0;
|
|
||||||
rectangle->y = 0;
|
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
|
static const struct _cairo_surface_backend cairo_beos_surface_backend = {
|
||||||
|
|
@ -899,8 +882,6 @@ static const struct _cairo_surface_backend cairo_beos_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
_cairo_beos_surface_set_clip_region,
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_beos_surface_get_extents,
|
_cairo_beos_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -938,7 +919,9 @@ _cairo_beos_surface_create_internal (BView* view,
|
||||||
surface->bitmap = bmp;
|
surface->bitmap = bmp;
|
||||||
surface->owns_bitmap_view = owns_bitmap_view;
|
surface->owns_bitmap_view = owns_bitmap_view;
|
||||||
|
|
||||||
return (cairo_surface_t *) surface;
|
surface->clip_region = NULL;
|
||||||
|
|
||||||
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@
|
||||||
|
|
||||||
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
|
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CAIRO_CLIP_PATH_HAS_REGION = 0x1,
|
||||||
|
CAIRO_CLIP_PATH_REGION_IS_UNSUPPORTED = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
struct _cairo_clip_path {
|
struct _cairo_clip_path {
|
||||||
cairo_reference_count_t ref_count;
|
cairo_reference_count_t ref_count;
|
||||||
cairo_path_fixed_t path;
|
cairo_path_fixed_t path;
|
||||||
|
|
@ -50,84 +55,74 @@ struct _cairo_clip_path {
|
||||||
double tolerance;
|
double tolerance;
|
||||||
cairo_antialias_t antialias;
|
cairo_antialias_t antialias;
|
||||||
cairo_clip_path_t *prev;
|
cairo_clip_path_t *prev;
|
||||||
|
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
|
/* partial caches */
|
||||||
|
unsigned int flags;
|
||||||
|
cairo_region_t *region;
|
||||||
|
cairo_surface_t *surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _cairo_clip {
|
struct _cairo_clip {
|
||||||
cairo_clip_mode_t mode;
|
/* can be used as a cairo_hash_entry_t for live clips */
|
||||||
|
cairo_clip_path_t *path;
|
||||||
|
|
||||||
cairo_bool_t all_clipped;
|
cairo_bool_t all_clipped;
|
||||||
|
|
||||||
/*
|
|
||||||
* Mask-based clipping for cases where the backend
|
|
||||||
* clipping isn't sufficiently able.
|
|
||||||
*
|
|
||||||
* The rectangle here represents the
|
|
||||||
* portion of the destination surface that this
|
|
||||||
* clip surface maps to, it does not
|
|
||||||
* represent the extents of the clip region or
|
|
||||||
* clip paths
|
|
||||||
*/
|
|
||||||
cairo_surface_t *surface;
|
|
||||||
cairo_rectangle_int_t surface_rect;
|
|
||||||
/*
|
|
||||||
* Surface clip serial number to store
|
|
||||||
* in the surface when this clip is set
|
|
||||||
*/
|
|
||||||
unsigned int serial;
|
|
||||||
/*
|
|
||||||
* A clip region that can be placed in the surface
|
|
||||||
*/
|
|
||||||
cairo_region_t *region;
|
|
||||||
/*
|
|
||||||
* If the surface supports path clipping, we store the list of
|
|
||||||
* clipping paths that has been set here as a linked list.
|
|
||||||
*/
|
|
||||||
cairo_clip_path_t *path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target);
|
_cairo_clip_init (cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
|
_cairo_clip_init_rectangle (cairo_clip_t *clip,
|
||||||
|
const cairo_rectangle_int_t *rect);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
|
_cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
_cairo_clip_init_copy_transformed (cairo_clip_t *clip,
|
||||||
cairo_clip_t *other,
|
cairo_clip_t *other,
|
||||||
cairo_surface_t *target);
|
const cairo_matrix_t *matrix);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_clip_reset (cairo_clip_t *clip);
|
_cairo_clip_reset (cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_clip_clip (cairo_clip_t *clip,
|
_cairo_clip_clip (cairo_clip_t *clip,
|
||||||
cairo_path_fixed_t *path,
|
const cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias);
|
||||||
cairo_surface_t *target);
|
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
_cairo_clip_apply_clip (cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *rectangle);
|
const cairo_clip_t *other);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private const cairo_rectangle_int_t *
|
||||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
_cairo_clip_get_extents (const cairo_clip_t *clip);
|
||||||
cairo_region_t *region);
|
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_surface_t *
|
||||||
_cairo_clip_combine_to_surface (cairo_clip_t *clip,
|
_cairo_clip_get_surface (cairo_clip_t *clip, cairo_surface_t *dst);
|
||||||
cairo_operator_t op,
|
|
||||||
cairo_surface_t *dst,
|
cairo_private cairo_int_status_t
|
||||||
int dst_x,
|
_cairo_clip_get_region (cairo_clip_t *clip,
|
||||||
int dst_y,
|
cairo_region_t **region);
|
||||||
const cairo_rectangle_int_t *extents);
|
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_clip_translate (cairo_clip_t *clip,
|
_cairo_clip_translate (cairo_clip_t *clip,
|
||||||
cairo_fixed_t tx,
|
cairo_fixed_t tx,
|
||||||
cairo_fixed_t ty);
|
cairo_fixed_t ty);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_clip_transform (cairo_clip_t *clip,
|
||||||
|
const cairo_matrix_t *transform);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_clip_drop_cache (cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_rectangle_list_t*
|
cairo_private cairo_rectangle_list_t*
|
||||||
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
|
_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate);
|
||||||
|
|
||||||
|
|
|
||||||
1452
src/cairo-clip.c
|
|
@ -75,6 +75,8 @@ cairo_debug_reset_static_data (void)
|
||||||
|
|
||||||
_cairo_pattern_reset_static_data ();
|
_cairo_pattern_reset_static_data ();
|
||||||
|
|
||||||
|
_cairo_clip_reset_static_data ();
|
||||||
|
|
||||||
CAIRO_MUTEX_FINALIZE ();
|
CAIRO_MUTEX_FINALIZE ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,14 +38,16 @@
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
#include "cairo-directfb.h"
|
#include "cairo-directfb.h"
|
||||||
|
|
||||||
|
#include "cairo-clip-private.h"
|
||||||
|
|
||||||
|
#include <pixman.h>
|
||||||
|
|
||||||
#include <directfb.h>
|
#include <directfb.h>
|
||||||
#include <direct/types.h>
|
#include <direct/types.h>
|
||||||
#include <direct/debug.h>
|
#include <direct/debug.h>
|
||||||
#include <direct/memcpy.h>
|
#include <direct/memcpy.h>
|
||||||
#include <direct/util.h>
|
#include <direct/util.h>
|
||||||
|
|
||||||
#include "cairo-clip-private.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rectangle works fine.
|
* Rectangle works fine.
|
||||||
* Bugs 361377, 359553, 359243 in Gnome BTS are caused
|
* Bugs 361377, 359553, 359243 in Gnome BTS are caused
|
||||||
|
|
@ -68,6 +70,8 @@
|
||||||
*/
|
*/
|
||||||
#define DFB_SHOW_GLYPHS 1
|
#define DFB_SHOW_GLYPHS 1
|
||||||
|
|
||||||
|
#define PIXMAN_invalid (pixman_format_code_t) 0
|
||||||
|
|
||||||
|
|
||||||
D_DEBUG_DOMAIN (CairoDFB_Acquire, "CairoDFB/Acquire", "Cairo DirectFB Acquire");
|
D_DEBUG_DOMAIN (CairoDFB_Acquire, "CairoDFB/Acquire", "Cairo DirectFB Acquire");
|
||||||
D_DEBUG_DOMAIN (CairoDFB_Clip, "CairoDFB/Clip", "Cairo DirectFB Clipping");
|
D_DEBUG_DOMAIN (CairoDFB_Clip, "CairoDFB/Clip", "Cairo DirectFB Clipping");
|
||||||
|
|
@ -78,17 +82,15 @@ D_DEBUG_DOMAIN (CairoDFB_Surface, "CairoDFB/Surface", "Cairo DirectFB Surface");
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
typedef struct _cairo_directfb_surface {
|
typedef struct _cairo_directfb_surface {
|
||||||
cairo_surface_t base;
|
cairo_surface_t base;
|
||||||
cairo_format_t format;
|
|
||||||
cairo_content_t content;
|
|
||||||
|
|
||||||
IDirectFB *dfb;
|
pixman_format_code_t pixman_format;
|
||||||
IDirectFBSurface *dfbsurface;
|
cairo_bool_t supported_destination;
|
||||||
IDirectFBSurface *tmpsurface;
|
|
||||||
|
|
||||||
cairo_bool_t has_clip;
|
IDirectFB *dfb;
|
||||||
DFBRegion *clips;
|
IDirectFBSurface *dfbsurface;
|
||||||
int n_clips;
|
IDirectFBSurface *tmpsurface;
|
||||||
|
pixman_format_code_t tmpformat;
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
|
@ -119,13 +121,18 @@ static int _directfb_argb_font = 0;
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#define RUN_CLIPPED(surface, clip, func) {\
|
#define RUN_CLIPPED(surface, clip_region, clip, func) {\
|
||||||
if ((surface)->has_clip) {\
|
if ((clip_region) != NULL) {\
|
||||||
int k;\
|
int n_clips = cairo_region_num_rectangles (clip_region), n; \
|
||||||
for (k = 0; k < (surface)->n_clips; k++) {\
|
for (n = 0; n < n_clips; n++) {\
|
||||||
if (clip) {\
|
if (clip) {\
|
||||||
DFBRegion reg = (surface)->clips[k];\
|
DFBRegion reg, *cli = (clip); \
|
||||||
DFBRegion *cli = (clip);\
|
cairo_rectangle_int_t rect; \
|
||||||
|
cairo_region_get_rectangle (clip_region, n, &rect); \
|
||||||
|
reg.x1 = rect.x; \
|
||||||
|
reg.y1 = rect.y; \
|
||||||
|
reg.x2 = rect.x + rect.width - 1; \
|
||||||
|
reg.y2 = rect.y + rect.height - 1; \
|
||||||
if (reg.x2 < cli->x1 || reg.y2 < cli->y1 ||\
|
if (reg.x2 < cli->x1 || reg.y2 < cli->y1 ||\
|
||||||
reg.x1 > cli->x2 || reg.y1 > cli->y2)\
|
reg.x1 > cli->x2 || reg.y1 > cli->y2)\
|
||||||
continue;\
|
continue;\
|
||||||
|
|
@ -139,8 +146,14 @@ static int _directfb_argb_font = 0;
|
||||||
reg.y2 = cli->y2;\
|
reg.y2 = cli->y2;\
|
||||||
(surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®);\
|
(surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®);\
|
||||||
} else {\
|
} else {\
|
||||||
(surface)->dfbsurface->SetClip ((surface)->dfbsurface,\
|
DFBRegion reg; \
|
||||||
&(surface)->clips[k]);\
|
cairo_rectangle_int_t rect; \
|
||||||
|
cairo_region_get_rectangle (clip_region, n, &rect); \
|
||||||
|
reg.x1 = rect.x; \
|
||||||
|
reg.y1 = rect.y; \
|
||||||
|
reg.x2 = rect.x + rect.width - 1; \
|
||||||
|
reg.y2 = rect.y + rect.height - 1; \
|
||||||
|
(surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®); \
|
||||||
}\
|
}\
|
||||||
func;\
|
func;\
|
||||||
}\
|
}\
|
||||||
|
|
@ -150,19 +163,19 @@ static int _directfb_argb_font = 0;
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TRANSFORM_POINT2X(m, x, y, ret_x, ret_y) {\
|
#define TRANSFORM_POINT2X(m, x, y, ret_x, ret_y) do { \
|
||||||
double _x = (x);\
|
double _x = (x); \
|
||||||
double _y = (y);\
|
double _y = (y); \
|
||||||
(ret_x) = (_x * (m).xx + (m).x0);\
|
(ret_x) = (_x * (m).xx + (m).x0); \
|
||||||
(ret_y) = (_y * (m).yy + (m).y0);\
|
(ret_y) = (_y * (m).yy + (m).y0); \
|
||||||
}
|
} while (0)
|
||||||
|
|
||||||
#define TRANSFORM_POINT3X(m, x, y, ret_x, ret_y) {\
|
#define TRANSFORM_POINT3X(m, x, y, ret_x, ret_y) do { \
|
||||||
double _x = (x);\
|
double _x = (x); \
|
||||||
double _y = (y);\
|
double _y = (y); \
|
||||||
(ret_x) = (_x * (m).xx + _y * (m).xy + (m).x0);\
|
(ret_x) = (_x * (m).xx + _y * (m).xy + (m).x0); \
|
||||||
(ret_y) = (_x * (m).yx + _y * (m).yy + (m).y0);\
|
(ret_y) = (_x * (m).yx + _y * (m).yy + (m).y0); \
|
||||||
}
|
} while (0)
|
||||||
|
|
||||||
/* XXX: A1 has a different bits ordering in cairo.
|
/* XXX: A1 has a different bits ordering in cairo.
|
||||||
* Probably we should drop it.
|
* Probably we should drop it.
|
||||||
|
|
@ -200,23 +213,65 @@ _cairo_to_directfb_format (cairo_format_t format)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline cairo_format_t
|
static inline pixman_format_code_t
|
||||||
_directfb_to_cairo_format (DFBSurfacePixelFormat format)
|
_directfb_to_pixman_format (DFBSurfacePixelFormat format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case DSPF_RGB32:
|
case DSPF_UNKNOWN: return PIXMAN_invalid;
|
||||||
return CAIRO_FORMAT_RGB24;
|
case DSPF_ARGB1555: return PIXMAN_a1r5g5b5;
|
||||||
case DSPF_ARGB:
|
case DSPF_RGB16: return PIXMAN_r5g6b5;
|
||||||
return CAIRO_FORMAT_ARGB32;
|
case DSPF_RGB24: return PIXMAN_r8g8b8;
|
||||||
case DSPF_A8:
|
case DSPF_RGB32: return PIXMAN_x8r8g8b8;
|
||||||
return CAIRO_FORMAT_A8;
|
case DSPF_ARGB: return PIXMAN_a8r8g8b8;
|
||||||
case DSPF_A1:
|
case DSPF_A8: return PIXMAN_a8;
|
||||||
return CAIRO_FORMAT_A1;
|
case DSPF_YUY2: return PIXMAN_yuy2;
|
||||||
default:
|
case DSPF_RGB332: return PIXMAN_r3g3b2;
|
||||||
break;
|
case DSPF_UYVY: return PIXMAN_invalid;
|
||||||
|
case DSPF_I420: return PIXMAN_invalid;
|
||||||
|
case DSPF_YV12: return PIXMAN_yv12;
|
||||||
|
case DSPF_LUT8: return PIXMAN_invalid;
|
||||||
|
case DSPF_ALUT44: return PIXMAN_invalid;
|
||||||
|
case DSPF_AiRGB: return PIXMAN_invalid;
|
||||||
|
case DSPF_A1: return PIXMAN_a1; /* bit reversed, oops */
|
||||||
|
case DSPF_NV12: return PIXMAN_invalid;
|
||||||
|
case DSPF_NV16: return PIXMAN_invalid;
|
||||||
|
case DSPF_ARGB2554: return PIXMAN_invalid;
|
||||||
|
case DSPF_ARGB4444: return PIXMAN_a4r4g4b4;
|
||||||
|
case DSPF_NV21: return PIXMAN_invalid;
|
||||||
|
case DSPF_AYUV: return PIXMAN_invalid;
|
||||||
|
case DSPF_A4: return PIXMAN_a4;
|
||||||
|
case DSPF_ARGB1666: return PIXMAN_invalid;
|
||||||
|
case DSPF_ARGB6666: return PIXMAN_invalid;
|
||||||
|
case DSPF_RGB18: return PIXMAN_invalid;
|
||||||
|
case DSPF_LUT2: return PIXMAN_invalid;
|
||||||
|
case DSPF_RGB444: return PIXMAN_x4r4g4b4;
|
||||||
|
case DSPF_RGB555: return PIXMAN_x1r5g5b5;
|
||||||
|
case DSPF_BGR555: return PIXMAN_x1b5g5r5;
|
||||||
}
|
}
|
||||||
|
return PIXMAN_invalid;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
static inline DFBSurfacePixelFormat
|
||||||
|
_directfb_from_pixman_format (pixman_format_code_t format)
|
||||||
|
{
|
||||||
|
switch ((int) format) {
|
||||||
|
case PIXMAN_a1r5g5b5: return DSPF_ARGB1555;
|
||||||
|
case PIXMAN_r5g6b5: return DSPF_RGB16;
|
||||||
|
case PIXMAN_r8g8b8: return DSPF_RGB24;
|
||||||
|
case PIXMAN_x8r8g8b8: return DSPF_RGB32;
|
||||||
|
case PIXMAN_a8r8g8b8: return DSPF_ARGB;
|
||||||
|
case PIXMAN_a8: return DSPF_A8;
|
||||||
|
case PIXMAN_yuy2: return DSPF_YUY2;
|
||||||
|
case PIXMAN_r3g3b2: return DSPF_RGB332;
|
||||||
|
case PIXMAN_yv12: return DSPF_YV12;
|
||||||
|
case PIXMAN_a1: return DSPF_A1; /* bit reversed, oops */
|
||||||
|
case PIXMAN_a4r4g4b4: return DSPF_ARGB4444;
|
||||||
|
case PIXMAN_a4: return DSPF_A4;
|
||||||
|
case PIXMAN_x4r4g4b4: return DSPF_RGB444;
|
||||||
|
case PIXMAN_x1r5g5b5: return DSPF_RGB555;
|
||||||
|
case PIXMAN_x1b5g5r5: return DSPF_BGR555;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -350,17 +405,14 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
|
||||||
IDirectFBSurface *buffer = NULL;
|
IDirectFBSurface *buffer = NULL;
|
||||||
DFBRectangle source_rect;
|
DFBRectangle source_rect;
|
||||||
cairo_surface_t *image;
|
cairo_surface_t *image;
|
||||||
cairo_format_t cairo_format;
|
pixman_image_t *pixman_image;
|
||||||
|
pixman_format_code_t pixman_format;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
void *data;
|
void *data;
|
||||||
int pitch;
|
int pitch;
|
||||||
|
|
||||||
if (surface->format == (cairo_format_t) -1 ||
|
if (surface->pixman_format == PIXMAN_invalid) {
|
||||||
(lock_flags & DSLF_WRITE && surface->has_clip))
|
if (intrest_rec != NULL) {
|
||||||
{
|
|
||||||
DFBSurfaceCapabilities caps;
|
|
||||||
|
|
||||||
if (intrest_rec) {
|
|
||||||
source_rect.x = intrest_rec->x;
|
source_rect.x = intrest_rec->x;
|
||||||
source_rect.y = intrest_rec->y;
|
source_rect.y = intrest_rec->y;
|
||||||
source_rect.w = intrest_rec->width;
|
source_rect.w = intrest_rec->width;
|
||||||
|
|
@ -372,30 +424,38 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
|
||||||
&source_rect.w, &source_rect.h);
|
&source_rect.w, &source_rect.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surface->tmpsurface) {
|
if (surface->tmpsurface != NULL) {
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
surface->tmpsurface->GetSize (surface->tmpsurface, &w, &h);
|
surface->tmpsurface->GetSize (surface->tmpsurface, &w, &h);
|
||||||
if (w < source_rect.w || h < source_rect.h) {
|
if (w < source_rect.w || h < source_rect.h) {
|
||||||
surface->tmpsurface->Release (surface->tmpsurface);
|
surface->tmpsurface->Release (surface->tmpsurface);
|
||||||
surface->tmpsurface = NULL;
|
surface->tmpsurface = NULL;
|
||||||
|
surface->tmpformat = PIXMAN_invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_format = _cairo_format_from_content (surface->content);
|
if (surface->tmpsurface == NULL) {
|
||||||
if (!surface->tmpsurface) {
|
DFBSurfacePixelFormat format;
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Acquire, "Allocating buffer for surface %p.\n", surface);
|
D_DEBUG_AT (CairoDFB_Acquire, "Allocating buffer for surface %p.\n", surface);
|
||||||
|
|
||||||
|
format = _cairo_to_directfb_format (_cairo_format_from_content (surface->base.content));
|
||||||
status =
|
status =
|
||||||
_directfb_buffer_surface_create (surface->dfb,
|
_directfb_buffer_surface_create (surface->dfb, format,
|
||||||
_cairo_to_directfb_format (cairo_format),
|
|
||||||
source_rect.w, source_rect.h,
|
source_rect.w, source_rect.h,
|
||||||
&surface->tmpsurface);
|
&surface->tmpsurface);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
|
|
||||||
|
surface->tmpformat = _directfb_to_pixman_format (format);
|
||||||
}
|
}
|
||||||
buffer = surface->tmpsurface;
|
buffer = surface->tmpsurface;
|
||||||
|
pixman_format = surface->tmpformat;
|
||||||
|
|
||||||
|
|
||||||
/* surface->dfbsurface->GetCapabilities (surface->dfbsurface, &caps);
|
/* surface->dfbsurface->GetCapabilities (surface->dfbsurface, &caps);
|
||||||
|
DFBSurfaceCapabilities caps;
|
||||||
if (caps & DSCAPS_FLIPPING) {
|
if (caps & DSCAPS_FLIPPING) {
|
||||||
DFBRegion region = { .x1 = source_rect.x, .y1 = source_rect.y,
|
DFBRegion region = { .x1 = source_rect.x, .y1 = source_rect.y,
|
||||||
.x2 = source_rect.x + source_rect.w - 1,
|
.x2 = source_rect.x + source_rect.w - 1,
|
||||||
|
|
@ -406,7 +466,7 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
|
||||||
} else {
|
} else {
|
||||||
/*might be a subsurface get the offset*/
|
/*might be a subsurface get the offset*/
|
||||||
surface->dfbsurface->GetVisibleRectangle (surface->dfbsurface, &source_rect);
|
surface->dfbsurface->GetVisibleRectangle (surface->dfbsurface, &source_rect);
|
||||||
cairo_format = surface->format;
|
pixman_format = surface->pixman_format;
|
||||||
buffer = surface->dfbsurface;
|
buffer = surface->dfbsurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -416,9 +476,16 @@ _directfb_acquire_surface (cairo_directfb_surface_t *surface,
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
image = cairo_image_surface_create_for_data (data, cairo_format,
|
pixman_image = pixman_image_create_bits (pixman_format,
|
||||||
source_rect.w, source_rect.h,
|
source_rect.w, source_rect.h,
|
||||||
pitch);
|
data, pitch);
|
||||||
|
if (pixman_image == NULL) {
|
||||||
|
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
goto ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
image = _cairo_image_surface_create_for_pixman_image (pixman_image,
|
||||||
|
pixman_format);
|
||||||
status = image->status;
|
status = image->status;
|
||||||
if (status)
|
if (status)
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
|
|
@ -451,37 +518,27 @@ ERROR:
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_directfb_surface_create_similar (void *abstract_src,
|
_cairo_directfb_surface_create_internal (IDirectFB *dfb,
|
||||||
cairo_content_t content,
|
DFBSurfacePixelFormat format,
|
||||||
int width,
|
cairo_content_t content,
|
||||||
int height)
|
int width,
|
||||||
|
int height)
|
||||||
{
|
{
|
||||||
cairo_directfb_surface_t *source = abstract_src;
|
|
||||||
cairo_directfb_surface_t *surface;
|
cairo_directfb_surface_t *surface;
|
||||||
cairo_format_t format;
|
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Surface,
|
|
||||||
"%s( src=%p, content=0x%x, width=%d, height=%d).\n",
|
|
||||||
__FUNCTION__, source, content, width, height);
|
|
||||||
|
|
||||||
width = (width <= 0) ? 1 : width;
|
|
||||||
height = (height<= 0) ? 1 : height;
|
|
||||||
|
|
||||||
format = _cairo_format_from_content (content);
|
|
||||||
surface = calloc (1, sizeof (cairo_directfb_surface_t));
|
surface = calloc (1, sizeof (cairo_directfb_surface_t));
|
||||||
if (unlikely (surface == NULL))
|
if (unlikely (surface == NULL))
|
||||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||||
|
|
||||||
surface->dfb = source->dfb;
|
surface->dfb = dfb;
|
||||||
|
|
||||||
if (width < 8 || height < 8) {
|
if (width < 8 || height < 8) {
|
||||||
IDirectFBSurface *tmp;
|
IDirectFBSurface *tmp;
|
||||||
DFBRectangle rect = { .x=0, .y=0, .w=width, .h=height };
|
DFBRectangle rect = { .x=0, .y=0, .w=width, .h=height };
|
||||||
|
|
||||||
/* Some cards (e.g. Matrox) don't support surfaces smaller than 8x8 */
|
/* Some cards (e.g. Matrox) don't support surfaces smaller than 8x8 */
|
||||||
status = _directfb_buffer_surface_create (surface->dfb,
|
status = _directfb_buffer_surface_create (dfb, format,
|
||||||
_cairo_to_directfb_format (format),
|
|
||||||
MAX (width, 8), MAX (height, 8),
|
MAX (width, 8), MAX (height, 8),
|
||||||
&tmp);
|
&tmp);
|
||||||
if (status) {
|
if (status) {
|
||||||
|
|
@ -492,11 +549,9 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
|
||||||
tmp->GetSubSurface (tmp, &rect, &surface->dfbsurface);
|
tmp->GetSubSurface (tmp, &rect, &surface->dfbsurface);
|
||||||
tmp->Release (tmp);
|
tmp->Release (tmp);
|
||||||
} else {
|
} else {
|
||||||
status =
|
status = _directfb_buffer_surface_create (dfb, format,
|
||||||
_directfb_buffer_surface_create (surface->dfb,
|
width, height,
|
||||||
_cairo_to_directfb_format (format),
|
&surface->dfbsurface);
|
||||||
width, height,
|
|
||||||
&surface->dfbsurface);
|
|
||||||
if (status) {
|
if (status) {
|
||||||
free (surface);
|
free (surface);
|
||||||
return _cairo_surface_create_in_error (status);
|
return _cairo_surface_create_in_error (status);
|
||||||
|
|
@ -506,8 +561,9 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
|
||||||
_cairo_surface_init (&surface->base,
|
_cairo_surface_init (&surface->base,
|
||||||
&_cairo_directfb_surface_backend,
|
&_cairo_directfb_surface_backend,
|
||||||
content);
|
content);
|
||||||
surface->format = format;
|
surface->pixman_format = _directfb_to_pixman_format (format);
|
||||||
surface->content = content;
|
surface->supported_destination = pixman_format_supported_destination (surface->pixman_format);
|
||||||
|
|
||||||
surface->width = width;
|
surface->width = width;
|
||||||
surface->height = height;
|
surface->height = height;
|
||||||
surface->local = TRUE;
|
surface->local = TRUE;
|
||||||
|
|
@ -516,6 +572,27 @@ _cairo_directfb_surface_create_similar (void *abstract_src,
|
||||||
return &surface->base;
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
_cairo_directfb_surface_create_similar (void *abstract_src,
|
||||||
|
cairo_content_t content,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
cairo_directfb_surface_t *other = abstract_src;
|
||||||
|
DFBSurfacePixelFormat format;
|
||||||
|
|
||||||
|
D_DEBUG_AT (CairoDFB_Surface,
|
||||||
|
"%s( src=%p, content=0x%x, width=%d, height=%d).\n",
|
||||||
|
__FUNCTION__, other, content, width, height);
|
||||||
|
|
||||||
|
width = (width <= 0) ? 1 : width;
|
||||||
|
height = (height<= 0) ? 1 : height;
|
||||||
|
|
||||||
|
format = _cairo_to_directfb_format (_cairo_format_from_content (content));
|
||||||
|
return _cairo_directfb_surface_create_internal (other->dfb, format,
|
||||||
|
content, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_directfb_surface_finish (void *data)
|
_cairo_directfb_surface_finish (void *data)
|
||||||
{
|
{
|
||||||
|
|
@ -523,12 +600,6 @@ _cairo_directfb_surface_finish (void *data)
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Surface, "%s( surface=%p ).\n", __FUNCTION__, surface);
|
D_DEBUG_AT (CairoDFB_Surface, "%s( surface=%p ).\n", __FUNCTION__, surface);
|
||||||
|
|
||||||
if (surface->clips) {
|
|
||||||
free (surface->clips);
|
|
||||||
surface->clips = NULL;
|
|
||||||
surface->n_clips = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surface->tmpsurface) {
|
if (surface->tmpsurface) {
|
||||||
surface->tmpsurface->Release (surface->tmpsurface);
|
surface->tmpsurface->Release (surface->tmpsurface);
|
||||||
surface->tmpsurface = NULL;
|
surface->tmpsurface = NULL;
|
||||||
|
|
@ -564,11 +635,10 @@ _cairo_directfb_surface_release_source_image (void *abstract_su
|
||||||
cairo_image_surface_t *image,
|
cairo_image_surface_t *image,
|
||||||
void *image_extra)
|
void *image_extra)
|
||||||
{
|
{
|
||||||
cairo_directfb_surface_t *surface = abstract_surface;
|
|
||||||
IDirectFBSurface *buffer = image_extra;
|
IDirectFBSurface *buffer = image_extra;
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Acquire,
|
D_DEBUG_AT (CairoDFB_Acquire,
|
||||||
"%s( surface=%p ).\n", __FUNCTION__, surface);
|
"%s( release=%p ).\n", __FUNCTION__, abstract_surface);
|
||||||
|
|
||||||
buffer->Unlock (buffer);
|
buffer->Unlock (buffer);
|
||||||
|
|
||||||
|
|
@ -620,10 +690,10 @@ _cairo_directfb_surface_release_dest_image (void *abstract_surf
|
||||||
.y2 = interest_rect->y + interest_rect->height - 1
|
.y2 = interest_rect->y + interest_rect->height - 1
|
||||||
};
|
};
|
||||||
surface->dfbsurface->SetBlittingFlags (surface->dfbsurface, DSBLIT_NOFX);
|
surface->dfbsurface->SetBlittingFlags (surface->dfbsurface, DSBLIT_NOFX);
|
||||||
RUN_CLIPPED (surface, ®ion,
|
surface->dfbsurface->SetClip (surface->dfbsurface, ®ion);
|
||||||
surface->dfbsurface->Blit (surface->dfbsurface,
|
surface->dfbsurface->Blit (surface->dfbsurface,
|
||||||
buffer, NULL,
|
buffer, NULL,
|
||||||
image_rect->x, image_rect->y));
|
image_rect->x, image_rect->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_destroy (&image->base);
|
cairo_surface_destroy (&image->base);
|
||||||
|
|
@ -655,56 +725,51 @@ _cairo_directfb_surface_clone_similar (void *abstract_surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
} else if (_cairo_surface_is_image (src)) {
|
} else if (_cairo_surface_is_image (src)) {
|
||||||
cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
|
cairo_image_surface_t *image_src = (cairo_image_surface_t *) src;
|
||||||
unsigned char *dst, *src = image_src->data;
|
DFBSurfacePixelFormat format;
|
||||||
int pitch;
|
|
||||||
int i, j;
|
|
||||||
DFBResult ret;
|
DFBResult ret;
|
||||||
|
pixman_image_t *pixman_image;
|
||||||
|
void *data;
|
||||||
|
int pitch;
|
||||||
|
|
||||||
|
format = _directfb_from_pixman_format (image_src->pixman_format);
|
||||||
|
if (format == 0)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
clone = (cairo_directfb_surface_t *)
|
clone = (cairo_directfb_surface_t *)
|
||||||
_cairo_directfb_surface_create_similar (surface,
|
_cairo_directfb_surface_create_internal (surface->dfb, format,
|
||||||
_cairo_content_from_format (image_src->format),
|
image_src->base.content,
|
||||||
width, height);
|
width, height);
|
||||||
if (clone == NULL)
|
if (unlikely (clone->base.status))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
||||||
if (clone->base.status)
|
|
||||||
return clone->base.status;
|
return clone->base.status;
|
||||||
|
|
||||||
ret = clone->dfbsurface->Lock (clone->dfbsurface,
|
ret = clone->dfbsurface->Lock (clone->dfbsurface,
|
||||||
DSLF_WRITE, (void *)&dst, &pitch);
|
DSLF_WRITE, (void *)&data, &pitch);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DirectFBError ("IDirectFBSurface::Lock()", ret);
|
DirectFBError ("IDirectFBSurface::Lock()", ret);
|
||||||
cairo_surface_destroy (&clone->base);
|
cairo_surface_destroy (&clone->base);
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
src += image_src->stride * src_y;
|
pixman_image = pixman_image_create_bits (clone->pixman_format,
|
||||||
if (image_src->format == CAIRO_FORMAT_A1) {
|
width, height,
|
||||||
/* A1 -> A8 */
|
data, pitch);
|
||||||
dst -= src_x;
|
if (unlikely (pixman_image == NULL)) {
|
||||||
for (i = 0; i < height; i++) {
|
DirectFBError ("IDirectFBSurface::Lock()", ret);
|
||||||
for (j = src_x; j < src_x + width; j++)
|
cairo_surface_destroy (&clone->base);
|
||||||
dst[j] = (src[j>>3] & (1 << (j&7))) ? 0xff : 0x00;
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
dst += pitch;
|
|
||||||
src += image_src->stride;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (image_src->format == CAIRO_FORMAT_A8) {
|
|
||||||
src += src_x;
|
|
||||||
len = width;
|
|
||||||
} else {
|
|
||||||
src += src_x * 4;
|
|
||||||
len = width * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < height; i++) {
|
|
||||||
direct_memcpy (dst, src, len);
|
|
||||||
dst += pitch;
|
|
||||||
src += image_src->stride;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixman_image_composite (PIXMAN_OP_SRC,
|
||||||
|
image_src->pixman_image,
|
||||||
|
NULL,
|
||||||
|
pixman_image,
|
||||||
|
src_x, src_y,
|
||||||
|
0, 0,
|
||||||
|
0, 0,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
pixman_image_unref (pixman_image);
|
||||||
|
|
||||||
clone->dfbsurface->Unlock (clone->dfbsurface);
|
clone->dfbsurface->Unlock (clone->dfbsurface);
|
||||||
|
|
||||||
*clone_offset_x = src_x;
|
*clone_offset_x = src_x;
|
||||||
|
|
@ -745,8 +810,6 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
if (mask_pattern) {
|
if (mask_pattern) {
|
||||||
cairo_solid_pattern_t *pattern;
|
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID) {
|
if (mask_pattern->type != CAIRO_PATTERN_TYPE_SOLID) {
|
||||||
const cairo_pattern_t *tmp;
|
const cairo_pattern_t *tmp;
|
||||||
|
|
@ -794,7 +857,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src->content == CAIRO_CONTENT_COLOR) {
|
if ((src->base.content & CAIRO_CONTENT_ALPHA) == 0) {
|
||||||
if (sblend == DSBF_SRCALPHA)
|
if (sblend == DSBF_SRCALPHA)
|
||||||
sblend = DSBF_ONE;
|
sblend = DSBF_ONE;
|
||||||
else if (sblend == DSBF_INVSRCALPHA)
|
else if (sblend == DSBF_INVSRCALPHA)
|
||||||
|
|
@ -806,7 +869,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
||||||
dblend = DSBF_ZERO;
|
dblend = DSBF_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst->content == CAIRO_CONTENT_COLOR) {
|
if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) {
|
||||||
if (sblend == DSBF_DESTALPHA)
|
if (sblend == DSBF_DESTALPHA)
|
||||||
sblend = DSBF_ONE;
|
sblend = DSBF_ONE;
|
||||||
else if (sblend == DSBF_INVDESTALPHA)
|
else if (sblend == DSBF_INVDESTALPHA)
|
||||||
|
|
@ -913,7 +976,8 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
int mask_x, int mask_y,
|
int mask_x, int mask_y,
|
||||||
int dst_x, int dst_y,
|
int dst_x, int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_directfb_surface_t *dst = abstract_dst;
|
cairo_directfb_surface_t *dst = abstract_dst;
|
||||||
cairo_directfb_surface_t *src;
|
cairo_directfb_surface_t *src;
|
||||||
|
|
@ -930,6 +994,9 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
__FUNCTION__, op, src_pattern, mask_pattern, dst,
|
__FUNCTION__, op, src_pattern, mask_pattern, dst,
|
||||||
src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height);
|
src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height);
|
||||||
|
|
||||||
|
if (! dst->supported_destination)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
status = _directfb_prepare_composite (dst, src_pattern, mask_pattern, op,
|
status = _directfb_prepare_composite (dst, src_pattern, mask_pattern, op,
|
||||||
&src_x, &src_y, &mask_x, &mask_y,
|
&src_x, &src_y, &mask_x, &mask_y,
|
||||||
width, height, &src, &src_attr);
|
width, height, &src, &src_attr);
|
||||||
|
|
@ -956,7 +1023,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
src_x += src_attr.x_offset;
|
src_x += src_attr.x_offset;
|
||||||
src_y += src_attr.y_offset;
|
src_y += src_attr.y_offset;
|
||||||
|
|
||||||
switch (accel) {
|
switch ((int) accel) {
|
||||||
case DFXL_BLIT:
|
case DFXL_BLIT:
|
||||||
{
|
{
|
||||||
DFBRectangle sr;
|
DFBRectangle sr;
|
||||||
|
|
@ -974,11 +1041,10 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
if (src_attr.extend == CAIRO_EXTEND_NONE) {
|
if (src_attr.extend == CAIRO_EXTEND_NONE) {
|
||||||
D_DEBUG_AT (CairoDFB_Render, "Running Blit().\n");
|
D_DEBUG_AT (CairoDFB_Render, "Running Blit().\n");
|
||||||
|
|
||||||
RUN_CLIPPED (dst, NULL,
|
RUN_CLIPPED (dst, clip_region, NULL,
|
||||||
dst->dfbsurface->Blit (dst->dfbsurface,
|
dst->dfbsurface->Blit (dst->dfbsurface,
|
||||||
src->dfbsurface,
|
src->dfbsurface,
|
||||||
&sr,
|
&sr, dst_x, dst_y));
|
||||||
dst_x, dst_y));
|
|
||||||
} else if (src_attr.extend == CAIRO_EXTEND_REPEAT) {
|
} else if (src_attr.extend == CAIRO_EXTEND_REPEAT) {
|
||||||
DFBRegion clip;
|
DFBRegion clip;
|
||||||
|
|
||||||
|
|
@ -989,11 +1055,10 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Render, "Running TileBlit().\n");
|
D_DEBUG_AT (CairoDFB_Render, "Running TileBlit().\n");
|
||||||
|
|
||||||
RUN_CLIPPED (dst, &clip,
|
RUN_CLIPPED (dst, clip_region, &clip,
|
||||||
dst->dfbsurface->TileBlit (dst->dfbsurface,
|
dst->dfbsurface->TileBlit (dst->dfbsurface,
|
||||||
src->dfbsurface,
|
src->dfbsurface,
|
||||||
&sr,
|
&sr, dst_x, dst_y));
|
||||||
dst_x, dst_y));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1020,9 +1085,10 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Render, "Running StretchBlit().\n");
|
D_DEBUG_AT (CairoDFB_Render, "Running StretchBlit().\n");
|
||||||
|
|
||||||
RUN_CLIPPED (dst, NULL,
|
RUN_CLIPPED (dst, clip_region, NULL,
|
||||||
dst->dfbsurface->StretchBlit (dst->dfbsurface,
|
dst->dfbsurface->StretchBlit (dst->dfbsurface,
|
||||||
src->dfbsurface, &sr, &dr));
|
src->dfbsurface,
|
||||||
|
&sr, &dr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1044,29 +1110,25 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
|
|
||||||
src->dfbsurface->GetSize (src->dfbsurface, &w, &h);
|
src->dfbsurface->GetSize (src->dfbsurface, &w, &h);
|
||||||
|
|
||||||
TRANSFORM_POINT3X (src_attr.matrix,
|
TRANSFORM_POINT3X (src_attr.matrix, x1, y1, v[0].x, v[0].y);
|
||||||
x1, y1, v[0].x, v[0].y);
|
|
||||||
v[0].z = 0;
|
v[0].z = 0;
|
||||||
v[0].w = 1;
|
v[0].w = 1;
|
||||||
v[0].s = x1 / w;
|
v[0].s = x1 / w;
|
||||||
v[0].t = y1 / h;
|
v[0].t = y1 / h;
|
||||||
|
|
||||||
TRANSFORM_POINT3X (src_attr.matrix,
|
TRANSFORM_POINT3X (src_attr.matrix, x2, y1, v[1].x, v[1].y);
|
||||||
x2, y1, v[1].x, v[1].y);
|
|
||||||
v[1].z = 0;
|
v[1].z = 0;
|
||||||
v[1].w = 1;
|
v[1].w = 1;
|
||||||
v[1].s = x2 / w;
|
v[1].s = x2 / w;
|
||||||
v[1].t = y1 / h;
|
v[1].t = y1 / h;
|
||||||
|
|
||||||
TRANSFORM_POINT3X (src_attr.matrix,
|
TRANSFORM_POINT3X (src_attr.matrix, x2, y2, v[2].x, v[2].y);
|
||||||
x2, y2, v[2].x, v[2].y);
|
|
||||||
v[2].z = 0;
|
v[2].z = 0;
|
||||||
v[2].w = 1;
|
v[2].w = 1;
|
||||||
v[2].s = x2 / w;
|
v[2].s = x2 / w;
|
||||||
v[2].t = y2 / h;
|
v[2].t = y2 / h;
|
||||||
|
|
||||||
TRANSFORM_POINT3X (src_attr.matrix,
|
TRANSFORM_POINT3X (src_attr.matrix, x1, y2, v[3].x, v[3].y);
|
||||||
x1, y2, v[3].x, v[3].y);
|
|
||||||
v[3].z = 0;
|
v[3].z = 0;
|
||||||
v[3].w = 1;
|
v[3].w = 1;
|
||||||
v[3].s = x1 / w;
|
v[3].s = x1 / w;
|
||||||
|
|
@ -1079,9 +1141,11 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");
|
D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");
|
||||||
|
|
||||||
RUN_CLIPPED (dst, &clip,
|
RUN_CLIPPED (dst, clip_region, &clip,
|
||||||
dst->dfbsurface->TextureTriangles (dst->dfbsurface,
|
dst->dfbsurface->TextureTriangles (dst->dfbsurface,
|
||||||
src->dfbsurface, v, NULL, 4, DTTF_FAN));
|
src->dfbsurface,
|
||||||
|
v, NULL,
|
||||||
|
4, DTTF_FAN));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1092,7 +1156,7 @@ _cairo_directfb_surface_composite (cairo_operator_t op,
|
||||||
|
|
||||||
_directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);
|
_directfb_finish_composite (dst, src_pattern, &src->base, &src_attr);
|
||||||
|
|
||||||
return status;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif /* DFB_COMPOSITE */
|
#endif /* DFB_COMPOSITE */
|
||||||
|
|
||||||
|
|
@ -1115,8 +1179,8 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface
|
||||||
"%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n",
|
"%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n",
|
||||||
__FUNCTION__, dst, op, color, rects, n_rects);
|
__FUNCTION__, dst, op, color, rects, n_rects);
|
||||||
|
|
||||||
if (! _cairo_operator_bounded_by_source (op))
|
if (! dst->supported_destination)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
if (! _directfb_get_operator (op, &sblend, &dblend))
|
if (! _directfb_get_operator (op, &sblend, &dblend))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
@ -1132,7 +1196,7 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface
|
||||||
else if (dblend == DSBF_INVSRCALPHA)
|
else if (dblend == DSBF_INVSRCALPHA)
|
||||||
dblend = DSBF_ZERO;
|
dblend = DSBF_ZERO;
|
||||||
}
|
}
|
||||||
if (dst->content == CAIRO_CONTENT_COLOR) {
|
if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) {
|
||||||
if (sblend == DSBF_DESTALPHA)
|
if (sblend == DSBF_DESTALPHA)
|
||||||
sblend = DSBF_ONE;
|
sblend = DSBF_ONE;
|
||||||
else if (sblend == DSBF_INVDESTALPHA)
|
else if (sblend == DSBF_INVDESTALPHA)
|
||||||
|
|
@ -1164,7 +1228,7 @@ _cairo_directfb_surface_fill_rectangles (void *abstract_surface
|
||||||
r[i].h = rects[i].height;
|
r[i].h = rects[i].height;
|
||||||
}
|
}
|
||||||
|
|
||||||
RUN_CLIPPED (dst, NULL,
|
RUN_CLIPPED (dst, NULL, NULL,
|
||||||
dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects));
|
dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects));
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -1182,7 +1246,8 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int num_traps)
|
int num_traps,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_directfb_surface_t *dst = abstract_dst;
|
cairo_directfb_surface_t *dst = abstract_dst;
|
||||||
cairo_directfb_surface_t *src;
|
cairo_directfb_surface_t *src;
|
||||||
|
|
@ -1197,6 +1262,9 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
__FUNCTION__, op, pattern, dst, antialias,
|
__FUNCTION__, op, pattern, dst, antialias,
|
||||||
src_x, src_y, dst_x, dst_y, width, height, traps, num_traps);
|
src_x, src_y, dst_x, dst_y, width, height, traps, num_traps);
|
||||||
|
|
||||||
|
if (! dst->supported_destination)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
if (antialias != CAIRO_ANTIALIAS_NONE)
|
if (antialias != CAIRO_ANTIALIAS_NONE)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
|
@ -1291,7 +1359,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");
|
D_DEBUG_AT (CairoDFB_Render, "Running TextureTriangles().\n");
|
||||||
|
|
||||||
RUN_CLIPPED (dst, NULL,
|
RUN_CLIPPED (dst, clip_region, NULL,
|
||||||
dst->dfbsurface->TextureTriangles (dst->dfbsurface,
|
dst->dfbsurface->TextureTriangles (dst->dfbsurface,
|
||||||
src->dfbsurface,
|
src->dfbsurface,
|
||||||
vertex, NULL, n,
|
vertex, NULL, n,
|
||||||
|
|
@ -1306,64 +1374,7 @@ _cairo_directfb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
}
|
}
|
||||||
#endif /* DFB_COMPOSITE_TRAPEZOIDS */
|
#endif /* DFB_COMPOSITE_TRAPEZOIDS */
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
|
||||||
cairo_region_t *region)
|
|
||||||
{
|
|
||||||
cairo_directfb_surface_t *surface = abstract_surface;
|
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Clip,
|
|
||||||
"%s( surface=%p, region=%p ).\n",
|
|
||||||
__FUNCTION__, surface, region);
|
|
||||||
|
|
||||||
if (region) {
|
|
||||||
int n_rects;
|
|
||||||
cairo_status_t status;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
surface->has_clip = TRUE;
|
|
||||||
|
|
||||||
n_rects = cairo_region_num_rectangles (region);
|
|
||||||
|
|
||||||
if (n_rects == 0)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (surface->n_clips != n_rects) {
|
|
||||||
if (surface->clips)
|
|
||||||
free (surface->clips);
|
|
||||||
|
|
||||||
surface->clips = _cairo_malloc_ab (n_rects, sizeof (DFBRegion));
|
|
||||||
if (!surface->clips) {
|
|
||||||
surface->n_clips = 0;
|
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->n_clips = n_rects;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < n_rects; i++) {
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
|
|
||||||
cairo_region_get_rectangle (region, i, &rect);
|
|
||||||
|
|
||||||
surface->clips[i].x1 = rect.x;
|
|
||||||
surface->clips[i].y1 = rect.y;
|
|
||||||
surface->clips[i].x2 = rect.x + rect.width - 1;
|
|
||||||
surface->clips[i].y2 = rect.y + rect.height - 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
surface->has_clip = FALSE;
|
|
||||||
if (surface->clips) {
|
|
||||||
free (surface->clips);
|
|
||||||
surface->clips = NULL;
|
|
||||||
surface->n_clips = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
|
_cairo_directfb_abstract_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -1383,7 +1394,7 @@ _cairo_directfb_abstract_surface_get_extents (void *abstract_su
|
||||||
rectangle->width = surface->width;
|
rectangle->width = surface->width;
|
||||||
rectangle->height = surface->height;
|
rectangle->height = surface->height;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DFB_SHOW_GLYPHS
|
#if DFB_SHOW_GLYPHS
|
||||||
|
|
@ -1422,6 +1433,7 @@ _directfb_destroy_font_cache (cairo_directfb_font_cache_t *cache)
|
||||||
free (cache);
|
free (cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX hook into rtree font cache from drm */
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
_directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
|
|
@ -1473,6 +1485,7 @@ _directfb_acquire_font_cache (cairo_directfb_surface_t *surface,
|
||||||
case CAIRO_FORMAT_A8:
|
case CAIRO_FORMAT_A8:
|
||||||
case CAIRO_FORMAT_ARGB32:
|
case CAIRO_FORMAT_ARGB32:
|
||||||
break;
|
break;
|
||||||
|
case CAIRO_FORMAT_RGB24:
|
||||||
default:
|
default:
|
||||||
D_DEBUG_AT (CairoDFB_Font,
|
D_DEBUG_AT (CairoDFB_Font,
|
||||||
" -> Unsupported font format %d!\n", img->format);
|
" -> Unsupported font format %d!\n", img->format);
|
||||||
|
|
@ -1705,8 +1718,8 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_directfb_surface_t *dst = abstract_dst;
|
cairo_directfb_surface_t *dst = abstract_dst;
|
||||||
cairo_directfb_font_cache_t *cache;
|
cairo_directfb_font_cache_t *cache;
|
||||||
|
|
@ -1718,28 +1731,29 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst,
|
||||||
DFBPoint points[num_glyphs];
|
DFBPoint points[num_glyphs];
|
||||||
int num;
|
int num;
|
||||||
const cairo_color_t *color;
|
const cairo_color_t *color;
|
||||||
|
cairo_region_t *clip_region = NULL;
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Font,
|
D_DEBUG_AT (CairoDFB_Font,
|
||||||
"%s( dst=%p, op=%d, pattern=%p, glyphs=%p, num_glyphs=%d, scaled_font=%p ).\n",
|
"%s( dst=%p, op=%d, pattern=%p, glyphs=%p, num_glyphs=%d, scaled_font=%p ).\n",
|
||||||
__FUNCTION__, dst, op, pattern, glyphs, num_glyphs, scaled_font);
|
__FUNCTION__, dst, op, pattern, glyphs, num_glyphs, scaled_font);
|
||||||
|
|
||||||
|
if (! dst->supported_destination)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
|
if (pattern->type != CAIRO_PATTERN_TYPE_SOLID)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
/* Fallback if we need to emulate clip regions */
|
/* Fallback if we need to emulate clip regions */
|
||||||
if (dst->base.clip &&
|
if (clip != NULL) {
|
||||||
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
|
status = _cairo_clip_get_region (clip, &clip_region);
|
||||||
dst->base.clip->surface != NULL))
|
assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
|
||||||
{
|
if (status)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX Unbounded operators are not handled correctly */
|
/* XXX Unbounded operators are not handled correctly */
|
||||||
if (! _cairo_operator_bounded_by_mask (op))
|
if (! _cairo_operator_bounded_by_mask (op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
if (! _cairo_operator_bounded_by_source (op))
|
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
||||||
|
|
||||||
if (! _directfb_get_operator (op, &sblend, &dblend) ||
|
if (! _directfb_get_operator (op, &sblend, &dblend) ||
|
||||||
sblend == DSBF_DESTALPHA || sblend == DSBF_INVDESTALPHA)
|
sblend == DSBF_DESTALPHA || sblend == DSBF_INVDESTALPHA)
|
||||||
|
|
@ -1788,7 +1802,7 @@ _cairo_directfb_surface_show_glyphs (void *abstract_dst,
|
||||||
|
|
||||||
D_DEBUG_AT (CairoDFB_Font, "Running BatchBlit().\n");
|
D_DEBUG_AT (CairoDFB_Font, "Running BatchBlit().\n");
|
||||||
|
|
||||||
RUN_CLIPPED (dst, NULL,
|
RUN_CLIPPED (dst, clip_region, NULL,
|
||||||
dst->dfbsurface->BatchBlit (dst->dfbsurface,
|
dst->dfbsurface->BatchBlit (dst->dfbsurface,
|
||||||
cache->dfbsurface, rects, points, num));
|
cache->dfbsurface, rects, points, num));
|
||||||
|
|
||||||
|
|
@ -1835,8 +1849,6 @@ _cairo_directfb_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
_cairo_directfb_surface_set_clip_region,/* set_clip_region */
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_directfb_abstract_surface_get_extents,/* get_extents */
|
_cairo_directfb_abstract_surface_get_extents,/* get_extents */
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -1860,7 +1872,6 @@ _cairo_directfb_surface_backend = {
|
||||||
#endif
|
#endif
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
_cairo_directfb_surface_is_similar,
|
_cairo_directfb_surface_is_similar,
|
||||||
NULL /* reset */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1933,8 +1944,8 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
|
||||||
dfbsurface->GetSize (dfbsurface, &surface->width, &surface->height);
|
dfbsurface->GetSize (dfbsurface, &surface->width, &surface->height);
|
||||||
surface->dfb = dfb;
|
surface->dfb = dfb;
|
||||||
surface->dfbsurface = dfbsurface;
|
surface->dfbsurface = dfbsurface;
|
||||||
surface->format = _directfb_to_cairo_format (format);
|
surface->pixman_format = _directfb_to_pixman_format (format);
|
||||||
surface->content = _directfb_format_to_content (format);
|
surface->supported_destination = pixman_format_supported_destination (surface->pixman_format);
|
||||||
|
|
||||||
dfbsurface->GetCapabilities (dfbsurface, &caps);
|
dfbsurface->GetCapabilities (dfbsurface, &caps);
|
||||||
if (caps & DSCAPS_PREMULTIPLIED)
|
if (caps & DSCAPS_PREMULTIPLIED)
|
||||||
|
|
@ -1942,7 +1953,7 @@ cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface)
|
||||||
|
|
||||||
_cairo_surface_init (&surface->base,
|
_cairo_surface_init (&surface->base,
|
||||||
&_cairo_directfb_surface_backend,
|
&_cairo_directfb_surface_backend,
|
||||||
surface->content);
|
_directfb_format_to_content (format));
|
||||||
|
|
||||||
return &surface->base;
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1146,7 +1146,7 @@ _render_glyph_bitmap (FT_Face face,
|
||||||
cairo_image_surface_t **surface)
|
cairo_image_surface_t **surface)
|
||||||
{
|
{
|
||||||
FT_GlyphSlot glyphslot = face->glyph;
|
FT_GlyphSlot glyphslot = face->glyph;
|
||||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
cairo_status_t status;
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
|
||||||
/* According to the FreeType docs, glyphslot->format could be
|
/* According to the FreeType docs, glyphslot->format could be
|
||||||
|
|
@ -1162,7 +1162,9 @@ _render_glyph_bitmap (FT_Face face,
|
||||||
if (error == FT_Err_Out_Of_Memory)
|
if (error == FT_Err_Out_Of_Memory)
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface);
|
status = _get_bitmap_surface (&glyphslot->bitmap,
|
||||||
|
FALSE, font_options,
|
||||||
|
surface);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -1177,7 +1179,7 @@ _render_glyph_bitmap (FT_Face face,
|
||||||
-glyphslot->bitmap_left,
|
-glyphslot->bitmap_left,
|
||||||
+glyphslot->bitmap_top);
|
+glyphslot->bitmap_top);
|
||||||
|
|
||||||
return status;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
|
|
@ -1275,11 +1277,8 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||||
_cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
|
_cairo_pattern_init_for_surface (&pattern, &(*surface)->base);
|
||||||
cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
|
cairo_pattern_set_matrix (&pattern.base, &transformed_to_original);
|
||||||
|
|
||||||
status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
|
status = _cairo_surface_paint (image, CAIRO_OPERATOR_OVER,
|
||||||
&pattern.base, NULL, image,
|
&pattern.base, NULL);
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
width,
|
|
||||||
height);
|
|
||||||
|
|
||||||
_cairo_pattern_fini (&pattern.base);
|
_cairo_pattern_fini (&pattern.base);
|
||||||
|
|
||||||
|
|
@ -1301,7 +1300,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||||
cairo_surface_set_device_offset (&(*surface)->base,
|
cairo_surface_set_device_offset (&(*surface)->base,
|
||||||
_cairo_lround (origin_x),
|
_cairo_lround (origin_x),
|
||||||
_cairo_lround (origin_y));
|
_cairo_lround (origin_y));
|
||||||
return status;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
|
static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = {
|
||||||
|
|
@ -1390,8 +1389,8 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
|
||||||
ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FC_HINT_STYLE
|
#ifdef FC_HINT_STYLE
|
||||||
if (FcPatternGetInteger (pattern,
|
if (FcPatternGetInteger (pattern,
|
||||||
FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
|
FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
|
||||||
hintstyle = FC_HINT_FULL;
|
hintstyle = FC_HINT_FULL;
|
||||||
|
|
||||||
|
|
@ -1400,7 +1399,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
|
||||||
|
|
||||||
switch (hintstyle) {
|
switch (hintstyle) {
|
||||||
case FC_HINT_NONE:
|
case FC_HINT_NONE:
|
||||||
ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
|
ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
break;
|
break;
|
||||||
case FC_HINT_SLIGHT:
|
case FC_HINT_SLIGHT:
|
||||||
ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT;
|
||||||
|
|
@ -1444,14 +1443,14 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
|
||||||
|
|
||||||
if (vertical_layout)
|
if (vertical_layout)
|
||||||
ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT;
|
ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT;
|
||||||
|
|
||||||
#ifndef FC_EMBOLDEN
|
#ifndef FC_EMBOLDEN
|
||||||
#define FC_EMBOLDEN "embolden"
|
#define FC_EMBOLDEN "embolden"
|
||||||
#endif
|
#endif
|
||||||
if (FcPatternGetBool (pattern,
|
if (FcPatternGetBool (pattern,
|
||||||
FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
|
FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
|
||||||
embolden = FcFalse;
|
embolden = FcFalse;
|
||||||
|
|
||||||
if (embolden)
|
if (embolden)
|
||||||
ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
|
ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
|
||||||
|
|
||||||
|
|
@ -1468,7 +1467,7 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
|
||||||
|
|
||||||
/* clear load target mode */
|
/* clear load target mode */
|
||||||
load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags)));
|
load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags)));
|
||||||
|
|
||||||
if (load_flags & FT_LOAD_NO_HINTING)
|
if (load_flags & FT_LOAD_NO_HINTING)
|
||||||
other->base.hint_style = CAIRO_HINT_STYLE_NONE;
|
other->base.hint_style = CAIRO_HINT_STYLE_NONE;
|
||||||
|
|
||||||
|
|
@ -1479,7 +1478,7 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&
|
if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&
|
||||||
(options->base.antialias == CAIRO_ANTIALIAS_DEFAULT ||
|
(options->base.antialias == CAIRO_ANTIALIAS_DEFAULT ||
|
||||||
options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {
|
options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {
|
||||||
options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
|
||||||
options->base.subpixel_order = other->base.subpixel_order;
|
options->base.subpixel_order = other->base.subpixel_order;
|
||||||
|
|
@ -1934,12 +1933,12 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||||
x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
|
x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
|
||||||
y1 = (-metrics->horiBearingY) & -64;
|
y1 = (-metrics->horiBearingY) & -64;
|
||||||
y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;
|
y2 = (-metrics->horiBearingY + metrics->height + 63) & -64;
|
||||||
|
|
||||||
advance = ((metrics->horiAdvance + 32) & -64);
|
advance = ((metrics->horiAdvance + 32) & -64);
|
||||||
|
|
||||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
|
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
|
||||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
|
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
|
||||||
|
|
||||||
fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
|
fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
|
||||||
fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
|
fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
|
||||||
|
|
||||||
|
|
@ -1950,12 +1949,12 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||||
x2 = (metrics->vertBearingX + metrics->width + 63) & -64;
|
x2 = (metrics->vertBearingX + metrics->width + 63) & -64;
|
||||||
y1 = (metrics->vertBearingY) & -64;
|
y1 = (metrics->vertBearingY) & -64;
|
||||||
y2 = (metrics->vertBearingY + metrics->height + 63) & -64;
|
y2 = (metrics->vertBearingY + metrics->height + 63) & -64;
|
||||||
|
|
||||||
advance = ((metrics->vertAdvance + 32) & -64);
|
advance = ((metrics->vertAdvance + 32) & -64);
|
||||||
|
|
||||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
|
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor;
|
||||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
|
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor;
|
||||||
|
|
||||||
fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
|
fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
|
||||||
fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
|
fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
|
||||||
|
|
||||||
|
|
@ -1969,7 +1968,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||||
if (!vertical_layout) {
|
if (!vertical_layout) {
|
||||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
|
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor;
|
||||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;
|
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor;
|
||||||
|
|
||||||
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||||
fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
|
fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
|
||||||
else
|
else
|
||||||
|
|
@ -1978,7 +1977,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||||
} else {
|
} else {
|
||||||
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor;
|
fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor;
|
||||||
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor;
|
fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor;
|
||||||
|
|
||||||
fs_metrics.x_advance = 0 * x_factor;
|
fs_metrics.x_advance = 0 * x_factor;
|
||||||
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||||
fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
|
fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
|
||||||
|
|
@ -2154,7 +2153,7 @@ static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = {
|
||||||
_cairo_ft_scaled_glyph_init,
|
_cairo_ft_scaled_glyph_init,
|
||||||
NULL, /* text_to_glyphs */
|
NULL, /* text_to_glyphs */
|
||||||
_cairo_ft_ucs4_to_index,
|
_cairo_ft_ucs4_to_index,
|
||||||
NULL, /* show_glyphs */
|
NULL, /* show_glyphs */
|
||||||
_cairo_ft_load_truetype_table,
|
_cairo_ft_load_truetype_table,
|
||||||
_cairo_ft_index_to_ucs4
|
_cairo_ft_index_to_ucs4
|
||||||
};
|
};
|
||||||
|
|
@ -2911,10 +2910,10 @@ cairo_bool_t
|
||||||
_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
|
_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font)
|
||||||
{
|
{
|
||||||
cairo_ft_scaled_font_t *ft_scaled_font;
|
cairo_ft_scaled_font_t *ft_scaled_font;
|
||||||
|
|
||||||
if (!_cairo_scaled_font_is_ft (scaled_font))
|
if (!_cairo_scaled_font_is_ft (scaled_font))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
|
ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font;
|
||||||
if (ft_scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)
|
if (ft_scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ typedef struct _cairo_gl_surface {
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
GLuint tex; /* GL texture object containing our data. */
|
GLuint tex; /* GL texture object containing our data. */
|
||||||
|
GLuint depth_stencil_tex;
|
||||||
GLuint fb; /* GL framebuffer object wrapping our data. */
|
GLuint fb; /* GL framebuffer object wrapping our data. */
|
||||||
} cairo_gl_surface_t;
|
} cairo_gl_surface_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,10 @@ _cairo_gl_get_image_format_and_type (pixman_format_code_t pixman_format,
|
||||||
case PIXMAN_g1:
|
case PIXMAN_g1:
|
||||||
case PIXMAN_yuy2:
|
case PIXMAN_yuy2:
|
||||||
case PIXMAN_yv12:
|
case PIXMAN_yv12:
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16)
|
||||||
|
case PIXMAN_x2r10g10b10:
|
||||||
|
case PIXMAN_a2r10g10b10:
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
@ -766,6 +770,8 @@ _cairo_gl_surface_finish (void *abstract_surface)
|
||||||
|
|
||||||
glDeleteFramebuffersEXT (1, &surface->fb);
|
glDeleteFramebuffersEXT (1, &surface->fb);
|
||||||
glDeleteTextures (1, &surface->tex);
|
glDeleteTextures (1, &surface->tex);
|
||||||
|
if (surface->depth_stencil_tex)
|
||||||
|
glDeleteTextures (1, &surface->depth_stencil_tex);
|
||||||
|
|
||||||
if (surface->ctx->current_target == surface)
|
if (surface->ctx->current_target == surface)
|
||||||
surface->ctx->current_target = NULL;
|
surface->ctx->current_target = NULL;
|
||||||
|
|
@ -1264,16 +1270,20 @@ _cairo_gl_surface_composite (cairo_operator_t op,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_gl_surface_t *dst = abstract_dst;
|
cairo_gl_surface_t *dst = abstract_dst;
|
||||||
cairo_surface_attributes_t *src_attributes, *mask_attributes = NULL;
|
cairo_surface_attributes_t *src_attributes, *mask_attributes = NULL;
|
||||||
cairo_gl_context_t *ctx;
|
cairo_gl_context_t *ctx;
|
||||||
GLfloat vertices[4][2];
|
struct gl_point {
|
||||||
GLfloat texcoord_src[4][2];
|
GLfloat x, y;
|
||||||
GLfloat texcoord_mask[4][2];
|
} vertices_stack[8], texcoord_src_stack[8], texcoord_mask_stack[8];
|
||||||
|
struct gl_point *vertices = vertices_stack;
|
||||||
|
struct gl_point *texcoord_src = texcoord_src_stack;
|
||||||
|
struct gl_point *texcoord_mask = texcoord_mask_stack;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
int i;
|
int num_vertices, i;
|
||||||
GLenum err;
|
GLenum err;
|
||||||
cairo_gl_composite_setup_t setup;
|
cairo_gl_composite_setup_t setup;
|
||||||
|
|
||||||
|
|
@ -1345,27 +1355,62 @@ _cairo_gl_surface_composite (cairo_operator_t op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vertices[0][0] = dst_x;
|
if (clip_region != NULL) {
|
||||||
vertices[0][1] = dst_y;
|
int num_rectangles;
|
||||||
vertices[1][0] = dst_x + width;
|
|
||||||
vertices[1][1] = dst_y;
|
num_rectangles = cairo_region_num_rectangles (clip_region);
|
||||||
vertices[2][0] = dst_x + width;
|
if (num_rectangles * 4 > ARRAY_LENGTH (vertices_stack)) {
|
||||||
vertices[2][1] = dst_y + height;
|
vertices = _cairo_malloc_ab (num_rectangles,
|
||||||
vertices[3][0] = dst_x;
|
4*3*sizeof (vertices[0]));
|
||||||
vertices[3][1] = dst_y + height;
|
if (unlikely (vertices == NULL)) {
|
||||||
|
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
goto CONTEXT_RELEASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
texcoord_src = vertices + num_rectangles * 4;
|
||||||
|
texcoord_mask = texcoord_src + num_rectangles * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_rectangles; i++) {
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
cairo_region_get_rectangle (clip_region, i, &rect);
|
||||||
|
vertices[4*i + 0].x = rect.x;
|
||||||
|
vertices[4*i + 0].y = rect.y;
|
||||||
|
vertices[4*i + 1].x = rect.x + rect.width;
|
||||||
|
vertices[4*i + 1].y = rect.y;
|
||||||
|
vertices[4*i + 2].x = rect.x + rect.width;
|
||||||
|
vertices[4*i + 2].y = rect.y + rect.height;
|
||||||
|
vertices[4*i + 3].x = rect.x;
|
||||||
|
vertices[4*i + 3].y = rect.y + rect.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_vertices = 4 * num_rectangles;
|
||||||
|
} else {
|
||||||
|
vertices[0].x = dst_x;
|
||||||
|
vertices[0].y = dst_y;
|
||||||
|
vertices[1].x = dst_x + width;
|
||||||
|
vertices[1].y = dst_y;
|
||||||
|
vertices[2].x = dst_x + width;
|
||||||
|
vertices[2].y = dst_y + height;
|
||||||
|
vertices[3].x = dst_x;
|
||||||
|
vertices[3].y = dst_y + height;
|
||||||
|
|
||||||
|
num_vertices = 4;
|
||||||
|
}
|
||||||
|
|
||||||
glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, vertices);
|
glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, vertices);
|
||||||
glEnableClientState (GL_VERTEX_ARRAY);
|
glEnableClientState (GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
if (setup.src.type == OPERAND_TEXTURE) {
|
if (setup.src.type == OPERAND_TEXTURE) {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < num_vertices; i++) {
|
||||||
double s, t;
|
double s, t;
|
||||||
|
|
||||||
s = vertices[i][0];
|
s = vertices[i].x;
|
||||||
t = vertices[i][1];
|
t = vertices[i].y;
|
||||||
cairo_matrix_transform_point (&src_attributes->matrix, &s, &t);
|
cairo_matrix_transform_point (&src_attributes->matrix, &s, &t);
|
||||||
texcoord_src[i][0] = s;
|
texcoord_src[i].x = s;
|
||||||
texcoord_src[i][1] = t;
|
texcoord_src[i].y = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
glClientActiveTexture (GL_TEXTURE0);
|
glClientActiveTexture (GL_TEXTURE0);
|
||||||
|
|
@ -1375,14 +1420,14 @@ _cairo_gl_surface_composite (cairo_operator_t op,
|
||||||
|
|
||||||
if (mask != NULL) {
|
if (mask != NULL) {
|
||||||
if (setup.mask.type == OPERAND_TEXTURE) {
|
if (setup.mask.type == OPERAND_TEXTURE) {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < num_vertices; i++) {
|
||||||
double s, t;
|
double s, t;
|
||||||
|
|
||||||
s = vertices[i][0];
|
s = vertices[i].x;
|
||||||
t = vertices[i][1];
|
t = vertices[i].y;
|
||||||
cairo_matrix_transform_point (&mask_attributes->matrix, &s, &t);
|
cairo_matrix_transform_point (&mask_attributes->matrix, &s, &t);
|
||||||
texcoord_mask[i][0] = s;
|
texcoord_mask[i].x = s;
|
||||||
texcoord_mask[i][1] = t;
|
texcoord_mask[i].y = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
glClientActiveTexture (GL_TEXTURE1);
|
glClientActiveTexture (GL_TEXTURE1);
|
||||||
|
|
@ -1391,7 +1436,7 @@ _cairo_gl_surface_composite (cairo_operator_t op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays (GL_QUADS, 0, num_vertices);
|
||||||
|
|
||||||
glDisable (GL_BLEND);
|
glDisable (GL_BLEND);
|
||||||
|
|
||||||
|
|
@ -1410,13 +1455,17 @@ _cairo_gl_surface_composite (cairo_operator_t op,
|
||||||
while ((err = glGetError ()))
|
while ((err = glGetError ()))
|
||||||
fprintf (stderr, "GL error 0x%08x\n", (int) err);
|
fprintf (stderr, "GL error 0x%08x\n", (int) err);
|
||||||
|
|
||||||
|
CONTEXT_RELEASE:
|
||||||
_cairo_gl_context_release (ctx);
|
_cairo_gl_context_release (ctx);
|
||||||
|
|
||||||
_cairo_gl_operand_destroy (&setup.src);
|
_cairo_gl_operand_destroy (&setup.src);
|
||||||
if (mask != NULL)
|
if (mask != NULL)
|
||||||
_cairo_gl_operand_destroy (&setup.mask);
|
_cairo_gl_operand_destroy (&setup.mask);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
if (vertices != vertices_stack)
|
||||||
|
free (vertices);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -1429,7 +1478,8 @@ _cairo_gl_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int num_traps)
|
int num_traps,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_gl_surface_t *dst = abstract_dst;
|
cairo_gl_surface_t *dst = abstract_dst;
|
||||||
cairo_surface_pattern_t traps_pattern;
|
cairo_surface_pattern_t traps_pattern;
|
||||||
|
|
@ -1447,7 +1497,8 @@ _cairo_gl_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
dst_x, dst_y,
|
dst_x, dst_y,
|
||||||
width, height);
|
width, height,
|
||||||
|
clip_region);
|
||||||
|
|
||||||
_cairo_pattern_fini (&traps_pattern.base);
|
_cairo_pattern_fini (&traps_pattern.base);
|
||||||
|
|
||||||
|
|
@ -1737,6 +1788,7 @@ _cairo_gl_surface_span_renderer_finish (void *abstract_renderer)
|
||||||
glDisable (GL_TEXTURE_2D);
|
glDisable (GL_TEXTURE_2D);
|
||||||
|
|
||||||
glDisable (GL_BLEND);
|
glDisable (GL_BLEND);
|
||||||
|
glDisable (GL_DEPTH_TEST);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -1756,27 +1808,112 @@ _cairo_gl_surface_check_span_renderer (cairo_operator_t op,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cairo_gl_surface_ensure_depth_buffer (cairo_gl_surface_t *surface)
|
||||||
|
{
|
||||||
|
if (surface->depth_stencil_tex)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glGenTextures (1, &surface->depth_stencil_tex);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, surface->depth_stencil_tex);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT,
|
||||||
|
surface->width, surface->height, 0,
|
||||||
|
GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
|
||||||
|
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_DEPTH_ATTACHMENT_EXT,
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
surface->depth_stencil_tex, 0);
|
||||||
|
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_STENCIL_ATTACHMENT_EXT,
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
surface->depth_stencil_tex, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_gl_surface_set_clip_region (cairo_gl_surface_t *surface,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
|
{
|
||||||
|
GLfloat vertices_stack[CAIRO_STACK_ARRAY_LENGTH(GLfloat)], *vertices;
|
||||||
|
int num_rectangles, i, n;
|
||||||
|
|
||||||
|
if (clip_region == NULL)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
num_rectangles = cairo_region_num_rectangles (clip_region);
|
||||||
|
|
||||||
|
vertices = vertices_stack;
|
||||||
|
if (num_rectangles * 8 > ARRAY_LENGTH (vertices_stack)) {
|
||||||
|
vertices = _cairo_malloc_ab (num_rectangles,
|
||||||
|
4*3*sizeof (vertices[0]));
|
||||||
|
if (unlikely (vertices == NULL))
|
||||||
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = n = 0; i < num_rectangles; i++) {
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
cairo_region_get_rectangle (clip_region, i, &rect);
|
||||||
|
vertices[n++] = rect.x;
|
||||||
|
vertices[n++] = rect.y;
|
||||||
|
vertices[n++] = rect.x + rect.width;
|
||||||
|
vertices[n++] = rect.y;
|
||||||
|
vertices[n++] = rect.x + rect.width;
|
||||||
|
vertices[n++] = rect.y + rect.height;
|
||||||
|
vertices[n++] = rect.x;
|
||||||
|
vertices[n++] = rect.y +rect. height;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cairo_gl_surface_ensure_depth_buffer (surface);
|
||||||
|
|
||||||
|
glDisable (GL_BLEND);
|
||||||
|
glDepthFunc (GL_ALWAYS);
|
||||||
|
glEnable (GL_DEPTH_TEST);
|
||||||
|
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
|
|
||||||
|
glDepthMask (GL_TRUE);
|
||||||
|
glClear (GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 2, vertices);
|
||||||
|
glEnableClientState (GL_VERTEX_ARRAY);
|
||||||
|
glDrawArrays (GL_QUADS, 0, 4 * num_rectangles);
|
||||||
|
glDisableClientState (GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
|
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glDepthFunc (GL_EQUAL);
|
||||||
|
glDepthMask (GL_FALSE);
|
||||||
|
|
||||||
|
if (vertices != vertices_stack)
|
||||||
|
free (vertices);
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_span_renderer_t *
|
static cairo_span_renderer_t *
|
||||||
_cairo_gl_surface_create_span_renderer (cairo_operator_t op,
|
_cairo_gl_surface_create_span_renderer (cairo_operator_t op,
|
||||||
const cairo_pattern_t *src,
|
const cairo_pattern_t *src,
|
||||||
void *abstract_dst,
|
void *abstract_dst,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
const cairo_composite_rectangles_t *rects)
|
const cairo_composite_rectangles_t *rects,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_gl_surface_t *dst = abstract_dst;
|
cairo_gl_surface_t *dst = abstract_dst;
|
||||||
cairo_gl_surface_span_renderer_t *renderer = calloc (1, sizeof (*renderer));
|
cairo_gl_surface_span_renderer_t *renderer;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
int width = rects->width;
|
int width = rects->width;
|
||||||
int height = rects->height;
|
int height = rects->height;
|
||||||
cairo_surface_attributes_t *src_attributes;
|
cairo_surface_attributes_t *src_attributes;
|
||||||
GLenum err;
|
GLenum err;
|
||||||
|
|
||||||
if (renderer == NULL)
|
|
||||||
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
|
|
||||||
if (!GLEW_ARB_vertex_buffer_object)
|
if (!GLEW_ARB_vertex_buffer_object)
|
||||||
return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED);
|
return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED);
|
||||||
|
|
||||||
|
renderer = calloc (1, sizeof (*renderer));
|
||||||
|
if (unlikely (renderer == NULL))
|
||||||
|
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
renderer->base.destroy = _cairo_gl_surface_span_renderer_destroy;
|
renderer->base.destroy = _cairo_gl_surface_span_renderer_destroy;
|
||||||
renderer->base.finish = _cairo_gl_surface_span_renderer_finish;
|
renderer->base.finish = _cairo_gl_surface_span_renderer_finish;
|
||||||
renderer->base.render_row =
|
renderer->base.render_row =
|
||||||
|
|
@ -1801,6 +1938,12 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
|
||||||
|
|
||||||
_cairo_gl_set_destination (dst);
|
_cairo_gl_set_destination (dst);
|
||||||
|
|
||||||
|
status = _cairo_gl_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
_cairo_gl_surface_span_renderer_destroy (renderer);
|
||||||
|
return _cairo_span_renderer_create_in_error (status);
|
||||||
|
}
|
||||||
|
|
||||||
src_attributes = &renderer->setup.src.operand.texture.attributes;
|
src_attributes = &renderer->setup.src.operand.texture.attributes;
|
||||||
|
|
||||||
status = _cairo_gl_set_operator (dst, op);
|
status = _cairo_gl_set_operator (dst, op);
|
||||||
|
|
@ -1838,7 +1981,7 @@ _cairo_gl_surface_create_span_renderer (cairo_operator_t op,
|
||||||
return &renderer->base;
|
return &renderer->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_gl_surface_get_extents (void *abstract_surface,
|
_cairo_gl_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -1849,7 +1992,7 @@ _cairo_gl_surface_get_extents (void *abstract_surface,
|
||||||
rectangle->width = surface->width;
|
rectangle->width = surface->width;
|
||||||
rectangle->height = surface->height;
|
rectangle->height = surface->height;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -1888,20 +2031,21 @@ static const cairo_surface_backend_t _cairo_gl_surface_backend = {
|
||||||
CAIRO_SURFACE_TYPE_GL,
|
CAIRO_SURFACE_TYPE_GL,
|
||||||
_cairo_gl_surface_create_similar,
|
_cairo_gl_surface_create_similar,
|
||||||
_cairo_gl_surface_finish,
|
_cairo_gl_surface_finish,
|
||||||
|
|
||||||
_cairo_gl_surface_acquire_source_image,
|
_cairo_gl_surface_acquire_source_image,
|
||||||
_cairo_gl_surface_release_source_image,
|
_cairo_gl_surface_release_source_image,
|
||||||
_cairo_gl_surface_acquire_dest_image,
|
_cairo_gl_surface_acquire_dest_image,
|
||||||
_cairo_gl_surface_release_dest_image,
|
_cairo_gl_surface_release_dest_image,
|
||||||
|
|
||||||
_cairo_gl_surface_clone_similar,
|
_cairo_gl_surface_clone_similar,
|
||||||
_cairo_gl_surface_composite,
|
_cairo_gl_surface_composite,
|
||||||
_cairo_gl_surface_fill_rectangles,
|
_cairo_gl_surface_fill_rectangles,
|
||||||
_cairo_gl_surface_composite_trapezoids,
|
_cairo_gl_surface_composite_trapezoids,
|
||||||
_cairo_gl_surface_create_span_renderer,
|
_cairo_gl_surface_create_span_renderer,
|
||||||
_cairo_gl_surface_check_span_renderer,
|
_cairo_gl_surface_check_span_renderer,
|
||||||
|
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_gl_surface_get_extents,
|
_cairo_gl_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
_cairo_gl_surface_get_font_options,
|
_cairo_gl_surface_get_font_options,
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
#include "cairo-glitz.h"
|
#include "cairo-glitz.h"
|
||||||
#include "cairo-glitz-private.h"
|
#include "cairo-glitz-private.h"
|
||||||
|
#include "cairo-region-private.h"
|
||||||
|
|
||||||
typedef struct _cairo_glitz_surface {
|
typedef struct _cairo_glitz_surface {
|
||||||
cairo_surface_t base;
|
cairo_surface_t base;
|
||||||
|
|
@ -34,6 +35,7 @@ typedef struct _cairo_glitz_surface {
|
||||||
glitz_surface_t *surface;
|
glitz_surface_t *surface;
|
||||||
glitz_format_t *format;
|
glitz_format_t *format;
|
||||||
|
|
||||||
|
cairo_region_t *clip_region;
|
||||||
cairo_bool_t has_clip;
|
cairo_bool_t has_clip;
|
||||||
glitz_box_t *clip_boxes;
|
glitz_box_t *clip_boxes;
|
||||||
int num_clip_boxes;
|
int num_clip_boxes;
|
||||||
|
|
@ -50,6 +52,7 @@ _cairo_glitz_surface_finish (void *abstract_surface)
|
||||||
if (surface->clip_boxes)
|
if (surface->clip_boxes)
|
||||||
free (surface->clip_boxes);
|
free (surface->clip_boxes);
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
glitz_surface_destroy (surface->surface);
|
glitz_surface_destroy (surface->surface);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -106,43 +109,6 @@ _cairo_glitz_surface_create_similar (void *abstract_src,
|
||||||
return crsurface;
|
return crsurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_cairo_glitz_get_boxes_from_region (cairo_region_t *region,
|
|
||||||
glitz_box_t **boxes,
|
|
||||||
int *nboxes)
|
|
||||||
{
|
|
||||||
pixman_box32_t *pboxes;
|
|
||||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
int n, i;
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
pboxes = pixman_region32_rectangles (®ion->rgn, &n);
|
|
||||||
if (n == 0) {
|
|
||||||
*nboxes = 0;
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n > *nboxes) {
|
|
||||||
*boxes = _cairo_malloc_ab (n, sizeof (glitz_box_t));
|
|
||||||
if (*boxes == NULL) {
|
|
||||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
(*boxes)[i].x1 = pboxes[i].x1;
|
|
||||||
(*boxes)[i].y1 = pboxes[i].y1;
|
|
||||||
(*boxes)[i].x2 = pboxes[i].x2;
|
|
||||||
(*boxes)[i].y2 = pboxes[i].y2;
|
|
||||||
}
|
|
||||||
|
|
||||||
*nboxes = n;
|
|
||||||
done:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
_cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface,
|
||||||
cairo_rectangle_int_t *interest,
|
cairo_rectangle_int_t *interest,
|
||||||
|
|
@ -463,6 +429,8 @@ _is_supported_operator (cairo_operator_t op)
|
||||||
case CAIRO_OPERATOR_ADD:
|
case CAIRO_OPERATOR_ADD:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED;
|
||||||
case CAIRO_OPERATOR_SATURATE:
|
case CAIRO_OPERATOR_SATURATE:
|
||||||
/* nobody likes saturate, expect that it's required to do
|
/* nobody likes saturate, expect that it's required to do
|
||||||
* seamless polygons!
|
* seamless polygons!
|
||||||
|
|
@ -485,6 +453,7 @@ _is_supported_operator (cairo_operator_t op)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static glitz_operator_t
|
static glitz_operator_t
|
||||||
_glitz_operator (cairo_operator_t op)
|
_glitz_operator (cairo_operator_t op)
|
||||||
{
|
{
|
||||||
|
|
@ -686,9 +655,9 @@ _cairo_glitz_pattern_acquire_surface (const cairo_pattern_t *pattern,
|
||||||
}
|
}
|
||||||
|
|
||||||
src = (cairo_glitz_surface_t *)
|
src = (cairo_glitz_surface_t *)
|
||||||
_cairo_surface_create_similar_scratch (&dst->base,
|
_cairo_glitz_surface_create_similar (&dst->base,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA,
|
CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
gradient->n_stops, 1);
|
gradient->n_stops, 1);
|
||||||
if (src->base.status) {
|
if (src->base.status) {
|
||||||
glitz_buffer_destroy (buffer);
|
glitz_buffer_destroy (buffer);
|
||||||
free (data);
|
free (data);
|
||||||
|
|
@ -914,6 +883,77 @@ _cairo_glitz_surface_set_attributes (cairo_glitz_surface_t *surface,
|
||||||
a->params, a->n_params);
|
a->params, a->n_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_glitz_get_boxes_from_region (cairo_region_t *region,
|
||||||
|
glitz_box_t **boxes,
|
||||||
|
int *nboxes)
|
||||||
|
{
|
||||||
|
pixman_box32_t *pboxes;
|
||||||
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
int n, i;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
pboxes = pixman_region32_rectangles (®ion->rgn, &n);
|
||||||
|
if (n == 0) {
|
||||||
|
*nboxes = 0;
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n > *nboxes) {
|
||||||
|
*boxes = _cairo_malloc_ab (n, sizeof (glitz_box_t));
|
||||||
|
if (*boxes == NULL) {
|
||||||
|
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
(*boxes)[i].x1 = pboxes[i].x1;
|
||||||
|
(*boxes)[i].y1 = pboxes[i].y1;
|
||||||
|
(*boxes)[i].x2 = pboxes[i].x2;
|
||||||
|
(*boxes)[i].y2 = pboxes[i].y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nboxes = n;
|
||||||
|
done:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_glitz_surface_set_clip_region (void *abstract_surface,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
cairo_glitz_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
if (region == surface->clip_region)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
surface->clip_region = cairo_region_reference (region);
|
||||||
|
|
||||||
|
if (region != NULL) {
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_glitz_get_boxes_from_region (region,
|
||||||
|
&surface->clip_boxes,
|
||||||
|
&surface->num_clip_boxes);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
glitz_surface_set_clip_region (surface->surface,
|
||||||
|
0, 0,
|
||||||
|
surface->clip_boxes,
|
||||||
|
surface->num_clip_boxes);
|
||||||
|
surface->has_clip = TRUE;
|
||||||
|
} else {
|
||||||
|
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
|
||||||
|
surface->has_clip = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_glitz_surface_composite (cairo_operator_t op,
|
_cairo_glitz_surface_composite (cairo_operator_t op,
|
||||||
const cairo_pattern_t *src_pattern,
|
const cairo_pattern_t *src_pattern,
|
||||||
|
|
@ -926,7 +966,8 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_glitz_surface_attributes_t src_attr, mask_attr;
|
cairo_glitz_surface_attributes_t src_attr, mask_attr;
|
||||||
cairo_glitz_surface_t *dst = abstract_dst;
|
cairo_glitz_surface_t *dst = abstract_dst;
|
||||||
|
|
@ -940,6 +981,10 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
||||||
if (_glitz_ensure_target (dst->surface))
|
if (_glitz_ensure_target (dst->surface))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_glitz_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
status = _cairo_glitz_pattern_acquire_surfaces (src_pattern, mask_pattern,
|
status = _cairo_glitz_pattern_acquire_surfaces (src_pattern, mask_pattern,
|
||||||
dst,
|
dst,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
|
|
@ -1006,7 +1051,8 @@ _cairo_glitz_surface_composite (cairo_operator_t op,
|
||||||
mask_width, mask_height,
|
mask_width, mask_height,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
mask_x, mask_y,
|
mask_x, mask_y,
|
||||||
dst_x, dst_y, width, height);
|
dst_x, dst_y, width, height,
|
||||||
|
clip_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
|
|
@ -1037,11 +1083,15 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
|
||||||
glitz_rectangle_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (glitz_rectangle_t)];
|
glitz_rectangle_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (glitz_rectangle_t)];
|
||||||
glitz_rectangle_t *glitz_rects = stack_rects;
|
glitz_rectangle_t *glitz_rects = stack_rects;
|
||||||
glitz_rectangle_t *current_rect;
|
glitz_rectangle_t *current_rect;
|
||||||
|
cairo_status_t status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (! _is_supported_operator (op))
|
if (! _is_supported_operator (op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_glitz_surface_set_clip_region (dst, NULL);
|
||||||
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
if (n_rects > ARRAY_LENGTH (stack_rects)) {
|
if (n_rects > ARRAY_LENGTH (stack_rects)) {
|
||||||
glitz_rects = _cairo_malloc_ab (n_rects, sizeof (glitz_rectangle_t));
|
glitz_rects = _cairo_malloc_ab (n_rects, sizeof (glitz_rectangle_t));
|
||||||
if (glitz_rects == NULL)
|
if (glitz_rects == NULL)
|
||||||
|
|
@ -1104,12 +1154,12 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst,
|
||||||
_cairo_surface_create_similar_solid (&dst->base,
|
_cairo_surface_create_similar_solid (&dst->base,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA,
|
CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
1, 1,
|
1, 1,
|
||||||
(cairo_color_t *) color);
|
(cairo_color_t *) color,
|
||||||
if (src->base.status)
|
FALSE);
|
||||||
{
|
if (src == NULL || src->base.status) {
|
||||||
if (glitz_rects != stack_rects)
|
if (glitz_rects != stack_rects)
|
||||||
free (glitz_rects);
|
free (glitz_rects);
|
||||||
return src->base.status;
|
return src ? src->base.status : CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
|
glitz_surface_set_fill (src->surface, GLITZ_FILL_REPEAT);
|
||||||
|
|
@ -1153,7 +1203,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int n_traps)
|
int n_traps,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_glitz_surface_attributes_t attributes;
|
cairo_glitz_surface_attributes_t attributes;
|
||||||
cairo_glitz_surface_t *dst = abstract_dst;
|
cairo_glitz_surface_t *dst = abstract_dst;
|
||||||
|
|
@ -1179,6 +1230,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
if (_glitz_ensure_target (dst->surface))
|
if (_glitz_ensure_target (dst->surface))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_glitz_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
/* Convert traps to pixman traps */
|
/* Convert traps to pixman traps */
|
||||||
if (n_traps > ARRAY_LENGTH (stack_traps)) {
|
if (n_traps > ARRAY_LENGTH (stack_traps)) {
|
||||||
pixman_traps = _cairo_malloc_ab (n_traps, sizeof (pixman_trapezoid_t));
|
pixman_traps = _cairo_malloc_ab (n_traps, sizeof (pixman_trapezoid_t));
|
||||||
|
|
@ -1321,7 +1376,7 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
n_traps, (pixman_trapezoid_t *) pixman_traps);
|
n_traps, (pixman_trapezoid_t *) pixman_traps);
|
||||||
|
|
||||||
mask = (cairo_glitz_surface_t *)
|
mask = (cairo_glitz_surface_t *)
|
||||||
_cairo_surface_create_similar_scratch (&dst->base,
|
_cairo_glitz_surface_create_similar (&dst->base,
|
||||||
CAIRO_CONTENT_ALPHA,
|
CAIRO_CONTENT_ALPHA,
|
||||||
width, height);
|
width, height);
|
||||||
status = mask->base.status;
|
status = mask->base.status;
|
||||||
|
|
@ -1378,7 +1433,8 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
dst_x, dst_y,
|
dst_x, dst_y,
|
||||||
width, height);
|
width, height,
|
||||||
|
clip_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
FAIL:
|
FAIL:
|
||||||
|
|
@ -1393,35 +1449,7 @@ FAIL:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_glitz_surface_set_clip_region (void *abstract_surface,
|
|
||||||
cairo_region_t *region)
|
|
||||||
{
|
|
||||||
cairo_glitz_surface_t *surface = abstract_surface;
|
|
||||||
|
|
||||||
if (region != NULL) {
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_glitz_get_boxes_from_region (region,
|
|
||||||
&surface->clip_boxes,
|
|
||||||
&surface->num_clip_boxes);
|
|
||||||
if (status)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
glitz_surface_set_clip_region (surface->surface,
|
|
||||||
0, 0,
|
|
||||||
surface->clip_boxes,
|
|
||||||
surface->num_clip_boxes);
|
|
||||||
surface->has_clip = TRUE;
|
|
||||||
} else {
|
|
||||||
glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0);
|
|
||||||
surface->has_clip = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_glitz_surface_get_extents (void *abstract_surface,
|
_cairo_glitz_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -1432,7 +1460,7 @@ _cairo_glitz_surface_get_extents (void *abstract_surface,
|
||||||
rectangle->width = glitz_surface_get_width (surface->surface);
|
rectangle->width = glitz_surface_get_width (surface->surface);
|
||||||
rectangle->height = glitz_surface_get_height (surface->surface);
|
rectangle->height = glitz_surface_get_height (surface->surface);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CAIRO_GLITZ_AREA_AVAILABLE 0
|
#define CAIRO_GLITZ_AREA_AVAILABLE 0
|
||||||
|
|
@ -2035,7 +2063,8 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs)
|
int num_glyphs,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_glitz_surface_attributes_t attributes;
|
cairo_glitz_surface_attributes_t attributes;
|
||||||
cairo_glitz_surface_glyph_private_t *glyph_private;
|
cairo_glitz_surface_glyph_private_t *glyph_private;
|
||||||
|
|
@ -2078,6 +2107,10 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
if (_glitz_ensure_target (dst->surface))
|
if (_glitz_ensure_target (dst->surface))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_glitz_surface_set_clip_region (dst, NULL);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
|
status = _cairo_glitz_pattern_acquire_surface (pattern, dst,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
width, height,
|
width, height,
|
||||||
|
|
@ -2326,25 +2359,13 @@ _cairo_glitz_surface_is_similar (void *surface_a,
|
||||||
return drawable_a == drawable_b;
|
return drawable_a == drawable_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_cairo_glitz_surface_reset (void *abstract_surface)
|
|
||||||
{
|
|
||||||
cairo_glitz_surface_t *surface = abstract_surface;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_glitz_surface_set_clip_region (surface, NULL);
|
|
||||||
if (status)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
||||||
CAIRO_SURFACE_TYPE_GLITZ,
|
CAIRO_SURFACE_TYPE_GLITZ,
|
||||||
_cairo_glitz_surface_create_similar,
|
_cairo_glitz_surface_create_similar,
|
||||||
_cairo_glitz_surface_finish,
|
_cairo_glitz_surface_finish,
|
||||||
_cairo_glitz_surface_acquire_source_image,
|
_cairo_glitz_surface_acquire_source_image,
|
||||||
_cairo_glitz_surface_release_source_image,
|
_cairo_glitz_surface_release_source_image,
|
||||||
|
|
||||||
_cairo_glitz_surface_acquire_dest_image,
|
_cairo_glitz_surface_acquire_dest_image,
|
||||||
_cairo_glitz_surface_release_dest_image,
|
_cairo_glitz_surface_release_dest_image,
|
||||||
_cairo_glitz_surface_clone_similar,
|
_cairo_glitz_surface_clone_similar,
|
||||||
|
|
@ -2353,10 +2374,9 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
||||||
_cairo_glitz_surface_composite_trapezoids,
|
_cairo_glitz_surface_composite_trapezoids,
|
||||||
NULL, /* create_span_renderer */
|
NULL, /* create_span_renderer */
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
|
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
_cairo_glitz_surface_set_clip_region,
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_glitz_surface_get_extents,
|
_cairo_glitz_surface_get_extents,
|
||||||
_cairo_glitz_surface_old_show_glyphs,
|
_cairo_glitz_surface_old_show_glyphs,
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -2373,8 +2393,6 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
||||||
|
|
||||||
_cairo_glitz_surface_snapshot,
|
_cairo_glitz_surface_snapshot,
|
||||||
_cairo_glitz_surface_is_similar,
|
_cairo_glitz_surface_is_similar,
|
||||||
|
|
||||||
_cairo_glitz_surface_reset
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const cairo_surface_backend_t *
|
static const cairo_surface_backend_t *
|
||||||
|
|
@ -2424,6 +2442,7 @@ cairo_glitz_surface_create (glitz_surface_t *surface)
|
||||||
crsurface->has_clip = FALSE;
|
crsurface->has_clip = FALSE;
|
||||||
crsurface->clip_boxes = NULL;
|
crsurface->clip_boxes = NULL;
|
||||||
crsurface->num_clip_boxes = 0;
|
crsurface->num_clip_boxes = 0;
|
||||||
|
crsurface->clip_region = NULL;
|
||||||
|
|
||||||
return &crsurface->base;
|
return &crsurface->base;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
|
||||||
|
|
||||||
_cairo_font_options_init_default (&gstate->font_options);
|
_cairo_font_options_init_default (&gstate->font_options);
|
||||||
|
|
||||||
_cairo_clip_init (&gstate->clip, target);
|
_cairo_clip_init (&gstate->clip);
|
||||||
|
|
||||||
gstate->target = cairo_surface_reference (target);
|
gstate->target = cairo_surface_reference (target);
|
||||||
gstate->parent_target = NULL;
|
gstate->parent_target = NULL;
|
||||||
|
|
@ -164,14 +164,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
||||||
|
|
||||||
_cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
|
_cairo_font_options_init_copy (&gstate->font_options , &other->font_options);
|
||||||
|
|
||||||
status = _cairo_clip_init_copy (&gstate->clip, &other->clip);
|
_cairo_clip_init_copy (&gstate->clip, &other->clip);
|
||||||
if (unlikely (status)) {
|
|
||||||
_cairo_stroke_style_fini (&gstate->stroke_style);
|
|
||||||
cairo_font_face_destroy (gstate->font_face);
|
|
||||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
|
||||||
cairo_scaled_font_destroy (gstate->previous_scaled_font);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
gstate->target = cairo_surface_reference (other->target);
|
gstate->target = cairo_surface_reference (other->target);
|
||||||
/* parent_target is always set to NULL; it's only ever set by redirect_target */
|
/* parent_target is always set to NULL; it's only ever set by redirect_target */
|
||||||
|
|
@ -299,7 +292,7 @@ _cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
|
_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_matrix_t matrix;
|
||||||
|
|
||||||
/* If this gstate is already redirected, this is an error; we need a
|
/* If this gstate is already redirected, this is an error; we need a
|
||||||
* new gstate to be able to redirect */
|
* new gstate to be able to redirect */
|
||||||
|
|
@ -315,18 +308,15 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child)
|
||||||
* since its ref is now owned by gstate->parent_target */
|
* since its ref is now owned by gstate->parent_target */
|
||||||
gstate->target = cairo_surface_reference (child);
|
gstate->target = cairo_surface_reference (child);
|
||||||
|
|
||||||
_cairo_clip_reset (&gstate->clip);
|
|
||||||
status = _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
/* The clip is in surface backend coordinates for the previous target;
|
/* The clip is in surface backend coordinates for the previous target;
|
||||||
* translate it into the child's backend coordinates. */
|
* translate it into the child's backend coordinates. */
|
||||||
_cairo_clip_translate (&gstate->clip,
|
cairo_matrix_init_translate (&matrix,
|
||||||
_cairo_fixed_from_double (child->device_transform.x0 - gstate->parent_target->device_transform.x0),
|
child->device_transform.x0 - gstate->parent_target->device_transform.x0,
|
||||||
_cairo_fixed_from_double (child->device_transform.y0 - gstate->parent_target->device_transform.y0));
|
child->device_transform.y0 - gstate->parent_target->device_transform.y0);
|
||||||
|
_cairo_clip_reset (&gstate->clip);
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return _cairo_clip_init_copy_transformed (&gstate->clip,
|
||||||
|
&gstate->next->clip,
|
||||||
|
&matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -870,43 +860,63 @@ _cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate,
|
||||||
&gstate->ctm_inverse);
|
&gstate->ctm_inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _gstate_get_clip(g) ((g)->clip.path ? &(g)->clip : NULL)
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
_clipped (const cairo_gstate_t *gstate)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
|
if (gstate->clip.all_clipped)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (gstate->clip.path == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (_cairo_surface_get_extents (gstate->target, &extents)) {
|
||||||
|
if (! _cairo_rectangle_intersect (&extents,
|
||||||
|
&gstate->clip.path->extents))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_gstate_paint (cairo_gstate_t *gstate)
|
_cairo_gstate_paint (cairo_gstate_t *gstate)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
|
||||||
cairo_pattern_union_t pattern;
|
cairo_pattern_union_t pattern;
|
||||||
|
|
||||||
if (gstate->source->status)
|
if (unlikely (gstate->source->status))
|
||||||
return gstate->source->status;
|
return gstate->source->status;
|
||||||
|
|
||||||
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
|
if (_clipped (gstate))
|
||||||
if (unlikely (status))
|
return CAIRO_STATUS_SUCCESS;
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_gstate_copy_transformed_source (gstate, &pattern.base);
|
_cairo_gstate_copy_transformed_source (gstate, &pattern.base);
|
||||||
|
|
||||||
return _cairo_surface_paint (gstate->target,
|
return _cairo_surface_paint (gstate->target,
|
||||||
gstate->op,
|
gstate->op,
|
||||||
&pattern.base,
|
&pattern.base,
|
||||||
NULL);
|
_gstate_get_clip (gstate));
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_gstate_mask (cairo_gstate_t *gstate,
|
_cairo_gstate_mask (cairo_gstate_t *gstate,
|
||||||
cairo_pattern_t *mask)
|
cairo_pattern_t *mask)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
|
||||||
cairo_pattern_union_t source_pattern, mask_pattern;
|
cairo_pattern_union_t source_pattern, mask_pattern;
|
||||||
|
|
||||||
if (mask->status)
|
if (unlikely (mask->status))
|
||||||
return mask->status;
|
return mask->status;
|
||||||
|
|
||||||
if (gstate->source->status)
|
if (unlikely (gstate->source->status))
|
||||||
return gstate->source->status;
|
return gstate->source->status;
|
||||||
|
|
||||||
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
|
if (_clipped (gstate))
|
||||||
if (unlikely (status))
|
return CAIRO_STATUS_SUCCESS;
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
||||||
_cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
|
_cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
|
||||||
|
|
@ -915,24 +925,22 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
|
||||||
gstate->op,
|
gstate->op,
|
||||||
&source_pattern.base,
|
&source_pattern.base,
|
||||||
&mask_pattern.base,
|
&mask_pattern.base,
|
||||||
NULL);
|
_gstate_get_clip (gstate));
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
|
||||||
cairo_pattern_union_t source_pattern;
|
cairo_pattern_union_t source_pattern;
|
||||||
|
|
||||||
if (gstate->source->status)
|
if (unlikely (gstate->source->status))
|
||||||
return gstate->source->status;
|
return gstate->source->status;
|
||||||
|
|
||||||
if (gstate->stroke_style.line_width <= 0.0)
|
if (gstate->stroke_style.line_width <= 0.0)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
|
if (_clipped (gstate))
|
||||||
if (unlikely (status))
|
return CAIRO_STATUS_SUCCESS;
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
||||||
|
|
||||||
|
|
@ -945,7 +953,7 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||||
&gstate->ctm_inverse,
|
&gstate->ctm_inverse,
|
||||||
gstate->tolerance,
|
gstate->tolerance,
|
||||||
gstate->antialias,
|
gstate->antialias,
|
||||||
NULL);
|
_gstate_get_clip (gstate));
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
|
|
@ -1009,15 +1017,26 @@ BAIL:
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
|
||||||
cairo_pattern_union_t pattern;
|
cairo_pattern_union_t pattern;
|
||||||
|
|
||||||
if (gstate->source->status)
|
if (unlikely (gstate->source->status))
|
||||||
return gstate->source->status;
|
return gstate->source->status;
|
||||||
|
|
||||||
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
|
if (_clipped (gstate))
|
||||||
if (unlikely (status))
|
return CAIRO_STATUS_SUCCESS;
|
||||||
return status;
|
|
||||||
|
if (_cairo_path_fixed_fill_is_empty (path)) {
|
||||||
|
if (_cairo_operator_bounded_by_mask (gstate->op))
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
_cairo_pattern_init_solid (&pattern.solid,
|
||||||
|
CAIRO_COLOR_TRANSPARENT,
|
||||||
|
CAIRO_CONTENT_COLOR_ALPHA);
|
||||||
|
return _cairo_surface_paint (gstate->target,
|
||||||
|
CAIRO_OPERATOR_CLEAR,
|
||||||
|
&pattern.base,
|
||||||
|
_gstate_get_clip (gstate));
|
||||||
|
}
|
||||||
|
|
||||||
_cairo_gstate_copy_transformed_source (gstate, &pattern.base);
|
_cairo_gstate_copy_transformed_source (gstate, &pattern.base);
|
||||||
|
|
||||||
|
|
@ -1028,23 +1047,56 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||||
gstate->fill_rule,
|
gstate->fill_rule,
|
||||||
gstate->tolerance,
|
gstate->tolerance,
|
||||||
gstate->antialias,
|
gstate->antialias,
|
||||||
NULL);
|
_gstate_get_clip (gstate));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
cairo_bool_t
|
||||||
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
|
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y)
|
||||||
cairo_bool_t *inside_ret)
|
|
||||||
{
|
{
|
||||||
_cairo_gstate_user_to_backend (gstate, &x, &y);
|
_cairo_gstate_user_to_backend (gstate, &x, &y);
|
||||||
|
|
||||||
_cairo_path_fixed_in_fill (path,
|
return _cairo_path_fixed_in_fill (path,
|
||||||
gstate->fill_rule,
|
gstate->fill_rule,
|
||||||
gstate->tolerance,
|
gstate->tolerance,
|
||||||
x, y,
|
x, y);
|
||||||
inside_ret);
|
}
|
||||||
|
|
||||||
|
cairo_bool_t
|
||||||
|
_cairo_gstate_in_clip (cairo_gstate_t *gstate,
|
||||||
|
double x,
|
||||||
|
double y)
|
||||||
|
{
|
||||||
|
cairo_clip_path_t *clip_path;
|
||||||
|
|
||||||
|
if (gstate->clip.all_clipped)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
clip_path = gstate->clip.path;
|
||||||
|
if (clip_path == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
_cairo_gstate_user_to_backend (gstate, &x, &y);
|
||||||
|
|
||||||
|
if (x < clip_path->extents.x ||
|
||||||
|
x >= clip_path->extents.x + clip_path->extents.width ||
|
||||||
|
y < clip_path->extents.y ||
|
||||||
|
y >= clip_path->extents.y + clip_path->extents.height)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (! _cairo_path_fixed_in_fill (&clip_path->path,
|
||||||
|
clip_path->fill_rule,
|
||||||
|
clip_path->tolerance,
|
||||||
|
x, y))
|
||||||
|
return FALSE;
|
||||||
|
} while ((clip_path = clip_path->prev) != NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
|
|
@ -1179,26 +1231,31 @@ cairo_status_t
|
||||||
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
return _cairo_clip_clip (&gstate->clip,
|
return _cairo_clip_clip (&gstate->clip,
|
||||||
path, gstate->fill_rule, gstate->tolerance,
|
path, gstate->fill_rule,
|
||||||
gstate->antialias, gstate->target);
|
gstate->tolerance, gstate->antialias);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_bool_t
|
||||||
_cairo_gstate_int_clip_extents (cairo_gstate_t *gstate,
|
_cairo_gstate_int_clip_extents (cairo_gstate_t *gstate,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
const cairo_rectangle_int_t *clip_extents;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (gstate->target, extents);
|
is_bounded = _cairo_surface_get_extents (gstate->target, extents);
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = _cairo_clip_intersect_to_rectangle (&gstate->clip, extents);
|
clip_extents = _cairo_clip_get_extents (&gstate->clip);
|
||||||
|
if (clip_extents != NULL) {
|
||||||
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
return status;
|
is_empty = _cairo_rectangle_intersect (extents, clip_extents);
|
||||||
|
is_bounded = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_bounded;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_bool_t
|
||||||
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
||||||
double *x1,
|
double *x1,
|
||||||
double *y1,
|
double *y1,
|
||||||
|
|
@ -1207,11 +1264,9 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
double px1, py1, px2, py2;
|
double px1, py1, px2, py2;
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_gstate_int_clip_extents (gstate, &extents);
|
if (! _cairo_gstate_int_clip_extents (gstate, &extents))
|
||||||
if (unlikely (status))
|
return FALSE;
|
||||||
return status;
|
|
||||||
|
|
||||||
px1 = extents.x;
|
px1 = extents.x;
|
||||||
py1 = extents.y;
|
py1 = extents.y;
|
||||||
|
|
@ -1231,7 +1286,7 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
||||||
if (y2)
|
if (y2)
|
||||||
*y2 = py2;
|
*y2 = py2;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_rectangle_list_t*
|
cairo_rectangle_list_t*
|
||||||
|
|
@ -1576,12 +1631,11 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||||
cairo_text_cluster_t *transformed_clusters;
|
cairo_text_cluster_t *transformed_clusters;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
if (gstate->source->status)
|
if (unlikely (gstate->source->status))
|
||||||
return gstate->source->status;
|
return gstate->source->status;
|
||||||
|
|
||||||
status = _cairo_surface_set_clip (gstate->target, &gstate->clip);
|
if (_clipped (gstate))
|
||||||
if (unlikely (status))
|
return CAIRO_STATUS_SUCCESS;
|
||||||
return status;
|
|
||||||
|
|
||||||
status = _cairo_gstate_ensure_scaled_font (gstate);
|
status = _cairo_gstate_ensure_scaled_font (gstate);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -1635,7 +1689,8 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||||
*
|
*
|
||||||
* Needless to say, do this only if show_text_glyphs is not available. */
|
* Needless to say, do this only if show_text_glyphs is not available. */
|
||||||
if (cairo_surface_has_show_text_glyphs (gstate->target) ||
|
if (cairo_surface_has_show_text_glyphs (gstate->target) ||
|
||||||
_cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240) {
|
_cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240)
|
||||||
|
{
|
||||||
status = _cairo_surface_show_text_glyphs (gstate->target,
|
status = _cairo_surface_show_text_glyphs (gstate->target,
|
||||||
gstate->op,
|
gstate->op,
|
||||||
&source_pattern.base,
|
&source_pattern.base,
|
||||||
|
|
@ -1643,8 +1698,11 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||||
transformed_glyphs, num_glyphs,
|
transformed_glyphs, num_glyphs,
|
||||||
transformed_clusters, num_clusters,
|
transformed_clusters, num_clusters,
|
||||||
cluster_flags,
|
cluster_flags,
|
||||||
gstate->scaled_font, NULL);
|
gstate->scaled_font,
|
||||||
} else {
|
_gstate_get_clip (gstate));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
cairo_path_fixed_t path;
|
cairo_path_fixed_t path;
|
||||||
|
|
||||||
_cairo_path_fixed_init (&path);
|
_cairo_path_fixed_init (&path);
|
||||||
|
|
@ -1653,14 +1711,16 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||||
transformed_glyphs, num_glyphs,
|
transformed_glyphs, num_glyphs,
|
||||||
&path);
|
&path);
|
||||||
|
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
if (status == CAIRO_STATUS_SUCCESS) {
|
||||||
status = _cairo_surface_fill (gstate->target,
|
status = _cairo_surface_fill (gstate->target,
|
||||||
gstate->op,
|
gstate->op,
|
||||||
&source_pattern.base,
|
&source_pattern.base,
|
||||||
&path,
|
&path,
|
||||||
CAIRO_FILL_RULE_WINDING,
|
CAIRO_FILL_RULE_WINDING,
|
||||||
gstate->tolerance,
|
gstate->tolerance,
|
||||||
gstate->scaled_font->options.antialias, NULL);
|
gstate->scaled_font->options.antialias,
|
||||||
|
_gstate_get_clip (gstate));
|
||||||
|
}
|
||||||
|
|
||||||
_cairo_path_fixed_fini (&path);
|
_cairo_path_fixed_fini (&path);
|
||||||
}
|
}
|
||||||
|
|
@ -1765,17 +1825,12 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
|
||||||
cairo_matrix_t *device_transform = &gstate->target->device_transform;
|
cairo_matrix_t *device_transform = &gstate->target->device_transform;
|
||||||
cairo_bool_t drop = FALSE;
|
cairo_bool_t drop = FALSE;
|
||||||
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
|
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
if (num_transformed_glyphs != NULL) {
|
if (num_transformed_glyphs != NULL) {
|
||||||
cairo_rectangle_int_t surface_extents;
|
cairo_rectangle_int_t surface_extents;
|
||||||
|
|
||||||
drop = TRUE;
|
drop = TRUE;
|
||||||
status = _cairo_gstate_int_clip_extents (gstate, &surface_extents);
|
if (! _cairo_gstate_int_clip_extents (gstate, &surface_extents)) {
|
||||||
if (_cairo_status_is_error (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
|
||||||
drop = FALSE; /* unbounded surface */
|
drop = FALSE; /* unbounded surface */
|
||||||
} else {
|
} else {
|
||||||
double scale10 = 10 * _cairo_scaled_font_get_max_scale (gstate->scaled_font);
|
double scale10 = 10 * _cairo_scaled_font_get_max_scale (gstate->scaled_font);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@
|
||||||
|
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
|
|
||||||
|
#include "cairo-clip-private.h"
|
||||||
|
#include "cairo-region-private.h"
|
||||||
|
|
||||||
static cairo_format_t
|
static cairo_format_t
|
||||||
_cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
|
_cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
|
||||||
{
|
{
|
||||||
|
|
@ -63,6 +66,14 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
|
||||||
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9)
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9)
|
||||||
case PIXMAN_x2b10g10r10:
|
case PIXMAN_x2b10g10r10:
|
||||||
case PIXMAN_a2b10g10r10:
|
case PIXMAN_a2b10g10r10:
|
||||||
|
#endif
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,14,1)
|
||||||
|
case PIXMAN_b8g8r8x8:
|
||||||
|
case PIXMAN_b8g8r8a8:
|
||||||
|
#endif
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16)
|
||||||
|
case PIXMAN_x2r10g10b10:
|
||||||
|
case PIXMAN_a2r10g10b10:
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return CAIRO_FORMAT_INVALID;
|
return CAIRO_FORMAT_INVALID;
|
||||||
|
|
@ -87,6 +98,12 @@ _cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
|
||||||
case PIXMAN_a1b1g1r1:
|
case PIXMAN_a1b1g1r1:
|
||||||
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9)
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9)
|
||||||
case PIXMAN_a2b10g10r10:
|
case PIXMAN_a2b10g10r10:
|
||||||
|
#endif
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,14,1)
|
||||||
|
case PIXMAN_b8g8r8a8:
|
||||||
|
#endif
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16)
|
||||||
|
case PIXMAN_a2r10g10b10:
|
||||||
#endif
|
#endif
|
||||||
return CAIRO_CONTENT_COLOR_ALPHA;
|
return CAIRO_CONTENT_COLOR_ALPHA;
|
||||||
case PIXMAN_x8r8g8b8:
|
case PIXMAN_x8r8g8b8:
|
||||||
|
|
@ -112,6 +129,12 @@ _cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
|
||||||
case PIXMAN_yv12:
|
case PIXMAN_yv12:
|
||||||
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9)
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,11,9)
|
||||||
case PIXMAN_x2b10g10r10:
|
case PIXMAN_x2b10g10r10:
|
||||||
|
#endif
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,14,1)
|
||||||
|
case PIXMAN_b8g8r8x8:
|
||||||
|
#endif
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,15,16)
|
||||||
|
case PIXMAN_x2r10g10b10:
|
||||||
#endif
|
#endif
|
||||||
return CAIRO_CONTENT_COLOR;
|
return CAIRO_CONTENT_COLOR;
|
||||||
case PIXMAN_a8:
|
case PIXMAN_a8:
|
||||||
|
|
@ -143,7 +166,6 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||||
surface->format = _cairo_format_from_pixman_format (pixman_format);
|
surface->format = _cairo_format_from_pixman_format (pixman_format);
|
||||||
surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
|
surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
|
||||||
surface->owns_data = FALSE;
|
surface->owns_data = FALSE;
|
||||||
surface->has_clip = FALSE;
|
|
||||||
surface->transparency = CAIRO_IMAGE_UNKNOWN;
|
surface->transparency = CAIRO_IMAGE_UNKNOWN;
|
||||||
|
|
||||||
surface->width = pixman_image_get_width (pixman_image);
|
surface->width = pixman_image_get_width (pixman_image);
|
||||||
|
|
@ -151,6 +173,8 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||||
surface->stride = pixman_image_get_stride (pixman_image);
|
surface->stride = pixman_image_get_stride (pixman_image);
|
||||||
surface->depth = pixman_image_get_depth (pixman_image);
|
surface->depth = pixman_image_get_depth (pixman_image);
|
||||||
|
|
||||||
|
surface->clip_region = NULL;
|
||||||
|
|
||||||
return &surface->base;
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -725,6 +749,8 @@ _cairo_image_surface_finish (void *abstract_surface)
|
||||||
surface->data = NULL;
|
surface->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -974,25 +1000,52 @@ _pixman_operator (cairo_operator_t op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_image_surface_set_clip_region (cairo_image_surface_t *surface,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
if (region == surface->clip_region)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (cairo_region_equal (surface->clip_region, region))
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
surface->clip_region = cairo_region_reference (region);
|
||||||
|
|
||||||
|
if (! pixman_image_set_clip_region32 (surface->pixman_image,
|
||||||
|
region ? ®ion->rgn : NULL))
|
||||||
|
{
|
||||||
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_image_surface_composite (cairo_operator_t op,
|
_cairo_image_surface_composite (cairo_operator_t op,
|
||||||
const cairo_pattern_t *src_pattern,
|
const cairo_pattern_t *src_pattern,
|
||||||
const cairo_pattern_t *mask_pattern,
|
const cairo_pattern_t *mask_pattern,
|
||||||
void *abstract_dst,
|
void *abstract_dst,
|
||||||
int src_x,
|
int src_x,
|
||||||
int src_y,
|
int src_y,
|
||||||
int mask_x,
|
int mask_x,
|
||||||
int mask_y,
|
int mask_y,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_surface_attributes_t src_attr, mask_attr;
|
cairo_surface_attributes_t src_attr, mask_attr;
|
||||||
cairo_image_surface_t *dst = abstract_dst;
|
cairo_image_surface_t *dst = abstract_dst;
|
||||||
cairo_image_surface_t *src;
|
cairo_image_surface_t *src;
|
||||||
cairo_image_surface_t *mask;
|
cairo_image_surface_t *mask;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_image_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern,
|
status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern,
|
||||||
&dst->base,
|
&dst->base,
|
||||||
|
|
@ -1013,8 +1066,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto CLEANUP_SURFACES;
|
goto CLEANUP_SURFACES;
|
||||||
|
|
||||||
if (mask)
|
if (mask) {
|
||||||
{
|
|
||||||
status = _cairo_image_surface_set_attributes (mask, &mask_attr,
|
status = _cairo_image_surface_set_attributes (mask, &mask_attr,
|
||||||
dst_x + width / 2.,
|
dst_x + width / 2.,
|
||||||
dst_y + height / 2.);
|
dst_y + height / 2.);
|
||||||
|
|
@ -1031,9 +1083,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
||||||
mask_y + mask_attr.y_offset,
|
mask_y + mask_attr.y_offset,
|
||||||
dst_x, dst_y,
|
dst_x, dst_y,
|
||||||
width, height);
|
width, height);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
pixman_image_composite (_pixman_operator (op),
|
pixman_image_composite (_pixman_operator (op),
|
||||||
src->pixman_image,
|
src->pixman_image,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
@ -1045,7 +1095,7 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
||||||
width, height);
|
width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! _cairo_operator_bounded_by_source (op))
|
if (! _cairo_operator_bounded_by_source (op)) {
|
||||||
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
|
status = _cairo_surface_composite_fixup_unbounded (&dst->base,
|
||||||
&src_attr, src->width, src->height,
|
&src_attr, src->width, src->height,
|
||||||
mask ? &mask_attr : NULL,
|
mask ? &mask_attr : NULL,
|
||||||
|
|
@ -1053,7 +1103,9 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
||||||
mask ? mask->height : 0,
|
mask ? mask->height : 0,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
mask_x, mask_y,
|
mask_x, mask_y,
|
||||||
dst_x, dst_y, width, height);
|
dst_x, dst_y, width, height,
|
||||||
|
clip_region);
|
||||||
|
}
|
||||||
|
|
||||||
CLEANUP_SURFACES:
|
CLEANUP_SURFACES:
|
||||||
if (mask)
|
if (mask)
|
||||||
|
|
@ -1078,7 +1130,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||||
pixman_rectangle16_t *pixman_rects = stack_rects;
|
pixman_rectangle16_t *pixman_rects = stack_rects;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
cairo_int_status_t status;
|
||||||
|
|
||||||
if (CAIRO_INJECT_FAULT ())
|
if (CAIRO_INJECT_FAULT ())
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
@ -1088,6 +1140,9 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||||
pixman_color.blue = color->blue_short;
|
pixman_color.blue = color->blue_short;
|
||||||
pixman_color.alpha = color->alpha_short;
|
pixman_color.alpha = color->alpha_short;
|
||||||
|
|
||||||
|
status = _cairo_image_surface_set_clip_region (surface, NULL);
|
||||||
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
if (num_rects > ARRAY_LENGTH (stack_rects)) {
|
if (num_rects > ARRAY_LENGTH (stack_rects)) {
|
||||||
pixman_rects = _cairo_malloc_ab (num_rects, sizeof (pixman_rectangle16_t));
|
pixman_rects = _cairo_malloc_ab (num_rects, sizeof (pixman_rectangle16_t));
|
||||||
if (unlikely (pixman_rects == NULL))
|
if (unlikely (pixman_rects == NULL))
|
||||||
|
|
@ -1101,7 +1156,8 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||||
pixman_rects[i].height = rects[i].height;
|
pixman_rects[i].height = rects[i].height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: pixman_fill_rectangles() should be implemented */
|
/* XXX: pixman_fill_region() should be implemented */
|
||||||
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
if (! pixman_image_fill_rectangles (_pixman_operator (op),
|
if (! pixman_image_fill_rectangles (_pixman_operator (op),
|
||||||
surface->pixman_image,
|
surface->pixman_image,
|
||||||
&pixman_color,
|
&pixman_color,
|
||||||
|
|
@ -1165,7 +1221,8 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int num_traps)
|
int num_traps,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_surface_attributes_t attributes;
|
cairo_surface_attributes_t attributes;
|
||||||
cairo_image_surface_t *dst = abstract_dst;
|
cairo_image_surface_t *dst = abstract_dst;
|
||||||
|
|
@ -1186,22 +1243,26 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
* contained within the surface is bounded by [dst_x,dst_y,width,height];
|
* contained within the surface is bounded by [dst_x,dst_y,width,height];
|
||||||
* the Cairo core code passes bounds based on the trapezoid extents.
|
* the Cairo core code passes bounds based on the trapezoid extents.
|
||||||
*
|
*
|
||||||
* Currently the check surface->has_clip is needed for correct
|
* Currently the check clip_region == NULL is needed for correct
|
||||||
* functioning, since pixman_add_trapezoids() doesn't obey the
|
* functioning, since pixman_add_trapezoids() doesn't obey the
|
||||||
* surface clip, which is a libpixman bug , but there's no harm in
|
* surface clip, which is a libpixman bug , but there's no harm in
|
||||||
* falling through to the general case when the surface is clipped
|
* falling through to the general case when the surface is clipped
|
||||||
* since libpixman would have to generate an intermediate mask anyways.
|
* since libpixman would have to generate an intermediate mask anyways.
|
||||||
*/
|
*/
|
||||||
if (op == CAIRO_OPERATOR_ADD &&
|
if (op == CAIRO_OPERATOR_ADD &&
|
||||||
|
clip_region == NULL &&
|
||||||
_cairo_pattern_is_opaque_solid (pattern) &&
|
_cairo_pattern_is_opaque_solid (pattern) &&
|
||||||
dst->base.content == CAIRO_CONTENT_ALPHA &&
|
dst->base.content == CAIRO_CONTENT_ALPHA &&
|
||||||
! dst->has_clip &&
|
|
||||||
antialias != CAIRO_ANTIALIAS_NONE)
|
antialias != CAIRO_ANTIALIAS_NONE)
|
||||||
{
|
{
|
||||||
_pixman_add_trapezoids (dst->pixman_image, 0, 0, traps, num_traps);
|
_pixman_add_trapezoids (dst->pixman_image, 0, 0, traps, num_traps);
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = _cairo_image_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA,
|
CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
src_x, src_y, width, height,
|
src_x, src_y, width, height,
|
||||||
|
|
@ -1238,14 +1299,16 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
|
|
||||||
pixman_image_unref (mask);
|
pixman_image_unref (mask);
|
||||||
|
|
||||||
if (! _cairo_operator_bounded_by_mask (op))
|
if (! _cairo_operator_bounded_by_mask (op)) {
|
||||||
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
|
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
|
||||||
&attributes,
|
&attributes,
|
||||||
src->width, src->height,
|
src->width, src->height,
|
||||||
width, height,
|
width, height,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
dst_x, dst_y, width, height);
|
dst_x, dst_y, width, height,
|
||||||
|
clip_region);
|
||||||
|
}
|
||||||
|
|
||||||
CLEANUP_SOURCE:
|
CLEANUP_SOURCE:
|
||||||
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
|
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
|
||||||
|
|
@ -1382,7 +1445,7 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
|
||||||
rects->dst.x, rects->dst.y,
|
rects->dst.x, rects->dst.y,
|
||||||
width, height);
|
width, height);
|
||||||
|
|
||||||
if (! _cairo_operator_bounded_by_mask (renderer->op))
|
if (! _cairo_operator_bounded_by_mask (renderer->op)) {
|
||||||
status = _cairo_surface_composite_shape_fixup_unbounded (
|
status = _cairo_surface_composite_shape_fixup_unbounded (
|
||||||
&dst->base,
|
&dst->base,
|
||||||
src_attributes,
|
src_attributes,
|
||||||
|
|
@ -1391,7 +1454,9 @@ _cairo_image_surface_span_renderer_finish (void *abstract_renderer)
|
||||||
rects->src.x, rects->src.y,
|
rects->src.x, rects->src.y,
|
||||||
0, 0, /* mask.x, mask.y */
|
0, 0, /* mask.x, mask.y */
|
||||||
rects->dst.x, rects->dst.y,
|
rects->dst.x, rects->dst.y,
|
||||||
rects->width, rects->height);
|
rects->width, rects->height,
|
||||||
|
dst->clip_region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (status != CAIRO_STATUS_SUCCESS)
|
if (status != CAIRO_STATUS_SUCCESS)
|
||||||
return _cairo_span_renderer_set_error (abstract_renderer,
|
return _cairo_span_renderer_set_error (abstract_renderer,
|
||||||
|
|
@ -1406,12 +1471,12 @@ _cairo_image_surface_check_span_renderer (cairo_operator_t op,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
const cairo_composite_rectangles_t *rects)
|
const cairo_composite_rectangles_t *rects)
|
||||||
{
|
{
|
||||||
|
return TRUE;
|
||||||
(void) op;
|
(void) op;
|
||||||
(void) pattern;
|
(void) pattern;
|
||||||
(void) abstract_dst;
|
(void) abstract_dst;
|
||||||
(void) antialias;
|
(void) antialias;
|
||||||
(void) rects;
|
(void) rects;
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_span_renderer_t *
|
static cairo_span_renderer_t *
|
||||||
|
|
@ -1419,22 +1484,25 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
|
||||||
const cairo_pattern_t *pattern,
|
const cairo_pattern_t *pattern,
|
||||||
void *abstract_dst,
|
void *abstract_dst,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
const cairo_composite_rectangles_t *rects)
|
const cairo_composite_rectangles_t *rects,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_image_surface_t *dst = abstract_dst;
|
cairo_image_surface_t *dst = abstract_dst;
|
||||||
cairo_image_surface_span_renderer_t *renderer
|
cairo_image_surface_span_renderer_t *renderer = calloc(1, sizeof(*renderer));
|
||||||
= calloc(1, sizeof(*renderer));
|
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
int width = rects->width;
|
int width = rects->width;
|
||||||
int height = rects->height;
|
int height = rects->height;
|
||||||
|
|
||||||
|
status = _cairo_image_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
return _cairo_span_renderer_create_in_error (status);
|
||||||
|
|
||||||
if (renderer == NULL)
|
if (renderer == NULL)
|
||||||
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
renderer->base.destroy = _cairo_image_surface_span_renderer_destroy;
|
renderer->base.destroy = _cairo_image_surface_span_renderer_destroy;
|
||||||
renderer->base.finish = _cairo_image_surface_span_renderer_finish;
|
renderer->base.finish = _cairo_image_surface_span_renderer_finish;
|
||||||
renderer->base.render_row =
|
renderer->base.render_row = _cairo_image_surface_span_renderer_render_row;
|
||||||
_cairo_image_surface_span_renderer_render_row;
|
|
||||||
renderer->op = op;
|
renderer->op = op;
|
||||||
renderer->pattern = pattern;
|
renderer->pattern = pattern;
|
||||||
renderer->antialias = antialias;
|
renderer->antialias = antialias;
|
||||||
|
|
@ -1475,21 +1543,7 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
|
||||||
return &renderer->base;
|
return &renderer->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_image_surface_set_clip_region (void *abstract_surface,
|
|
||||||
cairo_region_t *region)
|
|
||||||
{
|
|
||||||
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
|
|
||||||
|
|
||||||
if (! pixman_image_set_clip_region32 (surface->pixman_image, region? ®ion->rgn : NULL))
|
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
|
|
||||||
surface->has_clip = region != NULL;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_image_surface_get_extents (void *abstract_surface,
|
_cairo_image_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -1500,7 +1554,7 @@ _cairo_image_surface_get_extents (void *abstract_surface,
|
||||||
rectangle->width = surface->width;
|
rectangle->width = surface->width;
|
||||||
rectangle->height = surface->height;
|
rectangle->height = surface->height;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -1512,18 +1566,6 @@ _cairo_image_surface_get_font_options (void *abstract_surface,
|
||||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
|
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_cairo_image_surface_reset (void *abstract_surface)
|
|
||||||
{
|
|
||||||
cairo_image_surface_t *surface = abstract_surface;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_image_surface_set_clip_region (surface, NULL);
|
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _cairo_surface_is_image:
|
* _cairo_surface_is_image:
|
||||||
* @surface: a #cairo_surface_t
|
* @surface: a #cairo_surface_t
|
||||||
|
|
@ -1554,8 +1596,6 @@ const cairo_surface_backend_t _cairo_image_surface_backend = {
|
||||||
_cairo_image_surface_check_span_renderer,
|
_cairo_image_surface_check_span_renderer,
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
_cairo_image_surface_set_clip_region,
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_image_surface_get_extents,
|
_cairo_image_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
_cairo_image_surface_get_font_options,
|
_cairo_image_surface_get_font_options,
|
||||||
|
|
@ -1571,8 +1611,6 @@ const cairo_surface_backend_t _cairo_image_surface_backend = {
|
||||||
NULL, /* show_glyphs */
|
NULL, /* show_glyphs */
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
|
|
||||||
_cairo_image_surface_reset
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A convenience function for when one needs to coerce an image
|
/* A convenience function for when one needs to coerce an image
|
||||||
|
|
@ -1600,7 +1638,8 @@ _cairo_image_surface_coerce (cairo_image_surface_t *surface,
|
||||||
_cairo_pattern_init_for_surface (&pattern, &surface->base);
|
_cairo_pattern_init_for_surface (&pattern, &surface->base);
|
||||||
status = _cairo_surface_paint (&clone->base,
|
status = _cairo_surface_paint (&clone->base,
|
||||||
CAIRO_OPERATOR_SOURCE,
|
CAIRO_OPERATOR_SOURCE,
|
||||||
&pattern.base, NULL);
|
&pattern.base,
|
||||||
|
NULL);
|
||||||
_cairo_pattern_fini (&pattern.base);
|
_cairo_pattern_fini (&pattern.base);
|
||||||
|
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
#include "cairo-path-fixed-private.h"
|
#include "cairo-path-fixed-private.h"
|
||||||
|
#include "cairo-clip-private.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* The 5 basic drawing operations. */
|
/* The 5 basic drawing operations. */
|
||||||
|
|
@ -47,15 +48,6 @@ typedef enum {
|
||||||
CAIRO_COMMAND_STROKE,
|
CAIRO_COMMAND_STROKE,
|
||||||
CAIRO_COMMAND_FILL,
|
CAIRO_COMMAND_FILL,
|
||||||
CAIRO_COMMAND_SHOW_TEXT_GLYPHS,
|
CAIRO_COMMAND_SHOW_TEXT_GLYPHS,
|
||||||
|
|
||||||
/* Other junk. For most of these, we should be able to assert that
|
|
||||||
* they never get called except as part of fallbacks for the 5
|
|
||||||
* basic drawing operations (which we implement already so the
|
|
||||||
* fallbacks should never get triggered). So the plan is to
|
|
||||||
* eliminate as many of these as possible. */
|
|
||||||
|
|
||||||
CAIRO_COMMAND_INTERSECT_CLIP_PATH
|
|
||||||
|
|
||||||
} cairo_command_type_t;
|
} cairo_command_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
@ -67,25 +59,23 @@ typedef enum {
|
||||||
typedef struct _cairo_command_header {
|
typedef struct _cairo_command_header {
|
||||||
cairo_command_type_t type;
|
cairo_command_type_t type;
|
||||||
cairo_meta_region_type_t region;
|
cairo_meta_region_type_t region;
|
||||||
cairo_rectangle_int_t extents;
|
cairo_operator_t op;
|
||||||
|
cairo_clip_t clip;
|
||||||
} cairo_command_header_t;
|
} cairo_command_header_t;
|
||||||
|
|
||||||
typedef struct _cairo_command_paint {
|
typedef struct _cairo_command_paint {
|
||||||
cairo_command_header_t header;
|
cairo_command_header_t header;
|
||||||
cairo_operator_t op;
|
|
||||||
cairo_pattern_union_t source;
|
cairo_pattern_union_t source;
|
||||||
} cairo_command_paint_t;
|
} cairo_command_paint_t;
|
||||||
|
|
||||||
typedef struct _cairo_command_mask {
|
typedef struct _cairo_command_mask {
|
||||||
cairo_command_header_t header;
|
cairo_command_header_t header;
|
||||||
cairo_operator_t op;
|
|
||||||
cairo_pattern_union_t source;
|
cairo_pattern_union_t source;
|
||||||
cairo_pattern_union_t mask;
|
cairo_pattern_union_t mask;
|
||||||
} cairo_command_mask_t;
|
} cairo_command_mask_t;
|
||||||
|
|
||||||
typedef struct _cairo_command_stroke {
|
typedef struct _cairo_command_stroke {
|
||||||
cairo_command_header_t header;
|
cairo_command_header_t header;
|
||||||
cairo_operator_t op;
|
|
||||||
cairo_pattern_union_t source;
|
cairo_pattern_union_t source;
|
||||||
cairo_path_fixed_t path;
|
cairo_path_fixed_t path;
|
||||||
cairo_stroke_style_t style;
|
cairo_stroke_style_t style;
|
||||||
|
|
@ -97,7 +87,6 @@ typedef struct _cairo_command_stroke {
|
||||||
|
|
||||||
typedef struct _cairo_command_fill {
|
typedef struct _cairo_command_fill {
|
||||||
cairo_command_header_t header;
|
cairo_command_header_t header;
|
||||||
cairo_operator_t op;
|
|
||||||
cairo_pattern_union_t source;
|
cairo_pattern_union_t source;
|
||||||
cairo_path_fixed_t path;
|
cairo_path_fixed_t path;
|
||||||
cairo_fill_rule_t fill_rule;
|
cairo_fill_rule_t fill_rule;
|
||||||
|
|
@ -107,7 +96,6 @@ typedef struct _cairo_command_fill {
|
||||||
|
|
||||||
typedef struct _cairo_command_show_text_glyphs {
|
typedef struct _cairo_command_show_text_glyphs {
|
||||||
cairo_command_header_t header;
|
cairo_command_header_t header;
|
||||||
cairo_operator_t op;
|
|
||||||
cairo_pattern_union_t source;
|
cairo_pattern_union_t source;
|
||||||
char *utf8;
|
char *utf8;
|
||||||
int utf8_len;
|
int utf8_len;
|
||||||
|
|
@ -119,27 +107,14 @@ typedef struct _cairo_command_show_text_glyphs {
|
||||||
cairo_scaled_font_t *scaled_font;
|
cairo_scaled_font_t *scaled_font;
|
||||||
} cairo_command_show_text_glyphs_t;
|
} cairo_command_show_text_glyphs_t;
|
||||||
|
|
||||||
typedef struct _cairo_command_intersect_clip_path {
|
|
||||||
cairo_command_header_t header;
|
|
||||||
cairo_path_fixed_t *path_pointer;
|
|
||||||
cairo_path_fixed_t path;
|
|
||||||
cairo_fill_rule_t fill_rule;
|
|
||||||
double tolerance;
|
|
||||||
cairo_antialias_t antialias;
|
|
||||||
} cairo_command_intersect_clip_path_t;
|
|
||||||
|
|
||||||
typedef union _cairo_command {
|
typedef union _cairo_command {
|
||||||
cairo_command_header_t header;
|
cairo_command_header_t header;
|
||||||
|
|
||||||
/* The 5 basic drawing operations. */
|
|
||||||
cairo_command_paint_t paint;
|
cairo_command_paint_t paint;
|
||||||
cairo_command_mask_t mask;
|
cairo_command_mask_t mask;
|
||||||
cairo_command_stroke_t stroke;
|
cairo_command_stroke_t stroke;
|
||||||
cairo_command_fill_t fill;
|
cairo_command_fill_t fill;
|
||||||
cairo_command_show_text_glyphs_t show_text_glyphs;
|
cairo_command_show_text_glyphs_t show_text_glyphs;
|
||||||
|
|
||||||
/* The other junk. */
|
|
||||||
cairo_command_intersect_clip_path_t intersect_clip_path;
|
|
||||||
} cairo_command_t;
|
} cairo_command_t;
|
||||||
|
|
||||||
typedef struct _cairo_meta_surface {
|
typedef struct _cairo_meta_surface {
|
||||||
|
|
@ -150,14 +125,15 @@ typedef struct _cairo_meta_surface {
|
||||||
/* A meta-surface is logically unbounded, but when used as a
|
/* A meta-surface is logically unbounded, but when used as a
|
||||||
* source we need to render it to an image, so we need a size at
|
* source we need to render it to an image, so we need a size at
|
||||||
* which to create that image. */
|
* which to create that image. */
|
||||||
double width_pixels;
|
cairo_rectangle_t extents_pixels;
|
||||||
double height_pixels;
|
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
|
cairo_bool_t unbounded;
|
||||||
|
|
||||||
|
cairo_clip_t clip;
|
||||||
|
|
||||||
cairo_array_t commands;
|
cairo_array_t commands;
|
||||||
cairo_surface_t *commands_owner;
|
cairo_surface_t *commands_owner;
|
||||||
|
|
||||||
cairo_bool_t is_clipped;
|
|
||||||
int replay_start_idx;
|
int replay_start_idx;
|
||||||
} cairo_meta_surface_t;
|
} cairo_meta_surface_t;
|
||||||
|
|
||||||
|
|
@ -181,6 +157,11 @@ _cairo_meta_surface_replay_region (cairo_surface_t *surface,
|
||||||
cairo_surface_t *target,
|
cairo_surface_t *target,
|
||||||
cairo_meta_region_type_t region);
|
cairo_meta_region_type_t region);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_meta_surface_get_bbox (cairo_meta_surface_t *meta,
|
||||||
|
cairo_box_t *bbox,
|
||||||
|
const cairo_matrix_t *transform);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_surface_is_meta (const cairo_surface_t *surface);
|
_cairo_surface_is_meta (const cairo_surface_t *surface);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@
|
||||||
* that would have been obtained if the original operations applied to
|
* that would have been obtained if the original operations applied to
|
||||||
* the meta surface had instead been applied to the target surface.
|
* the meta surface had instead been applied to the target surface.
|
||||||
*
|
*
|
||||||
|
* A meta surface is logically unbounded, i.e. it has no implicit constraint
|
||||||
|
* on the size of the drawing surface. However, in practice this is rarely
|
||||||
|
* useful as you wish to replay against a particular target surface with
|
||||||
|
* known bounds. For this case, it is more efficient to specify the target
|
||||||
|
* extents to the meta surface upon creation.
|
||||||
|
*
|
||||||
* The recording phase of the meta surface is careful to snapshot all
|
* The recording phase of the meta surface is careful to snapshot all
|
||||||
* necessary objects (paths, patterns, etc.), in order to achieve
|
* necessary objects (paths, patterns, etc.), in order to achieve
|
||||||
* accurate replay. The efficiency of the meta surface could be
|
* accurate replay. The efficiency of the meta surface could be
|
||||||
|
|
@ -58,10 +64,13 @@
|
||||||
* copy-on-write implementation for _cairo_surface_snapshot.
|
* copy-on-write implementation for _cairo_surface_snapshot.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* XXX Rename to recording surface */
|
||||||
|
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
#include "cairo-analysis-surface-private.h"
|
#include "cairo-analysis-surface-private.h"
|
||||||
#include "cairo-meta-surface-private.h"
|
#include "cairo-meta-surface-private.h"
|
||||||
#include "cairo-clip-private.h"
|
#include "cairo-clip-private.h"
|
||||||
|
#include "cairo-surface-wrapper-private.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CAIRO_META_REPLAY,
|
CAIRO_META_REPLAY,
|
||||||
|
|
@ -82,8 +91,8 @@ static const cairo_surface_backend_t cairo_meta_surface_backend;
|
||||||
/**
|
/**
|
||||||
* cairo_meta_surface_create:
|
* cairo_meta_surface_create:
|
||||||
* @content: the content of the meta surface
|
* @content: the content of the meta surface
|
||||||
* @width_pixels: width of the surface, in pixels
|
* @extents_pixels: the extents to record in pixels, can be %NULL to record
|
||||||
* @height_pixels: height of the surface, in pixels
|
* unbounded operations.
|
||||||
*
|
*
|
||||||
* Creates a meta-surface which can be used to record all drawing operations
|
* Creates a meta-surface which can be used to record all drawing operations
|
||||||
* at the highest level (that is, the level of paint, mask, stroke, fill
|
* at the highest level (that is, the level of paint, mask, stroke, fill
|
||||||
|
|
@ -105,50 +114,45 @@ static const cairo_surface_backend_t cairo_meta_surface_backend;
|
||||||
* Since 1.10
|
* Since 1.10
|
||||||
**/
|
**/
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
cairo_meta_surface_create (cairo_content_t content,
|
cairo_meta_surface_create (cairo_content_t content,
|
||||||
double width_pixels,
|
const cairo_rectangle_t *extents)
|
||||||
double height_pixels)
|
|
||||||
{
|
{
|
||||||
cairo_meta_surface_t *meta;
|
cairo_meta_surface_t *meta;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
meta = malloc (sizeof (cairo_meta_surface_t));
|
meta = malloc (sizeof (cairo_meta_surface_t));
|
||||||
if (unlikely (meta == NULL))
|
if (unlikely (meta == NULL))
|
||||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||||
|
|
||||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
|
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend, content);
|
||||||
content);
|
|
||||||
|
|
||||||
meta->content = content;
|
meta->content = content;
|
||||||
meta->width_pixels = width_pixels;
|
|
||||||
meta->height_pixels = height_pixels;
|
|
||||||
|
|
||||||
/* unbounded -> 'infinite' extents */
|
/* unbounded -> 'infinite' extents */
|
||||||
if (width_pixels < 0) {
|
if (extents != NULL) {
|
||||||
meta->extents.x = CAIRO_RECT_INT_MIN;
|
meta->extents_pixels = *extents;
|
||||||
meta->extents.width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
|
||||||
} else {
|
|
||||||
meta->extents.x = 0;
|
|
||||||
if (ceil (width_pixels) > CAIRO_RECT_INT_MAX)
|
|
||||||
meta->extents.width = CAIRO_RECT_INT_MAX;
|
|
||||||
else
|
|
||||||
meta->extents.width = ceil (width_pixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (height_pixels < 0) {
|
/* XXX check for overflow */
|
||||||
meta->extents.y = CAIRO_RECT_INT_MIN;
|
meta->extents.x = floor (extents->x);
|
||||||
meta->extents.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
meta->extents.y = floor (extents->y);
|
||||||
|
meta->extents.width = ceil (extents->x + extents->width) - meta->extents.x;
|
||||||
|
meta->extents.height = ceil (extents->y + extents->height) - meta->extents.y;
|
||||||
|
|
||||||
|
status = _cairo_clip_init_rectangle (&meta->clip, &meta->extents);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
free (meta);
|
||||||
|
return _cairo_surface_create_in_error (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
meta->unbounded = FALSE;
|
||||||
} else {
|
} else {
|
||||||
meta->extents.y = 0;
|
meta->unbounded = TRUE;
|
||||||
if (ceil (height_pixels) > CAIRO_RECT_INT_MAX)
|
_cairo_clip_init (&meta->clip);
|
||||||
meta->extents.height = CAIRO_RECT_INT_MAX;
|
|
||||||
else
|
|
||||||
meta->extents.height = ceil (height_pixels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_array_init (&meta->commands, sizeof (cairo_command_t *));
|
_cairo_array_init (&meta->commands, sizeof (cairo_command_t *));
|
||||||
meta->commands_owner = NULL;
|
meta->commands_owner = NULL;
|
||||||
|
|
||||||
meta->is_clipped = FALSE;
|
|
||||||
meta->replay_start_idx = 0;
|
meta->replay_start_idx = 0;
|
||||||
|
|
||||||
return &meta->base;
|
return &meta->base;
|
||||||
|
|
@ -161,14 +165,17 @@ _cairo_meta_surface_create_similar (void *abstract_surface,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
return cairo_meta_surface_create (content, width, height);
|
cairo_rectangle_t extents;
|
||||||
|
extents.x = extents.y = 0;
|
||||||
|
extents.width = width;
|
||||||
|
extents.height = height;
|
||||||
|
return cairo_meta_surface_create (content, &extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_meta_surface_finish (void *abstract_surface)
|
_cairo_meta_surface_finish (void *abstract_surface)
|
||||||
{
|
{
|
||||||
cairo_meta_surface_t *meta = abstract_surface;
|
cairo_meta_surface_t *meta = abstract_surface;
|
||||||
cairo_command_t *command;
|
|
||||||
cairo_command_t **elements;
|
cairo_command_t **elements;
|
||||||
int i, num_elements;
|
int i, num_elements;
|
||||||
|
|
||||||
|
|
@ -180,11 +187,11 @@ _cairo_meta_surface_finish (void *abstract_surface)
|
||||||
num_elements = meta->commands.num_elements;
|
num_elements = meta->commands.num_elements;
|
||||||
elements = _cairo_array_index (&meta->commands, 0);
|
elements = _cairo_array_index (&meta->commands, 0);
|
||||||
for (i = 0; i < num_elements; i++) {
|
for (i = 0; i < num_elements; i++) {
|
||||||
command = elements[i];
|
cairo_command_t *command = elements[i];
|
||||||
|
|
||||||
|
_cairo_clip_reset (&command->header.clip);
|
||||||
|
|
||||||
switch (command->header.type) {
|
switch (command->header.type) {
|
||||||
|
|
||||||
/* 5 basic drawing operations */
|
|
||||||
|
|
||||||
case CAIRO_COMMAND_PAINT:
|
case CAIRO_COMMAND_PAINT:
|
||||||
_cairo_pattern_fini_snapshot (&command->paint.source.base);
|
_cairo_pattern_fini_snapshot (&command->paint.source.base);
|
||||||
free (command);
|
free (command);
|
||||||
|
|
@ -218,19 +225,13 @@ _cairo_meta_surface_finish (void *abstract_surface)
|
||||||
free (command);
|
free (command);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Other junk. */
|
|
||||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
|
||||||
if (command->intersect_clip_path.path_pointer)
|
|
||||||
_cairo_path_fixed_fini (&command->intersect_clip_path.path);
|
|
||||||
free (command);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED;
|
ASSERT_NOT_REACHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_array_fini (&meta->commands);
|
_cairo_array_fini (&meta->commands);
|
||||||
|
_cairo_clip_reset (&meta->clip);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -254,8 +255,12 @@ _cairo_meta_surface_acquire_source_image (void *abstract_surface,
|
||||||
}
|
}
|
||||||
|
|
||||||
image = _cairo_image_surface_create_with_content (surface->content,
|
image = _cairo_image_surface_create_with_content (surface->content,
|
||||||
ceil (surface->width_pixels),
|
surface->extents.width,
|
||||||
ceil (surface->height_pixels));
|
surface->extents.height);
|
||||||
|
|
||||||
|
cairo_surface_set_device_offset (image,
|
||||||
|
-surface->extents.x,
|
||||||
|
-surface->extents.y);
|
||||||
|
|
||||||
status = cairo_meta_surface_replay (&surface->base, image);
|
status = cairo_meta_surface_replay (&surface->base, image);
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
|
|
@ -282,21 +287,30 @@ _cairo_meta_surface_release_source_image (void *abstract_surface,
|
||||||
cairo_surface_destroy (&image->base);
|
cairo_surface_destroy (&image->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static cairo_status_t
|
||||||
_draw_command_init (cairo_command_header_t *command,
|
_command_init (cairo_meta_surface_t *meta,
|
||||||
cairo_command_type_t type,
|
cairo_command_header_t *command,
|
||||||
cairo_meta_surface_t *meta)
|
cairo_command_type_t type,
|
||||||
|
cairo_operator_t op,
|
||||||
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
command->type = type;
|
command->type = type;
|
||||||
|
command->op = op;
|
||||||
command->region = CAIRO_META_REGION_ALL;
|
command->region = CAIRO_META_REGION_ALL;
|
||||||
command->extents = meta->extents;
|
_cairo_clip_init_copy (&command->clip, clip);
|
||||||
|
if (meta->clip.path != NULL)
|
||||||
|
status = _cairo_clip_apply_clip (&command->clip, &meta->clip);
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_meta_surface_paint (void *abstract_surface,
|
_cairo_meta_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_meta_surface_t *meta = abstract_surface;
|
cairo_meta_surface_t *meta = abstract_surface;
|
||||||
|
|
@ -306,8 +320,10 @@ _cairo_meta_surface_paint (void *abstract_surface,
|
||||||
if (unlikely (command == NULL))
|
if (unlikely (command == NULL))
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
_draw_command_init (&command->header, CAIRO_COMMAND_PAINT, meta);
|
status = _command_init (meta,
|
||||||
command->op = op;
|
&command->header, CAIRO_COMMAND_PAINT, op, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto CLEANUP_COMMAND;
|
||||||
|
|
||||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -320,7 +336,7 @@ _cairo_meta_surface_paint (void *abstract_surface,
|
||||||
/* An optimisation that takes care to not replay what was done
|
/* An optimisation that takes care to not replay what was done
|
||||||
* before surface is cleared. We don't erase recorded commands
|
* before surface is cleared. We don't erase recorded commands
|
||||||
* since we may have earlier snapshots of this surface. */
|
* since we may have earlier snapshots of this surface. */
|
||||||
if (op == CAIRO_OPERATOR_CLEAR && !meta->is_clipped)
|
if (op == CAIRO_OPERATOR_CLEAR && clip == NULL)
|
||||||
meta->replay_start_idx = meta->commands.num_elements;
|
meta->replay_start_idx = meta->commands.num_elements;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -337,7 +353,7 @@ _cairo_meta_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_meta_surface_t *meta = abstract_surface;
|
cairo_meta_surface_t *meta = abstract_surface;
|
||||||
|
|
@ -347,8 +363,10 @@ _cairo_meta_surface_mask (void *abstract_surface,
|
||||||
if (unlikely (command == NULL))
|
if (unlikely (command == NULL))
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
_draw_command_init (&command->header, CAIRO_COMMAND_MASK, meta);
|
status = _command_init (meta,
|
||||||
command->op = op;
|
&command->header, CAIRO_COMMAND_MASK, op, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto CLEANUP_COMMAND;
|
||||||
|
|
||||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -383,7 +401,7 @@ _cairo_meta_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_meta_surface_t *meta = abstract_surface;
|
cairo_meta_surface_t *meta = abstract_surface;
|
||||||
|
|
@ -393,8 +411,10 @@ _cairo_meta_surface_stroke (void *abstract_surface,
|
||||||
if (unlikely (command == NULL))
|
if (unlikely (command == NULL))
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
_draw_command_init (&command->header, CAIRO_COMMAND_STROKE, meta);
|
status = _command_init (meta,
|
||||||
command->op = op;
|
&command->header, CAIRO_COMMAND_STROKE, op, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto CLEANUP_COMMAND;
|
||||||
|
|
||||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -438,7 +458,7 @@ _cairo_meta_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_meta_surface_t *meta = abstract_surface;
|
cairo_meta_surface_t *meta = abstract_surface;
|
||||||
|
|
@ -448,8 +468,10 @@ _cairo_meta_surface_fill (void *abstract_surface,
|
||||||
if (unlikely (command == NULL))
|
if (unlikely (command == NULL))
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
_draw_command_init (&command->header, CAIRO_COMMAND_FILL, meta);
|
status =_command_init (meta,
|
||||||
command->op = op;
|
&command->header, CAIRO_COMMAND_FILL, op, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto CLEANUP_COMMAND;
|
||||||
|
|
||||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -496,7 +518,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_meta_surface_t *meta = abstract_surface;
|
cairo_meta_surface_t *meta = abstract_surface;
|
||||||
|
|
@ -506,8 +528,11 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
|
||||||
if (unlikely (command == NULL))
|
if (unlikely (command == NULL))
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
_draw_command_init (&command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS, meta);
|
status = _command_init (meta,
|
||||||
command->op = op;
|
&command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS,
|
||||||
|
op, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto CLEANUP_COMMAND;
|
||||||
|
|
||||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -594,82 +619,31 @@ _cairo_meta_surface_snapshot (void *abstract_other)
|
||||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
|
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
|
||||||
other->base.content);
|
other->base.content);
|
||||||
|
|
||||||
meta->width_pixels = other->width_pixels;
|
meta->extents_pixels = other->extents_pixels;
|
||||||
meta->height_pixels = other->height_pixels;
|
|
||||||
meta->extents = other->extents;
|
meta->extents = other->extents;
|
||||||
|
meta->unbounded = other->unbounded;
|
||||||
meta->replay_start_idx = other->replay_start_idx;
|
meta->replay_start_idx = other->replay_start_idx;
|
||||||
meta->content = other->content;
|
meta->content = other->content;
|
||||||
|
|
||||||
_cairo_array_init_snapshot (&meta->commands, &other->commands);
|
_cairo_array_init_snapshot (&meta->commands, &other->commands);
|
||||||
meta->commands_owner = cairo_surface_reference (&other->base);
|
meta->commands_owner = cairo_surface_reference (&other->base);
|
||||||
|
|
||||||
|
_cairo_clip_init_copy (&meta->clip, &other->clip);
|
||||||
|
|
||||||
return &meta->base;
|
return &meta->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_meta_surface_intersect_clip_path (void *dst,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias)
|
|
||||||
{
|
|
||||||
cairo_meta_surface_t *meta = dst;
|
|
||||||
cairo_command_intersect_clip_path_t *command;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
command = malloc (sizeof (cairo_command_intersect_clip_path_t));
|
|
||||||
if (unlikely (command == NULL))
|
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
|
|
||||||
command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH;
|
|
||||||
command->header.region = CAIRO_META_REGION_ALL;
|
|
||||||
|
|
||||||
if (path) {
|
|
||||||
status = _cairo_path_fixed_init_copy (&command->path, path);
|
|
||||||
if (unlikely (status)) {
|
|
||||||
free (command);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
command->path_pointer = &command->path;
|
|
||||||
meta->is_clipped = TRUE;
|
|
||||||
} else {
|
|
||||||
command->path_pointer = NULL;
|
|
||||||
meta->is_clipped = FALSE;
|
|
||||||
}
|
|
||||||
command->fill_rule = fill_rule;
|
|
||||||
command->tolerance = tolerance;
|
|
||||||
command->antialias = antialias;
|
|
||||||
|
|
||||||
status = _cairo_array_append (&meta->commands, &command);
|
|
||||||
if (unlikely (status)) {
|
|
||||||
if (path)
|
|
||||||
_cairo_path_fixed_fini (&command->path);
|
|
||||||
free (command);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Currently, we're using as the "size" of a meta surface the largest
|
|
||||||
* surface size against which the meta-surface is expected to be
|
|
||||||
* replayed, (as passed in to cairo_meta_surface_create()).
|
|
||||||
*/
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
cairo_meta_surface_t *surface = abstract_surface;
|
cairo_meta_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
if (surface->width_pixels < 0 || surface->height_pixels < 0)
|
if (surface->unbounded)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return FALSE;
|
||||||
|
|
||||||
rectangle->x = 0;
|
*rectangle = surface->extents;
|
||||||
rectangle->y = 0;
|
return TRUE;
|
||||||
rectangle->width = ceil (surface->width_pixels);
|
|
||||||
rectangle->height = ceil (surface->height_pixels);
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -702,8 +676,6 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_meta_surface_intersect_clip_path,
|
|
||||||
_cairo_meta_surface_get_extents,
|
_cairo_meta_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -726,7 +698,6 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
||||||
_cairo_meta_surface_snapshot,
|
_cairo_meta_surface_snapshot,
|
||||||
|
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
@ -735,32 +706,12 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
||||||
_cairo_meta_surface_show_text_glyphs
|
_cairo_meta_surface_show_text_glyphs
|
||||||
};
|
};
|
||||||
|
|
||||||
static cairo_path_fixed_t *
|
|
||||||
_cairo_command_get_path (cairo_command_t *command)
|
|
||||||
{
|
|
||||||
switch (command->header.type) {
|
|
||||||
case CAIRO_COMMAND_PAINT:
|
|
||||||
case CAIRO_COMMAND_MASK:
|
|
||||||
case CAIRO_COMMAND_SHOW_TEXT_GLYPHS:
|
|
||||||
return NULL;
|
|
||||||
case CAIRO_COMMAND_STROKE:
|
|
||||||
return &command->stroke.path;
|
|
||||||
case CAIRO_COMMAND_FILL:
|
|
||||||
return &command->fill.path;
|
|
||||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
|
||||||
return command->intersect_clip_path.path_pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_NOT_REACHED;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_int_status_t
|
cairo_int_status_t
|
||||||
_cairo_meta_surface_get_path (cairo_surface_t *surface,
|
_cairo_meta_surface_get_path (cairo_surface_t *surface,
|
||||||
cairo_path_fixed_t *path)
|
cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
cairo_meta_surface_t *meta;
|
cairo_meta_surface_t *meta;
|
||||||
cairo_command_t *command, **elements;
|
cairo_command_t **elements;
|
||||||
int i, num_elements;
|
int i, num_elements;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
|
||||||
|
|
@ -773,12 +724,11 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface,
|
||||||
num_elements = meta->commands.num_elements;
|
num_elements = meta->commands.num_elements;
|
||||||
elements = _cairo_array_index (&meta->commands, 0);
|
elements = _cairo_array_index (&meta->commands, 0);
|
||||||
for (i = meta->replay_start_idx; i < num_elements; i++) {
|
for (i = meta->replay_start_idx; i < num_elements; i++) {
|
||||||
command = elements[i];
|
cairo_command_t *command = elements[i];
|
||||||
|
|
||||||
switch (command->header.type) {
|
switch (command->header.type) {
|
||||||
case CAIRO_COMMAND_PAINT:
|
case CAIRO_COMMAND_PAINT:
|
||||||
case CAIRO_COMMAND_MASK:
|
case CAIRO_COMMAND_MASK:
|
||||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
|
||||||
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -804,7 +754,9 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface,
|
||||||
}
|
}
|
||||||
case CAIRO_COMMAND_FILL:
|
case CAIRO_COMMAND_FILL:
|
||||||
{
|
{
|
||||||
status = _cairo_path_fixed_append (path, &command->fill.path, CAIRO_DIRECTION_FORWARD);
|
status = _cairo_path_fixed_append (path,
|
||||||
|
&command->fill.path, CAIRO_DIRECTION_FORWARD,
|
||||||
|
0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CAIRO_COMMAND_SHOW_TEXT_GLYPHS:
|
case CAIRO_COMMAND_SHOW_TEXT_GLYPHS:
|
||||||
|
|
@ -827,6 +779,7 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface,
|
||||||
return _cairo_surface_set_error (surface, status);
|
return _cairo_surface_set_error (surface, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _clip(c) ((c)->header.clip.path ? &(c)->header.clip : NULL)
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
_cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||||
cairo_surface_t *target,
|
cairo_surface_t *target,
|
||||||
|
|
@ -834,209 +787,155 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||||
cairo_meta_region_type_t region)
|
cairo_meta_region_type_t region)
|
||||||
{
|
{
|
||||||
cairo_meta_surface_t *meta;
|
cairo_meta_surface_t *meta;
|
||||||
cairo_command_t *command, **elements;
|
cairo_command_t **elements;
|
||||||
int i, num_elements;
|
int i, num_elements;
|
||||||
cairo_int_status_t status, status2;
|
cairo_int_status_t status;
|
||||||
cairo_clip_t clip, *old_clip;
|
cairo_surface_wrapper_t wrapper;
|
||||||
cairo_bool_t has_device_transform = _cairo_surface_has_device_transform (target);
|
|
||||||
cairo_matrix_t *device_transform = &target->device_transform;
|
|
||||||
cairo_path_fixed_t path_copy, *dev_path;
|
|
||||||
|
|
||||||
if (surface->status)
|
if (unlikely (surface->status))
|
||||||
return surface->status;
|
return surface->status;
|
||||||
|
|
||||||
if (target->status)
|
if (unlikely (target->status))
|
||||||
return _cairo_surface_set_error (surface, target->status);
|
return _cairo_surface_set_error (surface, target->status);
|
||||||
|
|
||||||
|
_cairo_surface_wrapper_init (&wrapper, target);
|
||||||
|
|
||||||
meta = (cairo_meta_surface_t *) surface;
|
meta = (cairo_meta_surface_t *) surface;
|
||||||
status = CAIRO_STATUS_SUCCESS;
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
_cairo_clip_init (&clip, target);
|
|
||||||
old_clip = _cairo_surface_get_clip (target);
|
|
||||||
|
|
||||||
num_elements = meta->commands.num_elements;
|
num_elements = meta->commands.num_elements;
|
||||||
elements = _cairo_array_index (&meta->commands, 0);
|
elements = _cairo_array_index (&meta->commands, 0);
|
||||||
for (i = meta->replay_start_idx; i < num_elements; i++) {
|
for (i = meta->replay_start_idx; i < num_elements; i++) {
|
||||||
command = elements[i];
|
cairo_command_t *command = elements[i];
|
||||||
|
|
||||||
if (type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL) {
|
if (type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL) {
|
||||||
if (command->header.region != region)
|
if (command->header.region != region)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For all commands except intersect_clip_path, we have to
|
|
||||||
* ensure the current clip gets set on the surface. */
|
|
||||||
if (command->header.type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) {
|
|
||||||
status = _cairo_surface_set_clip (target, &clip);
|
|
||||||
if (unlikely (status))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_path = _cairo_command_get_path (command);
|
|
||||||
if (dev_path && has_device_transform) {
|
|
||||||
status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
|
|
||||||
if (unlikely (status))
|
|
||||||
break;
|
|
||||||
_cairo_path_fixed_transform (&path_copy, device_transform);
|
|
||||||
dev_path = &path_copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (command->header.type) {
|
switch (command->header.type) {
|
||||||
case CAIRO_COMMAND_PAINT:
|
case CAIRO_COMMAND_PAINT:
|
||||||
status = _cairo_surface_paint (target,
|
status = _cairo_surface_wrapper_paint (&wrapper,
|
||||||
command->paint.op,
|
command->header.op,
|
||||||
&command->paint.source.base, &command->header.extents);
|
&command->paint.source.base,
|
||||||
|
_clip (command));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAIRO_COMMAND_MASK:
|
case CAIRO_COMMAND_MASK:
|
||||||
status = _cairo_surface_mask (target,
|
status = _cairo_surface_wrapper_mask (&wrapper,
|
||||||
command->mask.op,
|
command->header.op,
|
||||||
&command->mask.source.base,
|
&command->mask.source.base,
|
||||||
&command->mask.mask.base, &command->header.extents);
|
&command->mask.mask.base,
|
||||||
|
_clip (command));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAIRO_COMMAND_STROKE:
|
case CAIRO_COMMAND_STROKE:
|
||||||
{
|
{
|
||||||
cairo_matrix_t dev_ctm = command->stroke.ctm;
|
status = _cairo_surface_wrapper_stroke (&wrapper,
|
||||||
cairo_matrix_t dev_ctm_inverse = command->stroke.ctm_inverse;
|
command->header.op,
|
||||||
|
&command->stroke.source.base,
|
||||||
if (has_device_transform) {
|
&command->stroke.path,
|
||||||
cairo_matrix_multiply (&dev_ctm, &dev_ctm, device_transform);
|
&command->stroke.style,
|
||||||
cairo_matrix_multiply (&dev_ctm_inverse,
|
&command->stroke.ctm,
|
||||||
&target->device_transform_inverse,
|
&command->stroke.ctm_inverse,
|
||||||
&dev_ctm_inverse);
|
command->stroke.tolerance,
|
||||||
}
|
command->stroke.antialias,
|
||||||
|
_clip (command));
|
||||||
status = _cairo_surface_stroke (target,
|
|
||||||
command->stroke.op,
|
|
||||||
&command->stroke.source.base,
|
|
||||||
dev_path,
|
|
||||||
&command->stroke.style,
|
|
||||||
&dev_ctm,
|
|
||||||
&dev_ctm_inverse,
|
|
||||||
command->stroke.tolerance,
|
|
||||||
command->stroke.antialias, &command->header.extents);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CAIRO_COMMAND_FILL:
|
case CAIRO_COMMAND_FILL:
|
||||||
{
|
{
|
||||||
cairo_command_t *stroke_command;
|
cairo_command_t *stroke_command;
|
||||||
|
|
||||||
if (type != CAIRO_META_CREATE_REGIONS)
|
stroke_command = NULL;
|
||||||
stroke_command = (i < num_elements - 1) ? elements[i + 1] : NULL;
|
if (type != CAIRO_META_CREATE_REGIONS && i < num_elements - 1)
|
||||||
else
|
stroke_command = elements[i + 1];
|
||||||
stroke_command = NULL;
|
|
||||||
|
|
||||||
if (stroke_command != NULL &&
|
if (stroke_command != NULL &&
|
||||||
type == CAIRO_META_REPLAY && region != CAIRO_META_REGION_ALL)
|
type == CAIRO_META_REPLAY &&
|
||||||
|
region != CAIRO_META_REGION_ALL)
|
||||||
{
|
{
|
||||||
if (stroke_command->header.region != region)
|
if (stroke_command->header.region != region)
|
||||||
stroke_command = NULL;
|
stroke_command = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stroke_command != NULL &&
|
if (stroke_command != NULL &&
|
||||||
stroke_command->header.type == CAIRO_COMMAND_STROKE &&
|
stroke_command->header.type == CAIRO_COMMAND_STROKE &&
|
||||||
_cairo_path_fixed_is_equal (dev_path, _cairo_command_get_path (stroke_command))) {
|
_cairo_path_fixed_is_equal (&command->fill.path,
|
||||||
cairo_matrix_t dev_ctm;
|
&stroke_command->stroke.path))
|
||||||
cairo_matrix_t dev_ctm_inverse;
|
{
|
||||||
|
status = _cairo_surface_wrapper_fill_stroke (&wrapper,
|
||||||
dev_ctm = stroke_command->stroke.ctm;
|
command->header.op,
|
||||||
dev_ctm_inverse = stroke_command->stroke.ctm_inverse;
|
&command->fill.source.base,
|
||||||
|
command->fill.fill_rule,
|
||||||
if (has_device_transform) {
|
command->fill.tolerance,
|
||||||
cairo_matrix_multiply (&dev_ctm, &dev_ctm, device_transform);
|
command->fill.antialias,
|
||||||
cairo_matrix_multiply (&dev_ctm_inverse,
|
&command->fill.path,
|
||||||
&surface->device_transform_inverse,
|
stroke_command->header.op,
|
||||||
&dev_ctm_inverse);
|
&stroke_command->stroke.source.base,
|
||||||
}
|
&stroke_command->stroke.style,
|
||||||
|
&stroke_command->stroke.ctm,
|
||||||
status = _cairo_surface_fill_stroke (target,
|
&stroke_command->stroke.ctm_inverse,
|
||||||
command->fill.op,
|
stroke_command->stroke.tolerance,
|
||||||
&command->fill.source.base,
|
stroke_command->stroke.antialias,
|
||||||
command->fill.fill_rule,
|
_clip (command));
|
||||||
command->fill.tolerance,
|
|
||||||
command->fill.antialias,
|
|
||||||
dev_path,
|
|
||||||
stroke_command->stroke.op,
|
|
||||||
&stroke_command->stroke.source.base,
|
|
||||||
&stroke_command->stroke.style,
|
|
||||||
&dev_ctm,
|
|
||||||
&dev_ctm_inverse,
|
|
||||||
stroke_command->stroke.tolerance,
|
|
||||||
stroke_command->stroke.antialias,
|
|
||||||
&stroke_command->header.extents);
|
|
||||||
i++;
|
i++;
|
||||||
} else
|
}
|
||||||
status = _cairo_surface_fill (target,
|
else
|
||||||
command->fill.op,
|
{
|
||||||
&command->fill.source.base,
|
status = _cairo_surface_wrapper_fill (&wrapper,
|
||||||
dev_path,
|
command->header.op,
|
||||||
command->fill.fill_rule,
|
&command->fill.source.base,
|
||||||
command->fill.tolerance,
|
&command->fill.path,
|
||||||
command->fill.antialias, &command->header.extents);
|
command->fill.fill_rule,
|
||||||
|
command->fill.tolerance,
|
||||||
|
command->fill.antialias,
|
||||||
|
_clip (command));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CAIRO_COMMAND_SHOW_TEXT_GLYPHS:
|
case CAIRO_COMMAND_SHOW_TEXT_GLYPHS:
|
||||||
{
|
{
|
||||||
cairo_glyph_t *glyphs = command->show_text_glyphs.glyphs;
|
cairo_glyph_t *glyphs = command->show_text_glyphs.glyphs;
|
||||||
cairo_glyph_t *dev_glyphs;
|
cairo_glyph_t *glyphs_copy;
|
||||||
int i, num_glyphs = command->show_text_glyphs.num_glyphs;
|
int num_glyphs = command->show_text_glyphs.num_glyphs;
|
||||||
|
|
||||||
/* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed
|
/* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed
|
||||||
* to modify the glyph array that's passed in. We must always
|
* to modify the glyph array that's passed in. We must always
|
||||||
* copy the array before handing it to the backend.
|
* copy the array before handing it to the backend.
|
||||||
*/
|
*/
|
||||||
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||||
if (unlikely (dev_glyphs == NULL)) {
|
if (unlikely (glyphs_copy == NULL)) {
|
||||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_device_transform) {
|
memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
|
||||||
for (i = 0; i < num_glyphs; i++) {
|
|
||||||
dev_glyphs[i] = glyphs[i];
|
|
||||||
cairo_matrix_transform_point (device_transform,
|
|
||||||
&dev_glyphs[i].x,
|
|
||||||
&dev_glyphs[i].y);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _cairo_surface_show_text_glyphs (target,
|
status = _cairo_surface_wrapper_show_text_glyphs (&wrapper,
|
||||||
command->show_text_glyphs.op,
|
command->header.op,
|
||||||
&command->show_text_glyphs.source.base,
|
&command->show_text_glyphs.source.base,
|
||||||
command->show_text_glyphs.utf8, command->show_text_glyphs.utf8_len,
|
command->show_text_glyphs.utf8, command->show_text_glyphs.utf8_len,
|
||||||
dev_glyphs, num_glyphs,
|
glyphs_copy, num_glyphs,
|
||||||
command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters,
|
command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters,
|
||||||
command->show_text_glyphs.cluster_flags,
|
command->show_text_glyphs.cluster_flags,
|
||||||
command->show_text_glyphs.scaled_font, &command->header.extents);
|
command->show_text_glyphs.scaled_font,
|
||||||
|
_clip (command));
|
||||||
free (dev_glyphs);
|
free (glyphs_copy);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CAIRO_COMMAND_INTERSECT_CLIP_PATH:
|
|
||||||
/* XXX Meta surface clipping is broken and requires some
|
|
||||||
* cairo-gstate.c rewriting. Work around it for now. */
|
|
||||||
if (dev_path == NULL)
|
|
||||||
_cairo_clip_reset (&clip);
|
|
||||||
else
|
|
||||||
status = _cairo_clip_clip (&clip, dev_path,
|
|
||||||
command->intersect_clip_path.fill_rule,
|
|
||||||
command->intersect_clip_path.tolerance,
|
|
||||||
command->intersect_clip_path.antialias,
|
|
||||||
target);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED;
|
ASSERT_NOT_REACHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_path == &path_copy)
|
|
||||||
_cairo_path_fixed_fini (&path_copy);
|
|
||||||
|
|
||||||
if (type == CAIRO_META_CREATE_REGIONS) {
|
if (type == CAIRO_META_CREATE_REGIONS) {
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
if (status == CAIRO_STATUS_SUCCESS) {
|
||||||
command->header.region = CAIRO_META_REGION_NATIVE;
|
command->header.region = CAIRO_META_REGION_NATIVE;
|
||||||
} else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
|
} else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) {
|
||||||
command->header.region = CAIRO_META_REGION_IMAGE_FALLBACK;
|
command->header.region = CAIRO_META_REGION_IMAGE_FALLBACK;
|
||||||
status = CAIRO_STATUS_SUCCESS;
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
assert (_cairo_status_is_error (status));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1044,10 +943,14 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_clip_reset (&clip);
|
/* free up any caches */
|
||||||
status2 = _cairo_surface_set_clip (target, old_clip);
|
for (i = meta->replay_start_idx; i < num_elements; i++) {
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
cairo_command_t *command = elements[i];
|
||||||
status = status2;
|
|
||||||
|
_cairo_clip_drop_cache (&command->header.clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
_cairo_surface_wrapper_fini (&wrapper);
|
||||||
|
|
||||||
return _cairo_surface_set_error (surface, status);
|
return _cairo_surface_set_error (surface, status);
|
||||||
}
|
}
|
||||||
|
|
@ -1104,6 +1007,33 @@ _cairo_meta_surface_replay_region (cairo_surface_t *surface,
|
||||||
region);
|
region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_meta_surface_get_ink_bbox (cairo_meta_surface_t *surface,
|
||||||
|
cairo_box_t *bbox,
|
||||||
|
const cairo_matrix_t *transform)
|
||||||
|
{
|
||||||
|
cairo_surface_t *null_surface;
|
||||||
|
cairo_surface_t *analysis_surface;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
null_surface = _cairo_null_surface_create (surface->content);
|
||||||
|
analysis_surface = _cairo_analysis_surface_create (null_surface);
|
||||||
|
cairo_surface_destroy (null_surface);
|
||||||
|
|
||||||
|
status = analysis_surface->status;
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (transform != NULL)
|
||||||
|
_cairo_analysis_surface_set_ctm (analysis_surface, transform);
|
||||||
|
|
||||||
|
status = cairo_meta_surface_replay (&surface->base, analysis_surface);
|
||||||
|
_cairo_analysis_surface_get_bounding_box (analysis_surface, bbox);
|
||||||
|
cairo_surface_destroy (analysis_surface);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cairo_meta_surface_ink_extents:
|
* cairo_meta_surface_ink_extents:
|
||||||
* @surface: a #cairo_meta_surface_t
|
* @surface: a #cairo_meta_surface_t
|
||||||
|
|
@ -1114,7 +1044,7 @@ _cairo_meta_surface_replay_region (cairo_surface_t *surface,
|
||||||
*
|
*
|
||||||
* Measures the extents of the operations stored within the meta-surface.
|
* Measures the extents of the operations stored within the meta-surface.
|
||||||
* This is useful to compute the required size of an image surface (or
|
* This is useful to compute the required size of an image surface (or
|
||||||
* equivalent) into which to replay the full sequence of drawing operaitions.
|
* equivalent) into which to replay the full sequence of drawing operations.
|
||||||
*
|
*
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
|
|
@ -1125,8 +1055,6 @@ cairo_meta_surface_ink_extents (cairo_surface_t *surface,
|
||||||
double *width,
|
double *width,
|
||||||
double *height)
|
double *height)
|
||||||
{
|
{
|
||||||
cairo_surface_t *null_surface;
|
|
||||||
cairo_surface_t *analysis_surface;
|
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_box_t bbox;
|
cairo_box_t bbox;
|
||||||
|
|
||||||
|
|
@ -1137,17 +1065,11 @@ cairo_meta_surface_ink_extents (cairo_surface_t *surface,
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
null_surface = _cairo_null_surface_create (CAIRO_CONTENT_COLOR_ALPHA);
|
status = _meta_surface_get_ink_bbox ((cairo_meta_surface_t *) surface,
|
||||||
analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
|
&bbox,
|
||||||
cairo_surface_destroy (null_surface);
|
NULL);
|
||||||
|
|
||||||
status = analysis_surface->status;
|
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto DONE;
|
status = _cairo_surface_set_error (surface, status);
|
||||||
|
|
||||||
status = cairo_meta_surface_replay (surface, analysis_surface);
|
|
||||||
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
|
|
||||||
cairo_surface_destroy (analysis_surface);
|
|
||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
if (x0)
|
if (x0)
|
||||||
|
|
@ -1159,3 +1081,19 @@ DONE:
|
||||||
if (height)
|
if (height)
|
||||||
*height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
|
*height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_meta_surface_get_bbox (cairo_meta_surface_t *surface,
|
||||||
|
cairo_box_t *bbox,
|
||||||
|
const cairo_matrix_t *transform)
|
||||||
|
{
|
||||||
|
if (! surface->unbounded) {
|
||||||
|
_cairo_box_from_rectangle (bbox, &surface->extents);
|
||||||
|
if (transform != NULL)
|
||||||
|
_cairo_matrix_transform_bounding_box_fixed (transform, bbox, NULL);
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _meta_surface_get_ink_bbox (surface, bbox, transform);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -716,26 +716,18 @@ _cairo_os2_surface_release_dest_image (void *abstract_surface
|
||||||
DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields);
|
DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_os2_surface_get_extents (void *abstract_surface,
|
_cairo_os2_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
cairo_os2_surface_t *local_os2_surface;
|
cairo_os2_surface_t *local_os2_surface;
|
||||||
|
|
||||||
local_os2_surface = (cairo_os2_surface_t *) abstract_surface;
|
|
||||||
if ((!local_os2_surface) ||
|
|
||||||
(local_os2_surface->base.backend != &cairo_os2_surface_backend))
|
|
||||||
{
|
|
||||||
/* Invalid parameter (wrong surface)! */
|
|
||||||
return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
rectangle->x = 0;
|
rectangle->x = 0;
|
||||||
rectangle->y = 0;
|
rectangle->y = 0;
|
||||||
rectangle->width = local_os2_surface->bitmap_info.cx;
|
rectangle->width = local_os2_surface->bitmap_info.cx;
|
||||||
rectangle->height = local_os2_surface->bitmap_info.cy;
|
rectangle->height = local_os2_surface->bitmap_info.cy;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1327,8 +1319,6 @@ static const cairo_surface_backend_t cairo_os2_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_os2_surface_get_extents,
|
_cairo_os2_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,6 @@ struct _cairo_paginated_surface_backend {
|
||||||
cairo_private cairo_surface_t *
|
cairo_private cairo_surface_t *
|
||||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||||
cairo_content_t content,
|
cairo_content_t content,
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
const cairo_paginated_surface_backend_t *backend);
|
const cairo_paginated_surface_backend_t *backend);
|
||||||
|
|
||||||
cairo_private cairo_surface_t *
|
cairo_private cairo_surface_t *
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,6 @@ typedef struct _cairo_paginated_surface {
|
||||||
|
|
||||||
cairo_content_t content;
|
cairo_content_t content;
|
||||||
|
|
||||||
/* XXX: These shouldn't actually exist. We inherit this ugliness
|
|
||||||
* from _cairo_meta_surface_create. The width/height parameters
|
|
||||||
* from that function also should not exist. The fix that will
|
|
||||||
* allow us to remove all of these is to fix acquire_source_image
|
|
||||||
* to pass an interest rectangle. */
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
/* Paginated-surface specific functions for the target */
|
/* Paginated-surface specific functions for the target */
|
||||||
const cairo_paginated_surface_backend_t *backend;
|
const cairo_paginated_surface_backend_t *backend;
|
||||||
|
|
||||||
|
|
@ -66,7 +58,6 @@ typedef struct _cairo_paginated_surface {
|
||||||
|
|
||||||
int page_num;
|
int page_num;
|
||||||
cairo_bool_t page_is_blank;
|
cairo_bool_t page_is_blank;
|
||||||
|
|
||||||
} cairo_paginated_surface_t;
|
} cairo_paginated_surface_t;
|
||||||
|
|
||||||
#endif /* CAIRO_PAGINATED_SURFACE_H */
|
#endif /* CAIRO_PAGINATED_SURFACE_H */
|
||||||
|
|
|
||||||
|
|
@ -60,17 +60,36 @@ _cairo_paginated_surface_create_similar (void *abstract_surface,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
cairo_rectangle_t rect;
|
||||||
return cairo_surface_create_similar (surface->target, content,
|
rect.x = rect.y = 0.;
|
||||||
width, height);
|
rect.width = width;
|
||||||
|
rect.height = height;
|
||||||
|
return cairo_meta_surface_create (content, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
_create_meta_surface_for_target (cairo_surface_t *target,
|
||||||
|
cairo_content_t content)
|
||||||
|
{
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
if (_cairo_surface_get_extents (target, &rect)) {
|
||||||
|
cairo_rectangle_t meta_extents;
|
||||||
|
|
||||||
|
meta_extents.x = rect.x;
|
||||||
|
meta_extents.y = rect.y;
|
||||||
|
meta_extents.width = rect.width;
|
||||||
|
meta_extents.height = rect.height;
|
||||||
|
|
||||||
|
return cairo_meta_surface_create (content, &meta_extents);
|
||||||
|
} else {
|
||||||
|
return cairo_meta_surface_create (content, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX The integer width,height here should be doubles and all uses updated */
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_paginated_surface_create (cairo_surface_t *target,
|
_cairo_paginated_surface_create (cairo_surface_t *target,
|
||||||
cairo_content_t content,
|
cairo_content_t content,
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
const cairo_paginated_surface_backend_t *backend)
|
const cairo_paginated_surface_backend_t *backend)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface;
|
cairo_paginated_surface_t *surface;
|
||||||
|
|
@ -87,18 +106,15 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
|
||||||
|
|
||||||
/* Override surface->base.type with target's type so we don't leak
|
/* Override surface->base.type with target's type so we don't leak
|
||||||
* evidence of the paginated wrapper out to the user. */
|
* evidence of the paginated wrapper out to the user. */
|
||||||
surface->base.type = cairo_surface_get_type (target);
|
surface->base.type = target->type;
|
||||||
|
|
||||||
surface->target = cairo_surface_reference (target);
|
surface->target = cairo_surface_reference (target);
|
||||||
|
|
||||||
surface->content = content;
|
surface->content = content;
|
||||||
surface->width = width;
|
|
||||||
surface->height = height;
|
|
||||||
|
|
||||||
surface->backend = backend;
|
surface->backend = backend;
|
||||||
|
|
||||||
surface->meta = cairo_meta_surface_create (content, width, height);
|
surface->meta = _create_meta_surface_for_target (target, content);
|
||||||
status = cairo_surface_status (surface->meta);
|
status = surface->meta->status;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto FAIL_CLEANUP_SURFACE;
|
goto FAIL_CLEANUP_SURFACE;
|
||||||
|
|
||||||
|
|
@ -132,31 +148,6 @@ _cairo_paginated_surface_get_target (cairo_surface_t *surface)
|
||||||
return paginated_surface->target;
|
return paginated_surface->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
|
||||||
_cairo_paginated_surface_set_size (cairo_surface_t *surface,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
cairo_paginated_surface_t *paginated_surface;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
assert (_cairo_surface_is_paginated (surface));
|
|
||||||
|
|
||||||
paginated_surface = (cairo_paginated_surface_t *) surface;
|
|
||||||
|
|
||||||
paginated_surface->width = width;
|
|
||||||
paginated_surface->height = height;
|
|
||||||
|
|
||||||
cairo_surface_destroy (paginated_surface->meta);
|
|
||||||
paginated_surface->meta = cairo_meta_surface_create (paginated_surface->content,
|
|
||||||
width, height);
|
|
||||||
status = cairo_surface_status (paginated_surface->meta);
|
|
||||||
if (unlikely (status))
|
|
||||||
return _cairo_surface_set_error (surface, status);
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_paginated_surface_finish (void *abstract_surface)
|
_cairo_paginated_surface_finish (void *abstract_surface)
|
||||||
{
|
{
|
||||||
|
|
@ -168,18 +159,11 @@ _cairo_paginated_surface_finish (void *abstract_surface)
|
||||||
status = cairo_surface_status (abstract_surface);
|
status = cairo_surface_status (abstract_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
|
||||||
cairo_surface_finish (surface->target);
|
|
||||||
status = cairo_surface_status (surface->target);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
|
||||||
cairo_surface_finish (surface->meta);
|
|
||||||
status = cairo_surface_status (surface->meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_surface_destroy (surface->target);
|
cairo_surface_destroy (surface->target);
|
||||||
|
|
||||||
|
cairo_surface_finish (surface->meta);
|
||||||
|
if (status == CAIRO_STATUS_SUCCESS)
|
||||||
|
status = cairo_surface_status (surface->meta);
|
||||||
cairo_surface_destroy (surface->meta);
|
cairo_surface_destroy (surface->meta);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -210,13 +194,14 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface,
|
||||||
void **image_extra)
|
void **image_extra)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
cairo_paginated_surface_t *surface = abstract_surface;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
cairo_surface_t *image;
|
cairo_surface_t *image;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (surface->target, &extents);
|
is_bounded = _cairo_surface_get_extents (surface->target, &extents);
|
||||||
if (unlikely (status))
|
if (! is_bounded)
|
||||||
return status;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
image = _cairo_paginated_surface_create_image_surface (surface,
|
image = _cairo_paginated_surface_create_image_surface (surface,
|
||||||
extents.width,
|
extents.width,
|
||||||
|
|
@ -248,11 +233,11 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
|
||||||
{
|
{
|
||||||
double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution;
|
double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution;
|
||||||
double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution;
|
double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution;
|
||||||
cairo_matrix_t matrix;
|
|
||||||
int x, y, width, height;
|
int x, y, width, height;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_surface_t *image;
|
cairo_surface_t *image;
|
||||||
cairo_surface_pattern_t pattern;
|
cairo_surface_pattern_t pattern;
|
||||||
|
cairo_clip_t clip;
|
||||||
|
|
||||||
x = rect->x;
|
x = rect->x;
|
||||||
y = rect->y;
|
y = rect->y;
|
||||||
|
|
@ -271,15 +256,21 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
|
||||||
goto CLEANUP_IMAGE;
|
goto CLEANUP_IMAGE;
|
||||||
|
|
||||||
_cairo_pattern_init_for_surface (&pattern, image);
|
_cairo_pattern_init_for_surface (&pattern, image);
|
||||||
cairo_matrix_init (&matrix, x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale);
|
cairo_matrix_init (&pattern.base.matrix,
|
||||||
cairo_pattern_set_matrix (&pattern.base, &matrix);
|
x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale);
|
||||||
/* the fallback should be rendered at native resolution, so disable
|
/* the fallback should be rendered at native resolution, so disable
|
||||||
* filtering (if possible) to avoid introducing potential artifacts. */
|
* filtering (if possible) to avoid introducing potential artifacts. */
|
||||||
pattern.base.filter = CAIRO_FILTER_NEAREST;
|
pattern.base.filter = CAIRO_FILTER_NEAREST;
|
||||||
|
|
||||||
|
status = _cairo_clip_init_rectangle (&clip, rect);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto CLEANUP_IMAGE;
|
||||||
|
|
||||||
status = _cairo_surface_paint (surface->target,
|
status = _cairo_surface_paint (surface->target,
|
||||||
CAIRO_OPERATOR_SOURCE,
|
CAIRO_OPERATOR_SOURCE,
|
||||||
&pattern.base, NULL);
|
&pattern.base, &clip);
|
||||||
|
|
||||||
|
_cairo_clip_reset (&clip);
|
||||||
|
|
||||||
_cairo_pattern_fini (&pattern.base);
|
_cairo_pattern_fini (&pattern.base);
|
||||||
CLEANUP_IMAGE:
|
CLEANUP_IMAGE:
|
||||||
|
|
@ -295,12 +286,11 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
|
cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
|
||||||
|
|
||||||
if (surface->target->status)
|
if (unlikely (surface->target->status))
|
||||||
return surface->target->status;
|
return surface->target->status;
|
||||||
|
|
||||||
analysis = _cairo_analysis_surface_create (surface->target,
|
analysis = _cairo_analysis_surface_create (surface->target);
|
||||||
surface->width, surface->height);
|
if (unlikely (analysis->status))
|
||||||
if (analysis->status)
|
|
||||||
return _cairo_surface_set_error (surface->target, analysis->status);
|
return _cairo_surface_set_error (surface->target, analysis->status);
|
||||||
|
|
||||||
surface->backend->set_paginated_mode (surface->target,
|
surface->backend->set_paginated_mode (surface->target,
|
||||||
|
|
@ -365,16 +355,19 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_page_fallback) {
|
if (has_page_fallback) {
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t extents;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
|
|
||||||
surface->backend->set_paginated_mode (surface->target,
|
surface->backend->set_paginated_mode (surface->target,
|
||||||
CAIRO_PAGINATED_MODE_FALLBACK);
|
CAIRO_PAGINATED_MODE_FALLBACK);
|
||||||
|
|
||||||
rect.x = 0;
|
is_bounded = _cairo_surface_get_extents (surface->target, &extents);
|
||||||
rect.y = 0;
|
if (! is_bounded) {
|
||||||
rect.width = surface->width;
|
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
rect.height = surface->height;
|
goto FAIL;
|
||||||
status = _paint_fallback_image (surface, &rect);
|
}
|
||||||
|
|
||||||
|
status = _paint_fallback_image (surface, &extents);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
|
|
@ -386,15 +379,6 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||||
surface->backend->set_paginated_mode (surface->target,
|
surface->backend->set_paginated_mode (surface->target,
|
||||||
CAIRO_PAGINATED_MODE_FALLBACK);
|
CAIRO_PAGINATED_MODE_FALLBACK);
|
||||||
|
|
||||||
/* Reset clip region before drawing the fall back images */
|
|
||||||
status = _cairo_surface_intersect_clip_path (surface->target,
|
|
||||||
NULL,
|
|
||||||
CAIRO_FILL_RULE_WINDING,
|
|
||||||
CAIRO_GSTATE_TOLERANCE_DEFAULT,
|
|
||||||
CAIRO_ANTIALIAS_DEFAULT);
|
|
||||||
if (unlikely (status))
|
|
||||||
goto FAIL;
|
|
||||||
|
|
||||||
region = _cairo_analysis_surface_get_unsupported (analysis);
|
region = _cairo_analysis_surface_get_unsupported (analysis);
|
||||||
|
|
||||||
num_rects = cairo_region_num_rectangles (region);
|
num_rects = cairo_region_num_rectangles (region);
|
||||||
|
|
@ -402,9 +386,7 @@ _paint_page (cairo_paginated_surface_t *surface)
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
cairo_region_get_rectangle (region, i, &rect);
|
cairo_region_get_rectangle (region, i, &rect);
|
||||||
|
|
||||||
status = _paint_fallback_image (surface, &rect);
|
status = _paint_fallback_image (surface, &rect);
|
||||||
|
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
}
|
}
|
||||||
|
|
@ -445,7 +427,7 @@ _cairo_paginated_surface_copy_page (void *abstract_surface)
|
||||||
|
|
||||||
surface->page_num++;
|
surface->page_num++;
|
||||||
|
|
||||||
/* XXX: It might make sense to add some suport here for calling
|
/* XXX: It might make sense to add some support here for calling
|
||||||
* cairo_surface_copy_page on the target surface. It would be an
|
* cairo_surface_copy_page on the target surface. It would be an
|
||||||
* optimization for the output, but the interaction with image
|
* optimization for the output, but the interaction with image
|
||||||
* fallbacks gets tricky. For now, we just let the target see a
|
* fallbacks gets tricky. For now, we just let the target see a
|
||||||
|
|
@ -471,20 +453,19 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
cairo_surface_show_page (surface->target);
|
cairo_surface_show_page (surface->target);
|
||||||
status = cairo_surface_status (surface->target);
|
status = surface->target->status;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = cairo_surface_status (surface->meta);
|
status = surface->meta->status;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
cairo_surface_destroy (surface->meta);
|
cairo_surface_destroy (surface->meta);
|
||||||
|
|
||||||
surface->meta = cairo_meta_surface_create (surface->content,
|
surface->meta = _create_meta_surface_for_target (surface->target,
|
||||||
surface->width,
|
surface->content);
|
||||||
surface->height);
|
status = surface->meta->status;
|
||||||
status = cairo_surface_status (surface->meta);
|
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -494,21 +475,7 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_paginated_surface_intersect_clip_path (void *abstract_surface,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias)
|
|
||||||
{
|
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
|
||||||
|
|
||||||
return _cairo_surface_intersect_clip_path (surface->meta,
|
|
||||||
path, fill_rule,
|
|
||||||
tolerance, antialias);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_paginated_surface_get_extents (void *abstract_surface,
|
_cairo_paginated_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -530,7 +497,7 @@ static cairo_int_status_t
|
||||||
_cairo_paginated_surface_paint (void *abstract_surface,
|
_cairo_paginated_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
cairo_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
|
@ -540,7 +507,7 @@ _cairo_paginated_surface_paint (void *abstract_surface,
|
||||||
|
|
||||||
surface->page_is_blank = FALSE;
|
surface->page_is_blank = FALSE;
|
||||||
|
|
||||||
return _cairo_surface_paint (surface->meta, op, source, NULL);
|
return _cairo_surface_paint (surface->meta, op, source, clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -548,11 +515,17 @@ _cairo_paginated_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
cairo_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
return _cairo_surface_mask (surface->meta, op, source, mask, NULL);
|
/* Optimize away erasing of nothing. */
|
||||||
|
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
surface->page_is_blank = FALSE;
|
||||||
|
|
||||||
|
return _cairo_surface_mask (surface->meta, op, source, mask, clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -565,7 +538,7 @@ _cairo_paginated_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
cairo_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
|
@ -578,7 +551,8 @@ _cairo_paginated_surface_stroke (void *abstract_surface,
|
||||||
return _cairo_surface_stroke (surface->meta, op, source,
|
return _cairo_surface_stroke (surface->meta, op, source,
|
||||||
path, style,
|
path, style,
|
||||||
ctm, ctm_inverse,
|
ctm, ctm_inverse,
|
||||||
tolerance, antialias, NULL);
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -589,7 +563,7 @@ _cairo_paginated_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
cairo_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
|
@ -601,7 +575,8 @@ _cairo_paginated_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
return _cairo_surface_fill (surface->meta, op, source,
|
return _cairo_surface_fill (surface->meta, op, source,
|
||||||
path, fill_rule,
|
path, fill_rule,
|
||||||
tolerance, antialias, NULL);
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -614,20 +589,19 @@ _cairo_paginated_surface_has_show_text_glyphs (void *abstract_surface)
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_paginated_surface_show_text_glyphs (void *abstract_surface,
|
_cairo_paginated_surface_show_text_glyphs (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const char *utf8,
|
const char *utf8,
|
||||||
int utf8_len,
|
int utf8_len,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
const cairo_text_cluster_t *clusters,
|
const cairo_text_cluster_t *clusters,
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_paginated_surface_t *surface = abstract_surface;
|
cairo_paginated_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status;
|
|
||||||
|
|
||||||
/* Optimize away erasing of nothing. */
|
/* Optimize away erasing of nothing. */
|
||||||
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
if (surface->page_is_blank && op == CAIRO_OPERATOR_CLEAR)
|
||||||
|
|
@ -635,24 +609,13 @@ _cairo_paginated_surface_show_text_glyphs (void *abstract_surface,
|
||||||
|
|
||||||
surface->page_is_blank = FALSE;
|
surface->page_is_blank = FALSE;
|
||||||
|
|
||||||
/* Since this is a "wrapping" surface, we're calling back into
|
return _cairo_surface_show_text_glyphs (surface->meta, op, source,
|
||||||
* _cairo_surface_show_text_glyphs from within a call to the same.
|
utf8, utf8_len,
|
||||||
* Since _cairo_surface_show_text_glyphs acquires a mutex, we release
|
glyphs, num_glyphs,
|
||||||
* and re-acquire the mutex around this nested call.
|
clusters, num_clusters,
|
||||||
*
|
cluster_flags,
|
||||||
* Yes, this is ugly, but we consider it pragmatic as compared to
|
scaled_font,
|
||||||
* adding locking code to all 18 surface-backend-specific
|
clip);
|
||||||
* show_glyphs functions, (which would get less testing and likely
|
|
||||||
* lead to bugs).
|
|
||||||
*/
|
|
||||||
status = _cairo_surface_show_text_glyphs (surface->meta, op, source,
|
|
||||||
utf8, utf8_len,
|
|
||||||
glyphs, num_glyphs,
|
|
||||||
clusters, num_clusters,
|
|
||||||
cluster_flags,
|
|
||||||
scaled_font, NULL);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
|
|
@ -679,8 +642,6 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
_cairo_paginated_surface_copy_page,
|
_cairo_paginated_surface_copy_page,
|
||||||
_cairo_paginated_surface_show_page,
|
_cairo_paginated_surface_show_page,
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_paginated_surface_intersect_clip_path,
|
|
||||||
_cairo_paginated_surface_get_extents,
|
_cairo_paginated_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
_cairo_paginated_surface_get_font_options,
|
_cairo_paginated_surface_get_font_options,
|
||||||
|
|
@ -695,7 +656,6 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = {
|
||||||
NULL, /* show_glyphs */
|
NULL, /* show_glyphs */
|
||||||
_cairo_paginated_surface_snapshot,
|
_cairo_paginated_surface_snapshot,
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ _cairo_path_bounder_close_path (void *closure)
|
||||||
* the control points of the curves, not the flattened path).
|
* the control points of the curves, not the flattened path).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_cairo_path_fixed_approximate_clip_extents (cairo_path_fixed_t *path,
|
_cairo_path_fixed_approximate_clip_extents (const cairo_path_fixed_t *path,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
cairo_path_bounder_t bounder;
|
cairo_path_bounder_t bounder;
|
||||||
|
|
@ -203,7 +203,7 @@ _cairo_path_fixed_approximate_clip_extents (cairo_path_fixed_t *path,
|
||||||
* Bezier, but we continue to ignore winding.
|
* Bezier, but we continue to ignore winding.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_cairo_path_fixed_approximate_fill_extents (cairo_path_fixed_t *path,
|
_cairo_path_fixed_approximate_fill_extents (const cairo_path_fixed_t *path,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
cairo_path_bounder_t bounder;
|
cairo_path_bounder_t bounder;
|
||||||
|
|
@ -229,9 +229,37 @@ _cairo_path_fixed_approximate_fill_extents (cairo_path_fixed_t *path,
|
||||||
_cairo_path_bounder_fini (&bounder);
|
_cairo_path_bounder_fini (&bounder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cairo_path_fixed_fill_extents (const cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_rectangle_int_t *extents)
|
||||||
|
{
|
||||||
|
cairo_path_bounder_t bounder;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
_cairo_path_bounder_init (&bounder);
|
||||||
|
|
||||||
|
status = _cairo_path_fixed_interpret_flat (path, CAIRO_DIRECTION_FORWARD,
|
||||||
|
_cairo_path_bounder_move_to,
|
||||||
|
_cairo_path_bounder_line_to,
|
||||||
|
_cairo_path_bounder_close_path,
|
||||||
|
&bounder, tolerance);
|
||||||
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
if (bounder.has_point) {
|
||||||
|
_cairo_box_round_to_rectangle (&bounder.extents, extents);
|
||||||
|
} else {
|
||||||
|
extents->x = extents->y = 0;
|
||||||
|
extents->width = extents->height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cairo_path_bounder_fini (&bounder);
|
||||||
|
}
|
||||||
|
|
||||||
/* Adjusts the fill extents (above) by the device-space pen. */
|
/* Adjusts the fill extents (above) by the device-space pen. */
|
||||||
void
|
void
|
||||||
_cairo_path_fixed_approximate_stroke_extents (cairo_path_fixed_t *path,
|
_cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path,
|
||||||
cairo_stroke_style_t *style,
|
cairo_stroke_style_t *style,
|
||||||
const cairo_matrix_t *ctm,
|
const cairo_matrix_t *ctm,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
|
|
@ -268,8 +296,37 @@ _cairo_path_fixed_approximate_stroke_extents (cairo_path_fixed_t *path,
|
||||||
_cairo_path_bounder_fini (&bounder);
|
_cairo_path_bounder_fini (&bounder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t *path,
|
||||||
|
cairo_stroke_style_t *stroke_style,
|
||||||
|
const cairo_matrix_t *ctm,
|
||||||
|
const cairo_matrix_t *ctm_inverse,
|
||||||
|
double tolerance,
|
||||||
|
cairo_rectangle_int_t *extents)
|
||||||
|
{
|
||||||
|
cairo_traps_t traps;
|
||||||
|
cairo_box_t bbox;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
_cairo_traps_init (&traps);
|
||||||
|
|
||||||
|
status = _cairo_path_fixed_stroke_to_traps (path,
|
||||||
|
stroke_style,
|
||||||
|
ctm,
|
||||||
|
ctm_inverse,
|
||||||
|
tolerance,
|
||||||
|
&traps);
|
||||||
|
|
||||||
|
_cairo_traps_extents (&traps, &bbox);
|
||||||
|
_cairo_traps_fini (&traps);
|
||||||
|
|
||||||
|
_cairo_box_round_to_rectangle (&bbox, extents);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
|
_cairo_path_fixed_bounds (const cairo_path_fixed_t *path,
|
||||||
double *x1, double *y1,
|
double *x1, double *y1,
|
||||||
double *x2, double *y2)
|
double *x2, double *y2)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -125,12 +125,12 @@ _cairo_filler_close_path (void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path,
|
_cairo_path_fixed_fill_rectangle (const cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
cairo_traps_t *traps);
|
cairo_traps_t *traps);
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
_cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_traps_t *traps)
|
cairo_traps_t *traps)
|
||||||
|
|
@ -138,6 +138,8 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
||||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
cairo_filler_t filler;
|
cairo_filler_t filler;
|
||||||
|
|
||||||
|
traps->maybe_region = path->maybe_fill_region;
|
||||||
|
|
||||||
/* Before we do anything else, we use a special-case filler for
|
/* Before we do anything else, we use a special-case filler for
|
||||||
* a device-axis aligned rectangle if possible. */
|
* a device-axis aligned rectangle if possible. */
|
||||||
status = _cairo_path_fixed_fill_rectangle (path, fill_rule, traps);
|
status = _cairo_path_fixed_fill_rectangle (path, fill_rule, traps);
|
||||||
|
|
@ -181,12 +183,15 @@ BAIL:
|
||||||
* this function will return %CAIRO_INT_STATUS_UNSUPPORTED.
|
* this function will return %CAIRO_INT_STATUS_UNSUPPORTED.
|
||||||
*/
|
*/
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path,
|
_cairo_path_fixed_fill_rectangle (const cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
cairo_traps_t *traps)
|
cairo_traps_t *traps)
|
||||||
{
|
{
|
||||||
cairo_box_t box;
|
cairo_box_t box;
|
||||||
|
|
||||||
|
if (! path->is_rectilinear)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
if (_cairo_path_fixed_is_box (path, &box)) {
|
if (_cairo_path_fixed_is_box (path, &box)) {
|
||||||
if (box.p1.x > box.p2.x) {
|
if (box.p1.x > box.p2.x) {
|
||||||
cairo_fixed_t t;
|
cairo_fixed_t t;
|
||||||
|
|
|
||||||
|
|
@ -81,12 +81,26 @@ struct _cairo_path_fixed {
|
||||||
cairo_point_t current_point;
|
cairo_point_t current_point;
|
||||||
unsigned int has_current_point : 1;
|
unsigned int has_current_point : 1;
|
||||||
unsigned int has_curve_to : 1;
|
unsigned int has_curve_to : 1;
|
||||||
unsigned int is_box : 1;
|
unsigned int is_rectilinear : 1;
|
||||||
unsigned int is_region : 1;
|
unsigned int maybe_fill_region : 1;
|
||||||
|
unsigned int is_empty_fill : 1;
|
||||||
|
|
||||||
cairo_path_buf_fixed_t buf;
|
cairo_path_buf_fixed_t buf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_path_fixed_translate (cairo_path_fixed_t *path,
|
||||||
|
cairo_fixed_t offx,
|
||||||
|
cairo_fixed_t offy);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_path_fixed_append (cairo_path_fixed_t *path,
|
||||||
|
const cairo_path_fixed_t *other,
|
||||||
|
cairo_direction_t dir,
|
||||||
|
cairo_fixed_t tx,
|
||||||
|
cairo_fixed_t ty);
|
||||||
|
|
||||||
cairo_private unsigned long
|
cairo_private unsigned long
|
||||||
_cairo_path_fixed_hash (const cairo_path_fixed_t *path);
|
_cairo_path_fixed_hash (const cairo_path_fixed_t *path);
|
||||||
|
|
||||||
|
|
@ -98,14 +112,14 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
|
||||||
const cairo_path_fixed_t *b);
|
const cairo_path_fixed_t *b);
|
||||||
|
|
||||||
typedef struct _cairo_path_fixed_iter {
|
typedef struct _cairo_path_fixed_iter {
|
||||||
cairo_path_buf_t *buf;
|
const cairo_path_buf_t *buf;
|
||||||
unsigned int n_op;
|
unsigned int n_op;
|
||||||
unsigned int n_point;
|
unsigned int n_point;
|
||||||
} cairo_path_fixed_iter_t;
|
} cairo_path_fixed_iter_t;
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
|
_cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
|
||||||
cairo_path_fixed_t *path);
|
const cairo_path_fixed_t *path);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter,
|
_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter,
|
||||||
|
|
@ -115,13 +129,19 @@ cairo_private cairo_bool_t
|
||||||
_cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter);
|
_cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter);
|
||||||
|
|
||||||
static inline cairo_bool_t
|
static inline cairo_bool_t
|
||||||
_cairo_path_fixed_is_region (cairo_path_fixed_t *path)
|
_cairo_path_fixed_fill_is_empty (const cairo_path_fixed_t *path)
|
||||||
|
{
|
||||||
|
return path->is_empty_fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline cairo_bool_t
|
||||||
|
_cairo_path_fixed_maybe_fill_region (const cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
#if WATCH_PATH
|
#if WATCH_PATH
|
||||||
fprintf (stderr, "_cairo_path_fixed_is_region () = %s\n",
|
fprintf (stderr, "_cairo_path_fixed_maybe_fill_region () = %s\n",
|
||||||
path->is_region ? "true" : "false");
|
path->maybe_fill_region ? "true" : "false");
|
||||||
#endif
|
#endif
|
||||||
return path->is_region;
|
return path->maybe_fill_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CAIRO_PATH_FIXED_PRIVATE_H */
|
#endif /* CAIRO_PATH_FIXED_PRIVATE_H */
|
||||||
|
|
|
||||||
|
|
@ -96,25 +96,32 @@ _cairo_path_fixed_init (cairo_path_fixed_t *path)
|
||||||
path->last_move_point = path->current_point;
|
path->last_move_point = path->current_point;
|
||||||
path->has_current_point = FALSE;
|
path->has_current_point = FALSE;
|
||||||
path->has_curve_to = FALSE;
|
path->has_curve_to = FALSE;
|
||||||
path->is_region = TRUE;
|
path->is_rectilinear = TRUE;
|
||||||
path->is_box = TRUE;
|
path->maybe_fill_region = TRUE;
|
||||||
|
path->is_empty_fill = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||||
cairo_path_fixed_t *other)
|
const cairo_path_fixed_t *other)
|
||||||
{
|
{
|
||||||
cairo_path_buf_t *buf, *other_buf;
|
cairo_path_buf_t *buf, *other_buf;
|
||||||
unsigned int num_points, num_ops, buf_size;
|
unsigned int num_points, num_ops, buf_size;
|
||||||
|
|
||||||
_cairo_path_fixed_init (path);
|
VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t)));
|
||||||
|
|
||||||
|
cairo_list_init (&path->buf.base.link);
|
||||||
|
|
||||||
|
path->buf.base.op = path->buf.op;
|
||||||
|
path->buf.base.points = path->buf.points;
|
||||||
|
|
||||||
path->current_point = other->current_point;
|
path->current_point = other->current_point;
|
||||||
path->has_current_point = other->has_current_point;
|
|
||||||
path->last_move_point = other->last_move_point;
|
path->last_move_point = other->last_move_point;
|
||||||
|
path->has_current_point = other->has_current_point;
|
||||||
path->has_curve_to = other->has_curve_to;
|
path->has_curve_to = other->has_curve_to;
|
||||||
path->is_box = other->is_box;
|
path->is_rectilinear = other->is_rectilinear;
|
||||||
path->is_region = other->is_region;
|
path->maybe_fill_region = other->maybe_fill_region;
|
||||||
|
path->is_empty_fill = other->is_empty_fill;
|
||||||
|
|
||||||
path->buf.base.num_ops = other->buf.base.num_ops;
|
path->buf.base.num_ops = other->buf.base.num_ops;
|
||||||
path->buf.base.num_points = other->buf.base.num_points;
|
path->buf.base.num_points = other->buf.base.num_points;
|
||||||
|
|
@ -214,9 +221,10 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* use the flags to quickly differentiate based on contents */
|
/* use the flags to quickly differentiate based on contents */
|
||||||
if (a->has_curve_to != b->has_curve_to ||
|
if (a->is_empty_fill != b->is_empty_fill ||
|
||||||
a->is_region != b->is_region ||
|
a->has_curve_to != b->has_curve_to ||
|
||||||
a->is_box != b->is_box)
|
a->maybe_fill_region != b->maybe_fill_region ||
|
||||||
|
a->is_rectilinear != b->is_rectilinear)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -378,15 +386,16 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (path->has_current_point && path->is_box) {
|
if (path->has_current_point && path->is_rectilinear) {
|
||||||
/* a move-to is first an implicit close */
|
/* a move-to is first an implicit close */
|
||||||
path->is_box = path->current_point.x == path->last_move_point.x ||
|
path->is_rectilinear = path->current_point.x == path->last_move_point.x ||
|
||||||
path->current_point.y == path->last_move_point.y;
|
path->current_point.y == path->last_move_point.y;
|
||||||
path->is_region &= path->is_box;
|
path->maybe_fill_region &= path->is_rectilinear;
|
||||||
}
|
}
|
||||||
if (path->is_region) {
|
if (path->maybe_fill_region) {
|
||||||
path->is_region = _cairo_fixed_is_integer (x) &&
|
path->maybe_fill_region =
|
||||||
_cairo_fixed_is_integer (y);
|
_cairo_fixed_is_integer (path->last_move_point.x) &&
|
||||||
|
_cairo_fixed_is_integer (path->last_move_point.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -437,14 +446,18 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
|
||||||
status = _cairo_path_fixed_move_to (path, point.x, point.y);
|
status = _cairo_path_fixed_move_to (path, point.x, point.y);
|
||||||
} else {
|
} else {
|
||||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||||
if (path->is_box) {
|
if (path->is_rectilinear) {
|
||||||
path->is_box = path->current_point.x == x ||
|
path->is_rectilinear = path->current_point.x == x ||
|
||||||
path->current_point.y == y;
|
path->current_point.y == y;
|
||||||
path->is_region &= path->is_box;
|
path->maybe_fill_region &= path->is_rectilinear;
|
||||||
}
|
}
|
||||||
if (path->is_region) {
|
if (path->maybe_fill_region) {
|
||||||
path->is_region = _cairo_fixed_is_integer (x) &&
|
path->maybe_fill_region = _cairo_fixed_is_integer (x) &&
|
||||||
_cairo_fixed_is_integer (y);
|
_cairo_fixed_is_integer (y);
|
||||||
|
}
|
||||||
|
if (path->is_empty_fill) {
|
||||||
|
path->is_empty_fill = path->current_point.x == x &&
|
||||||
|
path->current_point.y == y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -495,9 +508,10 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
|
||||||
|
|
||||||
path->current_point = point[2];
|
path->current_point = point[2];
|
||||||
path->has_current_point = TRUE;
|
path->has_current_point = TRUE;
|
||||||
|
path->is_empty_fill = FALSE;
|
||||||
path->has_curve_to = TRUE;
|
path->has_curve_to = TRUE;
|
||||||
path->is_box = FALSE;
|
path->is_rectilinear = FALSE;
|
||||||
path->is_region = FALSE;
|
path->maybe_fill_region = FALSE;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -732,49 +746,77 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _cairo_path_fixed_append_closure {
|
||||||
|
cairo_point_t offset;
|
||||||
|
cairo_path_fixed_t *path;
|
||||||
|
} cairo_path_fixed_append_closure_t;
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_append_move_to (void *closure,
|
_append_move_to (void *abstract_closure,
|
||||||
const cairo_point_t *point)
|
const cairo_point_t *point)
|
||||||
{
|
{
|
||||||
return _cairo_path_fixed_move_to (closure, point->x, point->y);
|
cairo_path_fixed_append_closure_t *closure = abstract_closure;
|
||||||
|
|
||||||
|
return _cairo_path_fixed_move_to (closure->path,
|
||||||
|
point->x + closure->offset.x,
|
||||||
|
point->y + closure->offset.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_append_line_to (void *closure,
|
_append_line_to (void *abstract_closure,
|
||||||
const cairo_point_t *point)
|
const cairo_point_t *point)
|
||||||
{
|
{
|
||||||
return _cairo_path_fixed_line_to (closure, point->x, point->y);
|
cairo_path_fixed_append_closure_t *closure = abstract_closure;
|
||||||
|
|
||||||
|
return _cairo_path_fixed_line_to (closure->path,
|
||||||
|
point->x + closure->offset.x,
|
||||||
|
point->y + closure->offset.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_append_curve_to (void *closure,
|
_append_curve_to (void *abstract_closure,
|
||||||
const cairo_point_t *p0,
|
const cairo_point_t *p0,
|
||||||
const cairo_point_t *p1,
|
const cairo_point_t *p1,
|
||||||
const cairo_point_t *p2)
|
const cairo_point_t *p2)
|
||||||
{
|
{
|
||||||
return _cairo_path_fixed_curve_to (closure,
|
cairo_path_fixed_append_closure_t *closure = abstract_closure;
|
||||||
p0->x, p0->y,
|
|
||||||
p1->x, p1->y,
|
return _cairo_path_fixed_curve_to (closure->path,
|
||||||
p2->x, p2->y);
|
p0->x + closure->offset.x,
|
||||||
|
p0->y + closure->offset.y,
|
||||||
|
p1->x + closure->offset.x,
|
||||||
|
p1->y + closure->offset.y,
|
||||||
|
p2->x + closure->offset.x,
|
||||||
|
p2->y + closure->offset.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_append_close_path (void *closure)
|
_append_close_path (void *abstract_closure)
|
||||||
{
|
{
|
||||||
return _cairo_path_fixed_close_path (closure);
|
cairo_path_fixed_append_closure_t *closure = abstract_closure;
|
||||||
|
|
||||||
|
return _cairo_path_fixed_close_path (closure->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_path_fixed_append (cairo_path_fixed_t *path,
|
_cairo_path_fixed_append (cairo_path_fixed_t *path,
|
||||||
const cairo_path_fixed_t *other,
|
const cairo_path_fixed_t *other,
|
||||||
cairo_direction_t dir)
|
cairo_direction_t dir,
|
||||||
|
cairo_fixed_t tx,
|
||||||
|
cairo_fixed_t ty)
|
||||||
{
|
{
|
||||||
|
cairo_path_fixed_append_closure_t closure;
|
||||||
|
|
||||||
|
closure.path = path;
|
||||||
|
closure.offset.x = tx;
|
||||||
|
closure.offset.y = ty;
|
||||||
|
|
||||||
return _cairo_path_fixed_interpret (other, dir,
|
return _cairo_path_fixed_interpret (other, dir,
|
||||||
_append_move_to,
|
_append_move_to,
|
||||||
_append_line_to,
|
_append_line_to,
|
||||||
_append_curve_to,
|
_append_curve_to,
|
||||||
_append_close_path,
|
_append_close_path,
|
||||||
path);
|
&closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -787,6 +829,13 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||||
cairo_path_buf_t *buf;
|
cairo_path_buf_t *buf;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
if (path->maybe_fill_region) {
|
||||||
|
path->maybe_fill_region = _cairo_fixed_is_integer (offx) &&
|
||||||
|
_cairo_fixed_is_integer (offy) &&
|
||||||
|
_cairo_fixed_is_integer (scalex) &&
|
||||||
|
_cairo_fixed_is_integer (scaley);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_path_foreach_buf_start (buf, path) {
|
cairo_path_foreach_buf_start (buf, path) {
|
||||||
for (i = 0; i < buf->num_points; i++) {
|
for (i = 0; i < buf->num_points; i++) {
|
||||||
if (scalex != CAIRO_FIXED_ONE)
|
if (scalex != CAIRO_FIXED_ONE)
|
||||||
|
|
@ -800,6 +849,36 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||||
} cairo_path_foreach_buf_end (buf, path);
|
} cairo_path_foreach_buf_end (buf, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cairo_path_fixed_translate (cairo_path_fixed_t *path,
|
||||||
|
cairo_fixed_t offx,
|
||||||
|
cairo_fixed_t offy)
|
||||||
|
{
|
||||||
|
cairo_path_buf_t *buf;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (offx == 0 && offy == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (path->maybe_fill_region &&
|
||||||
|
! (_cairo_fixed_is_integer (offx) && _cairo_fixed_is_integer (offy)))
|
||||||
|
{
|
||||||
|
path->maybe_fill_region = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
path->last_move_point.x += offx;
|
||||||
|
path->last_move_point.y += offx;
|
||||||
|
path->current_point.x += offx;
|
||||||
|
path->current_point.y += offx;
|
||||||
|
|
||||||
|
cairo_path_foreach_buf_start (buf, path) {
|
||||||
|
for (i = 0; i < buf->num_points; i++) {
|
||||||
|
buf->points[i].x += offx;
|
||||||
|
buf->points[i].y += offy;
|
||||||
|
}
|
||||||
|
} cairo_path_foreach_buf_end (buf, path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* _cairo_path_fixed_transform:
|
* _cairo_path_fixed_transform:
|
||||||
* @path: a #cairo_path_fixed_t to be transformed
|
* @path: a #cairo_path_fixed_t to be transformed
|
||||||
|
|
@ -811,12 +890,14 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
_cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
_cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
||||||
cairo_matrix_t *matrix)
|
const cairo_matrix_t *matrix)
|
||||||
{
|
{
|
||||||
cairo_path_buf_t *buf;
|
cairo_path_buf_t *buf;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
double dx, dy;
|
double dx, dy;
|
||||||
|
|
||||||
|
/* XXX current_point, last_move_to */
|
||||||
|
|
||||||
if (matrix->yx == 0.0 && matrix->xy == 0.0) {
|
if (matrix->yx == 0.0 && matrix->xy == 0.0) {
|
||||||
/* Fast path for the common case of scale+transform */
|
/* Fast path for the common case of scale+transform */
|
||||||
_cairo_path_fixed_offset_and_scale (path,
|
_cairo_path_fixed_offset_and_scale (path,
|
||||||
|
|
@ -827,6 +908,7 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path->maybe_fill_region = FALSE;
|
||||||
cairo_path_foreach_buf_start (buf, path) {
|
cairo_path_foreach_buf_start (buf, path) {
|
||||||
for (i = 0; i < buf->num_points; i++) {
|
for (i = 0; i < buf->num_points; i++) {
|
||||||
dx = _cairo_fixed_to_double (buf->points[i].x);
|
dx = _cairo_fixed_to_double (buf->points[i].x);
|
||||||
|
|
@ -841,20 +923,22 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_bool_t
|
cairo_bool_t
|
||||||
_cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
|
_cairo_path_fixed_is_equal (const cairo_path_fixed_t *path,
|
||||||
cairo_path_fixed_t *other)
|
const cairo_path_fixed_t *other)
|
||||||
{
|
{
|
||||||
cairo_path_buf_t *path_buf, *other_buf;
|
const cairo_path_buf_t *path_buf, *other_buf;
|
||||||
|
|
||||||
if (path->current_point.x != other->current_point.x ||
|
if (path->current_point.x != other->current_point.x ||
|
||||||
path->current_point.y != other->current_point.y ||
|
path->current_point.y != other->current_point.y ||
|
||||||
path->has_current_point != other->has_current_point ||
|
path->has_current_point != other->has_current_point ||
|
||||||
path->has_curve_to != other->has_curve_to ||
|
path->has_curve_to != other->has_curve_to ||
|
||||||
path->is_box != other->is_box ||
|
path->is_rectilinear != other->is_rectilinear ||
|
||||||
path->is_region != other->is_region ||
|
path->maybe_fill_region != other->maybe_fill_region ||
|
||||||
path->last_move_point.x != other->last_move_point.x ||
|
path->last_move_point.x != other->last_move_point.x ||
|
||||||
path->last_move_point.y != other->last_move_point.y)
|
path->last_move_point.y != other->last_move_point.y)
|
||||||
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
other_buf = cairo_path_head (other);
|
other_buf = cairo_path_head (other);
|
||||||
cairo_path_foreach_buf_start (path_buf, path) {
|
cairo_path_foreach_buf_start (path_buf, path) {
|
||||||
|
|
@ -970,25 +1054,16 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path,
|
||||||
&flattener);
|
&flattener);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_bool_t
|
|
||||||
_cairo_path_fixed_is_empty (cairo_path_fixed_t *path)
|
|
||||||
{
|
|
||||||
if (cairo_path_head (path)->num_ops == 0)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the given path contains a single rectangle.
|
* Check whether the given path contains a single rectangle.
|
||||||
*/
|
*/
|
||||||
cairo_bool_t
|
cairo_bool_t
|
||||||
_cairo_path_fixed_is_box (cairo_path_fixed_t *path,
|
_cairo_path_fixed_is_box (const cairo_path_fixed_t *path,
|
||||||
cairo_box_t *box)
|
cairo_box_t *box)
|
||||||
{
|
{
|
||||||
cairo_path_buf_t *buf = cairo_path_head (path);
|
const cairo_path_buf_t *buf = cairo_path_head (path);
|
||||||
|
|
||||||
if (! path->is_box)
|
if (! path->is_rectilinear)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Do we have the right number of ops? */
|
/* Do we have the right number of ops? */
|
||||||
|
|
@ -1058,12 +1133,12 @@ _cairo_path_fixed_is_box (cairo_path_fixed_t *path,
|
||||||
* </programlisting></informalexample>
|
* </programlisting></informalexample>
|
||||||
*/
|
*/
|
||||||
cairo_bool_t
|
cairo_bool_t
|
||||||
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
|
_cairo_path_fixed_is_rectangle (const cairo_path_fixed_t *path,
|
||||||
cairo_box_t *box)
|
cairo_box_t *box)
|
||||||
{
|
{
|
||||||
cairo_path_buf_t *buf;
|
const cairo_path_buf_t *buf;
|
||||||
|
|
||||||
if (!_cairo_path_fixed_is_box (path, box))
|
if (! _cairo_path_fixed_is_box (path, box))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
buf = cairo_path_head (path);
|
buf = cairo_path_head (path);
|
||||||
|
|
@ -1075,7 +1150,7 @@ _cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
|
||||||
|
|
||||||
void
|
void
|
||||||
_cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
|
_cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
|
||||||
cairo_path_fixed_t *path)
|
const cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
iter->buf = cairo_path_head (path);
|
iter->buf = cairo_path_head (path);
|
||||||
iter->n_op = 0;
|
iter->n_op = 0;
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,10 @@
|
||||||
|
|
||||||
typedef struct cairo_in_fill {
|
typedef struct cairo_in_fill {
|
||||||
double tolerance;
|
double tolerance;
|
||||||
|
cairo_bool_t on_edge;
|
||||||
int winding;
|
int winding;
|
||||||
|
|
||||||
cairo_fixed_t x, y;
|
cairo_fixed_t x, y;
|
||||||
cairo_bool_t on_edge;
|
|
||||||
|
|
||||||
cairo_bool_t has_current_point;
|
cairo_bool_t has_current_point;
|
||||||
cairo_point_t current_point;
|
cairo_point_t current_point;
|
||||||
|
|
@ -54,12 +54,12 @@ _cairo_in_fill_init (cairo_in_fill_t *in_fill,
|
||||||
double x,
|
double x,
|
||||||
double y)
|
double y)
|
||||||
{
|
{
|
||||||
|
in_fill->on_edge = FALSE;
|
||||||
in_fill->winding = 0;
|
in_fill->winding = 0;
|
||||||
in_fill->tolerance = tolerance;
|
in_fill->tolerance = tolerance;
|
||||||
|
|
||||||
in_fill->x = _cairo_fixed_from_double (x);
|
in_fill->x = _cairo_fixed_from_double (x);
|
||||||
in_fill->y = _cairo_fixed_from_double (y);
|
in_fill->y = _cairo_fixed_from_double (y);
|
||||||
in_fill->on_edge = FALSE;
|
|
||||||
|
|
||||||
in_fill->has_current_point = FALSE;
|
in_fill->has_current_point = FALSE;
|
||||||
in_fill->current_point.x = 0;
|
in_fill->current_point.x = 0;
|
||||||
|
|
@ -142,7 +142,7 @@ _cairo_in_fill_add_edge (cairo_in_fill_t *in_fill,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((p1->x <= in_fill->x && p2->x <= in_fill->x) ||
|
if ((p1->x <= in_fill->x && p2->x <= in_fill->x) ||
|
||||||
edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) <= 0)
|
edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) < 0)
|
||||||
{
|
{
|
||||||
in_fill->winding += dir;
|
in_fill->winding += dir;
|
||||||
}
|
}
|
||||||
|
|
@ -243,16 +243,19 @@ _cairo_in_fill_close_path (void *closure)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
cairo_bool_t
|
||||||
_cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
|
_cairo_path_fixed_in_fill (const cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y)
|
||||||
cairo_bool_t *is_inside)
|
|
||||||
{
|
{
|
||||||
cairo_in_fill_t in_fill;
|
cairo_in_fill_t in_fill;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
cairo_bool_t is_inside;
|
||||||
|
|
||||||
|
if (path->is_empty_fill)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
_cairo_in_fill_init (&in_fill, tolerance, x, y);
|
_cairo_in_fill_init (&in_fill, tolerance, x, y);
|
||||||
|
|
||||||
|
|
@ -268,19 +271,21 @@ _cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
|
||||||
_cairo_in_fill_close_path (&in_fill);
|
_cairo_in_fill_close_path (&in_fill);
|
||||||
|
|
||||||
if (in_fill.on_edge) {
|
if (in_fill.on_edge) {
|
||||||
*is_inside = TRUE;
|
is_inside = TRUE;
|
||||||
} else switch (fill_rule) {
|
} else switch (fill_rule) {
|
||||||
case CAIRO_FILL_RULE_EVEN_ODD:
|
case CAIRO_FILL_RULE_EVEN_ODD:
|
||||||
*is_inside = in_fill.winding & 1;
|
is_inside = in_fill.winding & 1;
|
||||||
break;
|
break;
|
||||||
case CAIRO_FILL_RULE_WINDING:
|
case CAIRO_FILL_RULE_WINDING:
|
||||||
*is_inside = in_fill.winding != 0;
|
is_inside = in_fill.winding != 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED;
|
ASSERT_NOT_REACHED;
|
||||||
*is_inside = FALSE;
|
is_inside = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_in_fill_fini (&in_fill);
|
_cairo_in_fill_fini (&in_fill);
|
||||||
|
|
||||||
|
return is_inside;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1140,13 +1140,13 @@ _cairo_stroker_close_path (void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path,
|
_cairo_path_fixed_stroke_rectilinear (const cairo_path_fixed_t *path,
|
||||||
cairo_stroke_style_t *stroke_style,
|
cairo_stroke_style_t *stroke_style,
|
||||||
const cairo_matrix_t *ctm,
|
const cairo_matrix_t *ctm,
|
||||||
cairo_traps_t *traps);
|
cairo_traps_t *traps);
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
_cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path,
|
||||||
cairo_stroke_style_t *stroke_style,
|
cairo_stroke_style_t *stroke_style,
|
||||||
const cairo_matrix_t *ctm,
|
const cairo_matrix_t *ctm,
|
||||||
const cairo_matrix_t *ctm_inverse,
|
const cairo_matrix_t *ctm_inverse,
|
||||||
|
|
@ -1737,7 +1737,7 @@ _cairo_rectilinear_stroker_close_path (void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path,
|
_cairo_path_fixed_stroke_rectilinear (const cairo_path_fixed_t *path,
|
||||||
cairo_stroke_style_t *stroke_style,
|
cairo_stroke_style_t *stroke_style,
|
||||||
const cairo_matrix_t *ctm,
|
const cairo_matrix_t *ctm,
|
||||||
cairo_traps_t *traps)
|
cairo_traps_t *traps)
|
||||||
|
|
@ -1755,7 +1755,7 @@ _cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path,
|
||||||
* UNSUPPORTED from _cairo_rectilinear_stroker_line_to if any
|
* UNSUPPORTED from _cairo_rectilinear_stroker_line_to if any
|
||||||
* non-rectilinear line_to is encountered.
|
* non-rectilinear line_to is encountered.
|
||||||
*/
|
*/
|
||||||
if (path->has_curve_to)
|
if (! path->is_rectilinear)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER)
|
if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
|
||||||
|
|
@ -1686,10 +1686,6 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt
|
||||||
pattern,
|
pattern,
|
||||||
dst))
|
dst))
|
||||||
{
|
{
|
||||||
status = _cairo_surface_reset (solid_surface_cache.cache[i].surface);
|
|
||||||
if (unlikely (status))
|
|
||||||
goto UNLOCK;
|
|
||||||
|
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1698,10 +1694,6 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt
|
||||||
pattern,
|
pattern,
|
||||||
dst))
|
dst))
|
||||||
{
|
{
|
||||||
status = _cairo_surface_reset (solid_surface_cache.cache[i].surface);
|
|
||||||
if (unlikely (status))
|
|
||||||
goto UNLOCK;
|
|
||||||
|
|
||||||
goto DONE;
|
goto DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1717,11 +1709,6 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt
|
||||||
dst))
|
dst))
|
||||||
{
|
{
|
||||||
/* Reuse the surface instead of evicting */
|
/* Reuse the surface instead of evicting */
|
||||||
|
|
||||||
status = _cairo_surface_reset (surface);
|
|
||||||
if (unlikely (status))
|
|
||||||
goto EVICT;
|
|
||||||
|
|
||||||
status = _cairo_surface_repaint_solid_pattern_surface (dst, surface, pattern);
|
status = _cairo_surface_repaint_solid_pattern_surface (dst, surface, pattern);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto EVICT;
|
goto EVICT;
|
||||||
|
|
@ -1738,14 +1725,21 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt
|
||||||
if (surface == NULL) {
|
if (surface == NULL) {
|
||||||
/* Not cached, need to create new */
|
/* Not cached, need to create new */
|
||||||
surface = _cairo_surface_create_solid_pattern_surface (dst, pattern);
|
surface = _cairo_surface_create_solid_pattern_surface (dst, pattern);
|
||||||
if (surface->status) {
|
if (surface == NULL) {
|
||||||
|
status = CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
goto UNLOCK;
|
||||||
|
}
|
||||||
|
if (unlikely (surface->status)) {
|
||||||
status = surface->status;
|
status = surface->status;
|
||||||
goto UNLOCK;
|
goto UNLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! _cairo_surface_is_similar (surface, dst, pattern->content)) {
|
if (unlikely (! _cairo_surface_is_similar (surface,
|
||||||
/* in the rare event of a substitute surface being returned (e.g.
|
dst, pattern->content)))
|
||||||
* malloc failure) don't cache the fallback surface */
|
{
|
||||||
|
/* In the rare event of a substitute surface being returned,
|
||||||
|
* don't cache the fallback.
|
||||||
|
*/
|
||||||
*out = surface;
|
*out = surface;
|
||||||
goto NOCACHE;
|
goto NOCACHE;
|
||||||
}
|
}
|
||||||
|
|
@ -1953,6 +1947,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||||
double pad;
|
double pad;
|
||||||
cairo_bool_t is_identity;
|
cairo_bool_t is_identity;
|
||||||
cairo_bool_t is_empty;
|
cairo_bool_t is_empty;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
|
||||||
surface = cairo_surface_reference (pattern->surface);
|
surface = cairo_surface_reference (pattern->surface);
|
||||||
|
|
@ -2010,9 +2005,8 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||||
cairo_surface_t *src;
|
cairo_surface_t *src;
|
||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (surface, &extents);
|
is_bounded = _cairo_surface_get_extents (surface, &extents);
|
||||||
if (unlikely (status))
|
assert (is_bounded);
|
||||||
goto BAIL;
|
|
||||||
|
|
||||||
status = _cairo_surface_clone_similar (dst, surface, content,
|
status = _cairo_surface_clone_similar (dst, surface, content,
|
||||||
extents.x, extents.y,
|
extents.x, extents.y,
|
||||||
|
|
@ -2045,8 +2039,13 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_destroy (surface);
|
cairo_surface_destroy (surface);
|
||||||
surface = cairo_surface_create_similar (dst, dst->content, w, h);
|
surface = _cairo_surface_create_similar_solid (dst,
|
||||||
if (surface->status) {
|
dst->content, w, h,
|
||||||
|
CAIRO_COLOR_TRANSPARENT,
|
||||||
|
FALSE);
|
||||||
|
if (surface == NULL)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
if (unlikely (surface->status)) {
|
||||||
cairo_surface_destroy (src);
|
cairo_surface_destroy (src);
|
||||||
return surface->status;
|
return surface->status;
|
||||||
}
|
}
|
||||||
|
|
@ -2092,10 +2091,6 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||||
attr->extend = CAIRO_EXTEND_REPEAT;
|
attr->extend = CAIRO_EXTEND_REPEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (surface, &extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
goto BAIL;
|
|
||||||
|
|
||||||
/* We first transform the rectangle to the coordinate space of the
|
/* We first transform the rectangle to the coordinate space of the
|
||||||
* source surface so that we only need to clone that portion of the
|
* source surface so that we only need to clone that portion of the
|
||||||
* surface that will be read.
|
* surface that will be read.
|
||||||
|
|
@ -2118,36 +2113,38 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||||
sampled_area.x += tx;
|
sampled_area.x += tx;
|
||||||
sampled_area.y += ty;
|
sampled_area.y += ty;
|
||||||
|
|
||||||
if (attr->extend != CAIRO_EXTEND_REPEAT) {
|
if ( _cairo_surface_get_extents (surface, &extents)) {
|
||||||
/* Never acquire a larger area than the source itself */
|
if (attr->extend != CAIRO_EXTEND_REPEAT) {
|
||||||
is_empty = _cairo_rectangle_intersect (&extents, &sampled_area);
|
/* Never acquire a larger area than the source itself */
|
||||||
} else {
|
is_empty = _cairo_rectangle_intersect (&extents, &sampled_area);
|
||||||
int trim = 0;
|
} else {
|
||||||
|
int trim = 0;
|
||||||
|
|
||||||
if (sampled_area.x >= extents.x &&
|
if (sampled_area.x >= extents.x &&
|
||||||
sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width)
|
sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width)
|
||||||
{
|
{
|
||||||
/* source is horizontally contained within extents, trim */
|
/* source is horizontally contained within extents, trim */
|
||||||
extents.x = sampled_area.x;
|
extents.x = sampled_area.x;
|
||||||
extents.width = sampled_area.width;
|
extents.width = sampled_area.width;
|
||||||
trim |= 0x1;
|
trim |= 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sampled_area.y >= extents.y &&
|
||||||
|
sampled_area.y + (int) sampled_area.height <= extents.y + (int) extents.height)
|
||||||
|
{
|
||||||
|
/* source is vertically contained within extents, trim */
|
||||||
|
extents.y = sampled_area.y;
|
||||||
|
extents.height = sampled_area.height;
|
||||||
|
trim |= 0x2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trim == 0x3) {
|
||||||
|
/* source is wholly contained within extents, drop the REPEAT */
|
||||||
|
attr->extend = CAIRO_EXTEND_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_empty = extents.width == 0 || extents.height == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sampled_area.y >= extents.y &&
|
|
||||||
sampled_area.y + (int) sampled_area.height <= extents.y + (int) extents.height)
|
|
||||||
{
|
|
||||||
/* source is vertically contained within extents, trim */
|
|
||||||
extents.y = sampled_area.y;
|
|
||||||
extents.height = sampled_area.height;
|
|
||||||
trim |= 0x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trim == 0x3) {
|
|
||||||
/* source is wholly contained within extents, drop the REPEAT */
|
|
||||||
attr->extend = CAIRO_EXTEND_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
is_empty = extents.width == 0 || extents.height == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX can we use is_empty? */
|
/* XXX can we use is_empty? */
|
||||||
|
|
@ -2237,7 +2234,7 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
if (pattern->status) {
|
if (unlikely (pattern->status)) {
|
||||||
*surface_out = NULL;
|
*surface_out = NULL;
|
||||||
return pattern->status;
|
return pattern->status;
|
||||||
}
|
}
|
||||||
|
|
@ -2371,9 +2368,9 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
cairo_pattern_union_t src_tmp;
|
cairo_pattern_union_t src_tmp;
|
||||||
|
|
||||||
if (src->status)
|
if (unlikely (src->status))
|
||||||
return src->status;
|
return src->status;
|
||||||
if (mask && mask->status)
|
if (unlikely (mask != NULL && mask->status))
|
||||||
return mask->status;
|
return mask->status;
|
||||||
|
|
||||||
/* If src and mask are both solid, then the mask alpha can be
|
/* If src and mask are both solid, then the mask alpha can be
|
||||||
|
|
@ -2441,7 +2438,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
|
||||||
* "infinite" extents, though it would be possible to optimize these
|
* "infinite" extents, though it would be possible to optimize these
|
||||||
* with a little more work.
|
* with a little more work.
|
||||||
**/
|
**/
|
||||||
cairo_status_t
|
void
|
||||||
_cairo_pattern_get_extents (const cairo_pattern_t *pattern,
|
_cairo_pattern_get_extents (const cairo_pattern_t *pattern,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
|
|
@ -2457,11 +2454,8 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
|
||||||
double x1, y1, x2, y2;
|
double x1, y1, x2, y2;
|
||||||
double pad;
|
double pad;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (surface, &surface_extents);
|
if (! _cairo_surface_get_extents (surface, &surface_extents))
|
||||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
|
|
||||||
goto UNBOUNDED;
|
goto UNBOUNDED;
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
/* The filter can effectively enlarge the extents of the
|
/* The filter can effectively enlarge the extents of the
|
||||||
* pattern, so extend as necessary.
|
* pattern, so extend as necessary.
|
||||||
|
|
@ -2497,8 +2491,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
|
||||||
|
|
||||||
extents->x = x1; extents->width = x2 - x1;
|
extents->x = x1; extents->width = x2 - x1;
|
||||||
extents->y = y1; extents->height = y2 - y1;
|
extents->y = y1; extents->height = y2 - y1;
|
||||||
|
return;
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: We could optimize gradients with pattern->extend of NONE
|
/* XXX: We could optimize gradients with pattern->extend of NONE
|
||||||
|
|
@ -2508,12 +2501,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern,
|
||||||
|
|
||||||
UNBOUNDED:
|
UNBOUNDED:
|
||||||
/* unbounded patterns -> 'infinite' extents */
|
/* unbounded patterns -> 'infinite' extents */
|
||||||
extents->x = CAIRO_RECT_INT_MIN;
|
_cairo_unbounded_rectangle_init (extents);
|
||||||
extents->y = CAIRO_RECT_INT_MIN;
|
|
||||||
extents->width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
|
||||||
extents->height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2749,6 +2737,9 @@ _cairo_pattern_equal (const cairo_pattern_t *a, const cairo_pattern_t *b)
|
||||||
if (a->status || b->status)
|
if (a->status || b->status)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (a == b)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (a->type != b->type)
|
if (a->type != b->type)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@
|
||||||
#include "cairo-pdf.h"
|
#include "cairo-pdf.h"
|
||||||
|
|
||||||
#include "cairo-surface-private.h"
|
#include "cairo-surface-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
#include "cairo-pdf-operators-private.h"
|
#include "cairo-pdf-operators-private.h"
|
||||||
#include "cairo-path-fixed-private.h"
|
#include "cairo-path-fixed-private.h"
|
||||||
|
|
||||||
|
|
@ -174,6 +175,8 @@ struct _cairo_pdf_surface {
|
||||||
cairo_bool_t is_knockout;
|
cairo_bool_t is_knockout;
|
||||||
} group_stream;
|
} group_stream;
|
||||||
|
|
||||||
|
cairo_surface_clipper_t clipper;
|
||||||
|
|
||||||
cairo_pdf_operators_t pdf_operators;
|
cairo_pdf_operators_t pdf_operators;
|
||||||
cairo_paginated_mode_t paginated_mode;
|
cairo_paginated_mode_t paginated_mode;
|
||||||
cairo_bool_t select_pattern_gstate_saved;
|
cairo_bool_t select_pattern_gstate_saved;
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
#include "cairo-output-stream-private.h"
|
#include "cairo-output-stream-private.h"
|
||||||
#include "cairo-paginated-private.h"
|
#include "cairo-paginated-private.h"
|
||||||
#include "cairo-scaled-font-subsets-private.h"
|
#include "cairo-scaled-font-subsets-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
#include "cairo-type3-glyph-surface-private.h"
|
#include "cairo-type3-glyph-surface-private.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
@ -243,6 +244,34 @@ _cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface,
|
||||||
&surface->cairo_to_pdf);
|
&surface->cairo_to_pdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_pdf_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias)
|
||||||
|
{
|
||||||
|
cairo_pdf_surface_t *surface = cairo_container_of (clipper,
|
||||||
|
cairo_pdf_surface_t,
|
||||||
|
clipper);
|
||||||
|
cairo_int_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (path == NULL) {
|
||||||
|
_cairo_output_stream_printf (surface->output, "Q q\n");
|
||||||
|
|
||||||
|
surface->current_pattern_is_solid_color = FALSE;
|
||||||
|
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cairo_pdf_operators_clip (&surface->pdf_operators, path, fill_rule);
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
||||||
double width,
|
double width,
|
||||||
|
|
@ -313,6 +342,9 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
||||||
surface->current_operator = CAIRO_OPERATOR_OVER;
|
surface->current_operator = CAIRO_OPERATOR_OVER;
|
||||||
surface->header_emitted = FALSE;
|
surface->header_emitted = FALSE;
|
||||||
|
|
||||||
|
_cairo_surface_clipper_init (&surface->clipper,
|
||||||
|
_cairo_pdf_surface_clipper_intersect_clip_path);
|
||||||
|
|
||||||
_cairo_pdf_operators_init (&surface->pdf_operators,
|
_cairo_pdf_operators_init (&surface->pdf_operators,
|
||||||
surface->output,
|
surface->output,
|
||||||
&surface->cairo_to_pdf,
|
&surface->cairo_to_pdf,
|
||||||
|
|
@ -325,7 +357,6 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
||||||
surface->paginated_surface = _cairo_paginated_surface_create (
|
surface->paginated_surface = _cairo_paginated_surface_create (
|
||||||
&surface->base,
|
&surface->base,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA,
|
CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
width, height,
|
|
||||||
&cairo_pdf_surface_paginated_backend);
|
&cairo_pdf_surface_paginated_backend);
|
||||||
|
|
||||||
status = surface->paginated_surface->status;
|
status = surface->paginated_surface->status;
|
||||||
|
|
@ -572,11 +603,6 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface,
|
||||||
_cairo_pdf_surface_set_size_internal (pdf_surface,
|
_cairo_pdf_surface_set_size_internal (pdf_surface,
|
||||||
width_in_points,
|
width_in_points,
|
||||||
height_in_points);
|
height_in_points);
|
||||||
status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface,
|
|
||||||
width_in_points,
|
|
||||||
height_in_points);
|
|
||||||
if (unlikely (status))
|
|
||||||
status = _cairo_surface_set_error (surface, status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -981,9 +1007,9 @@ _get_jpx_image_info (cairo_surface_t *source,
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_get_jpeg_image_info (cairo_surface_t *source,
|
_get_jpeg_image_info (cairo_surface_t *source,
|
||||||
cairo_image_info_t *info,
|
cairo_image_info_t *info,
|
||||||
const unsigned char **mime_data,
|
const unsigned char **mime_data,
|
||||||
unsigned int *mime_data_length)
|
unsigned int *mime_data_length)
|
||||||
{
|
{
|
||||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
|
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
|
||||||
mime_data, mime_data_length);
|
mime_data, mime_data_length);
|
||||||
|
|
@ -998,52 +1024,48 @@ _get_source_surface_size (cairo_surface_t *source,
|
||||||
int *width,
|
int *width,
|
||||||
int *height)
|
int *height)
|
||||||
{
|
{
|
||||||
cairo_image_surface_t *image;
|
|
||||||
void *image_extra;
|
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
cairo_image_info_t info;
|
cairo_image_info_t info;
|
||||||
const unsigned char *mime_data;
|
const unsigned char *mime_data;
|
||||||
unsigned int mime_data_length;
|
unsigned int mime_data_length;
|
||||||
|
|
||||||
if (_cairo_surface_is_meta (source)) {
|
if (_cairo_surface_is_meta (source)) {
|
||||||
cairo_rectangle_int_t extents;
|
cairo_meta_surface_t *meta_surface = (cairo_meta_surface_t *) source;
|
||||||
|
cairo_box_t bbox;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (source, &extents);
|
status = _cairo_meta_surface_get_bbox (meta_surface, &bbox, NULL);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
_cairo_box_round_to_rectangle (&bbox, &extents);
|
||||||
|
|
||||||
*width = extents.width;
|
*width = extents.width;
|
||||||
*height = extents.height;
|
*height = extents.height;
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length);
|
status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length);
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||||
*width = info.width;
|
*width = info.width;
|
||||||
*height = info.height;
|
*height = info.height;
|
||||||
} else if (_cairo_status_is_error (status)) {
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length);
|
status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length);
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||||
*width = info.width;
|
*width = info.width;
|
||||||
*height = info.height;
|
*height = info.height;
|
||||||
} else if (_cairo_status_is_error (status)) {
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _cairo_surface_acquire_source_image (source, &image, &image_extra);
|
if (! _cairo_surface_get_extents (source, &extents))
|
||||||
if (unlikely (status))
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
return status;
|
|
||||||
|
|
||||||
*width = image->width;
|
*width = extents.width;
|
||||||
*height = image->height;
|
*height = extents.height;
|
||||||
|
|
||||||
_cairo_surface_release_source_image (source, image, image_extra);
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
|
|
@ -1123,7 +1145,7 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
|
_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
|
||||||
const cairo_pattern_t *pattern,
|
const cairo_pattern_t *pattern,
|
||||||
cairo_rectangle_int_t *extents,
|
cairo_clip_t *clip,
|
||||||
cairo_pdf_resource_t *pattern_res,
|
cairo_pdf_resource_t *pattern_res,
|
||||||
cairo_pdf_resource_t *gstate_res)
|
cairo_pdf_resource_t *gstate_res)
|
||||||
{
|
{
|
||||||
|
|
@ -1182,8 +1204,8 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
|
||||||
|
|
||||||
pdf_pattern.width = surface->width;
|
pdf_pattern.width = surface->width;
|
||||||
pdf_pattern.height = surface->height;
|
pdf_pattern.height = surface->height;
|
||||||
if (extents) {
|
if (clip != NULL) {
|
||||||
pdf_pattern.extents = *extents;
|
pdf_pattern.extents = clip->path->extents;
|
||||||
} else {
|
} else {
|
||||||
pdf_pattern.extents.x = 0;
|
pdf_pattern.extents.x = 0;
|
||||||
pdf_pattern.extents.y = 0;
|
pdf_pattern.extents.y = 0;
|
||||||
|
|
@ -1540,15 +1562,6 @@ _cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface)
|
||||||
return _cairo_output_stream_get_status (surface->output);
|
return _cairo_output_stream_get_status (surface->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
|
||||||
_cairo_pdf_surface_create_similar (void *abstract_surface,
|
|
||||||
cairo_content_t content,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
return cairo_meta_surface_create (content, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cairo_pdf_source_surface_entry_pluck (void *entry, void *closure)
|
_cairo_pdf_source_surface_entry_pluck (void *entry, void *closure)
|
||||||
{
|
{
|
||||||
|
|
@ -1653,6 +1666,8 @@ _cairo_pdf_surface_finish (void *abstract_surface)
|
||||||
surface->font_subsets = NULL;
|
surface->font_subsets = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2090,7 +2105,7 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
pad_image = &image->base;
|
pad_image = &image->base;
|
||||||
if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD) {
|
if (pattern->base.extend == CAIRO_EXTEND_PAD) {
|
||||||
cairo_box_t box;
|
cairo_box_t box;
|
||||||
cairo_rectangle_int_t rect;
|
cairo_rectangle_int_t rect;
|
||||||
cairo_surface_pattern_t pad_pattern;
|
cairo_surface_pattern_t pad_pattern;
|
||||||
|
|
@ -2121,7 +2136,8 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height);
|
rect.height,
|
||||||
|
NULL);
|
||||||
_cairo_pattern_fini (&pad_pattern.base);
|
_cairo_pattern_fini (&pad_pattern.base);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
|
|
@ -2173,19 +2189,18 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
|
||||||
{
|
{
|
||||||
double old_width, old_height;
|
double old_width, old_height;
|
||||||
cairo_paginated_mode_t old_paginated_mode;
|
cairo_paginated_mode_t old_paginated_mode;
|
||||||
cairo_clip_t *old_clip;
|
|
||||||
cairo_rectangle_int_t meta_extents;
|
cairo_rectangle_int_t meta_extents;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
int alpha = 0;
|
int alpha = 0;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
|
is_bounded = _cairo_surface_get_extents (meta_surface, &meta_extents);
|
||||||
if (unlikely (status))
|
assert (is_bounded);
|
||||||
return status;
|
|
||||||
|
|
||||||
old_width = surface->width;
|
old_width = surface->width;
|
||||||
old_height = surface->height;
|
old_height = surface->height;
|
||||||
old_paginated_mode = surface->paginated_mode;
|
old_paginated_mode = surface->paginated_mode;
|
||||||
old_clip = _cairo_surface_get_clip (&surface->base);
|
|
||||||
_cairo_pdf_surface_set_size_internal (surface,
|
_cairo_pdf_surface_set_size_internal (surface,
|
||||||
meta_extents.width,
|
meta_extents.width,
|
||||||
meta_extents.height);
|
meta_extents.height);
|
||||||
|
|
@ -2217,10 +2232,6 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = _cairo_surface_set_clip (&surface->base, old_clip);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
status = _cairo_pdf_surface_close_content_stream (surface);
|
status = _cairo_pdf_surface_close_content_stream (surface);
|
||||||
|
|
||||||
_cairo_pdf_surface_set_size_internal (surface,
|
_cairo_pdf_surface_set_size_internal (surface,
|
||||||
|
|
@ -2264,7 +2275,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
||||||
int bbox_x, bbox_y;
|
int bbox_x, bbox_y;
|
||||||
char draw_surface[200];
|
char draw_surface[200];
|
||||||
|
|
||||||
if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD &&
|
if (pattern->base.extend == CAIRO_EXTEND_PAD &&
|
||||||
! _cairo_surface_is_meta (pattern->surface))
|
! _cairo_surface_is_meta (pattern->surface))
|
||||||
{
|
{
|
||||||
status = _cairo_pdf_surface_emit_padded_image_surface (surface,
|
status = _cairo_pdf_surface_emit_padded_image_surface (surface,
|
||||||
|
|
@ -3249,7 +3260,7 @@ _cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->output,
|
_cairo_output_stream_printf (surface->output,
|
||||||
|
|
@ -3405,7 +3416,7 @@ _cairo_pdf_surface_show_page (void *abstract_surface)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_pdf_surface_get_extents (void *abstract_surface,
|
_cairo_pdf_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -3421,32 +3432,7 @@ _cairo_pdf_surface_get_extents (void *abstract_surface,
|
||||||
rectangle->width = (int) ceil (surface->width);
|
rectangle->width = (int) ceil (surface->width);
|
||||||
rectangle->height = (int) ceil (surface->height);
|
rectangle->height = (int) ceil (surface->height);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_pdf_surface_intersect_clip_path (void *abstract_surface,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias)
|
|
||||||
{
|
|
||||||
cairo_pdf_surface_t *surface = abstract_surface;
|
|
||||||
cairo_int_status_t status;
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->output, "Q q\n");
|
|
||||||
surface->current_pattern_is_solid_color = FALSE;
|
|
||||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _cairo_pdf_operators_clip (&surface->pdf_operators, path, fill_rule);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -5227,7 +5213,7 @@ static cairo_int_status_t
|
||||||
_cairo_pdf_surface_paint (void *abstract_surface,
|
_cairo_pdf_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_pdf_surface_t *surface = abstract_surface;
|
cairo_pdf_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -5244,17 +5230,21 @@ _cairo_pdf_surface_paint (void *abstract_surface,
|
||||||
|
|
||||||
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
pattern_res.id = 0;
|
pattern_res.id = 0;
|
||||||
gstate_res.id = 0;
|
gstate_res.id = 0;
|
||||||
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
|
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip,
|
||||||
&pattern_res, &gstate_res);
|
&pattern_res, &gstate_res);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = _cairo_pdf_surface_select_operator (surface, op);
|
status = _cairo_pdf_surface_select_operator (surface, op);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (gstate_res.id != 0) {
|
if (gstate_res.id != 0) {
|
||||||
|
|
@ -5292,7 +5282,8 @@ _cairo_pdf_surface_paint (void *abstract_surface,
|
||||||
gstate_res.id,
|
gstate_res.id,
|
||||||
group->group_res.id);
|
group->group_res.id);
|
||||||
} else {
|
} else {
|
||||||
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
|
status = _cairo_pdf_surface_select_pattern (surface, source,
|
||||||
|
pattern_res, FALSE);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -5313,7 +5304,7 @@ _cairo_pdf_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_pdf_surface_t *surface = abstract_surface;
|
cairo_pdf_surface_t *surface = abstract_surface;
|
||||||
cairo_pdf_smask_group_t *group;
|
cairo_pdf_smask_group_t *group;
|
||||||
|
|
@ -5341,6 +5332,10 @@ _cairo_pdf_surface_mask (void *abstract_surface,
|
||||||
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
||||||
assert (_cairo_pdf_surface_operation_supported (surface, op, mask));
|
assert (_cairo_pdf_surface_operation_supported (surface, op, mask));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
group = _cairo_pdf_surface_create_smask_group (surface);
|
group = _cairo_pdf_surface_create_smask_group (surface);
|
||||||
if (unlikely (group == NULL))
|
if (unlikely (group == NULL))
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
@ -5381,7 +5376,7 @@ _cairo_pdf_surface_mask (void *abstract_surface,
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = _cairo_pdf_surface_select_operator (surface, op);
|
status = _cairo_pdf_surface_select_operator (surface, op);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->output,
|
_cairo_output_stream_printf (surface->output,
|
||||||
|
|
@ -5402,7 +5397,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_pdf_surface_t *surface = abstract_surface;
|
cairo_pdf_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -5414,17 +5409,21 @@ _cairo_pdf_surface_stroke (void *abstract_surface,
|
||||||
|
|
||||||
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
pattern_res.id = 0;
|
pattern_res.id = 0;
|
||||||
gstate_res.id = 0;
|
gstate_res.id = 0;
|
||||||
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
|
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip,
|
||||||
&pattern_res, &gstate_res);
|
&pattern_res, &gstate_res);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = _cairo_pdf_surface_select_operator (surface, op);
|
status = _cairo_pdf_surface_select_operator (surface, op);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (gstate_res.id != 0) {
|
if (gstate_res.id != 0) {
|
||||||
|
|
@ -5499,7 +5498,7 @@ _cairo_pdf_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_pdf_surface_t *surface = abstract_surface;
|
cairo_pdf_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -5516,17 +5515,21 @@ _cairo_pdf_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
pattern_res.id = 0;
|
pattern_res.id = 0;
|
||||||
gstate_res.id = 0;
|
gstate_res.id = 0;
|
||||||
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
|
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip,
|
||||||
&pattern_res, &gstate_res);
|
&pattern_res, &gstate_res);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = _cairo_pdf_surface_select_operator (surface, op);
|
status = _cairo_pdf_surface_select_operator (surface, op);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (gstate_res.id != 0) {
|
if (gstate_res.id != 0) {
|
||||||
|
|
@ -5604,7 +5607,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *stroke_ctm_inverse,
|
cairo_matrix_t *stroke_ctm_inverse,
|
||||||
double stroke_tolerance,
|
double stroke_tolerance,
|
||||||
cairo_antialias_t stroke_antialias,
|
cairo_antialias_t stroke_antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_pdf_surface_t *surface = abstract_surface;
|
cairo_pdf_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -5632,14 +5635,18 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
|
||||||
if (fill_op != stroke_op)
|
if (fill_op != stroke_op)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
status = _cairo_pdf_surface_select_operator (surface, fill_op);
|
status = _cairo_pdf_surface_select_operator (surface, fill_op);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
fill_pattern_res.id = 0;
|
fill_pattern_res.id = 0;
|
||||||
gstate_res.id = 0;
|
gstate_res.id = 0;
|
||||||
status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
|
status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
|
||||||
extents,
|
clip,
|
||||||
&fill_pattern_res,
|
&fill_pattern_res,
|
||||||
&gstate_res);
|
&gstate_res);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -5651,7 +5658,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface,
|
||||||
gstate_res.id = 0;
|
gstate_res.id = 0;
|
||||||
status = _cairo_pdf_surface_add_pdf_pattern (surface,
|
status = _cairo_pdf_surface_add_pdf_pattern (surface,
|
||||||
stroke_source,
|
stroke_source,
|
||||||
extents,
|
clip,
|
||||||
&stroke_pattern_res,
|
&stroke_pattern_res,
|
||||||
&gstate_res);
|
&gstate_res);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -5705,7 +5712,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_pdf_surface_t *surface = abstract_surface;
|
cairo_pdf_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -5717,17 +5724,21 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
|
||||||
|
|
||||||
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
assert (_cairo_pdf_surface_operation_supported (surface, op, source));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
pattern_res.id = 0;
|
pattern_res.id = 0;
|
||||||
gstate_res.id = 0;
|
gstate_res.id = 0;
|
||||||
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, extents,
|
status = _cairo_pdf_surface_add_pdf_pattern (surface, source, clip,
|
||||||
&pattern_res, &gstate_res);
|
&pattern_res, &gstate_res);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = _cairo_pdf_surface_select_operator (surface, op);
|
status = _cairo_pdf_surface_select_operator (surface, op);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (gstate_res.id != 0) {
|
if (gstate_res.id != 0) {
|
||||||
|
|
@ -5840,7 +5851,7 @@ _cairo_pdf_surface_set_paginated_mode (void *abstract_surface,
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
||||||
CAIRO_SURFACE_TYPE_PDF,
|
CAIRO_SURFACE_TYPE_PDF,
|
||||||
_cairo_pdf_surface_create_similar,
|
NULL, /* create similar: handled by wrapper */
|
||||||
_cairo_pdf_surface_finish,
|
_cairo_pdf_surface_finish,
|
||||||
NULL, /* acquire_source_image */
|
NULL, /* acquire_source_image */
|
||||||
NULL, /* release_source_image */
|
NULL, /* release_source_image */
|
||||||
|
|
@ -5854,8 +5865,6 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* _cairo_pdf_surface_copy_page */
|
NULL, /* _cairo_pdf_surface_copy_page */
|
||||||
_cairo_pdf_surface_show_page,
|
_cairo_pdf_surface_show_page,
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_pdf_surface_intersect_clip_path,
|
|
||||||
_cairo_pdf_surface_get_extents,
|
_cairo_pdf_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
_cairo_pdf_surface_get_font_options,
|
_cairo_pdf_surface_get_font_options,
|
||||||
|
|
@ -5874,7 +5883,6 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = {
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
|
|
||||||
NULL, /* is_compatible */
|
NULL, /* is_compatible */
|
||||||
NULL, /* reset */
|
|
||||||
_cairo_pdf_surface_fill_stroke,
|
_cairo_pdf_surface_fill_stroke,
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "cairo-ps.h"
|
#include "cairo-ps.h"
|
||||||
|
|
||||||
#include "cairo-surface-private.h"
|
#include "cairo-surface-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
#include "cairo-pdf-operators-private.h"
|
#include "cairo-pdf-operators-private.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
@ -65,6 +66,7 @@ typedef struct cairo_ps_surface {
|
||||||
cairo_content_t content;
|
cairo_content_t content;
|
||||||
double width;
|
double width;
|
||||||
double height;
|
double height;
|
||||||
|
cairo_rectangle_int_t page_bbox;
|
||||||
int bbox_x1, bbox_y1, bbox_x2, bbox_y2;
|
int bbox_x1, bbox_y1, bbox_x2, bbox_y2;
|
||||||
cairo_matrix_t cairo_to_ps;
|
cairo_matrix_t cairo_to_ps;
|
||||||
|
|
||||||
|
|
@ -97,6 +99,8 @@ typedef struct cairo_ps_surface {
|
||||||
cairo_ps_level_t ps_level;
|
cairo_ps_level_t ps_level;
|
||||||
cairo_ps_level_t ps_level_used;
|
cairo_ps_level_t ps_level_used;
|
||||||
|
|
||||||
|
cairo_surface_clipper_t clipper;
|
||||||
|
|
||||||
cairo_pdf_operators_t pdf_operators;
|
cairo_pdf_operators_t pdf_operators;
|
||||||
cairo_surface_t *paginated_surface;
|
cairo_surface_t *paginated_surface;
|
||||||
} cairo_ps_surface_t;
|
} cairo_ps_surface_t;
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@
|
||||||
#include "cairo-scaled-font-subsets-private.h"
|
#include "cairo-scaled-font-subsets-private.h"
|
||||||
#include "cairo-paginated-private.h"
|
#include "cairo-paginated-private.h"
|
||||||
#include "cairo-meta-surface-private.h"
|
#include "cairo-meta-surface-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
#include "cairo-output-stream-private.h"
|
#include "cairo-output-stream-private.h"
|
||||||
#include "cairo-type3-glyph-surface-private.h"
|
#include "cairo-type3-glyph-surface-private.h"
|
||||||
#include "cairo-image-info-private.h"
|
#include "cairo-image-info-private.h"
|
||||||
|
|
@ -73,6 +74,13 @@
|
||||||
|
|
||||||
#define DEBUG_PS 0
|
#define DEBUG_PS 0
|
||||||
|
|
||||||
|
#if DEBUG_PS
|
||||||
|
#define DEBUG_FALLBACK(s) \
|
||||||
|
fprintf (stderr, "%s::%d -- %s\n", __FUNCTION__, __LINE__, (s))
|
||||||
|
#else
|
||||||
|
#define DEBUG_FALLBACK(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_CTIME_R
|
#ifndef HAVE_CTIME_R
|
||||||
#define ctime_r(T, BUF) ctime (T)
|
#define ctime_r(T, BUF) ctime (T)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -700,6 +708,74 @@ _cairo_ps_surface_emit_footer (cairo_ps_surface_t *surface)
|
||||||
"%%%%EOF\n");
|
"%%%%EOF\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
_path_covers_bbox (cairo_ps_surface_t *surface,
|
||||||
|
cairo_path_fixed_t *path)
|
||||||
|
{
|
||||||
|
cairo_box_t box;
|
||||||
|
|
||||||
|
if (_cairo_path_fixed_is_rectangle (path, &box)) {
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
_cairo_box_round_to_rectangle (&box, &rect);
|
||||||
|
|
||||||
|
/* skip trivial whole-page clips */
|
||||||
|
if (_cairo_rectangle_intersect (&rect, &surface->page_bbox)) {
|
||||||
|
if (rect.x == surface->page_bbox.x &&
|
||||||
|
rect.width == surface->page_bbox.width &&
|
||||||
|
rect.y == surface->page_bbox.y &&
|
||||||
|
rect.height == surface->page_bbox.height)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_ps_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias)
|
||||||
|
{
|
||||||
|
cairo_ps_surface_t *surface = cairo_container_of (clipper,
|
||||||
|
cairo_ps_surface_t,
|
||||||
|
clipper);
|
||||||
|
cairo_output_stream_t *stream = surface->stream;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
assert (surface->paginated_mode != CAIRO_PAGINATED_MODE_ANALYZE);
|
||||||
|
|
||||||
|
#if DEBUG_PS
|
||||||
|
_cairo_output_stream_printf (stream,
|
||||||
|
"%% _cairo_ps_surface_intersect_clip_path\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (path == NULL) {
|
||||||
|
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
_cairo_output_stream_printf (stream, "Q q\n");
|
||||||
|
|
||||||
|
surface->current_pattern_is_solid_color = FALSE;
|
||||||
|
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_path_covers_bbox (surface, path))
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
return _cairo_pdf_operators_clip (&surface->pdf_operators,
|
||||||
|
path,
|
||||||
|
fill_rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
_cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
||||||
double width,
|
double width,
|
||||||
|
|
@ -756,6 +832,9 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
||||||
surface->use_string_datasource = FALSE;
|
surface->use_string_datasource = FALSE;
|
||||||
surface->current_pattern_is_solid_color = FALSE;
|
surface->current_pattern_is_solid_color = FALSE;
|
||||||
|
|
||||||
|
_cairo_surface_clipper_init (&surface->clipper,
|
||||||
|
_cairo_ps_surface_clipper_intersect_clip_path);
|
||||||
|
|
||||||
_cairo_pdf_operators_init (&surface->pdf_operators,
|
_cairo_pdf_operators_init (&surface->pdf_operators,
|
||||||
surface->stream,
|
surface->stream,
|
||||||
&surface->cairo_to_ps,
|
&surface->cairo_to_ps,
|
||||||
|
|
@ -771,7 +850,6 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
|
||||||
surface->paginated_surface = _cairo_paginated_surface_create (
|
surface->paginated_surface = _cairo_paginated_surface_create (
|
||||||
&surface->base,
|
&surface->base,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA,
|
CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
width, height,
|
|
||||||
&cairo_ps_surface_paginated_backend);
|
&cairo_ps_surface_paginated_backend);
|
||||||
status = surface->paginated_surface->status;
|
status = surface->paginated_surface->status;
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
if (status == CAIRO_STATUS_SUCCESS) {
|
||||||
|
|
@ -1083,11 +1161,6 @@ cairo_ps_surface_set_size (cairo_surface_t *surface,
|
||||||
cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, -1, 0, height_in_points);
|
cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, -1, 0, height_in_points);
|
||||||
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&ps_surface->pdf_operators,
|
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&ps_surface->pdf_operators,
|
||||||
&ps_surface->cairo_to_ps);
|
&ps_surface->cairo_to_ps);
|
||||||
status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface,
|
|
||||||
width_in_points,
|
|
||||||
height_in_points);
|
|
||||||
if (unlikely (status))
|
|
||||||
status = _cairo_surface_set_error (surface, status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1288,15 +1361,6 @@ cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
|
||||||
_cairo_ps_surface_create_similar (void *abstract_surface,
|
|
||||||
cairo_content_t content,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
return cairo_meta_surface_create (content, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_ps_surface_finish (void *abstract_surface)
|
_cairo_ps_surface_finish (void *abstract_surface)
|
||||||
{
|
{
|
||||||
|
|
@ -1346,6 +1410,8 @@ CLEANUP:
|
||||||
free (comments[i]);
|
free (comments[i]);
|
||||||
_cairo_array_fini (&surface->dsc_page_setup_comments);
|
_cairo_array_fini (&surface->dsc_page_setup_comments);
|
||||||
|
|
||||||
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1369,8 +1435,11 @@ _cairo_ps_surface_end_page (cairo_ps_surface_t *surface)
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->stream,
|
if (surface->clipper.clip.path != NULL) {
|
||||||
"Q\n");
|
_cairo_output_stream_printf (surface->stream, "Q Q\n");
|
||||||
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
} else
|
||||||
|
_cairo_output_stream_printf (surface->stream, "Q\n");
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -1448,8 +1517,6 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
surface_pattern_supported (const cairo_surface_pattern_t *pattern)
|
surface_pattern_supported (const cairo_surface_pattern_t *pattern)
|
||||||
{
|
{
|
||||||
cairo_extend_t extend;
|
|
||||||
|
|
||||||
if (_cairo_surface_is_meta (pattern->surface))
|
if (_cairo_surface_is_meta (pattern->surface))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
@ -1465,24 +1532,7 @@ surface_pattern_supported (const cairo_surface_pattern_t *pattern)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Cast away the const, trusting get_extend not to muck with it.
|
return TRUE;
|
||||||
* And I really wish I had a way to cast away just the const, and
|
|
||||||
* not potentially coerce this pointer to an incorrect type at the
|
|
||||||
* same time. :-(
|
|
||||||
*/
|
|
||||||
extend = cairo_pattern_get_extend ((cairo_pattern_t*)&pattern->base);
|
|
||||||
switch (extend) {
|
|
||||||
case CAIRO_EXTEND_NONE:
|
|
||||||
case CAIRO_EXTEND_REPEAT:
|
|
||||||
case CAIRO_EXTEND_REFLECT:
|
|
||||||
/* There's no point returning FALSE for EXTEND_PAD, as the image
|
|
||||||
* surface does not currently implement it either */
|
|
||||||
case CAIRO_EXTEND_PAD:
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_NOT_REACHED;
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -1567,10 +1617,11 @@ _cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! pattern_supported (surface, pattern))
|
if (! pattern_supported (surface, pattern))
|
||||||
|
{
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(op == CAIRO_OPERATOR_SOURCE ||
|
if (! (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER))
|
||||||
op == CAIRO_OPERATOR_OVER))
|
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||||
|
|
@ -1596,7 +1647,6 @@ _cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface,
|
||||||
* render stage and we blend the transparency into the white
|
* render stage and we blend the transparency into the white
|
||||||
* background to convert the pattern to opaque.
|
* background to convert the pattern to opaque.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||||
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
|
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
|
||||||
|
|
||||||
|
|
@ -1606,8 +1656,8 @@ _cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface,
|
||||||
|
|
||||||
if (_cairo_pattern_is_opaque (pattern))
|
if (_cairo_pattern_is_opaque (pattern))
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
else
|
|
||||||
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -1824,7 +1874,8 @@ _cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t *surface,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
image->width,
|
image->width,
|
||||||
image->height);
|
image->height,
|
||||||
|
NULL);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
@ -2109,6 +2160,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
|
||||||
data_compressed,
|
data_compressed,
|
||||||
data_compressed_size,
|
data_compressed_size,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
_cairo_output_stream_printf (surface->stream, "\n");
|
||||||
} else {
|
} else {
|
||||||
status = CAIRO_STATUS_SUCCESS;
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -2221,31 +2273,31 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
|
||||||
double old_width, old_height;
|
double old_width, old_height;
|
||||||
cairo_matrix_t old_cairo_to_ps;
|
cairo_matrix_t old_cairo_to_ps;
|
||||||
cairo_content_t old_content;
|
cairo_content_t old_content;
|
||||||
cairo_clip_t *old_clip;
|
cairo_box_t bbox;
|
||||||
cairo_rectangle_int_t meta_extents;
|
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
old_content = surface->content;
|
old_content = surface->content;
|
||||||
old_width = surface->width;
|
old_width = surface->width;
|
||||||
old_height = surface->height;
|
old_height = surface->height;
|
||||||
old_cairo_to_ps = surface->cairo_to_ps;
|
old_cairo_to_ps = surface->cairo_to_ps;
|
||||||
old_clip = _cairo_surface_get_clip (&surface->base);
|
|
||||||
surface->width = meta_extents.width;
|
status =
|
||||||
surface->height = meta_extents.height;
|
_cairo_meta_surface_get_bbox ((cairo_meta_surface_t *) meta_surface,
|
||||||
|
&bbox,
|
||||||
|
NULL);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
/* XXX is this still necessary? */
|
||||||
|
surface->width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x);
|
||||||
|
surface->height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
|
||||||
|
|
||||||
surface->current_pattern_is_solid_color = FALSE;
|
surface->current_pattern_is_solid_color = FALSE;
|
||||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||||
cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
|
cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
|
||||||
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
|
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
|
||||||
&surface->cairo_to_ps);
|
&surface->cairo_to_ps);
|
||||||
_cairo_output_stream_printf (surface->stream,
|
_cairo_output_stream_printf (surface->stream, " q\n");
|
||||||
" q\n"
|
|
||||||
" 0 0 %f %f rectclip\n",
|
|
||||||
surface->width,
|
|
||||||
surface->height);
|
|
||||||
|
|
||||||
if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) {
|
if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) {
|
||||||
surface->content = CAIRO_CONTENT_COLOR;
|
surface->content = CAIRO_CONTENT_COLOR;
|
||||||
|
|
@ -2265,17 +2317,13 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface,
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->stream,
|
_cairo_output_stream_printf (surface->stream, " Q\n");
|
||||||
" Q\n");
|
|
||||||
surface->content = old_content;
|
surface->content = old_content;
|
||||||
surface->width = old_width;
|
surface->width = old_width;
|
||||||
surface->height = old_height;
|
surface->height = old_height;
|
||||||
surface->current_pattern_is_solid_color = FALSE;
|
surface->current_pattern_is_solid_color = FALSE;
|
||||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||||
surface->cairo_to_ps = old_cairo_to_ps;
|
surface->cairo_to_ps = old_cairo_to_ps;
|
||||||
status = _cairo_surface_set_clip (&surface->base, old_clip);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
|
_cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
|
||||||
&surface->cairo_to_ps);
|
&surface->cairo_to_ps);
|
||||||
|
|
@ -2331,11 +2379,11 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
|
||||||
cairo_rectangle_int_t *extents,
|
cairo_rectangle_int_t *extents,
|
||||||
int *width,
|
int *width,
|
||||||
int *height,
|
int *height,
|
||||||
int *origin_x,
|
int *origin_x,
|
||||||
int *origin_y)
|
int *origin_y)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_surface_t *pad_image;
|
cairo_surface_t *pad_image;
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
|
|
@ -2343,15 +2391,18 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
|
||||||
surface->image = NULL;
|
surface->image = NULL;
|
||||||
|
|
||||||
if (_cairo_surface_is_meta (pattern->surface)) {
|
if (_cairo_surface_is_meta (pattern->surface)) {
|
||||||
cairo_surface_t *meta_surface = pattern->surface;
|
cairo_meta_surface_t *meta_surface = (cairo_meta_surface_t *) pattern->surface;
|
||||||
cairo_rectangle_int_t pattern_extents;
|
cairo_box_t bbox;
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
|
status = _cairo_meta_surface_get_bbox (meta_surface, &bbox, NULL);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
*width = pattern_extents.width;
|
_cairo_box_round_to_rectangle (&bbox, &extents);
|
||||||
*height = pattern_extents.height;
|
*width = extents.width;
|
||||||
|
*height =extents.height;
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
status = _cairo_surface_acquire_source_image (pattern->surface,
|
status = _cairo_surface_acquire_source_image (pattern->surface,
|
||||||
&surface->acquired_image,
|
&surface->acquired_image,
|
||||||
|
|
@ -2391,7 +2442,8 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
rect.width,
|
rect.width,
|
||||||
rect.height);
|
rect.height,
|
||||||
|
NULL);
|
||||||
_cairo_pattern_fini (&pad_pattern.base);
|
_cairo_pattern_fini (&pad_pattern.base);
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
if (pad_image != &surface->acquired_image->base)
|
if (pad_image != &surface->acquired_image->base)
|
||||||
|
|
@ -2406,13 +2458,11 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface,
|
||||||
*height = surface->image->height;
|
*height = surface->image->height;
|
||||||
*origin_x = x;
|
*origin_x = x;
|
||||||
*origin_y = y;
|
*origin_y = y;
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
BAIL:
|
BAIL:
|
||||||
_cairo_ps_surface_release_surface (surface, pattern);
|
_cairo_ps_surface_release_surface (surface, pattern);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2428,10 +2478,9 @@ _cairo_ps_surface_emit_surface (cairo_ps_surface_t *surface,
|
||||||
if (_cairo_surface_is_meta (pattern->surface)) {
|
if (_cairo_surface_is_meta (pattern->surface)) {
|
||||||
cairo_surface_t *meta_surface = pattern->surface;
|
cairo_surface_t *meta_surface = pattern->surface;
|
||||||
|
|
||||||
status = _cairo_ps_surface_emit_meta_surface (surface,
|
status = _cairo_ps_surface_emit_meta_surface (surface, meta_surface);
|
||||||
meta_surface);
|
|
||||||
} else {
|
} else {
|
||||||
if (cairo_pattern_get_extend (&pattern->base) != CAIRO_EXTEND_PAD) {
|
if (pattern->base.extend != CAIRO_EXTEND_PAD) {
|
||||||
status = _cairo_ps_surface_emit_jpeg_image (surface, pattern->surface,
|
status = _cairo_ps_surface_emit_jpeg_image (surface, pattern->surface,
|
||||||
width, height);
|
width, height);
|
||||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||||
|
|
@ -2540,7 +2589,6 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
|
||||||
int pattern_height = 0; /* squelch bogus compiler warning */
|
int pattern_height = 0; /* squelch bogus compiler warning */
|
||||||
double xstep, ystep;
|
double xstep, ystep;
|
||||||
cairo_matrix_t cairo_p2d, ps_p2d;
|
cairo_matrix_t cairo_p2d, ps_p2d;
|
||||||
cairo_rectangle_int_t surface_extents;
|
|
||||||
cairo_bool_t old_use_string_datasource;
|
cairo_bool_t old_use_string_datasource;
|
||||||
int origin_x = 0;
|
int origin_x = 0;
|
||||||
int origin_y = 0;
|
int origin_y = 0;
|
||||||
|
|
@ -2550,12 +2598,6 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
|
||||||
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
ps_p2d = surface->cairo_to_ps;
|
|
||||||
cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
|
|
||||||
cairo_matrix_translate (&ps_p2d, -origin_x, -origin_y);
|
|
||||||
cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
|
|
||||||
cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
|
|
||||||
|
|
||||||
status = _cairo_ps_surface_acquire_surface (surface,
|
status = _cairo_ps_surface_acquire_surface (surface,
|
||||||
pattern,
|
pattern,
|
||||||
extents,
|
extents,
|
||||||
|
|
@ -2669,17 +2711,13 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface,
|
||||||
_cairo_output_stream_printf (surface->stream,
|
_cairo_output_stream_printf (surface->stream,
|
||||||
">>\n");
|
">>\n");
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &surface_extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
cairo_p2d = pattern->base.matrix;
|
cairo_p2d = pattern->base.matrix;
|
||||||
status = cairo_matrix_invert (&cairo_p2d);
|
status = cairo_matrix_invert (&cairo_p2d);
|
||||||
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
cairo_matrix_init_identity (&ps_p2d);
|
cairo_matrix_init_identity (&ps_p2d);
|
||||||
cairo_matrix_translate (&ps_p2d, 0.0, surface_extents.height);
|
cairo_matrix_translate (&ps_p2d, 0.0, surface->height);
|
||||||
cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
|
cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
|
||||||
cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
|
cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
|
||||||
cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
|
cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
|
||||||
|
|
@ -3163,43 +3201,7 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_ps_surface_intersect_clip_path (void *abstract_surface,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias)
|
|
||||||
{
|
|
||||||
cairo_ps_surface_t *surface = abstract_surface;
|
|
||||||
cairo_output_stream_t *stream = surface->stream;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
#if DEBUG_PS
|
|
||||||
_cairo_output_stream_printf (stream,
|
|
||||||
"%% _cairo_ps_surface_intersect_clip_path\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (stream, "Q q\n");
|
|
||||||
surface->current_pattern_is_solid_color = FALSE;
|
|
||||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _cairo_pdf_operators_clip (&surface->pdf_operators,
|
|
||||||
path,
|
|
||||||
fill_rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_ps_surface_get_extents (void *abstract_surface,
|
_cairo_ps_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -3215,7 +3217,7 @@ _cairo_ps_surface_get_extents (void *abstract_surface,
|
||||||
rectangle->width = (int) ceil (surface->width);
|
rectangle->width = (int) ceil (surface->width);
|
||||||
rectangle->height = (int) ceil (surface->height);
|
rectangle->height = (int) ceil (surface->height);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -3229,11 +3231,26 @@ _cairo_ps_surface_get_font_options (void *abstract_surface,
|
||||||
cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
|
cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
const cairo_rectangle_int_t *clip_extents;
|
||||||
|
|
||||||
|
clip_extents = NULL;
|
||||||
|
if (clip != NULL)
|
||||||
|
clip_extents = _cairo_clip_get_extents (clip);
|
||||||
|
|
||||||
|
if (clip_extents != NULL)
|
||||||
|
return _cairo_rectangle_intersect (extents, clip_extents);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_ps_surface_paint (void *abstract_surface,
|
_cairo_ps_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *paint_extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_ps_surface_t *surface = abstract_surface;
|
cairo_ps_surface_t *surface = abstract_surface;
|
||||||
cairo_output_stream_t *stream = surface->stream;
|
cairo_output_stream_t *stream = surface->stream;
|
||||||
|
|
@ -3250,11 +3267,11 @@ _cairo_ps_surface_paint (void *abstract_surface,
|
||||||
"%% _cairo_ps_surface_paint\n");
|
"%% _cairo_ps_surface_paint\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (&surface->base, &extents);
|
extents = surface->page_bbox;
|
||||||
if (unlikely (status))
|
if (! _rectangle_intersect_clip (&extents, clip))
|
||||||
return status;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -3262,28 +3279,25 @@ _cairo_ps_surface_paint (void *abstract_surface,
|
||||||
(source->extend == CAIRO_EXTEND_NONE ||
|
(source->extend == CAIRO_EXTEND_NONE ||
|
||||||
source->extend == CAIRO_EXTEND_PAD))
|
source->extend == CAIRO_EXTEND_PAD))
|
||||||
{
|
{
|
||||||
_cairo_output_stream_printf (stream, "q 0 0 %d %d rectclip\n",
|
_cairo_output_stream_printf (stream, "q\n");
|
||||||
extents.width,
|
|
||||||
extents.height);
|
|
||||||
|
|
||||||
status = _cairo_ps_surface_paint_surface (surface,
|
status = _cairo_ps_surface_paint_surface (surface,
|
||||||
(cairo_surface_pattern_t *) source,
|
(cairo_surface_pattern_t *) source,
|
||||||
paint_extents, op);
|
&extents, op);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (stream, "Q\n");
|
_cairo_output_stream_printf (stream, "Q\n");
|
||||||
} else {
|
} else {
|
||||||
status = _cairo_ps_surface_emit_pattern (surface, source, paint_extents, op);
|
status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (stream, "0 0 %d %d rectfill\n",
|
_cairo_output_stream_printf (stream, "%d %d %d %d rectfill\n",
|
||||||
extents.width,
|
extents.x, extents.y,
|
||||||
extents.height);
|
extents.width, extents.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -3299,10 +3313,11 @@ _cairo_ps_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_ps_surface_t *surface = abstract_surface;
|
cairo_ps_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||||
return _cairo_ps_surface_analyze_operation (surface, op, source);
|
return _cairo_ps_surface_analyze_operation (surface, op, source);
|
||||||
|
|
@ -3314,7 +3329,15 @@ _cairo_ps_surface_stroke (void *abstract_surface,
|
||||||
"%% _cairo_ps_surface_stroke\n");
|
"%% _cairo_ps_surface_stroke\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
status = _cairo_ps_surface_emit_pattern (surface, source, extents, op);
|
extents = surface->page_bbox;
|
||||||
|
if (! _rectangle_intersect_clip (&extents, clip))
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
@ -3336,10 +3359,11 @@ _cairo_ps_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_ps_surface_t *surface = abstract_surface;
|
cairo_ps_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||||
return _cairo_ps_surface_analyze_operation (surface, op, source);
|
return _cairo_ps_surface_analyze_operation (surface, op, source);
|
||||||
|
|
@ -3351,14 +3375,22 @@ _cairo_ps_surface_fill (void *abstract_surface,
|
||||||
"%% _cairo_ps_surface_fill\n");
|
"%% _cairo_ps_surface_fill\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extents = surface->page_bbox;
|
||||||
|
if (! _rectangle_intersect_clip (&extents, clip))
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
|
if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
|
||||||
(source->extend == CAIRO_EXTEND_NONE ||
|
(source->extend == CAIRO_EXTEND_NONE ||
|
||||||
source->extend == CAIRO_EXTEND_PAD))
|
source->extend == CAIRO_EXTEND_PAD))
|
||||||
{
|
{
|
||||||
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->stream, "q\n");
|
_cairo_output_stream_printf (surface->stream, "q\n");
|
||||||
|
|
||||||
status = _cairo_pdf_operators_clip (&surface->pdf_operators,
|
status = _cairo_pdf_operators_clip (&surface->pdf_operators,
|
||||||
|
|
@ -3369,14 +3401,14 @@ _cairo_ps_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
status = _cairo_ps_surface_paint_surface (surface,
|
status = _cairo_ps_surface_paint_surface (surface,
|
||||||
(cairo_surface_pattern_t *) source,
|
(cairo_surface_pattern_t *) source,
|
||||||
extents, op);
|
&extents, op);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->stream, "Q\n");
|
_cairo_output_stream_printf (surface->stream, "Q\n");
|
||||||
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
_cairo_pdf_operators_reset (&surface->pdf_operators);
|
||||||
} else {
|
} else {
|
||||||
status = _cairo_ps_surface_emit_pattern (surface, source, extents, op);
|
status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
@ -3398,11 +3430,12 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_ps_surface_t *surface = abstract_surface;
|
cairo_ps_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||||
return _cairo_ps_surface_analyze_operation (surface, op, source);
|
return _cairo_ps_surface_analyze_operation (surface, op, source);
|
||||||
|
|
@ -3417,7 +3450,15 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface,
|
||||||
if (num_glyphs <= 0)
|
if (num_glyphs <= 0)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
status = _cairo_ps_surface_emit_pattern (surface, source, extents, op);
|
extents = surface->page_bbox;
|
||||||
|
if (! _rectangle_intersect_clip (&extents, clip))
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = _cairo_ps_surface_emit_pattern (surface, source, &extents, op);
|
||||||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
@ -3439,6 +3480,11 @@ _cairo_ps_surface_set_paginated_mode (void *abstract_surface,
|
||||||
cairo_ps_surface_t *surface = abstract_surface;
|
cairo_ps_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
surface->paginated_mode = paginated_mode;
|
surface->paginated_mode = paginated_mode;
|
||||||
|
|
||||||
|
if (surface->clipper.clip.path != NULL) {
|
||||||
|
_cairo_output_stream_printf (surface->stream, "Q\n");
|
||||||
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -3462,6 +3508,11 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
|
||||||
y2 = (int) ceil (surface->height);
|
y2 = (int) ceil (surface->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
surface->page_bbox.x = x1;
|
||||||
|
surface->page_bbox.y = y1;
|
||||||
|
surface->page_bbox.width = x2 - x1;
|
||||||
|
surface->page_bbox.height = y2 - y1;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->stream,
|
_cairo_output_stream_printf (surface->stream,
|
||||||
"%%%%Page: %d %d\n",
|
"%%%%Page: %d %d\n",
|
||||||
surface->num_pages,
|
surface->num_pages,
|
||||||
|
|
@ -3486,7 +3537,11 @@ _cairo_ps_surface_set_bounding_box (void *abstract_surface,
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->stream,
|
_cairo_output_stream_printf (surface->stream,
|
||||||
"%%%%EndPageSetup\n"
|
"%%%%EndPageSetup\n"
|
||||||
"q\n");
|
"q %d %d %d %d rectclip q\n",
|
||||||
|
surface->page_bbox.x,
|
||||||
|
surface->page_bbox.y,
|
||||||
|
surface->page_bbox.width,
|
||||||
|
surface->page_bbox.height);
|
||||||
|
|
||||||
if (surface->num_pages == 1) {
|
if (surface->num_pages == 1) {
|
||||||
surface->bbox_x1 = x1;
|
surface->bbox_x1 = x1;
|
||||||
|
|
@ -3517,7 +3572,7 @@ _cairo_ps_surface_supports_fine_grained_fallbacks (void *abstract_surface)
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
||||||
CAIRO_SURFACE_TYPE_PS,
|
CAIRO_SURFACE_TYPE_PS,
|
||||||
_cairo_ps_surface_create_similar,
|
NULL, /* create similar: handled by wrapper */
|
||||||
_cairo_ps_surface_finish,
|
_cairo_ps_surface_finish,
|
||||||
NULL, /* acquire_source_image */
|
NULL, /* acquire_source_image */
|
||||||
NULL, /* release_source_image */
|
NULL, /* release_source_image */
|
||||||
|
|
@ -3531,8 +3586,6 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* cairo_ps_surface_copy_page */
|
NULL, /* cairo_ps_surface_copy_page */
|
||||||
_cairo_ps_surface_show_page,
|
_cairo_ps_surface_show_page,
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_ps_surface_intersect_clip_path,
|
|
||||||
_cairo_ps_surface_get_extents,
|
_cairo_ps_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
_cairo_ps_surface_get_font_options,
|
_cairo_ps_surface_get_font_options,
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@
|
||||||
|
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
#include "cairo-types-private.h"
|
#include "cairo-types-private.h"
|
||||||
|
#include "cairo-clip-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
#include "cairo-region-private.h"
|
||||||
|
|
||||||
#include "cairo-qt.h"
|
#include "cairo-qt.h"
|
||||||
|
|
||||||
|
|
@ -65,6 +68,8 @@
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define ENABLE_FAST_FILL 1 /* Enable workaround slow regional Qt paths */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define D(x) x
|
#define D(x) x
|
||||||
static const char *
|
static const char *
|
||||||
|
|
@ -104,14 +109,9 @@ _opstr (cairo_operator_t op)
|
||||||
#define DOT_LENGTH 1.0
|
#define DOT_LENGTH 1.0
|
||||||
#define DASH_LENGTH 3.0
|
#define DASH_LENGTH 3.0
|
||||||
|
|
||||||
typedef struct {
|
struct cairo_qt_surface_t {
|
||||||
cairo_surface_t base;
|
cairo_surface_t base;
|
||||||
|
|
||||||
bool has_clipping;
|
|
||||||
// if this is true, calls to intersect_clip_path won't
|
|
||||||
// update the clip_bounds rect
|
|
||||||
bool no_update_clip_bounds;
|
|
||||||
|
|
||||||
cairo_bool_t supports_porter_duff;
|
cairo_bool_t supports_porter_duff;
|
||||||
|
|
||||||
#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
|
#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
|
||||||
|
|
@ -131,11 +131,10 @@ typedef struct {
|
||||||
|
|
||||||
QRect window;
|
QRect window;
|
||||||
|
|
||||||
|
cairo_surface_clipper_t clipper;
|
||||||
QRect clip_bounds;
|
|
||||||
|
|
||||||
cairo_surface_t *image_equiv;
|
cairo_surface_t *image_equiv;
|
||||||
} cairo_qt_surface_t;
|
};
|
||||||
|
|
||||||
/* Will be true if we ever try to create a QPixmap and end
|
/* Will be true if we ever try to create a QPixmap and end
|
||||||
* up with one without an alpha channel.
|
* up with one without an alpha channel.
|
||||||
|
|
@ -186,6 +185,21 @@ _qpainter_compositionmode_from_cairo_op (cairo_operator_t op)
|
||||||
default:
|
default:
|
||||||
case CAIRO_OPERATOR_ADD:
|
case CAIRO_OPERATOR_ADD:
|
||||||
case CAIRO_OPERATOR_SATURATE:
|
case CAIRO_OPERATOR_SATURATE:
|
||||||
|
case CAIRO_OPERATOR_MULTIPLY:
|
||||||
|
case CAIRO_OPERATOR_SCREEN:
|
||||||
|
case CAIRO_OPERATOR_OVERLAY:
|
||||||
|
case CAIRO_OPERATOR_DARKEN:
|
||||||
|
case CAIRO_OPERATOR_LIGHTEN:
|
||||||
|
case CAIRO_OPERATOR_COLOR_DODGE:
|
||||||
|
case CAIRO_OPERATOR_COLOR_BURN:
|
||||||
|
case CAIRO_OPERATOR_HARD_LIGHT:
|
||||||
|
case CAIRO_OPERATOR_SOFT_LIGHT:
|
||||||
|
case CAIRO_OPERATOR_DIFFERENCE:
|
||||||
|
case CAIRO_OPERATOR_EXCLUSION:
|
||||||
|
case CAIRO_OPERATOR_HSL_HUE:
|
||||||
|
case CAIRO_OPERATOR_HSL_SATURATION:
|
||||||
|
case CAIRO_OPERATOR_HSL_COLOR:
|
||||||
|
case CAIRO_OPERATOR_HSL_LUMINOSITY:
|
||||||
ASSERT_NOT_REACHED;
|
ASSERT_NOT_REACHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -211,12 +225,27 @@ _op_is_supported (cairo_qt_surface_t *qs, cairo_operator_t op)
|
||||||
case CAIRO_OPERATOR_XOR:
|
case CAIRO_OPERATOR_XOR:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case CAIRO_OPERATOR_ADD:
|
|
||||||
case CAIRO_OPERATOR_SATURATE:
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED;
|
ASSERT_NOT_REACHED;
|
||||||
|
case CAIRO_OPERATOR_ADD:
|
||||||
|
case CAIRO_OPERATOR_SATURATE:
|
||||||
|
case CAIRO_OPERATOR_MULTIPLY:
|
||||||
|
case CAIRO_OPERATOR_SCREEN:
|
||||||
|
case CAIRO_OPERATOR_OVERLAY:
|
||||||
|
case CAIRO_OPERATOR_DARKEN:
|
||||||
|
case CAIRO_OPERATOR_LIGHTEN:
|
||||||
|
case CAIRO_OPERATOR_COLOR_DODGE:
|
||||||
|
case CAIRO_OPERATOR_COLOR_BURN:
|
||||||
|
case CAIRO_OPERATOR_HARD_LIGHT:
|
||||||
|
case CAIRO_OPERATOR_SOFT_LIGHT:
|
||||||
|
case CAIRO_OPERATOR_DIFFERENCE:
|
||||||
|
case CAIRO_OPERATOR_EXCLUSION:
|
||||||
|
case CAIRO_OPERATOR_HSL_HUE:
|
||||||
|
case CAIRO_OPERATOR_HSL_SATURATION:
|
||||||
|
case CAIRO_OPERATOR_HSL_COLOR:
|
||||||
|
case CAIRO_OPERATOR_HSL_LUMINOSITY:
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return op == CAIRO_OPERATOR_OVER;
|
return op == CAIRO_OPERATOR_OVER;
|
||||||
|
|
@ -458,6 +487,8 @@ _cairo_qt_surface_finish (void *abstract_surface)
|
||||||
if (qs->image_equiv)
|
if (qs->image_equiv)
|
||||||
cairo_surface_destroy (qs->image_equiv);
|
cairo_surface_destroy (qs->image_equiv);
|
||||||
|
|
||||||
|
_cairo_surface_clipper_reset (&qs->clipper);
|
||||||
|
|
||||||
#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
|
#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
|
||||||
if (qs->xlib_equiv)
|
if (qs->xlib_equiv)
|
||||||
cairo_surface_destroy (qs->xlib_equiv);
|
cairo_surface_destroy (qs->xlib_equiv);
|
||||||
|
|
@ -655,7 +686,7 @@ _cairo_qt_surface_clone_similar (void *abstract_surface,
|
||||||
return (cairo_status_t) CAIRO_INT_STATUS_UNSUPPORTED;
|
return (cairo_status_t) CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_qt_surface_get_extents (void *abstract_surface,
|
_cairo_qt_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
|
|
@ -666,25 +697,40 @@ _cairo_qt_surface_get_extents (void *abstract_surface,
|
||||||
extents->width = qs->window.width();
|
extents->width = qs->window.width();
|
||||||
extents->height = qs->window.height();
|
extents->height = qs->window.height();
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_status_t
|
||||||
_cairo_qt_surface_intersect_clip_path (void *abstract_surface,
|
_cairo_qt_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias)
|
cairo_antialias_t antialias)
|
||||||
{
|
{
|
||||||
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
cairo_qt_surface_t *qs = cairo_container_of (clipper,
|
||||||
|
cairo_qt_surface_t,
|
||||||
|
clipper);
|
||||||
|
QPainterPath qpath;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
D(fprintf(stderr, "q[%p] intersect_clip_path %s\n", abstract_surface, path ? "(path)" : "(clear)"));
|
// XXX Antialiasing is ignored
|
||||||
|
status = _cairo_quartz_cairo_path_to_qpainterpath (path,
|
||||||
|
&qpath,
|
||||||
|
fill_rule);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
if (!qs->p)
|
qs->p->setClipPath (qpath, Qt::IntersectClip);
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (path == NULL) {
|
static void
|
||||||
//fprintf (stderr, "clip clear\n");
|
_cairo_qt_surface_set_clip_region (cairo_qt_surface_t *qs,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
|
{
|
||||||
|
_cairo_surface_clipper_reset (&qs->clipper);
|
||||||
|
|
||||||
|
if (clip_region == NULL) {
|
||||||
// How the clip path is reset depends on whether we own p or not
|
// How the clip path is reset depends on whether we own p or not
|
||||||
if (qs->pixmap || qs->image) {
|
if (qs->pixmap || qs->image) {
|
||||||
// we own p
|
// we own p
|
||||||
|
|
@ -693,10 +739,38 @@ _cairo_qt_surface_intersect_clip_path (void *abstract_surface,
|
||||||
qs->p->restore ();
|
qs->p->restore ();
|
||||||
qs->p->save ();
|
qs->p->save ();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
QRegion qr;
|
||||||
|
int num_rects = cairo_region_num_rectangles (clip_region);
|
||||||
|
for (int i = 0; i < num_rects; ++i) {
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
if (!qs->no_update_clip_bounds) {
|
cairo_region_get_rectangle (clip_region, i, &rect);
|
||||||
qs->clip_bounds.setRect(0, 0, 0, 0);
|
|
||||||
qs->has_clipping = false;
|
QRect r(rect.x, rect.y, rect.width, rect.height);
|
||||||
|
qr = qr.unite(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
qs->p->setClipRegion (qr, Qt::IntersectClip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_cairo_qt_surface_set_clip (cairo_qt_surface_t *qs,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
|
||||||
|
D(fprintf(stderr, "q[%p] intersect_clip_path %s\n", abstract_surface, path ? "(path)" : "(clear)"));
|
||||||
|
|
||||||
|
if (clip == NULL) {
|
||||||
|
_cairo_surface_clipper_reset (&qs->clipper);
|
||||||
|
// How the clip path is reset depends on whether we own p or not
|
||||||
|
if (qs->pixmap || qs->image) {
|
||||||
|
// we own p
|
||||||
|
qs->p->setClipping (false);
|
||||||
|
} else {
|
||||||
|
qs->p->restore ();
|
||||||
|
qs->p->save ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
|
|
@ -711,125 +785,21 @@ _cairo_qt_surface_intersect_clip_path (void *abstract_surface,
|
||||||
// we do a bunch of work here to try to get rectangles or regions
|
// we do a bunch of work here to try to get rectangles or regions
|
||||||
// down to Qt for clipping.
|
// down to Qt for clipping.
|
||||||
|
|
||||||
QRect clip_bounds;
|
cairo_region_t *clip_region = NULL;
|
||||||
|
|
||||||
// First check if it's an integer-aligned single rectangle
|
cairo_int_status_t status;
|
||||||
cairo_box_t box;
|
status = _cairo_clip_get_region (clip, &clip_region);
|
||||||
if (_cairo_path_fixed_is_box (path, &box) &&
|
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||||
_cairo_fixed_is_integer (box.p1.x) &&
|
// We weren't able to extract a region from the traps.
|
||||||
_cairo_fixed_is_integer (box.p1.y) &&
|
// Just hand the path down to QPainter.
|
||||||
_cairo_fixed_is_integer (box.p2.x) &&
|
|
||||||
_cairo_fixed_is_integer (box.p2.y))
|
|
||||||
{
|
|
||||||
QRect r(_cairo_fixed_integer_part(box.p1.x),
|
|
||||||
_cairo_fixed_integer_part(box.p1.y),
|
|
||||||
_cairo_fixed_integer_part(box.p2.x - box.p1.x),
|
|
||||||
_cairo_fixed_integer_part(box.p2.y - box.p1.y));
|
|
||||||
|
|
||||||
r = r.normalized();
|
|
||||||
|
|
||||||
clip_bounds = r;
|
|
||||||
|
|
||||||
qs->p->setClipRect (r, Qt::IntersectClip);
|
|
||||||
} else {
|
|
||||||
// Then if it's not an integer-aligned rectangle, check
|
|
||||||
// if we can extract a region (a set of rectangles) out.
|
|
||||||
// We use cairo to convert the path to traps.
|
|
||||||
|
|
||||||
cairo_traps_t traps;
|
|
||||||
cairo_int_status_t status;
|
|
||||||
cairo_region_t *region = NULL;
|
|
||||||
|
|
||||||
_cairo_traps_init (&traps);
|
|
||||||
status = (cairo_int_status_t)
|
status = (cairo_int_status_t)
|
||||||
_cairo_path_fixed_fill_to_traps (path,
|
_cairo_surface_clipper_set_clip (&qs->clipper, clip);
|
||||||
fill_rule, tolerance, &traps);
|
} else if (status == CAIRO_INT_STATUS_SUCCESS) {
|
||||||
if (status) {
|
_cairo_qt_surface_set_clip_region (qs, clip_region);
|
||||||
_cairo_traps_fini (&traps);
|
status = CAIRO_INT_STATUS_SUCCESS;
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _cairo_traps_extract_region (&traps, ®ion);
|
|
||||||
_cairo_traps_fini (&traps);
|
|
||||||
|
|
||||||
if (_cairo_status_is_error ((cairo_status_t) status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (status == CAIRO_INT_STATUS_SUCCESS) {
|
|
||||||
#if 0
|
|
||||||
cairo_box_int_t *boxes;
|
|
||||||
int n_boxes;
|
|
||||||
|
|
||||||
QRegion qr;
|
|
||||||
|
|
||||||
_cairo_region_get_boxes (®ion, &n_boxes, &boxes);
|
|
||||||
|
|
||||||
for (int i = 0; i < n_boxes; i++) {
|
|
||||||
QRect r(boxes[i].p1.x,
|
|
||||||
boxes[i].p1.y,
|
|
||||||
boxes[i].p2.x - boxes[i].p1.x,
|
|
||||||
boxes[i].p2.y - boxes[i].p1.y);
|
|
||||||
|
|
||||||
if (i == 0)
|
|
||||||
clip_bounds = r;
|
|
||||||
else
|
|
||||||
clip_bounds = clip_bounds.united(r);
|
|
||||||
|
|
||||||
qr = qr.unite(r);
|
|
||||||
}
|
|
||||||
_cairo_region_boxes_fini (®ion, boxes);
|
|
||||||
#else
|
|
||||||
int n_boxes;
|
|
||||||
|
|
||||||
QRegion qr;
|
|
||||||
|
|
||||||
n_boxes = cairo_region_num_rectangles (region);
|
|
||||||
for (int i = 0; i < n_boxes; ++i) {
|
|
||||||
cairo_rectangle_int_t box;
|
|
||||||
cairo_region_get_rectangle (region, i, &box);
|
|
||||||
QRect r(box.x, box.y, box.width, box.height);
|
|
||||||
|
|
||||||
if (0 == i)
|
|
||||||
clip_bounds = r;
|
|
||||||
else
|
|
||||||
clip_bounds = clip_bounds.united(r);
|
|
||||||
|
|
||||||
qr = qr.unite(r);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
_cairo_region_fini (region);
|
|
||||||
|
|
||||||
qs->p->setClipRegion (qr, Qt::IntersectClip);
|
|
||||||
} else {
|
|
||||||
// We weren't able to extract a region from the traps.
|
|
||||||
// Just hand the path down to QPainter.
|
|
||||||
QPainterPath qpath;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_quartz_cairo_path_to_qpainterpath (path,
|
|
||||||
&qpath,
|
|
||||||
fill_rule);
|
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
|
||||||
|
|
||||||
clip_bounds = qpath.boundingRect().toAlignedRect();
|
|
||||||
|
|
||||||
// XXX Antialiasing is ignored
|
|
||||||
qs->p->setClipPath (qpath, Qt::IntersectClip);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!qs->no_update_clip_bounds) {
|
return status;
|
||||||
clip_bounds = qs->p->worldTransform().mapRect(clip_bounds);
|
|
||||||
|
|
||||||
if (qs->has_clipping) {
|
|
||||||
qs->clip_bounds = qs->clip_bounds.intersect(clip_bounds);
|
|
||||||
} else {
|
|
||||||
qs->clip_bounds = clip_bounds;
|
|
||||||
qs->has_clipping = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1156,10 +1126,12 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs,
|
||||||
double tolerance = 0.0,
|
double tolerance = 0.0,
|
||||||
cairo_antialias_t antialias = CAIRO_ANTIALIAS_NONE)
|
cairo_antialias_t antialias = CAIRO_ANTIALIAS_NONE)
|
||||||
{
|
{
|
||||||
|
#if ENABLE_FAST_FILL
|
||||||
QImage *qsSrc_image = NULL;
|
QImage *qsSrc_image = NULL;
|
||||||
QPixmap *qsSrc_pixmap = NULL;
|
QPixmap *qsSrc_pixmap = NULL;
|
||||||
std::auto_ptr<QImage> qsSrc_image_d;
|
std::auto_ptr<QImage> qsSrc_image_d;
|
||||||
|
|
||||||
|
|
||||||
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||||
cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) source;
|
cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) source;
|
||||||
if (spattern->surface->type == CAIRO_SURFACE_TYPE_QT) {
|
if (spattern->surface->type == CAIRO_SURFACE_TYPE_QT) {
|
||||||
|
|
@ -1190,7 +1162,6 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs,
|
||||||
}
|
}
|
||||||
|
|
||||||
QMatrix sourceMatrix = _qmatrix_from_cairo_matrix (source->matrix);
|
QMatrix sourceMatrix = _qmatrix_from_cairo_matrix (source->matrix);
|
||||||
cairo_int_status_t status;
|
|
||||||
|
|
||||||
// We can draw this faster by clipping and calling drawImage/drawPixmap.
|
// We can draw this faster by clipping and calling drawImage/drawPixmap.
|
||||||
// Use our own clipping function so that we can get the
|
// Use our own clipping function so that we can get the
|
||||||
|
|
@ -1201,14 +1172,29 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs,
|
||||||
qs->p->save();
|
qs->p->save();
|
||||||
|
|
||||||
if (path) {
|
if (path) {
|
||||||
qs->no_update_clip_bounds = true;
|
cairo_int_status_t status;
|
||||||
status = _cairo_qt_surface_intersect_clip_path (qs, path, fill_rule, tolerance, antialias);
|
|
||||||
qs->no_update_clip_bounds = false;
|
|
||||||
|
|
||||||
if (status != CAIRO_INT_STATUS_SUCCESS) {
|
cairo_clip_t clip, old_clip = qs->clipper.clip;
|
||||||
qs->p->restore();
|
|
||||||
return false;
|
_cairo_clip_init_copy (&clip, &qs->clipper.clip);
|
||||||
}
|
status = (cairo_int_status_t) _cairo_clip_clip (&clip,
|
||||||
|
path,
|
||||||
|
fill_rule,
|
||||||
|
tolerance,
|
||||||
|
antialias);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
qs->p->restore();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_qt_surface_set_clip (qs, &clip);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
qs->p->restore();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cairo_clip_reset (&clip);
|
||||||
|
qs->clipper.clip = old_clip;
|
||||||
}
|
}
|
||||||
|
|
||||||
qs->p->setWorldMatrix (sourceMatrix.inverted(), true);
|
qs->p->setWorldMatrix (sourceMatrix.inverted(), true);
|
||||||
|
|
@ -1242,16 +1228,19 @@ _cairo_qt_fast_fill (cairo_qt_surface_t *qs,
|
||||||
qs->p->restore();
|
qs->p->restore();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_qt_surface_paint (void *abstract_surface,
|
_cairo_qt_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
Q_UNUSED(extents);
|
|
||||||
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
||||||
|
cairo_int_status_t status;
|
||||||
|
|
||||||
D(fprintf(stderr, "q[%p] paint op:%s\n", abstract_surface, _opstr(op)));
|
D(fprintf(stderr, "q[%p] paint op:%s\n", abstract_surface, _opstr(op)));
|
||||||
|
|
||||||
|
|
@ -1261,6 +1250,10 @@ _cairo_qt_surface_paint (void *abstract_surface,
|
||||||
if (! _op_is_supported (qs, op))
|
if (! _op_is_supported (qs, op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_qt_surface_set_clip (qs, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
if (qs->supports_porter_duff)
|
if (qs->supports_porter_duff)
|
||||||
qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op));
|
qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op));
|
||||||
|
|
||||||
|
|
@ -1283,9 +1276,8 @@ _cairo_qt_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t * extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
Q_UNUSED(extents);
|
|
||||||
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
||||||
|
|
||||||
D(fprintf(stderr, "q[%p] fill op:%s\n", abstract_surface, _opstr(op)));
|
D(fprintf(stderr, "q[%p] fill op:%s\n", abstract_surface, _opstr(op)));
|
||||||
|
|
@ -1296,6 +1288,10 @@ _cairo_qt_surface_fill (void *abstract_surface,
|
||||||
if (! _op_is_supported (qs, op))
|
if (! _op_is_supported (qs, op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
cairo_int_status_t status = _cairo_qt_surface_set_clip (qs, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
if (qs->supports_porter_duff)
|
if (qs->supports_porter_duff)
|
||||||
qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op));
|
qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op));
|
||||||
|
|
||||||
|
|
@ -1333,9 +1329,8 @@ _cairo_qt_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
Q_UNUSED(extents);
|
|
||||||
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
||||||
|
|
||||||
D(fprintf(stderr, "q[%p] stroke op:%s\n", abstract_surface, _opstr(op)));
|
D(fprintf(stderr, "q[%p] stroke op:%s\n", abstract_surface, _opstr(op)));
|
||||||
|
|
@ -1346,6 +1341,10 @@ _cairo_qt_surface_stroke (void *abstract_surface,
|
||||||
if (! _op_is_supported (qs, op))
|
if (! _op_is_supported (qs, op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
cairo_int_status_t int_status = _cairo_qt_surface_set_clip (qs, clip);
|
||||||
|
if (unlikely (int_status))
|
||||||
|
return int_status;
|
||||||
|
|
||||||
QPainterPath qpath;
|
QPainterPath qpath;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
|
|
@ -1387,8 +1386,8 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
||||||
|
|
||||||
|
|
@ -1404,37 +1403,6 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface,
|
||||||
glyphs[i].y -= qs->redir_offset.y();
|
glyphs[i].y -= qs->redir_offset.y();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qs->has_clipping != qs->xlib_has_clipping ||
|
|
||||||
qs->clip_bounds != qs->xlib_clip_bounds)
|
|
||||||
{
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_surface_reset_clip (qs->xlib_equiv);
|
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
|
||||||
|
|
||||||
if (qs->has_clipping) {
|
|
||||||
cairo_region_t region;
|
|
||||||
cairo_rectangle_int_t rect = {
|
|
||||||
qs->clip_bounds.x() - qs->redir_offset.x(),
|
|
||||||
qs->clip_bounds.y() - qs->redir_offset.y(),
|
|
||||||
qs->clip_bounds.width(),
|
|
||||||
qs->clip_bounds.height()
|
|
||||||
};
|
|
||||||
|
|
||||||
_cairo_region_init_rectangle (®ion, &rect);
|
|
||||||
status = _cairo_surface_set_clip_region (qs->xlib_equiv,
|
|
||||||
®ion,
|
|
||||||
++qs->xlib_clip_serial);
|
|
||||||
_cairo_region_fini (®ion);
|
|
||||||
|
|
||||||
if (status)
|
|
||||||
return (cairo_int_status_t) status;
|
|
||||||
}
|
|
||||||
|
|
||||||
qs->xlib_has_clipping = qs->has_clipping;
|
|
||||||
qs->xlib_clip_bounds = qs->clip_bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (cairo_int_status_t)
|
return (cairo_int_status_t)
|
||||||
_cairo_surface_show_text_glyphs (qs->xlib_equiv,
|
_cairo_surface_show_text_glyphs (qs->xlib_equiv,
|
||||||
op, source,
|
op, source,
|
||||||
|
|
@ -1443,7 +1411,7 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
(cairo_text_cluster_flags_t) 0,
|
(cairo_text_cluster_flags_t) 0,
|
||||||
scaled_font,
|
scaled_font,
|
||||||
extents);
|
clip);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1452,12 +1420,11 @@ _cairo_qt_surface_show_glyphs (void *abstract_surface,
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_qt_surface_mask (void *abstract_surface,
|
_cairo_qt_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
Q_UNUSED(extents);
|
|
||||||
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
||||||
|
|
||||||
D(fprintf(stderr, "q[%p] mask op:%s\n", abstract_surface, _opstr(op)));
|
D(fprintf(stderr, "q[%p] mask op:%s\n", abstract_surface, _opstr(op)));
|
||||||
|
|
@ -1471,7 +1438,7 @@ _cairo_qt_surface_mask (void *abstract_surface,
|
||||||
|
|
||||||
qs->p->setOpacity (solid_mask->color.alpha);
|
qs->p->setOpacity (solid_mask->color.alpha);
|
||||||
|
|
||||||
result = _cairo_qt_surface_paint (abstract_surface, op, source, 0);
|
result = _cairo_qt_surface_paint (abstract_surface, op, source, clip);
|
||||||
|
|
||||||
qs->p->setOpacity (1.0);
|
qs->p->setOpacity (1.0);
|
||||||
|
|
||||||
|
|
@ -1498,7 +1465,8 @@ _cairo_qt_surface_composite (cairo_operator_t op,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface;
|
||||||
|
|
||||||
|
|
@ -1508,6 +1476,8 @@ _cairo_qt_surface_composite (cairo_operator_t op,
|
||||||
if (! _op_is_supported (qs, op))
|
if (! _op_is_supported (qs, op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
_cairo_qt_surface_set_clip_region (qs, clip_region);
|
||||||
|
|
||||||
D(fprintf(stderr, "q[%p] composite op:%s src:%p [%d %d] dst [%d %d] dim [%d %d]\n",
|
D(fprintf(stderr, "q[%p] composite op:%s src:%p [%d %d] dst [%d %d] dim [%d %d]\n",
|
||||||
abstract_surface, _opstr(op), (void*)pattern,
|
abstract_surface, _opstr(op), (void*)pattern,
|
||||||
src_x, src_y, dst_x, dst_y, width, height));
|
src_x, src_y, dst_x, dst_y, width, height));
|
||||||
|
|
@ -1618,8 +1588,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_qt_surface_intersect_clip_path,
|
|
||||||
_cairo_qt_surface_get_extents,
|
_cairo_qt_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -1636,7 +1604,6 @@ static const cairo_surface_backend_t cairo_qt_surface_backend = {
|
||||||
|
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
@ -1728,6 +1695,10 @@ cairo_qt_surface_create (QPainter *painter)
|
||||||
|
|
||||||
qs->window = painter->window();
|
qs->window = painter->window();
|
||||||
|
|
||||||
|
_cairo_surface_clipper_init (&qs->clipper,
|
||||||
|
_cairo_qt_surface_clipper_intersect_clip_path);
|
||||||
|
|
||||||
|
|
||||||
#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
|
#if defined(Q_WS_X11) && CAIRO_HAS_XLIB_XRENDER_SURFACE
|
||||||
qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs);
|
qs->xlib_equiv = _cairo_qt_create_xlib_surface (qs);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -58,9 +58,8 @@ _cairo_quartz_image_surface_create_similar (void *asurface,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
cairo_surface_t *result;
|
cairo_surface_t *result;
|
||||||
cairo_surface_t *isurf = cairo_image_surface_create (_cairo_format_from_content (content),
|
cairo_surface_t *isurf =
|
||||||
width,
|
_cairo_image_surface_create_for_content (content, width, height);
|
||||||
height);
|
|
||||||
if (cairo_surface_status(isurf))
|
if (cairo_surface_status(isurf))
|
||||||
return isurf;
|
return isurf;
|
||||||
|
|
||||||
|
|
@ -108,18 +107,16 @@ _cairo_quartz_image_surface_acquire_dest_image (void *asurface,
|
||||||
*image_extra = NULL;
|
*image_extra = NULL;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_quartz_image_surface_get_extents (void *asurface,
|
_cairo_quartz_image_surface_get_extents (void *asurface,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
|
cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface;
|
||||||
|
|
||||||
*extents = surface->extents;
|
*extents = surface->extents;
|
||||||
|
return TRUE;
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we assume some drawing happened to the image buffer; make sure it's
|
/* we assume some drawing happened to the image buffer; make sure it's
|
||||||
|
|
@ -168,8 +165,6 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_quartz_image_surface_get_extents,
|
_cairo_quartz_image_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -185,7 +180,6 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = {
|
||||||
NULL, /* surface_show_glyphs */
|
NULL, /* surface_show_glyphs */
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL /* fill_stroke */
|
NULL /* fill_stroke */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#if CAIRO_HAS_QUARTZ_SURFACE
|
#if CAIRO_HAS_QUARTZ_SURFACE
|
||||||
#include "cairo-quartz.h"
|
#include "cairo-quartz.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
|
||||||
typedef struct cairo_quartz_surface {
|
typedef struct cairo_quartz_surface {
|
||||||
cairo_surface_t base;
|
cairo_surface_t base;
|
||||||
|
|
@ -52,6 +53,7 @@ typedef struct cairo_quartz_surface {
|
||||||
void *imageData;
|
void *imageData;
|
||||||
cairo_surface_t *imageSurfaceEquiv;
|
cairo_surface_t *imageSurfaceEquiv;
|
||||||
|
|
||||||
|
cairo_surface_clipper_t clipper;
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
|
|
||||||
/* These are stored while drawing operations are in place, set up
|
/* These are stored while drawing operations are in place, set up
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
|
|
||||||
#include "cairo-quartz-private.h"
|
#include "cairo-quartz-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
|
@ -837,7 +838,8 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stype != CAIRO_SURFACE_TYPE_IMAGE) {
|
if (stype != CAIRO_SURFACE_TYPE_IMAGE) {
|
||||||
status = _cairo_surface_acquire_source_image (source, &isurf, &image_extra);
|
status = _cairo_surface_acquire_source_image (source,
|
||||||
|
&isurf, &image_extra);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -848,12 +850,11 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
|
||||||
*image_out = NULL;
|
*image_out = NULL;
|
||||||
} else {
|
} else {
|
||||||
cairo_image_surface_t *isurf_snap = NULL;
|
cairo_image_surface_t *isurf_snap = NULL;
|
||||||
isurf_snap = (cairo_image_surface_t*) _cairo_surface_snapshot ((cairo_surface_t*) isurf);
|
|
||||||
if (isurf_snap == NULL)
|
|
||||||
return CAIRO_STATUS_NO_MEMORY;
|
|
||||||
|
|
||||||
if (isurf_snap->base.type != CAIRO_SURFACE_TYPE_IMAGE)
|
isurf_snap = (cairo_image_surface_t*)
|
||||||
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
|
_cairo_surface_snapshot (&isurf->base);
|
||||||
|
if (isurf_snap->base.status)
|
||||||
|
return isurf_snap->base.status;
|
||||||
|
|
||||||
image = _cairo_quartz_create_cgimage (isurf_snap->format,
|
image = _cairo_quartz_create_cgimage (isurf_snap->format,
|
||||||
isurf_snap->width,
|
isurf_snap->width,
|
||||||
|
|
@ -868,10 +869,10 @@ _cairo_surface_to_cgimage (cairo_surface_t *target,
|
||||||
*image_out = image;
|
*image_out = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cairo_surface_t*) isurf != source)
|
if (&isurf->base != source)
|
||||||
_cairo_surface_release_source_image (source, isurf, image_extra);
|
_cairo_surface_release_source_image (source, isurf, image_extra);
|
||||||
|
|
||||||
return status;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generic #cairo_pattern_t -> CGPattern function */
|
/* Generic #cairo_pattern_t -> CGPattern function */
|
||||||
|
|
@ -942,6 +943,7 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
|
||||||
SurfacePatternDrawInfo *info;
|
SurfacePatternDrawInfo *info;
|
||||||
float rw, rh;
|
float rw, rh;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
|
|
||||||
cairo_matrix_t m;
|
cairo_matrix_t m;
|
||||||
|
|
||||||
|
|
@ -952,9 +954,8 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
|
||||||
spattern = (cairo_surface_pattern_t *) apattern;
|
spattern = (cairo_surface_pattern_t *) apattern;
|
||||||
pat_surf = spattern->surface;
|
pat_surf = spattern->surface;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (pat_surf, &extents);
|
is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
|
||||||
if (status)
|
assert (is_bounded);
|
||||||
return status;
|
|
||||||
|
|
||||||
status = _cairo_surface_to_cgimage ((cairo_surface_t*) dest, pat_surf, &image);
|
status = _cairo_surface_to_cgimage ((cairo_surface_t*) dest, pat_surf, &image);
|
||||||
if (status != CAIRO_STATUS_SUCCESS)
|
if (status != CAIRO_STATUS_SUCCESS)
|
||||||
|
|
@ -1042,9 +1043,7 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
|
||||||
double x0, y0, w, h;
|
double x0, y0, w, h;
|
||||||
|
|
||||||
cairo_surface_t *fallback;
|
cairo_surface_t *fallback;
|
||||||
cairo_t *fallback_cr;
|
|
||||||
CGImageRef img;
|
CGImageRef img;
|
||||||
cairo_pattern_t *source_copy;
|
|
||||||
|
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
|
|
@ -1070,20 +1069,38 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface,
|
||||||
fallback = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (int) w, (int) h);
|
fallback = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, (int) w, (int) h);
|
||||||
cairo_surface_set_device_offset (fallback, -x0, -y0);
|
cairo_surface_set_device_offset (fallback, -x0, -y0);
|
||||||
|
|
||||||
/* Paint the source onto our temporary */
|
#if 0
|
||||||
fallback_cr = cairo_create (fallback);
|
{
|
||||||
cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE);
|
cairo_t *fallback_cr;
|
||||||
|
cairo_pattern_t *source_copy;
|
||||||
|
|
||||||
/* Use a copy of the pattern because it is const and could be allocated
|
/* Paint the source onto our temporary */
|
||||||
* on the stack */
|
fallback_cr = cairo_create (fallback);
|
||||||
status = _cairo_pattern_create_copy (&source_copy, source);
|
cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE);
|
||||||
cairo_set_source (fallback_cr, source_copy);
|
|
||||||
cairo_pattern_destroy (source_copy);
|
|
||||||
|
|
||||||
cairo_paint (fallback_cr);
|
/* Use a copy of the pattern because it is const and could be allocated
|
||||||
cairo_destroy (fallback_cr);
|
* on the stack */
|
||||||
|
status = _cairo_pattern_create_copy (&source_copy, source);
|
||||||
|
cairo_set_source (fallback_cr, source_copy);
|
||||||
|
cairo_pattern_destroy (source_copy);
|
||||||
|
|
||||||
status = _cairo_surface_to_cgimage ((cairo_surface_t*) surface, fallback, &img);
|
cairo_paint (fallback_cr);
|
||||||
|
cairo_destroy (fallback_cr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
cairo_pattern_union_t pattern;
|
||||||
|
|
||||||
|
_cairo_pattern_init_static_copy (&pattern, source);
|
||||||
|
_cairo_pattern_transform (pattern_copy,
|
||||||
|
&fallback->device_transform_inverse);
|
||||||
|
status = _cairo_surface_paint (fallback,
|
||||||
|
CAIRO_OPERATOR_SOURCE,
|
||||||
|
&pattern.base, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
status = _cairo_surface_to_cgimage (&surface->base, fallback, &img);
|
||||||
if (status == CAIRO_STATUS_SUCCESS && img == NULL)
|
if (status == CAIRO_STATUS_SUCCESS && img == NULL)
|
||||||
return DO_NOTHING;
|
return DO_NOTHING;
|
||||||
if (status)
|
if (status)
|
||||||
|
|
@ -1251,6 +1268,7 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
|
||||||
CGAffineTransform xform;
|
CGAffineTransform xform;
|
||||||
CGRect srcRect;
|
CGRect srcRect;
|
||||||
cairo_fixed_t fw, fh;
|
cairo_fixed_t fw, fh;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
|
|
||||||
status = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf, &img);
|
status = _cairo_surface_to_cgimage ((cairo_surface_t *) surface, pat_surf, &img);
|
||||||
if (status == CAIRO_STATUS_SUCCESS && img == NULL)
|
if (status == CAIRO_STATUS_SUCCESS && img == NULL)
|
||||||
|
|
@ -1263,9 +1281,8 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface,
|
||||||
cairo_matrix_invert(&m);
|
cairo_matrix_invert(&m);
|
||||||
_cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceTransform);
|
_cairo_quartz_cairo_matrix_to_quartz (&m, &surface->sourceTransform);
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (pat_surf, &extents);
|
is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
|
||||||
if (status)
|
assert (is_bounded);
|
||||||
return DO_UNSUPPORTED;
|
|
||||||
|
|
||||||
if (source->extend == CAIRO_EXTEND_NONE) {
|
if (source->extend == CAIRO_EXTEND_NONE) {
|
||||||
surface->sourceImageRect = CGRectMake (0, 0, extents.width, extents.height);
|
surface->sourceImageRect = CGRectMake (0, 0, extents.width, extents.height);
|
||||||
|
|
@ -1485,6 +1502,7 @@ _cairo_quartz_surface_finish (void *abstract_surface)
|
||||||
|
|
||||||
/* Restore our saved gstate that we use to reset clipping */
|
/* Restore our saved gstate that we use to reset clipping */
|
||||||
CGContextRestoreGState (surface->cgContext);
|
CGContextRestoreGState (surface->cgContext);
|
||||||
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
|
||||||
CGContextRelease (surface->cgContext);
|
CGContextRelease (surface->cgContext);
|
||||||
|
|
||||||
|
|
@ -1700,22 +1718,21 @@ FINISH:
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_quartz_surface_get_extents (void *abstract_surface,
|
_cairo_quartz_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||||
|
|
||||||
*extents = surface->extents;
|
*extents = surface->extents;
|
||||||
|
return TRUE;
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_quartz_surface_paint (void *abstract_surface,
|
_cairo_quartz_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||||
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -1729,6 +1746,10 @@ _cairo_quartz_surface_paint (void *abstract_surface,
|
||||||
if (op == CAIRO_OPERATOR_DEST)
|
if (op == CAIRO_OPERATOR_DEST)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op));
|
CGContextSetCompositeOperation (surface->cgContext, _cairo_quartz_cairo_operator_to_quartz (op));
|
||||||
|
|
||||||
action = _cairo_quartz_setup_source (surface, source);
|
action = _cairo_quartz_setup_source (surface, source);
|
||||||
|
|
@ -1771,7 +1792,7 @@ _cairo_quartz_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||||
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -1790,7 +1811,7 @@ _cairo_quartz_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
/* Check whether the path would be a no-op */
|
/* Check whether the path would be a no-op */
|
||||||
/* XXX handle unbounded ops */
|
/* XXX handle unbounded ops */
|
||||||
if (_cairo_path_fixed_is_empty(path) ||
|
if (_cairo_path_fixed_fill_is_empty(path) ||
|
||||||
(_cairo_path_fixed_is_box(path, &box) &&
|
(_cairo_path_fixed_is_box(path, &box) &&
|
||||||
box.p1.x == box.p2.x &&
|
box.p1.x == box.p2.x &&
|
||||||
box.p1.y == box.p2.y))
|
box.p1.y == box.p2.y))
|
||||||
|
|
@ -1798,6 +1819,10 @@ _cairo_quartz_surface_fill (void *abstract_surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
CGContextSaveGState (surface->cgContext);
|
CGContextSaveGState (surface->cgContext);
|
||||||
|
|
||||||
CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE));
|
CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE));
|
||||||
|
|
@ -1879,7 +1904,7 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||||
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -1896,6 +1921,10 @@ _cairo_quartz_surface_stroke (void *abstract_surface,
|
||||||
if (op == CAIRO_OPERATOR_DEST)
|
if (op == CAIRO_OPERATOR_DEST)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
CGContextSaveGState (surface->cgContext);
|
CGContextSaveGState (surface->cgContext);
|
||||||
|
|
||||||
// Turning antialiasing off used to cause misrendering with
|
// Turning antialiasing off used to cause misrendering with
|
||||||
|
|
@ -2024,7 +2053,7 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
int *remaining_glyphs,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
CGAffineTransform textTransform, ctm;
|
CGAffineTransform textTransform, ctm;
|
||||||
#define STATIC_BUF_SIZE 64
|
#define STATIC_BUF_SIZE 64
|
||||||
|
|
@ -2055,6 +2084,10 @@ _cairo_quartz_surface_show_glyphs (void *abstract_surface,
|
||||||
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_QUARTZ)
|
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_QUARTZ)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
CGContextSaveGState (surface->cgContext);
|
CGContextSaveGState (surface->cgContext);
|
||||||
|
|
||||||
action = _cairo_quartz_setup_source (surface, source);
|
action = _cairo_quartz_setup_source (surface, source);
|
||||||
|
|
@ -2239,10 +2272,10 @@ _cairo_quartz_surface_mask_with_surface (cairo_quartz_surface_t *surface,
|
||||||
cairo_surface_t *pat_surf = mask->surface;
|
cairo_surface_t *pat_surf = mask->surface;
|
||||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
CGAffineTransform ctm, mask_matrix;
|
CGAffineTransform ctm, mask_matrix;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (pat_surf, &mask_extents);
|
is_bounded = _cairo_surface_get_extents (pat_surf, &mask_extents);
|
||||||
if (status)
|
assert (is_bounded);
|
||||||
return status;
|
|
||||||
|
|
||||||
// everything would be masked out, so do nothing
|
// everything would be masked out, so do nothing
|
||||||
if (mask_extents.width == 0 || mask_extents.height == 0)
|
if (mask_extents.width == 0 || mask_extents.height == 0)
|
||||||
|
|
@ -2347,7 +2380,7 @@ _cairo_quartz_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
||||||
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
cairo_int_status_t rv = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -2357,6 +2390,10 @@ _cairo_quartz_surface_mask (void *abstract_surface,
|
||||||
if (IS_EMPTY(surface))
|
if (IS_EMPTY(surface))
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
rv = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
|
if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||||
/* This is easy; we just need to paint with the alpha. */
|
/* This is easy; we just need to paint with the alpha. */
|
||||||
cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask;
|
cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask;
|
||||||
|
|
@ -2387,14 +2424,15 @@ _cairo_quartz_surface_mask (void *abstract_surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_status_t
|
||||||
_cairo_quartz_surface_intersect_clip_path (void *abstract_surface,
|
_cairo_quartz_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias)
|
cairo_antialias_t antialias)
|
||||||
{
|
{
|
||||||
cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
|
cairo_quartz_surface_t *surface =
|
||||||
|
cairo_container_of (clipper, cairo_quartz_surface_t, clipper);
|
||||||
quartz_stroke_t stroke;
|
quartz_stroke_t stroke;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
|
|
@ -2455,8 +2493,6 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_quartz_surface_intersect_clip_path,
|
|
||||||
_cairo_quartz_surface_get_extents,
|
_cairo_quartz_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -2477,7 +2513,6 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
|
||||||
|
|
||||||
_cairo_quartz_surface_snapshot,
|
_cairo_quartz_surface_snapshot,
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL /* fill_stroke */
|
NULL /* fill_stroke */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2501,6 +2536,9 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
|
||||||
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend,
|
_cairo_surface_init(&surface->base, &cairo_quartz_surface_backend,
|
||||||
content);
|
content);
|
||||||
|
|
||||||
|
_cairo_surface_clipper_init (&surface->clipper,
|
||||||
|
_cairo_quartz_surface_intersect_clip_path);
|
||||||
|
|
||||||
/* Save our extents */
|
/* Save our extents */
|
||||||
surface->extents.x = surface->extents.y = 0;
|
surface->extents.x = surface->extents.y = 0;
|
||||||
surface->extents.width = width;
|
surface->extents.width = width;
|
||||||
|
|
|
||||||
73
src/cairo-region-private.h
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
|
||||||
|
/* cairo - a vector graphics library with display and print output
|
||||||
|
*
|
||||||
|
* Copyright © 2005 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it either under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1 as published by the Free Software Foundation
|
||||||
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||||
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||||
|
* notice, a recipient may use your version of this file under either
|
||||||
|
* the MPL or the LGPL.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the LGPL along with this library
|
||||||
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
* You should have received a copy of the MPL along with this library
|
||||||
|
* in the file COPYING-MPL-1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||||
|
* the specific language governing rights and limitations.
|
||||||
|
*
|
||||||
|
* The Original Code is the cairo graphics library.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Owen Taylor <otaylor@redhat.com>
|
||||||
|
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||||
|
* Søren Sandmann <sandmann@daimi.au.dk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CAIRO_REGION_PRIVATE_H
|
||||||
|
#define CAIRO_REGION_PRIVATE_H
|
||||||
|
|
||||||
|
#include "cairo-types-private.h"
|
||||||
|
#include "cairo-reference-count-private.h"
|
||||||
|
|
||||||
|
#include <pixman.h>
|
||||||
|
|
||||||
|
CAIRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
struct _cairo_region {
|
||||||
|
cairo_reference_count_t ref_count;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
pixman_region32_t rgn;
|
||||||
|
};
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_region_init (cairo_region_t *region);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_region_init_rectangle (cairo_region_t *region,
|
||||||
|
const cairo_rectangle_int_t *rectangle);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_region_init_rectangles (cairo_region_t *region,
|
||||||
|
const cairo_rectangle_int_t *rects,
|
||||||
|
int count);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_region_fini (cairo_region_t *region);
|
||||||
|
|
||||||
|
CAIRO_END_DECLS
|
||||||
|
|
||||||
|
#endif /* CAIRO_REGION_PRIVATE_H */
|
||||||
|
|
@ -38,7 +38,13 @@
|
||||||
|
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
|
|
||||||
|
#include "cairo-region-private.h"
|
||||||
|
|
||||||
|
/* XXX need to update pixman headers to be const as appropriate */
|
||||||
|
#define CONST_CAST (pixman_region32_t *)
|
||||||
|
|
||||||
static const cairo_region_t _cairo_region_nil = {
|
static const cairo_region_t _cairo_region_nil = {
|
||||||
|
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -82,6 +88,7 @@ _cairo_region_init (cairo_region_t *region)
|
||||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
|
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
|
||||||
|
|
||||||
region->status = CAIRO_STATUS_SUCCESS;
|
region->status = CAIRO_STATUS_SUCCESS;
|
||||||
|
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0);
|
||||||
pixman_region32_init (®ion->rgn);
|
pixman_region32_init (®ion->rgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,6 +99,7 @@ _cairo_region_init_rectangle (cairo_region_t *region,
|
||||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
|
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
|
||||||
|
|
||||||
region->status = CAIRO_STATUS_SUCCESS;
|
region->status = CAIRO_STATUS_SUCCESS;
|
||||||
|
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0);
|
||||||
pixman_region32_init_rect (®ion->rgn,
|
pixman_region32_init_rect (®ion->rgn,
|
||||||
rectangle->x, rectangle->y,
|
rectangle->x, rectangle->y,
|
||||||
rectangle->width, rectangle->height);
|
rectangle->width, rectangle->height);
|
||||||
|
|
@ -100,6 +108,7 @@ _cairo_region_init_rectangle (cairo_region_t *region,
|
||||||
void
|
void
|
||||||
_cairo_region_fini (cairo_region_t *region)
|
_cairo_region_fini (cairo_region_t *region)
|
||||||
{
|
{
|
||||||
|
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count));
|
||||||
pixman_region32_fini (®ion->rgn);
|
pixman_region32_fini (®ion->rgn);
|
||||||
VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t)));
|
VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t)));
|
||||||
}
|
}
|
||||||
|
|
@ -127,6 +136,7 @@ cairo_region_create (void)
|
||||||
return (cairo_region_t *) &_cairo_region_nil;
|
return (cairo_region_t *) &_cairo_region_nil;
|
||||||
|
|
||||||
region->status = CAIRO_STATUS_SUCCESS;
|
region->status = CAIRO_STATUS_SUCCESS;
|
||||||
|
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1);
|
||||||
|
|
||||||
pixman_region32_init (®ion->rgn);
|
pixman_region32_init (®ion->rgn);
|
||||||
|
|
||||||
|
|
@ -134,29 +144,23 @@ cairo_region_create (void)
|
||||||
}
|
}
|
||||||
slim_hidden_def (cairo_region_create);
|
slim_hidden_def (cairo_region_create);
|
||||||
|
|
||||||
cairo_region_t *
|
cairo_status_t
|
||||||
cairo_region_create_rectangles (cairo_rectangle_int_t *rects,
|
_cairo_region_init_rectangles (cairo_region_t *region,
|
||||||
int count)
|
const cairo_rectangle_int_t *rects,
|
||||||
|
int count)
|
||||||
{
|
{
|
||||||
pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
|
pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
|
||||||
pixman_box32_t *pboxes = stack_pboxes;
|
pixman_box32_t *pboxes = stack_pboxes;
|
||||||
cairo_region_t *region;
|
cairo_status_t status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
region = _cairo_malloc (sizeof (cairo_region_t));
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
|
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0);
|
||||||
if (!region)
|
|
||||||
return (cairo_region_t *)&_cairo_region_nil;
|
|
||||||
|
|
||||||
region->status = CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (count > ARRAY_LENGTH (stack_pboxes)) {
|
if (count > ARRAY_LENGTH (stack_pboxes)) {
|
||||||
pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
|
pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
|
||||||
|
if (unlikely (pboxes == NULL))
|
||||||
if (unlikely (pboxes == NULL)) {
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
free (region);
|
|
||||||
return (cairo_region_t *)&_cairo_region_nil;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
|
@ -166,15 +170,35 @@ cairo_region_create_rectangles (cairo_rectangle_int_t *rects,
|
||||||
pboxes[i].y2 = rects[i].y + rects[i].height;
|
pboxes[i].y2 = rects[i].y + rects[i].height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) {
|
if (! pixman_region32_init_rects (®ion->rgn, pboxes, count))
|
||||||
free (region);
|
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
region = (cairo_region_t *)&_cairo_region_nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pboxes != stack_pboxes)
|
if (pboxes != stack_pboxes)
|
||||||
free (pboxes);
|
free (pboxes);
|
||||||
|
|
||||||
|
return region->status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_region_t *
|
||||||
|
cairo_region_create_rectangles (const cairo_rectangle_int_t *rects,
|
||||||
|
int count)
|
||||||
|
{
|
||||||
|
cairo_region_t *region;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
region = _cairo_malloc (sizeof (cairo_region_t));
|
||||||
|
if (unlikely (region == NULL)) {
|
||||||
|
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
return (cairo_region_t *) &_cairo_region_nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_region_init_rectangles (region, rects, count);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
cairo_region_destroy (region);
|
||||||
|
return (cairo_region_t *) &_cairo_region_nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1);
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
slim_hidden_def (cairo_region_create_rectangles);
|
slim_hidden_def (cairo_region_create_rectangles);
|
||||||
|
|
@ -199,10 +223,11 @@ cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle)
|
||||||
cairo_region_t *region;
|
cairo_region_t *region;
|
||||||
|
|
||||||
region = _cairo_malloc (sizeof (cairo_region_t));
|
region = _cairo_malloc (sizeof (cairo_region_t));
|
||||||
if (region == NULL)
|
if (unlikely (region == NULL))
|
||||||
return (cairo_region_t *) &_cairo_region_nil;
|
return (cairo_region_t *) &_cairo_region_nil;
|
||||||
|
|
||||||
region->status = CAIRO_STATUS_SUCCESS;
|
region->status = CAIRO_STATUS_SUCCESS;
|
||||||
|
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1);
|
||||||
|
|
||||||
pixman_region32_init_rect (®ion->rgn,
|
pixman_region32_init_rect (®ion->rgn,
|
||||||
rectangle->x, rectangle->y,
|
rectangle->x, rectangle->y,
|
||||||
|
|
@ -227,18 +252,20 @@ slim_hidden_def (cairo_region_create_rectangle);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
cairo_region_t *
|
cairo_region_t *
|
||||||
cairo_region_copy (cairo_region_t *original)
|
cairo_region_copy (const cairo_region_t *original)
|
||||||
{
|
{
|
||||||
cairo_region_t *copy;
|
cairo_region_t *copy;
|
||||||
|
|
||||||
if (original->status)
|
if (original != NULL && original->status)
|
||||||
return (cairo_region_t *) &_cairo_region_nil;
|
return (cairo_region_t *) &_cairo_region_nil;
|
||||||
|
|
||||||
copy = cairo_region_create ();
|
copy = cairo_region_create ();
|
||||||
if (copy->status)
|
if (unlikely (copy->status))
|
||||||
return copy;
|
return copy;
|
||||||
|
|
||||||
if (! pixman_region32_copy (©->rgn, &original->rgn)) {
|
if (original != NULL &&
|
||||||
|
! pixman_region32_copy (©->rgn, CONST_CAST &original->rgn))
|
||||||
|
{
|
||||||
cairo_region_destroy (copy);
|
cairo_region_destroy (copy);
|
||||||
return (cairo_region_t *) &_cairo_region_nil;
|
return (cairo_region_t *) &_cairo_region_nil;
|
||||||
}
|
}
|
||||||
|
|
@ -247,6 +274,31 @@ cairo_region_copy (cairo_region_t *original)
|
||||||
}
|
}
|
||||||
slim_hidden_def (cairo_region_copy);
|
slim_hidden_def (cairo_region_copy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cairo_region_reference:
|
||||||
|
* @region: a #cairo_region_t
|
||||||
|
*
|
||||||
|
* Increases the reference count on @region by one. This prevents
|
||||||
|
* @region from being destroyed until a matching call to
|
||||||
|
* cairo_region_destroy() is made.
|
||||||
|
*
|
||||||
|
* Return value: the referenced #cairo_region_t.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
**/
|
||||||
|
cairo_region_t *
|
||||||
|
cairo_region_reference (cairo_region_t *region)
|
||||||
|
{
|
||||||
|
if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count));
|
||||||
|
|
||||||
|
_cairo_reference_count_inc (®ion->ref_count);
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
slim_hidden_def (cairo_region_reference);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cairo_region_destroy:
|
* cairo_region_destroy:
|
||||||
* @region: a #cairo_region_t
|
* @region: a #cairo_region_t
|
||||||
|
|
@ -260,10 +312,15 @@ slim_hidden_def (cairo_region_copy);
|
||||||
void
|
void
|
||||||
cairo_region_destroy (cairo_region_t *region)
|
cairo_region_destroy (cairo_region_t *region)
|
||||||
{
|
{
|
||||||
if (region == (cairo_region_t *) &_cairo_region_nil)
|
if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pixman_region32_fini (®ion->rgn);
|
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count));
|
||||||
|
|
||||||
|
if (! _cairo_reference_count_dec_and_test (®ion->ref_count))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_cairo_region_fini (region);
|
||||||
free (region);
|
free (region);
|
||||||
}
|
}
|
||||||
slim_hidden_def (cairo_region_destroy);
|
slim_hidden_def (cairo_region_destroy);
|
||||||
|
|
@ -279,12 +336,12 @@ slim_hidden_def (cairo_region_destroy);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
int
|
int
|
||||||
cairo_region_num_rectangles (cairo_region_t *region)
|
cairo_region_num_rectangles (const cairo_region_t *region)
|
||||||
{
|
{
|
||||||
if (region->status)
|
if (region->status)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return pixman_region32_n_rects (®ion->rgn);
|
return pixman_region32_n_rects (CONST_CAST ®ion->rgn);
|
||||||
}
|
}
|
||||||
slim_hidden_def (cairo_region_num_rectangles);
|
slim_hidden_def (cairo_region_num_rectangles);
|
||||||
|
|
||||||
|
|
@ -299,7 +356,7 @@ slim_hidden_def (cairo_region_num_rectangles);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
cairo_region_get_rectangle (cairo_region_t *region,
|
cairo_region_get_rectangle (const cairo_region_t *region,
|
||||||
int nth,
|
int nth,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -311,7 +368,7 @@ cairo_region_get_rectangle (cairo_region_t *region,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth;
|
pbox = pixman_region32_rectangles (CONST_CAST ®ion->rgn, NULL) + nth;
|
||||||
|
|
||||||
rectangle->x = pbox->x1;
|
rectangle->x = pbox->x1;
|
||||||
rectangle->y = pbox->y1;
|
rectangle->y = pbox->y1;
|
||||||
|
|
@ -330,7 +387,7 @@ slim_hidden_def (cairo_region_get_rectangle);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
cairo_region_get_extents (cairo_region_t *region,
|
cairo_region_get_extents (const cairo_region_t *region,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
pixman_box32_t *pextents;
|
pixman_box32_t *pextents;
|
||||||
|
|
@ -341,7 +398,7 @@ cairo_region_get_extents (cairo_region_t *region,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pextents = pixman_region32_extents (®ion->rgn);
|
pextents = pixman_region32_extents (CONST_CAST ®ion->rgn);
|
||||||
|
|
||||||
extents->x = pextents->x1;
|
extents->x = pextents->x1;
|
||||||
extents->y = pextents->y1;
|
extents->y = pextents->y1;
|
||||||
|
|
@ -362,7 +419,7 @@ slim_hidden_def (cairo_region_get_extents);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
cairo_region_status (cairo_region_t *region)
|
cairo_region_status (const cairo_region_t *region)
|
||||||
{
|
{
|
||||||
return region->status;
|
return region->status;
|
||||||
}
|
}
|
||||||
|
|
@ -564,12 +621,12 @@ slim_hidden_def (cairo_region_union_rectangle);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
cairo_bool_t
|
cairo_bool_t
|
||||||
cairo_region_is_empty (cairo_region_t *region)
|
cairo_region_is_empty (const cairo_region_t *region)
|
||||||
{
|
{
|
||||||
if (region->status)
|
if (region->status)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return ! pixman_region32_not_empty (®ion->rgn);
|
return ! pixman_region32_not_empty (CONST_CAST ®ion->rgn);
|
||||||
}
|
}
|
||||||
slim_hidden_def (cairo_region_is_empty);
|
slim_hidden_def (cairo_region_is_empty);
|
||||||
|
|
||||||
|
|
@ -610,7 +667,7 @@ slim_hidden_def (cairo_region_translate);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
cairo_region_overlap_t
|
cairo_region_overlap_t
|
||||||
cairo_region_contains_rectangle (cairo_region_t *region,
|
cairo_region_contains_rectangle (const cairo_region_t *region,
|
||||||
const cairo_rectangle_int_t *rectangle)
|
const cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
pixman_box32_t pbox;
|
pixman_box32_t pbox;
|
||||||
|
|
@ -624,7 +681,8 @@ cairo_region_contains_rectangle (cairo_region_t *region,
|
||||||
pbox.x2 = rectangle->x + rectangle->width;
|
pbox.x2 = rectangle->x + rectangle->width;
|
||||||
pbox.y2 = rectangle->y + rectangle->height;
|
pbox.y2 = rectangle->y + rectangle->height;
|
||||||
|
|
||||||
poverlap = pixman_region32_contains_rectangle (®ion->rgn, &pbox);
|
poverlap = pixman_region32_contains_rectangle (CONST_CAST ®ion->rgn,
|
||||||
|
&pbox);
|
||||||
switch (poverlap) {
|
switch (poverlap) {
|
||||||
default:
|
default:
|
||||||
case PIXMAN_REGION_OUT: return CAIRO_REGION_OVERLAP_OUT;
|
case PIXMAN_REGION_OUT: return CAIRO_REGION_OVERLAP_OUT;
|
||||||
|
|
@ -647,14 +705,44 @@ slim_hidden_def (cairo_region_contains_rectangle);
|
||||||
* Since: 1.10
|
* Since: 1.10
|
||||||
**/
|
**/
|
||||||
cairo_bool_t
|
cairo_bool_t
|
||||||
cairo_region_contains_point (cairo_region_t *region,
|
cairo_region_contains_point (const cairo_region_t *region,
|
||||||
int x, int y)
|
int x, int y)
|
||||||
{
|
{
|
||||||
pixman_box32_t box;
|
pixman_box32_t box;
|
||||||
|
|
||||||
if (region->status)
|
if (region->status)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return pixman_region32_contains_point (®ion->rgn, x, y, &box);
|
return pixman_region32_contains_point (CONST_CAST ®ion->rgn, x, y, &box);
|
||||||
}
|
}
|
||||||
slim_hidden_def (cairo_region_contains_point);
|
slim_hidden_def (cairo_region_contains_point);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cairo_region_equal:
|
||||||
|
* @region_a: a #cairo_region_t
|
||||||
|
* @region_b: a #cairo_region_t
|
||||||
|
*
|
||||||
|
* Compares whether region_a is equivalent to region_b.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if both regions contained the same coverage,
|
||||||
|
* %FALSE if it is not.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
**/
|
||||||
|
cairo_bool_t
|
||||||
|
cairo_region_equal (const cairo_region_t *a,
|
||||||
|
const cairo_region_t *b)
|
||||||
|
{
|
||||||
|
/* error objects are never equal */
|
||||||
|
if ((a != NULL && a->status) || (b != NULL && b->status))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (a == b)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (a == NULL || b == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return pixman_region32_equal (CONST_CAST &a->rgn, CONST_CAST &b->rgn);
|
||||||
|
}
|
||||||
|
slim_hidden_def (cairo_region_equal);
|
||||||
|
|
|
||||||
|
|
@ -1969,18 +1969,19 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *pattern,
|
const cairo_pattern_t *pattern,
|
||||||
cairo_surface_t *surface,
|
cairo_surface_t *surface,
|
||||||
int source_x,
|
int source_x,
|
||||||
int source_y,
|
int source_y,
|
||||||
int dest_x,
|
int dest_x,
|
||||||
int dest_y,
|
int dest_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs)
|
int num_glyphs,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_surface_t *mask = NULL;
|
cairo_surface_t *mask = NULL;
|
||||||
|
|
@ -2008,7 +2009,9 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
source_x, source_y,
|
source_x, source_y,
|
||||||
dest_x, dest_y,
|
dest_x, dest_y,
|
||||||
width, height,
|
width, height,
|
||||||
glyphs, num_glyphs, &remaining_glyphs);
|
glyphs, num_glyphs,
|
||||||
|
clip_region,
|
||||||
|
&remaining_glyphs);
|
||||||
glyphs += num_glyphs - remaining_glyphs;
|
glyphs += num_glyphs - remaining_glyphs;
|
||||||
num_glyphs = remaining_glyphs;
|
num_glyphs = remaining_glyphs;
|
||||||
if (remaining_glyphs == 0)
|
if (remaining_glyphs == 0)
|
||||||
|
|
@ -2088,7 +2091,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
width, height);
|
width, height,
|
||||||
|
NULL);
|
||||||
|
|
||||||
_cairo_pattern_fini (&mask_pattern.base);
|
_cairo_pattern_fini (&mask_pattern.base);
|
||||||
|
|
||||||
|
|
@ -2116,7 +2120,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
0, 0,
|
0, 0,
|
||||||
x - dest_x, y - dest_y,
|
x - dest_x, y - dest_y,
|
||||||
glyph_surface->width,
|
glyph_surface->width,
|
||||||
glyph_surface->height);
|
glyph_surface->height,
|
||||||
|
NULL);
|
||||||
|
|
||||||
_cairo_pattern_fini (&glyph_pattern.base);
|
_cairo_pattern_fini (&glyph_pattern.base);
|
||||||
|
|
||||||
|
|
@ -2134,7 +2139,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
source_x, source_y,
|
source_x, source_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
dest_x, dest_y,
|
dest_x, dest_y,
|
||||||
width, height);
|
width, height,
|
||||||
|
clip_region);
|
||||||
|
|
||||||
_cairo_pattern_fini (&mask_pattern.base);
|
_cairo_pattern_fini (&mask_pattern.base);
|
||||||
|
|
||||||
|
|
@ -2148,58 +2154,6 @@ CLEANUP_MASK:
|
||||||
return _cairo_scaled_font_set_error (scaled_font, status);
|
return _cairo_scaled_font_set_error (scaled_font, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _cairo_scaled_glyph_path_closure {
|
|
||||||
cairo_point_t offset;
|
|
||||||
cairo_path_fixed_t *path;
|
|
||||||
} cairo_scaled_glyph_path_closure_t;
|
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_scaled_glyph_path_move_to (void *abstract_closure,
|
|
||||||
const cairo_point_t *point)
|
|
||||||
{
|
|
||||||
cairo_scaled_glyph_path_closure_t *closure = abstract_closure;
|
|
||||||
|
|
||||||
return _cairo_path_fixed_move_to (closure->path,
|
|
||||||
point->x + closure->offset.x,
|
|
||||||
point->y + closure->offset.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_scaled_glyph_path_line_to (void *abstract_closure,
|
|
||||||
const cairo_point_t *point)
|
|
||||||
{
|
|
||||||
cairo_scaled_glyph_path_closure_t *closure = abstract_closure;
|
|
||||||
|
|
||||||
return _cairo_path_fixed_line_to (closure->path,
|
|
||||||
point->x + closure->offset.x,
|
|
||||||
point->y + closure->offset.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_scaled_glyph_path_curve_to (void *abstract_closure,
|
|
||||||
const cairo_point_t *p0,
|
|
||||||
const cairo_point_t *p1,
|
|
||||||
const cairo_point_t *p2)
|
|
||||||
{
|
|
||||||
cairo_scaled_glyph_path_closure_t *closure = abstract_closure;
|
|
||||||
|
|
||||||
return _cairo_path_fixed_curve_to (closure->path,
|
|
||||||
p0->x + closure->offset.x,
|
|
||||||
p0->y + closure->offset.y,
|
|
||||||
p1->x + closure->offset.x,
|
|
||||||
p1->y + closure->offset.y,
|
|
||||||
p2->x + closure->offset.x,
|
|
||||||
p2->y + closure->offset.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_scaled_glyph_path_close_path (void *abstract_closure)
|
|
||||||
{
|
|
||||||
cairo_scaled_glyph_path_closure_t *closure = abstract_closure;
|
|
||||||
|
|
||||||
return _cairo_path_fixed_close_path (closure->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a single-device-unit rectangle to a path. */
|
/* Add a single-device-unit rectangle to a path. */
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_add_unit_rectangle_to_path (cairo_path_fixed_t *path, int x, int y)
|
_add_unit_rectangle_to_path (cairo_path_fixed_t *path, int x, int y)
|
||||||
|
|
@ -2309,14 +2263,13 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
int i;
|
int i;
|
||||||
cairo_scaled_glyph_path_closure_t closure;
|
cairo_path_fixed_t glyph_path_static;
|
||||||
cairo_path_fixed_t *glyph_path;
|
cairo_path_fixed_t *glyph_path;
|
||||||
|
|
||||||
status = scaled_font->status;
|
status = scaled_font->status;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
closure.path = path;
|
|
||||||
_cairo_scaled_font_freeze_cache (scaled_font);
|
_cairo_scaled_font_freeze_cache (scaled_font);
|
||||||
for (i = 0; i < num_glyphs; i++) {
|
for (i = 0; i < num_glyphs; i++) {
|
||||||
cairo_scaled_glyph_t *scaled_glyph;
|
cairo_scaled_glyph_t *scaled_glyph;
|
||||||
|
|
@ -2325,14 +2278,12 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||||
glyphs[i].index,
|
glyphs[i].index,
|
||||||
CAIRO_SCALED_GLYPH_INFO_PATH,
|
CAIRO_SCALED_GLYPH_INFO_PATH,
|
||||||
&scaled_glyph);
|
&scaled_glyph);
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
if (status == CAIRO_STATUS_SUCCESS) {
|
||||||
glyph_path = scaled_glyph->path;
|
glyph_path = scaled_glyph->path;
|
||||||
else if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
} else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||||
goto BAIL;
|
/* If the font is incapable of providing a path, then we'll
|
||||||
|
* have to trace our own from a surface.
|
||||||
/* If the font is incapable of providing a path, then we'll
|
*/
|
||||||
* have to trace our own from a surface. */
|
|
||||||
if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
|
|
||||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||||
glyphs[i].index,
|
glyphs[i].index,
|
||||||
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
CAIRO_SCALED_GLYPH_INFO_SURFACE,
|
||||||
|
|
@ -2340,31 +2291,22 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
|
|
||||||
glyph_path = _cairo_path_fixed_create ();
|
_cairo_path_fixed_init (&glyph_path_static);
|
||||||
if (unlikely (glyph_path == NULL)) {
|
glyph_path = &glyph_path_static;
|
||||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
goto BAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = _trace_mask_to_path (scaled_glyph->surface, glyph_path);
|
status = _trace_mask_to_path (scaled_glyph->surface, glyph_path);
|
||||||
if (unlikely (status)) {
|
if (unlikely (status))
|
||||||
_cairo_path_fixed_destroy (glyph_path);
|
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
}
|
} else {
|
||||||
|
goto BAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
closure.offset.x = _cairo_fixed_from_double (glyphs[i].x);
|
status = _cairo_path_fixed_append (path,
|
||||||
closure.offset.y = _cairo_fixed_from_double (glyphs[i].y);
|
glyph_path, CAIRO_DIRECTION_FORWARD,
|
||||||
|
_cairo_fixed_from_double (glyphs[i].x),
|
||||||
|
_cairo_fixed_from_double (glyphs[i].y));
|
||||||
|
|
||||||
status = _cairo_path_fixed_interpret (glyph_path,
|
|
||||||
CAIRO_DIRECTION_FORWARD,
|
|
||||||
_scaled_glyph_path_move_to,
|
|
||||||
_scaled_glyph_path_line_to,
|
|
||||||
_scaled_glyph_path_curve_to,
|
|
||||||
_scaled_glyph_path_close_path,
|
|
||||||
&closure);
|
|
||||||
if (glyph_path != scaled_glyph->path)
|
if (glyph_path != scaled_glyph->path)
|
||||||
_cairo_path_fixed_destroy (glyph_path);
|
_cairo_path_fixed_fini (glyph_path);
|
||||||
|
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,16 @@ cairo_script_surface_create_for_stream (cairo_write_func_t write_func,
|
||||||
double width,
|
double width,
|
||||||
double height);
|
double height);
|
||||||
|
|
||||||
|
cairo_public cairo_surface_t *
|
||||||
|
cairo_script_surface_create_for_target (cairo_surface_t *surface,
|
||||||
|
cairo_write_func_t write_func,
|
||||||
|
void *closure);
|
||||||
|
|
||||||
|
cairo_public void
|
||||||
|
cairo_script_surface_write_comment (cairo_surface_t *abstract_surface,
|
||||||
|
const char *comment,
|
||||||
|
int len);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CAIRO_SCRIPT_MODE_BINARY,
|
CAIRO_SCRIPT_MODE_BINARY,
|
||||||
CAIRO_SCRIPT_MODE_ASCII
|
CAIRO_SCRIPT_MODE_ASCII
|
||||||
|
|
|
||||||
|
|
@ -132,13 +132,14 @@ _cairo_span_renderer_set_error (void *abstract_renderer,
|
||||||
cairo_status_t error);
|
cairo_status_t error);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_path_fixed_fill_using_spans (
|
_cairo_path_fixed_fill_using_spans (cairo_operator_t op,
|
||||||
cairo_operator_t op,
|
const cairo_pattern_t *pattern,
|
||||||
const cairo_pattern_t *pattern,
|
cairo_path_fixed_t *path,
|
||||||
cairo_path_fixed_t *path,
|
cairo_surface_t *dst,
|
||||||
cairo_surface_t *dst,
|
cairo_fill_rule_t fill_rule,
|
||||||
cairo_fill_rule_t fill_rule,
|
double tolerance,
|
||||||
double tolerance,
|
cairo_antialias_t antialias,
|
||||||
cairo_antialias_t antialias,
|
const cairo_composite_rectangles_t *rects,
|
||||||
const cairo_composite_rectangles_t *rects);
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
#endif /* CAIRO_SPANS_PRIVATE_H */
|
#endif /* CAIRO_SPANS_PRIVATE_H */
|
||||||
|
|
|
||||||
|
|
@ -149,19 +149,19 @@ _create_scan_converter (cairo_fill_rule_t fill_rule,
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_path_fixed_fill_using_spans (
|
_cairo_path_fixed_fill_using_spans (cairo_operator_t op,
|
||||||
cairo_operator_t op,
|
const cairo_pattern_t *pattern,
|
||||||
const cairo_pattern_t *pattern,
|
cairo_path_fixed_t *path,
|
||||||
cairo_path_fixed_t *path,
|
cairo_surface_t *dst,
|
||||||
cairo_surface_t *dst,
|
cairo_fill_rule_t fill_rule,
|
||||||
cairo_fill_rule_t fill_rule,
|
double tolerance,
|
||||||
double tolerance,
|
cairo_antialias_t antialias,
|
||||||
cairo_antialias_t antialias,
|
const cairo_composite_rectangles_t *rects,
|
||||||
const cairo_composite_rectangles_t *rects)
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_span_renderer_t *renderer = _cairo_surface_create_span_renderer (
|
cairo_span_renderer_t *renderer = _cairo_surface_create_span_renderer (
|
||||||
op, pattern, dst, antialias, rects);
|
op, pattern, dst, antialias, rects, clip_region);
|
||||||
cairo_scan_converter_t *converter = _create_scan_converter (
|
cairo_scan_converter_t *converter = _create_scan_converter (
|
||||||
fill_rule, antialias, rects);
|
fill_rule, antialias, rects);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,13 +110,13 @@ _cairo_stroke_style_max_distance_from_path (const cairo_stroke_style_t *style,
|
||||||
style_expansion = M_SQRT1_2;
|
style_expansion = M_SQRT1_2;
|
||||||
|
|
||||||
if (style->line_join == CAIRO_LINE_JOIN_MITER &&
|
if (style->line_join == CAIRO_LINE_JOIN_MITER &&
|
||||||
style_expansion < style->miter_limit)
|
style_expansion < M_SQRT2 * style->miter_limit)
|
||||||
{
|
{
|
||||||
style_expansion = style->miter_limit;
|
style_expansion = M_SQRT2 * style->miter_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
style_expansion *= style->line_width;
|
style_expansion *= style->line_width;
|
||||||
|
|
||||||
*dx = style_expansion * (fabs (ctm->xx) + fabs (ctm->xy));
|
*dx = style_expansion * hypot (ctm->xx, ctm->xy);
|
||||||
*dy = style_expansion * (fabs (ctm->yy) + fabs (ctm->yx));
|
*dy = style_expansion * hypot (ctm->yy, ctm->yx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
72
src/cairo-surface-clipper-private.h
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* cairo - a vector graphics library with display and print output
|
||||||
|
*
|
||||||
|
* Copyright © 2009 Chris Wilson
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it either under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1 as published by the Free Software Foundation
|
||||||
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||||
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||||
|
* notice, a recipient may use your version of this file under either
|
||||||
|
* the MPL or the LGPL.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the LGPL along with this library
|
||||||
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
* You should have received a copy of the MPL along with this library
|
||||||
|
* in the file COPYING-MPL-1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||||
|
* the specific language governing rights and limitations.
|
||||||
|
*
|
||||||
|
* The Original Code is the cairo graphics library.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is University of Southern
|
||||||
|
* California.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Chris Wilson <chris@chris-wilson.co.u>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CAIRO_SURFACE_CLIPPER_PRIVATE_H
|
||||||
|
#define CAIRO_SURFACE_CLIPPER_PRIVATE_H
|
||||||
|
|
||||||
|
#include "cairo-types-private.h"
|
||||||
|
#include "cairo-clip-private.h"
|
||||||
|
|
||||||
|
CAIRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _cairo_surface_clipper cairo_surface_clipper_t;
|
||||||
|
|
||||||
|
typedef cairo_status_t
|
||||||
|
(*cairo_surface_clipper_intersect_clip_path_func_t) (cairo_surface_clipper_t *,
|
||||||
|
cairo_path_fixed_t *,
|
||||||
|
cairo_fill_rule_t,
|
||||||
|
double,
|
||||||
|
cairo_antialias_t);
|
||||||
|
struct _cairo_surface_clipper {
|
||||||
|
cairo_clip_t clip;
|
||||||
|
cairo_bool_t is_clipped;
|
||||||
|
cairo_surface_clipper_intersect_clip_path_func_t intersect_clip_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_surface_clipper_intersect_clip_path_func_t intersect);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper);
|
||||||
|
|
||||||
|
CAIRO_END_DECLS
|
||||||
|
|
||||||
|
#endif /* CAIRO_SURFACE_CLIPPER_PRIVATE_H */
|
||||||
138
src/cairo-surface-clipper.c
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
/* cairo - a vector graphics library with display and print output
|
||||||
|
*
|
||||||
|
* Copyright © 2009 Chris Wilson
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it either under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1 as published by the Free Software Foundation
|
||||||
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||||
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||||
|
* notice, a recipient may use your version of this file under either
|
||||||
|
* the MPL or the LGPL.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the LGPL along with this library
|
||||||
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
* You should have received a copy of the MPL along with this library
|
||||||
|
* in the file COPYING-MPL-1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||||
|
* the specific language governing rights and limitations.
|
||||||
|
*
|
||||||
|
* The Original Code is the cairo graphics library.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cairoint.h"
|
||||||
|
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
|
||||||
|
/* A collection of routines to facilitate vector surface clipping */
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_clip_path_t *clip_path)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
if (clip_path->prev != NULL) {
|
||||||
|
status =
|
||||||
|
_cairo_surface_clipper_intersect_clip_path_recursive (clipper,
|
||||||
|
clip_path->prev);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clipper->intersect_clip_path (clipper,
|
||||||
|
&clip_path->path,
|
||||||
|
clip_path->fill_rule,
|
||||||
|
clip_path->tolerance,
|
||||||
|
clip_path->antialias);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_bool_t clear;
|
||||||
|
|
||||||
|
/* XXX as we cache a reference to the path, and compare every time,
|
||||||
|
* we may in future need to install a notification if the clip->path
|
||||||
|
* is every modified (e.g. cairo_clip_translate).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (clip == NULL && clipper->clip.path == NULL)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (clip != NULL && clip->path == clipper->clip.path)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (clip != NULL && clipper->clip.path != NULL &&
|
||||||
|
_cairo_path_fixed_equal (&clip->path->path, &clipper->clip.path->path))
|
||||||
|
{
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all clipped out state should never propagate this far */
|
||||||
|
assert (clip == NULL || clip->path != NULL);
|
||||||
|
|
||||||
|
/* Check whether this clip is a continuation of the previous.
|
||||||
|
* If not, we have to remove the current clip and rebuild.
|
||||||
|
*/
|
||||||
|
clear = clip == NULL || clip->path->prev != clipper->clip.path;
|
||||||
|
|
||||||
|
_cairo_clip_reset (&clipper->clip);
|
||||||
|
_cairo_clip_init_copy (&clipper->clip, clip);
|
||||||
|
|
||||||
|
if (clear) {
|
||||||
|
clipper->is_clipped = FALSE;
|
||||||
|
status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
if (clip != NULL && clip->path != NULL) {
|
||||||
|
status =
|
||||||
|
_cairo_surface_clipper_intersect_clip_path_recursive (clipper,
|
||||||
|
clip->path);
|
||||||
|
clipper->is_clipped = TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cairo_clip_path_t *path = clip->path;
|
||||||
|
|
||||||
|
clipper->is_clipped = TRUE;
|
||||||
|
status = clipper->intersect_clip_path (clipper,
|
||||||
|
&path->path,
|
||||||
|
path->fill_rule,
|
||||||
|
path->tolerance,
|
||||||
|
path->antialias);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_surface_clipper_intersect_clip_path_func_t func)
|
||||||
|
{
|
||||||
|
_cairo_clip_init (&clipper->clip);
|
||||||
|
clipper->is_clipped = FALSE;
|
||||||
|
clipper->intersect_clip_path = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper)
|
||||||
|
{
|
||||||
|
_cairo_clip_reset (&clipper->clip);
|
||||||
|
clipper->is_clipped = FALSE;
|
||||||
|
}
|
||||||
|
|
@ -44,13 +44,15 @@
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fallback_paint (cairo_surface_t *surface,
|
_cairo_surface_fallback_paint (cairo_surface_t *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source);
|
const cairo_pattern_t *source,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fallback_mask (cairo_surface_t *surface,
|
_cairo_surface_fallback_mask (cairo_surface_t *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask);
|
const cairo_pattern_t *mask,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fallback_stroke (cairo_surface_t *surface,
|
_cairo_surface_fallback_stroke (cairo_surface_t *surface,
|
||||||
|
|
@ -61,7 +63,8 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface,
|
||||||
cairo_matrix_t *ctm,
|
cairo_matrix_t *ctm,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias);
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fallback_fill (cairo_surface_t *surface,
|
_cairo_surface_fallback_fill (cairo_surface_t *surface,
|
||||||
|
|
@ -70,7 +73,8 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias);
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
_cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
||||||
|
|
@ -78,7 +82,8 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font);
|
cairo_scaled_font_t *scaled_font,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_surface_t *
|
cairo_private cairo_surface_t *
|
||||||
_cairo_surface_fallback_snapshot (cairo_surface_t *surface);
|
_cairo_surface_fallback_snapshot (cairo_surface_t *surface);
|
||||||
|
|
@ -95,7 +100,8 @@ _cairo_surface_fallback_composite (cairo_operator_t op,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height);
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
_cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||||
|
|
@ -116,7 +122,8 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int num_traps);
|
int num_traps,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fallback_clone_similar (cairo_surface_t *surface,
|
_cairo_surface_fallback_clone_similar (cairo_surface_t *surface,
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#include "cairo-types-private.h"
|
#include "cairo-types-private.h"
|
||||||
#include "cairo-reference-count-private.h"
|
#include "cairo-reference-count-private.h"
|
||||||
|
#include "cairo-clip-private.h"
|
||||||
|
|
||||||
typedef void (*cairo_surface_func_t) (cairo_surface_t *);
|
typedef void (*cairo_surface_func_t) (cairo_surface_t *);
|
||||||
|
|
||||||
|
|
@ -77,24 +78,6 @@ struct _cairo_surface {
|
||||||
double x_fallback_resolution;
|
double x_fallback_resolution;
|
||||||
double y_fallback_resolution;
|
double y_fallback_resolution;
|
||||||
|
|
||||||
cairo_clip_t *clip;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each time a clip region is modified, it gets the next value in this
|
|
||||||
* sequence. This means that clip regions for this surface are uniquely
|
|
||||||
* identified and updates to the clip can be readily identified
|
|
||||||
*/
|
|
||||||
unsigned int next_clip_serial;
|
|
||||||
/*
|
|
||||||
* The serial number of the current clip. This is set when
|
|
||||||
* the surface clipping is set. The gstate can then cheaply
|
|
||||||
* check whether the surface clipping is already correct before
|
|
||||||
* performing a rendering operation.
|
|
||||||
*
|
|
||||||
* The special value '0' is reserved for the unclipped case.
|
|
||||||
*/
|
|
||||||
unsigned int current_clip_serial;
|
|
||||||
|
|
||||||
/* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */
|
/* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */
|
||||||
cairo_surface_t *snapshot_of;
|
cairo_surface_t *snapshot_of;
|
||||||
cairo_surface_func_t snapshot_detach;
|
cairo_surface_func_t snapshot_detach;
|
||||||
|
|
|
||||||
156
src/cairo-surface-wrapper-private.h
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
/* cairo - a vector graphics library with display and print output
|
||||||
|
*
|
||||||
|
* Copyright © 2002 University of Southern California
|
||||||
|
* Copyright © 2005 Red Hat, Inc.
|
||||||
|
* Copyright © 2009 Chris Wilson
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it either under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1 as published by the Free Software Foundation
|
||||||
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||||
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||||
|
* notice, a recipient may use your version of this file under either
|
||||||
|
* the MPL or the LGPL.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the LGPL along with this library
|
||||||
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
* You should have received a copy of the MPL along with this library
|
||||||
|
* in the file COPYING-MPL-1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||||
|
* the specific language governing rights and limitations.
|
||||||
|
*
|
||||||
|
* The Original Code is the cairo graphics library.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is University of Southern
|
||||||
|
* California.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Chris Wilson <chris@chris-wilson.co.u>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CAIRO_SURFACE_WRAPPER_PRIVATE_H
|
||||||
|
#define CAIRO_SURFACE_WRAPPER_PRIVATE_H
|
||||||
|
|
||||||
|
#include "cairo-types-private.h"
|
||||||
|
|
||||||
|
CAIRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
struct _cairo_surface_wrapper {
|
||||||
|
cairo_surface_t *target;
|
||||||
|
|
||||||
|
/* any other information? */
|
||||||
|
};
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_surface_t *target);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_image_surface_t **image_out,
|
||||||
|
void **image_extra);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_image_surface_t *image,
|
||||||
|
void *image_extra);
|
||||||
|
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
const cairo_pattern_t *mask,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_stroke_style_t *stroke_style,
|
||||||
|
cairo_matrix_t *ctm,
|
||||||
|
cairo_matrix_t *ctm_inverse,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t fill_op,
|
||||||
|
const cairo_pattern_t *fill_source,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double fill_tolerance,
|
||||||
|
cairo_antialias_t fill_antialias,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_operator_t stroke_op,
|
||||||
|
const cairo_pattern_t *stroke_source,
|
||||||
|
cairo_stroke_style_t *stroke_style,
|
||||||
|
cairo_matrix_t *stroke_ctm,
|
||||||
|
cairo_matrix_t *stroke_ctm_inverse,
|
||||||
|
double stroke_tolerance,
|
||||||
|
cairo_antialias_t stroke_antialias,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
const char *utf8,
|
||||||
|
int utf8_len,
|
||||||
|
cairo_glyph_t *glyphs,
|
||||||
|
int num_glyphs,
|
||||||
|
const cairo_text_cluster_t *clusters,
|
||||||
|
int num_clusters,
|
||||||
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
|
cairo_scaled_font_t *scaled_font,
|
||||||
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
|
cairo_private cairo_surface_t *
|
||||||
|
_cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_content_t content,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
cairo_private cairo_bool_t
|
||||||
|
_cairo_surface_wrapper_get_extents (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
|
cairo_private cairo_bool_t
|
||||||
|
_cairo_surface_wrapper_has_show_text_glyphs (cairo_surface_wrapper_t *wrapper);
|
||||||
|
|
||||||
|
static inline cairo_bool_t
|
||||||
|
_cairo_surface_wrapper_is_active (cairo_surface_wrapper_t *wrapper)
|
||||||
|
{
|
||||||
|
return wrapper->target != (cairo_surface_t *) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAIRO_END_DECLS
|
||||||
|
|
||||||
|
#endif /* CAIRO_SURFACE_WRAPPER_PRIVATE_H */
|
||||||
449
src/cairo-surface-wrapper.c
Normal file
|
|
@ -0,0 +1,449 @@
|
||||||
|
/* cairo - a vector graphics library with display and print output
|
||||||
|
*
|
||||||
|
* Copyright © 2005 Red Hat, Inc
|
||||||
|
* Copyright © 2007 Adrian Johnson
|
||||||
|
* Copyright © 2009 Chris Wilson
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it either under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1 as published by the Free Software Foundation
|
||||||
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||||
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||||
|
* notice, a recipient may use your version of this file under either
|
||||||
|
* the MPL or the LGPL.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the LGPL along with this library
|
||||||
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
* You should have received a copy of the MPL along with this library
|
||||||
|
* in the file COPYING-MPL-1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||||
|
* the specific language governing rights and limitations.
|
||||||
|
*
|
||||||
|
* The Original Code is the cairo graphics library.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cairoint.h"
|
||||||
|
|
||||||
|
#include "cairo-surface-wrapper-private.h"
|
||||||
|
|
||||||
|
/* A collection of routines to facilitate surface wrapping */
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
_cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_matrix_t *matrix)
|
||||||
|
{
|
||||||
|
if (_cairo_matrix_is_identity (&wrapper->target->device_transform))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*matrix = wrapper->target->device_transform;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_image_surface_t **image_out,
|
||||||
|
void **image_extra)
|
||||||
|
{
|
||||||
|
if (unlikely (wrapper->target->status))
|
||||||
|
return wrapper->target->status;
|
||||||
|
|
||||||
|
return _cairo_surface_acquire_source_image (wrapper->target,
|
||||||
|
image_out, image_extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_image_surface_t *image,
|
||||||
|
void *image_extra)
|
||||||
|
{
|
||||||
|
_cairo_surface_release_source_image (wrapper->target, image, image_extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_matrix_t device_transform;
|
||||||
|
cairo_clip_t clip_copy, *dev_clip = clip;
|
||||||
|
|
||||||
|
if (unlikely (wrapper->target->status))
|
||||||
|
return wrapper->target->status;
|
||||||
|
|
||||||
|
if (clip && clip->all_clipped)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (clip != NULL &&
|
||||||
|
_cairo_surface_wrapper_needs_device_transform (wrapper,
|
||||||
|
&device_transform))
|
||||||
|
{
|
||||||
|
status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
|
||||||
|
&device_transform);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
dev_clip = &clip_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_paint (wrapper->target, op, source, dev_clip);
|
||||||
|
|
||||||
|
FINISH:
|
||||||
|
if (dev_clip != clip)
|
||||||
|
_cairo_clip_reset (dev_clip);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
const cairo_pattern_t *mask,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_matrix_t device_transform;
|
||||||
|
cairo_clip_t clip_copy, *dev_clip = clip;
|
||||||
|
|
||||||
|
if (unlikely (wrapper->target->status))
|
||||||
|
return wrapper->target->status;
|
||||||
|
|
||||||
|
if (clip && clip->all_clipped)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (clip != NULL &&
|
||||||
|
_cairo_surface_wrapper_needs_device_transform (wrapper,
|
||||||
|
&device_transform))
|
||||||
|
{
|
||||||
|
status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
|
||||||
|
&device_transform);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
dev_clip = &clip_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip);
|
||||||
|
|
||||||
|
FINISH:
|
||||||
|
if (dev_clip != clip)
|
||||||
|
_cairo_clip_reset (dev_clip);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_stroke_style_t *stroke_style,
|
||||||
|
cairo_matrix_t *ctm,
|
||||||
|
cairo_matrix_t *ctm_inverse,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_matrix_t device_transform;
|
||||||
|
cairo_path_fixed_t path_copy, *dev_path = path;
|
||||||
|
cairo_clip_t clip_copy, *dev_clip = clip;
|
||||||
|
cairo_matrix_t dev_ctm = *ctm;
|
||||||
|
cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
|
||||||
|
|
||||||
|
if (unlikely (wrapper->target->status))
|
||||||
|
return wrapper->target->status;
|
||||||
|
|
||||||
|
if (clip && clip->all_clipped)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (_cairo_surface_wrapper_needs_device_transform (wrapper,
|
||||||
|
&device_transform))
|
||||||
|
{
|
||||||
|
status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
_cairo_path_fixed_transform (&path_copy, &device_transform);
|
||||||
|
dev_path = &path_copy;
|
||||||
|
|
||||||
|
if (clip != NULL) {
|
||||||
|
status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
|
||||||
|
&device_transform);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
dev_clip = &clip_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &device_transform);
|
||||||
|
status = cairo_matrix_invert (&device_transform);
|
||||||
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
cairo_matrix_multiply (&dev_ctm_inverse,
|
||||||
|
&device_transform,
|
||||||
|
&dev_ctm_inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_stroke (wrapper->target, op, source,
|
||||||
|
dev_path, stroke_style,
|
||||||
|
&dev_ctm, &dev_ctm_inverse,
|
||||||
|
tolerance, antialias,
|
||||||
|
dev_clip);
|
||||||
|
|
||||||
|
FINISH:
|
||||||
|
if (dev_path != path)
|
||||||
|
_cairo_path_fixed_fini (dev_path);
|
||||||
|
if (dev_clip != clip)
|
||||||
|
_cairo_clip_reset (dev_clip);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t fill_op,
|
||||||
|
const cairo_pattern_t *fill_source,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double fill_tolerance,
|
||||||
|
cairo_antialias_t fill_antialias,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_operator_t stroke_op,
|
||||||
|
const cairo_pattern_t *stroke_source,
|
||||||
|
cairo_stroke_style_t *stroke_style,
|
||||||
|
cairo_matrix_t *stroke_ctm,
|
||||||
|
cairo_matrix_t *stroke_ctm_inverse,
|
||||||
|
double stroke_tolerance,
|
||||||
|
cairo_antialias_t stroke_antialias,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_matrix_t device_transform;
|
||||||
|
cairo_path_fixed_t path_copy, *dev_path = path;
|
||||||
|
cairo_clip_t clip_copy, *dev_clip = clip;
|
||||||
|
cairo_matrix_t dev_ctm = *stroke_ctm;
|
||||||
|
cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
|
||||||
|
|
||||||
|
if (unlikely (wrapper->target->status))
|
||||||
|
return wrapper->target->status;
|
||||||
|
|
||||||
|
if (clip && clip->all_clipped)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (_cairo_surface_wrapper_needs_device_transform (wrapper,
|
||||||
|
&device_transform))
|
||||||
|
{
|
||||||
|
status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
_cairo_path_fixed_transform (&path_copy, &device_transform);
|
||||||
|
dev_path = &path_copy;
|
||||||
|
|
||||||
|
if (clip != NULL) {
|
||||||
|
status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
|
||||||
|
&device_transform);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
dev_clip = &clip_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_matrix_multiply (&dev_ctm, &dev_ctm, &device_transform);
|
||||||
|
status = cairo_matrix_invert (&device_transform);
|
||||||
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
cairo_matrix_multiply (&dev_ctm_inverse,
|
||||||
|
&device_transform,
|
||||||
|
&dev_ctm_inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_fill_stroke (wrapper->target,
|
||||||
|
fill_op, fill_source, fill_rule,
|
||||||
|
fill_tolerance, fill_antialias,
|
||||||
|
dev_path,
|
||||||
|
stroke_op, stroke_source,
|
||||||
|
stroke_style,
|
||||||
|
&dev_ctm, &dev_ctm_inverse,
|
||||||
|
stroke_tolerance, stroke_antialias,
|
||||||
|
dev_clip);
|
||||||
|
|
||||||
|
FINISH:
|
||||||
|
if (dev_path != path)
|
||||||
|
_cairo_path_fixed_fini (dev_path);
|
||||||
|
if (dev_clip != clip)
|
||||||
|
_cairo_clip_reset (dev_clip);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_matrix_t device_transform;
|
||||||
|
cairo_path_fixed_t path_copy, *dev_path = path;
|
||||||
|
cairo_clip_t clip_copy, *dev_clip = clip;
|
||||||
|
|
||||||
|
if (unlikely (wrapper->target->status))
|
||||||
|
return wrapper->target->status;
|
||||||
|
|
||||||
|
if (clip && clip->all_clipped)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (_cairo_surface_wrapper_needs_device_transform (wrapper,
|
||||||
|
&device_transform))
|
||||||
|
{
|
||||||
|
status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
_cairo_path_fixed_transform (&path_copy, &device_transform);
|
||||||
|
dev_path = &path_copy;
|
||||||
|
|
||||||
|
if (clip != NULL) {
|
||||||
|
status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
|
||||||
|
&device_transform);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
|
||||||
|
dev_clip = &clip_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_fill (wrapper->target, op, source,
|
||||||
|
dev_path, fill_rule,
|
||||||
|
tolerance, antialias,
|
||||||
|
dev_clip);
|
||||||
|
|
||||||
|
FINISH:
|
||||||
|
if (dev_path != path)
|
||||||
|
_cairo_path_fixed_fini (dev_path);
|
||||||
|
if (dev_clip != clip)
|
||||||
|
_cairo_clip_reset (dev_clip);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
const char *utf8,
|
||||||
|
int utf8_len,
|
||||||
|
cairo_glyph_t *glyphs,
|
||||||
|
int num_glyphs,
|
||||||
|
const cairo_text_cluster_t *clusters,
|
||||||
|
int num_clusters,
|
||||||
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
|
cairo_scaled_font_t *scaled_font,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_matrix_t device_transform;
|
||||||
|
cairo_clip_t clip_copy, *dev_clip = clip;
|
||||||
|
cairo_glyph_t *dev_glyphs = glyphs;
|
||||||
|
|
||||||
|
if (unlikely (wrapper->target->status))
|
||||||
|
return wrapper->target->status;
|
||||||
|
|
||||||
|
if (glyphs == NULL || num_glyphs == 0)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (clip && clip->all_clipped)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (_cairo_surface_wrapper_needs_device_transform (wrapper,
|
||||||
|
&device_transform))
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (clip != NULL) {
|
||||||
|
dev_clip = &clip_copy;
|
||||||
|
status = _cairo_clip_init_copy_transformed (&clip_copy, clip,
|
||||||
|
&device_transform);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto FINISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
|
||||||
|
if (dev_glyphs == NULL) {
|
||||||
|
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
goto FINISH;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_glyphs; i++) {
|
||||||
|
dev_glyphs[i] = glyphs[i];
|
||||||
|
cairo_matrix_transform_point (&device_transform,
|
||||||
|
&dev_glyphs[i].x,
|
||||||
|
&dev_glyphs[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_show_text_glyphs (wrapper->target, op, source,
|
||||||
|
utf8, utf8_len,
|
||||||
|
dev_glyphs, num_glyphs,
|
||||||
|
clusters, num_clusters,
|
||||||
|
cluster_flags,
|
||||||
|
scaled_font,
|
||||||
|
dev_clip);
|
||||||
|
FINISH:
|
||||||
|
if (dev_clip != clip)
|
||||||
|
_cairo_clip_reset (dev_clip);
|
||||||
|
if (dev_glyphs != glyphs)
|
||||||
|
free (dev_glyphs);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_surface_t *
|
||||||
|
_cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_content_t content,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
return _cairo_surface_create_similar_solid (wrapper->target,
|
||||||
|
content, width, height,
|
||||||
|
CAIRO_COLOR_TRANSPARENT,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_bool_t
|
||||||
|
_cairo_surface_wrapper_get_extents (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_rectangle_int_t *extents)
|
||||||
|
{
|
||||||
|
return _cairo_surface_get_extents (wrapper->target, extents);
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_bool_t
|
||||||
|
_cairo_surface_wrapper_has_show_text_glyphs (cairo_surface_wrapper_t *wrapper)
|
||||||
|
{
|
||||||
|
return cairo_surface_has_show_text_glyphs (wrapper->target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper,
|
||||||
|
cairo_surface_t *target)
|
||||||
|
{
|
||||||
|
wrapper->target = cairo_surface_reference (target);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper)
|
||||||
|
{
|
||||||
|
cairo_surface_destroy (wrapper->target);
|
||||||
|
}
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "cairo-svg.h"
|
#include "cairo-svg.h"
|
||||||
|
|
||||||
#include "cairo-surface-private.h"
|
#include "cairo-surface-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
|
||||||
typedef struct cairo_svg_document cairo_svg_document_t;
|
typedef struct cairo_svg_document cairo_svg_document_t;
|
||||||
|
|
||||||
|
|
@ -52,8 +53,6 @@ typedef struct cairo_svg_surface {
|
||||||
|
|
||||||
cairo_content_t content;
|
cairo_content_t content;
|
||||||
|
|
||||||
unsigned int id;
|
|
||||||
|
|
||||||
double width;
|
double width;
|
||||||
double height;
|
double height;
|
||||||
|
|
||||||
|
|
@ -62,6 +61,7 @@ typedef struct cairo_svg_surface {
|
||||||
cairo_output_stream_t *xml_node;
|
cairo_output_stream_t *xml_node;
|
||||||
cairo_array_t page_set;
|
cairo_array_t page_set;
|
||||||
|
|
||||||
|
cairo_surface_clipper_t clipper;
|
||||||
unsigned int clip_level;
|
unsigned int clip_level;
|
||||||
unsigned int base_clip;
|
unsigned int base_clip;
|
||||||
cairo_bool_t is_base_clip_emitted;
|
cairo_bool_t is_base_clip_emitted;
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@
|
||||||
#include "cairo-path-fixed-private.h"
|
#include "cairo-path-fixed-private.h"
|
||||||
#include "cairo-paginated-private.h"
|
#include "cairo-paginated-private.h"
|
||||||
#include "cairo-scaled-font-subsets-private.h"
|
#include "cairo-scaled-font-subsets-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
#include "cairo-svg-surface-private.h"
|
#include "cairo-svg-surface-private.h"
|
||||||
|
|
||||||
typedef struct cairo_svg_page cairo_svg_page_t;
|
typedef struct cairo_svg_page cairo_svg_page_t;
|
||||||
|
|
@ -63,6 +64,11 @@ static const cairo_svg_version_t _cairo_svg_versions[] =
|
||||||
|
|
||||||
#define CAIRO_SVG_VERSION_LAST ARRAY_LENGTH (_cairo_svg_versions)
|
#define CAIRO_SVG_VERSION_LAST ARRAY_LENGTH (_cairo_svg_versions)
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cairo_svg_surface_emit_path (cairo_output_stream_t *output,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_matrix_t *ctm_inverse);
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
_cairo_svg_version_has_page_set_support (cairo_svg_version_t version)
|
_cairo_svg_version_has_page_set_support (cairo_svg_version_t version)
|
||||||
{
|
{
|
||||||
|
|
@ -99,7 +105,6 @@ struct cairo_svg_document {
|
||||||
cairo_output_stream_t *xml_node_defs;
|
cairo_output_stream_t *xml_node_defs;
|
||||||
cairo_output_stream_t *xml_node_glyphs;
|
cairo_output_stream_t *xml_node_glyphs;
|
||||||
|
|
||||||
unsigned int surface_id;
|
|
||||||
unsigned int linear_pattern_id;
|
unsigned int linear_pattern_id;
|
||||||
unsigned int radial_pattern_id;
|
unsigned int radial_pattern_id;
|
||||||
unsigned int pattern_id;
|
unsigned int pattern_id;
|
||||||
|
|
@ -109,18 +114,11 @@ struct cairo_svg_document {
|
||||||
|
|
||||||
cairo_bool_t alpha_filter;
|
cairo_bool_t alpha_filter;
|
||||||
|
|
||||||
cairo_array_t meta_snapshots;
|
|
||||||
|
|
||||||
cairo_svg_version_t svg_version;
|
cairo_svg_version_t svg_version;
|
||||||
|
|
||||||
cairo_scaled_font_subsets_t *font_subsets;
|
cairo_scaled_font_subsets_t *font_subsets;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned int id;
|
|
||||||
cairo_meta_surface_t *meta;
|
|
||||||
} cairo_meta_snapshot_t;
|
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_svg_document_create (cairo_output_stream_t *stream,
|
_cairo_svg_document_create (cairo_output_stream_t *stream,
|
||||||
double width,
|
double width,
|
||||||
|
|
@ -278,8 +276,8 @@ _extract_svg_surface (cairo_surface_t *surface,
|
||||||
* Since: 1.2
|
* Since: 1.2
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface,
|
cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface,
|
||||||
cairo_svg_version_t version)
|
cairo_svg_version_t version)
|
||||||
{
|
{
|
||||||
cairo_svg_surface_t *surface = NULL; /* hide compiler warning */
|
cairo_svg_surface_t *surface = NULL; /* hide compiler warning */
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -306,7 +304,7 @@ cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface,
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
cairo_svg_get_versions (cairo_svg_version_t const **versions,
|
cairo_svg_get_versions (cairo_svg_version_t const **versions,
|
||||||
int *num_versions)
|
int *num_versions)
|
||||||
{
|
{
|
||||||
if (versions != NULL)
|
if (versions != NULL)
|
||||||
*versions = _cairo_svg_versions;
|
*versions = _cairo_svg_versions;
|
||||||
|
|
@ -336,6 +334,73 @@ cairo_svg_version_to_string (cairo_svg_version_t version)
|
||||||
return _cairo_svg_version_strings[version];
|
return _cairo_svg_version_strings[version];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
_cliprect_covers_surface (cairo_svg_surface_t *surface,
|
||||||
|
cairo_path_fixed_t *path)
|
||||||
|
{
|
||||||
|
cairo_box_t box;
|
||||||
|
|
||||||
|
if (_cairo_path_fixed_is_rectangle (path, &box)) {
|
||||||
|
if (box.p1.x <= 0 &&
|
||||||
|
box.p1.y <= 0 &&
|
||||||
|
_cairo_fixed_to_double (box.p2.x) >= surface->width &&
|
||||||
|
_cairo_fixed_to_double (box.p2.y) >= surface->height)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_svg_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias)
|
||||||
|
{
|
||||||
|
cairo_svg_surface_t *surface = cairo_container_of (clipper,
|
||||||
|
cairo_svg_surface_t,
|
||||||
|
clipper);
|
||||||
|
cairo_svg_document_t *document = surface->document;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (path == NULL) {
|
||||||
|
for (i = 0; i < surface->clip_level; i++)
|
||||||
|
_cairo_output_stream_printf (surface->xml_node, "</g>\n");
|
||||||
|
|
||||||
|
surface->clip_level = 0;
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip trivial whole-page clips */
|
||||||
|
if (_cliprect_covers_surface (surface, path))
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
_cairo_output_stream_printf (document->xml_node_defs,
|
||||||
|
"<clipPath id=\"clip%d\">\n"
|
||||||
|
" <path ",
|
||||||
|
document->clip_id);
|
||||||
|
_cairo_svg_surface_emit_path (document->xml_node_defs, path, NULL);
|
||||||
|
|
||||||
|
_cairo_output_stream_printf (document->xml_node_defs,
|
||||||
|
"/>\n"
|
||||||
|
"</clipPath>\n");
|
||||||
|
|
||||||
|
_cairo_output_stream_printf (surface->xml_node,
|
||||||
|
"<g clip-path=\"url(#clip%d)\" "
|
||||||
|
"clip-rule=\"%s\">\n",
|
||||||
|
document->clip_id,
|
||||||
|
fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
|
||||||
|
"evenodd" : "nonzero");
|
||||||
|
|
||||||
|
document->clip_id++;
|
||||||
|
surface->clip_level++;
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
_cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
||||||
cairo_content_t content,
|
cairo_content_t content,
|
||||||
|
|
@ -359,8 +424,9 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
||||||
surface->document = _cairo_svg_document_reference (document);
|
surface->document = _cairo_svg_document_reference (document);
|
||||||
|
|
||||||
surface->clip_level = 0;
|
surface->clip_level = 0;
|
||||||
|
_cairo_surface_clipper_init (&surface->clipper,
|
||||||
|
_cairo_svg_surface_clipper_intersect_clip_path);
|
||||||
|
|
||||||
surface->id = document->surface_id++;
|
|
||||||
surface->base_clip = document->clip_id++;
|
surface->base_clip = document->clip_id++;
|
||||||
surface->is_base_clip_emitted = FALSE;
|
surface->is_base_clip_emitted = FALSE;
|
||||||
|
|
||||||
|
|
@ -388,8 +454,6 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
|
||||||
|
|
||||||
paginated = _cairo_paginated_surface_create (&surface->base,
|
paginated = _cairo_paginated_surface_create (&surface->base,
|
||||||
surface->content,
|
surface->content,
|
||||||
surface->width,
|
|
||||||
surface->height,
|
|
||||||
&cairo_svg_surface_paginated_backend);
|
&cairo_svg_surface_paginated_backend);
|
||||||
status = paginated->status;
|
status = paginated->status;
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
if (status == CAIRO_STATUS_SUCCESS) {
|
||||||
|
|
@ -457,7 +521,7 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
page.surface_id = surface->id;
|
page.surface_id = surface->base.unique_id;
|
||||||
page.clip_level = surface->clip_level;
|
page.clip_level = surface->clip_level;
|
||||||
page.xml_node = surface->xml_node;
|
page.xml_node = surface->xml_node;
|
||||||
|
|
||||||
|
|
@ -468,11 +532,13 @@ _cairo_svg_surface_store_page (cairo_svg_surface_t *surface)
|
||||||
|
|
||||||
surface->xml_node = stream;
|
surface->xml_node = stream;
|
||||||
surface->clip_level = 0;
|
surface->clip_level = 0;
|
||||||
|
|
||||||
for (i = 0; i < page.clip_level; i++)
|
for (i = 0; i < page.clip_level; i++)
|
||||||
_cairo_output_stream_printf (page.xml_node, "</g>\n");
|
_cairo_output_stream_printf (page.xml_node, "</g>\n");
|
||||||
|
|
||||||
return _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1);
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
|
||||||
|
return _cairo_array_index (&surface->page_set,
|
||||||
|
surface->page_set.num_elements - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -486,7 +552,6 @@ _cairo_svg_surface_copy_page (void *abstract_surface)
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
_cairo_memory_stream_copy (page->xml_node, surface->xml_node);
|
_cairo_memory_stream_copy (page->xml_node, surface->xml_node);
|
||||||
surface->clip_level = page->clip_level;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -596,7 +661,7 @@ _cairo_svg_path_close_path (void *closure)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static void
|
||||||
_cairo_svg_surface_emit_path (cairo_output_stream_t *output,
|
_cairo_svg_surface_emit_path (cairo_output_stream_t *output,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
cairo_matrix_t *ctm_inverse)
|
cairo_matrix_t *ctm_inverse)
|
||||||
|
|
@ -615,12 +680,9 @@ _cairo_svg_surface_emit_path (cairo_output_stream_t *output,
|
||||||
_cairo_svg_path_curve_to,
|
_cairo_svg_path_curve_to,
|
||||||
_cairo_svg_path_close_path,
|
_cairo_svg_path_close_path,
|
||||||
&info);
|
&info);
|
||||||
if (unlikely (status))
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (output, "\"");
|
_cairo_output_stream_printf (output, "\"");
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -642,9 +704,8 @@ _cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document,
|
||||||
_cairo_output_stream_printf (document->xml_node_glyphs,
|
_cairo_output_stream_printf (document->xml_node_glyphs,
|
||||||
"<path style=\"stroke:none;\" ");
|
"<path style=\"stroke:none;\" ");
|
||||||
|
|
||||||
status = _cairo_svg_surface_emit_path (document->xml_node_glyphs, scaled_glyph->path, NULL);
|
_cairo_svg_surface_emit_path (document->xml_node_glyphs,
|
||||||
if (unlikely (status))
|
scaled_glyph->path, NULL);
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (document->xml_node_glyphs,
|
_cairo_output_stream_printf (document->xml_node_glyphs,
|
||||||
"/>\n");
|
"/>\n");
|
||||||
|
|
@ -847,22 +908,7 @@ _cairo_svg_surface_operation_supported (cairo_svg_surface_t *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *pattern)
|
const cairo_pattern_t *pattern)
|
||||||
{
|
{
|
||||||
if (_cairo_svg_surface_analyze_operation (surface, op, pattern)
|
return _cairo_svg_surface_analyze_operation (surface, op, pattern) != CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
!= CAIRO_INT_STATUS_UNSUPPORTED)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_surface_t *
|
|
||||||
_cairo_svg_surface_create_similar (void *abstract_src,
|
|
||||||
cairo_content_t content,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
return cairo_meta_surface_create (content, width, height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
|
|
@ -893,6 +939,8 @@ _cairo_svg_surface_finish (void *abstract_surface)
|
||||||
}
|
}
|
||||||
_cairo_array_fini (&surface->page_set);
|
_cairo_array_fini (&surface->page_set);
|
||||||
|
|
||||||
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
|
||||||
status2 = _cairo_svg_document_destroy (document);
|
status2 = _cairo_svg_document_destroy (document);
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
if (status == CAIRO_STATUS_SUCCESS)
|
||||||
status = status2;
|
status = status2;
|
||||||
|
|
@ -900,6 +948,7 @@ _cairo_svg_surface_finish (void *abstract_surface)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cairo_svg_surface_emit_alpha_filter (cairo_svg_document_t *document)
|
_cairo_svg_surface_emit_alpha_filter (cairo_svg_document_t *document)
|
||||||
{
|
{
|
||||||
|
|
@ -1120,112 +1169,139 @@ _cairo_svg_surface_emit_operator_for_style (cairo_output_stream_t *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output,
|
_cairo_svg_surface_emit_surface (cairo_svg_document_t *document,
|
||||||
cairo_svg_surface_t *svg_surface,
|
cairo_surface_t *surface)
|
||||||
cairo_operator_t op,
|
|
||||||
cairo_surface_pattern_t *pattern,
|
|
||||||
int pattern_id,
|
|
||||||
const cairo_matrix_t *parent_matrix,
|
|
||||||
const char *extra_attributes)
|
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_matrix_t p2u;
|
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (pattern->surface, &extents);
|
if (_cairo_user_data_array_get_data (&surface->user_data,
|
||||||
|
(cairo_user_data_key_t *) document))
|
||||||
|
{
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_bounded = _cairo_surface_get_extents (surface, &extents);
|
||||||
|
assert (is_bounded);
|
||||||
|
|
||||||
|
_cairo_output_stream_printf (document->xml_node_defs,
|
||||||
|
"<image id=\"image%d\" width=\"%d\" height=\"%d\"",
|
||||||
|
surface->unique_id,
|
||||||
|
extents.width, extents.height);
|
||||||
|
|
||||||
|
_cairo_output_stream_printf (document->xml_node_defs, " xlink:href=\"");
|
||||||
|
|
||||||
|
status = _cairo_surface_base64_encode (surface,
|
||||||
|
document->xml_node_defs);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
_cairo_output_stream_printf (document->xml_node_defs, "\"/>\n");
|
||||||
|
|
||||||
|
/* and tag it */
|
||||||
|
return _cairo_user_data_array_set_data (&surface->user_data,
|
||||||
|
(cairo_user_data_key_t *) document,
|
||||||
|
document, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_svg_surface_emit_composite_surface_pattern (cairo_output_stream_t *output,
|
||||||
|
cairo_svg_surface_t *svg_surface,
|
||||||
|
cairo_operator_t op,
|
||||||
|
cairo_surface_pattern_t *pattern,
|
||||||
|
int pattern_id,
|
||||||
|
const cairo_matrix_t *parent_matrix,
|
||||||
|
const char *extra_attributes)
|
||||||
|
{
|
||||||
|
cairo_status_t status;
|
||||||
|
cairo_matrix_t p2u;
|
||||||
|
|
||||||
p2u = pattern->base.matrix;
|
p2u = pattern->base.matrix;
|
||||||
status = cairo_matrix_invert (&p2u);
|
status = cairo_matrix_invert (&p2u);
|
||||||
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
|
status = _cairo_svg_surface_emit_surface (svg_surface->document,
|
||||||
|
pattern->surface);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
if (pattern_id != invalid_pattern_id) {
|
if (pattern_id != invalid_pattern_id) {
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
cairo_bool_t is_bounded;
|
||||||
|
|
||||||
|
is_bounded = _cairo_surface_get_extents (pattern->surface, &extents);
|
||||||
|
assert (is_bounded);
|
||||||
|
|
||||||
_cairo_output_stream_printf (output,
|
_cairo_output_stream_printf (output,
|
||||||
"<pattern id=\"pattern%d\" "
|
"<pattern id=\"pattern%d\" "
|
||||||
"patternUnits=\"userSpaceOnUse\" "
|
"patternUnits=\"userSpaceOnUse\" "
|
||||||
"width=\"%d\" height=\"%d\"",
|
"width=\"%d\" height=\"%d\" ",
|
||||||
pattern_id,
|
pattern_id,
|
||||||
extents.width, extents.height);
|
extents.width, extents.height);
|
||||||
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
|
_cairo_svg_surface_emit_transform (output,
|
||||||
_cairo_output_stream_printf (output, ">\n");
|
" patternTransform",
|
||||||
|
&p2u, parent_matrix);
|
||||||
|
_cairo_output_stream_printf (output, ">\n ");
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_output_stream_printf (output,
|
_cairo_output_stream_printf (output,
|
||||||
" <image width=\"%d\" height=\"%d\"",
|
"<use xlink:href=\"#image%d\"",
|
||||||
extents.width, extents.height);
|
pattern->surface->unique_id);
|
||||||
|
|
||||||
if (pattern_id == invalid_pattern_id) {
|
|
||||||
_cairo_svg_surface_emit_operator (output, svg_surface, op);
|
|
||||||
_cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extra_attributes)
|
if (extra_attributes)
|
||||||
_cairo_output_stream_printf (output, " %s", extra_attributes);
|
_cairo_output_stream_printf (output, " %s", extra_attributes);
|
||||||
|
|
||||||
_cairo_output_stream_printf (output, " xlink:href=\"");
|
if (pattern_id == invalid_pattern_id) {
|
||||||
|
_cairo_svg_surface_emit_operator (output, svg_surface, op);
|
||||||
|
_cairo_svg_surface_emit_transform (output,
|
||||||
|
" transform",
|
||||||
|
&p2u, parent_matrix);
|
||||||
|
}
|
||||||
|
_cairo_output_stream_printf (output, "/>\n");
|
||||||
|
|
||||||
status = _cairo_surface_base64_encode (pattern->surface, output);
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (output, "\"/>\n");
|
|
||||||
|
|
||||||
if (pattern_id != invalid_pattern_id)
|
if (pattern_id != invalid_pattern_id)
|
||||||
_cairo_output_stream_printf (output, "</pattern>\n");
|
_cairo_output_stream_printf (output, "</pattern>\n");
|
||||||
|
|
||||||
return status;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
_cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
||||||
cairo_meta_surface_t *surface,
|
cairo_meta_surface_t *source)
|
||||||
int *id)
|
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_surface_t *paginated_surface;
|
cairo_surface_t *paginated_surface;
|
||||||
cairo_svg_surface_t *svg_surface;
|
cairo_svg_surface_t *svg_surface;
|
||||||
cairo_meta_snapshot_t new_snapshot;
|
|
||||||
cairo_array_t *page_set;
|
cairo_array_t *page_set;
|
||||||
|
|
||||||
cairo_output_stream_t *contents;
|
cairo_output_stream_t *contents;
|
||||||
cairo_meta_surface_t *meta;
|
|
||||||
cairo_meta_snapshot_t *snapshot;
|
|
||||||
unsigned int num_elements;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
/* search in already emitted meta snapshots */
|
if (_cairo_user_data_array_get_data (&source->base.user_data,
|
||||||
num_elements = document->meta_snapshots.num_elements;
|
(cairo_user_data_key_t *) document))
|
||||||
for (i = 0; i < num_elements; i++) {
|
{
|
||||||
snapshot = _cairo_array_index (&document->meta_snapshots, i);
|
return CAIRO_STATUS_SUCCESS;
|
||||||
meta = snapshot->meta;
|
|
||||||
if (meta->commands.num_elements == surface->commands.num_elements &&
|
|
||||||
_cairo_array_index (&meta->commands, 0) == _cairo_array_index (&surface->commands, 0)) {
|
|
||||||
*id = snapshot->id;
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meta = (cairo_meta_surface_t *) _cairo_surface_snapshot (&surface->base);
|
|
||||||
if (unlikely (meta->base.status))
|
|
||||||
return meta->base.status;
|
|
||||||
|
|
||||||
paginated_surface = _cairo_svg_surface_create_for_document (document,
|
paginated_surface = _cairo_svg_surface_create_for_document (document,
|
||||||
meta->content,
|
source->content,
|
||||||
meta->width_pixels,
|
source->extents_pixels.width,
|
||||||
meta->height_pixels);
|
source->extents_pixels.height);
|
||||||
if (paginated_surface->status) {
|
if (unlikely (paginated_surface->status))
|
||||||
cairo_surface_destroy (&meta->base);
|
|
||||||
return paginated_surface->status;
|
return paginated_surface->status;
|
||||||
}
|
|
||||||
|
|
||||||
svg_surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (paginated_surface);
|
svg_surface = (cairo_svg_surface_t *)
|
||||||
|
_cairo_paginated_surface_get_target (paginated_surface);
|
||||||
cairo_surface_set_fallback_resolution (paginated_surface,
|
cairo_surface_set_fallback_resolution (paginated_surface,
|
||||||
document->owner->x_fallback_resolution,
|
document->owner->x_fallback_resolution,
|
||||||
document->owner->y_fallback_resolution);
|
document->owner->y_fallback_resolution);
|
||||||
|
cairo_surface_set_device_offset (&svg_surface->base,
|
||||||
|
-source->extents_pixels.x,
|
||||||
|
-source->extents_pixels.y);
|
||||||
|
|
||||||
status = cairo_meta_surface_replay (&meta->base, paginated_surface);
|
status = cairo_meta_surface_replay (&source->base, paginated_surface);
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
cairo_surface_destroy (&meta->base);
|
|
||||||
cairo_surface_destroy (paginated_surface);
|
cairo_surface_destroy (paginated_surface);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
@ -1233,21 +1309,11 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
||||||
cairo_surface_show_page (paginated_surface);
|
cairo_surface_show_page (paginated_surface);
|
||||||
status = cairo_surface_status (paginated_surface);
|
status = cairo_surface_status (paginated_surface);
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
cairo_surface_destroy (&meta->base);
|
|
||||||
cairo_surface_destroy (paginated_surface);
|
cairo_surface_destroy (paginated_surface);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_snapshot.meta = meta;
|
if (! svg_surface->is_base_clip_emitted) {
|
||||||
new_snapshot.id = svg_surface->id;
|
|
||||||
status = _cairo_array_append (&document->meta_snapshots, &new_snapshot);
|
|
||||||
if (unlikely (status)) {
|
|
||||||
cairo_surface_destroy (&meta->base);
|
|
||||||
cairo_surface_destroy (paginated_surface);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!svg_surface->is_base_clip_emitted) {
|
|
||||||
svg_surface->is_base_clip_emitted = TRUE;
|
svg_surface->is_base_clip_emitted = TRUE;
|
||||||
_cairo_output_stream_printf (document->xml_node_defs,
|
_cairo_output_stream_printf (document->xml_node_defs,
|
||||||
"<clipPath id=\"clip%d\">\n"
|
"<clipPath id=\"clip%d\">\n"
|
||||||
|
|
@ -1258,19 +1324,19 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
||||||
svg_surface->height);
|
svg_surface->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meta->content == CAIRO_CONTENT_ALPHA) {
|
if (source->content == CAIRO_CONTENT_ALPHA) {
|
||||||
_cairo_svg_surface_emit_alpha_filter (document);
|
_cairo_svg_surface_emit_alpha_filter (document);
|
||||||
_cairo_output_stream_printf (document->xml_node_defs,
|
_cairo_output_stream_printf (document->xml_node_defs,
|
||||||
"<g id=\"surface%d\" "
|
"<g id=\"surface%d\" "
|
||||||
"clip-path=\"url(#clip%d)\" "
|
"clip-path=\"url(#clip%d)\" "
|
||||||
"filter=\"url(#alpha)\">\n",
|
"filter=\"url(#alpha)\">\n",
|
||||||
svg_surface->id,
|
source->base.unique_id,
|
||||||
svg_surface->base_clip);
|
svg_surface->base_clip);
|
||||||
} else {
|
} else {
|
||||||
_cairo_output_stream_printf (document->xml_node_defs,
|
_cairo_output_stream_printf (document->xml_node_defs,
|
||||||
"<g id=\"surface%d\" "
|
"<g id=\"surface%d\" "
|
||||||
"clip-path=\"url(#clip%d)\">\n",
|
"clip-path=\"url(#clip%d)\">\n",
|
||||||
svg_surface->id,
|
source->base.unique_id,
|
||||||
svg_surface->base_clip);
|
svg_surface->base_clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1293,19 +1359,16 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
||||||
|
|
||||||
_cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
|
_cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
|
||||||
|
|
||||||
*id = new_snapshot.id;
|
|
||||||
|
|
||||||
status = cairo_surface_status (paginated_surface);
|
status = cairo_surface_status (paginated_surface);
|
||||||
cairo_surface_destroy (paginated_surface);
|
cairo_surface_destroy (paginated_surface);
|
||||||
|
|
||||||
/* FIXME: cairo_paginated_surface doesn't take a ref to the
|
if (unlikely (status))
|
||||||
* passed in target surface so we can't call destroy here.
|
return status;
|
||||||
* cairo_paginated_surface should be fixed, but for now just
|
|
||||||
* work around it. */
|
|
||||||
|
|
||||||
/* cairo_surface_destroy (svg_surface); */
|
/* and tag it */
|
||||||
|
return _cairo_user_data_array_set_data (&source->base.user_data,
|
||||||
return status;
|
(cairo_user_data_key_t *) document,
|
||||||
|
document, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
|
|
@ -1321,7 +1384,6 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
|
||||||
cairo_meta_surface_t *meta_surface;
|
cairo_meta_surface_t *meta_surface;
|
||||||
cairo_matrix_t p2u;
|
cairo_matrix_t p2u;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
int id = 0;
|
|
||||||
|
|
||||||
p2u = pattern->base.matrix;
|
p2u = pattern->base.matrix;
|
||||||
status = cairo_matrix_invert (&p2u);
|
status = cairo_matrix_invert (&p2u);
|
||||||
|
|
@ -1329,8 +1391,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
|
||||||
assert (status == CAIRO_STATUS_SUCCESS);
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
meta_surface = (cairo_meta_surface_t *) pattern->surface;
|
meta_surface = (cairo_meta_surface_t *) pattern->surface;
|
||||||
|
status = _cairo_svg_surface_emit_meta_surface (document, meta_surface);
|
||||||
status = _cairo_svg_surface_emit_meta_surface (document, meta_surface, &id);
|
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -1340,15 +1401,15 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
|
||||||
"patternUnits=\"userSpaceOnUse\" "
|
"patternUnits=\"userSpaceOnUse\" "
|
||||||
"width=\"%d\" height=\"%d\"",
|
"width=\"%d\" height=\"%d\"",
|
||||||
pattern_id,
|
pattern_id,
|
||||||
(int) ceil (meta_surface->width_pixels),
|
meta_surface->extents.width,
|
||||||
(int) ceil (meta_surface->height_pixels));
|
meta_surface->extents.height);
|
||||||
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
|
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
|
||||||
_cairo_output_stream_printf (output, ">\n");
|
_cairo_output_stream_printf (output, ">\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_output_stream_printf (output,
|
_cairo_output_stream_printf (output,
|
||||||
"<use xlink:href=\"#surface%d\"",
|
"<use xlink:href=\"#surface%d\"",
|
||||||
id);
|
meta_surface->base.unique_id);
|
||||||
|
|
||||||
if (pattern_id == invalid_pattern_id) {
|
if (pattern_id == invalid_pattern_id) {
|
||||||
_cairo_svg_surface_emit_operator (output, surface, op);
|
_cairo_svg_surface_emit_operator (output, surface, op);
|
||||||
|
|
@ -1377,12 +1438,18 @@ _cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t *output,
|
||||||
{
|
{
|
||||||
|
|
||||||
if (_cairo_surface_is_meta (pattern->surface)) {
|
if (_cairo_surface_is_meta (pattern->surface)) {
|
||||||
return _cairo_svg_surface_emit_composite_meta_pattern (output, surface, op, pattern,
|
return _cairo_svg_surface_emit_composite_meta_pattern (output, surface,
|
||||||
pattern_id, parent_matrix, extra_attributes);
|
op, pattern,
|
||||||
|
pattern_id,
|
||||||
|
parent_matrix,
|
||||||
|
extra_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _cairo_svg_surface_emit_composite_image_pattern (output, surface, op, pattern,
|
return _cairo_svg_surface_emit_composite_surface_pattern (output, surface,
|
||||||
pattern_id, parent_matrix, extra_attributes);
|
op, pattern,
|
||||||
|
pattern_id,
|
||||||
|
parent_matrix,
|
||||||
|
extra_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
|
|
@ -1716,7 +1783,9 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface,
|
||||||
document->radial_pattern_id,
|
document->radial_pattern_id,
|
||||||
x1, y1,
|
x1, y1,
|
||||||
x1, y1, r1);
|
x1, y1, r1);
|
||||||
_cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix);
|
_cairo_svg_surface_emit_transform (document->xml_node_defs,
|
||||||
|
"gradientTransform",
|
||||||
|
&p2u, parent_matrix);
|
||||||
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
|
_cairo_output_stream_printf (document->xml_node_defs, ">\n");
|
||||||
|
|
||||||
if (extend == CAIRO_EXTEND_NONE || n_stops < 1)
|
if (extend == CAIRO_EXTEND_NONE || n_stops < 1)
|
||||||
|
|
@ -1981,11 +2050,15 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *stroke_ctm_inverse,
|
cairo_matrix_t *stroke_ctm_inverse,
|
||||||
double stroke_tolerance,
|
double stroke_tolerance,
|
||||||
cairo_antialias_t stroke_antialias,
|
cairo_antialias_t stroke_antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_svg_surface_t *surface = abstract_surface;
|
cairo_svg_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "<path style=\"");
|
_cairo_output_stream_printf (surface->xml_node, "<path style=\"");
|
||||||
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op,
|
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op,
|
||||||
fill_source, fill_rule, stroke_ctm_inverse);
|
fill_source, fill_rule, stroke_ctm_inverse);
|
||||||
|
|
@ -1999,9 +2072,7 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface,
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "\" ");
|
_cairo_output_stream_printf (surface->xml_node, "\" ");
|
||||||
|
|
||||||
status = _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse);
|
_cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse);
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL);
|
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL);
|
||||||
_cairo_output_stream_printf (surface->xml_node, "/>\n");
|
_cairo_output_stream_printf (surface->xml_node, "/>\n");
|
||||||
|
|
@ -2017,7 +2088,7 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_svg_surface_t *surface = abstract_surface;
|
cairo_svg_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -2027,6 +2098,10 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;");
|
_cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;");
|
||||||
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL);
|
status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
|
|
@ -2034,16 +2109,14 @@ _cairo_svg_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "\" ");
|
_cairo_output_stream_printf (surface->xml_node, "\" ");
|
||||||
|
|
||||||
status = _cairo_svg_surface_emit_path (surface->xml_node, path, NULL);
|
_cairo_svg_surface_emit_path (surface->xml_node, path, NULL);
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "/>\n");
|
_cairo_output_stream_printf (surface->xml_node, "/>\n");
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_svg_surface_get_extents (void *abstract_surface,
|
_cairo_svg_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -2053,13 +2126,13 @@ _cairo_svg_surface_get_extents (void *abstract_surface,
|
||||||
rectangle->y = 0;
|
rectangle->y = 0;
|
||||||
|
|
||||||
/* XXX: The conversion to integers here is pretty bogus, (not to
|
/* XXX: The conversion to integers here is pretty bogus, (not to
|
||||||
* mention the aribitray limitation of width to a short(!). We
|
* mention the arbitrary limitation of width to a short(!). We
|
||||||
* may need to come up with a better interface for get_size.
|
* may need to come up with a better interface for get_size.
|
||||||
*/
|
*/
|
||||||
rectangle->width = (int) ceil (surface->width);
|
rectangle->width = (int) ceil (surface->width);
|
||||||
rectangle->height = (int) ceil (surface->height);
|
rectangle->height = (int) ceil (surface->height);
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
|
|
@ -2106,52 +2179,63 @@ static cairo_int_status_t
|
||||||
_cairo_svg_surface_paint (void *abstract_surface,
|
_cairo_svg_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_svg_surface_t *surface = abstract_surface;
|
cairo_svg_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
|
||||||
return _cairo_svg_surface_analyze_operation (surface, op, source);
|
|
||||||
|
|
||||||
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
|
||||||
|
|
||||||
/* Emulation of clear and source operators, when no clipping region
|
/* Emulation of clear and source operators, when no clipping region
|
||||||
* is defined. We just delete existing content of surface root node,
|
* is defined. We just delete existing content of surface root node,
|
||||||
* and exit early if operator is clear.
|
* and exit early if operator is clear.
|
||||||
* XXX: optimization of SOURCE operator doesn't work, since analyze
|
*/
|
||||||
* above always return FALSE. In order to make it work, we need a way
|
if ((op == CAIRO_OPERATOR_CLEAR || op == CAIRO_OPERATOR_SOURCE) &&
|
||||||
* to know if there's an active clipping path.
|
clip == NULL)
|
||||||
* Optimization of CLEAR works because of a test in paginated surface,
|
{
|
||||||
* and an optimization in meta surface. */
|
switch (surface->paginated_mode) {
|
||||||
if (surface->clip_level == 0 && op == CAIRO_OPERATOR_CLEAR) {
|
case CAIRO_PAGINATED_MODE_FALLBACK:
|
||||||
status = _cairo_output_stream_destroy (surface->xml_node);
|
ASSERT_NOT_REACHED;
|
||||||
if (unlikely (status)) {
|
case CAIRO_PAGINATED_MODE_ANALYZE:
|
||||||
surface->xml_node = NULL;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->xml_node = _cairo_memory_stream_create ();
|
|
||||||
if (_cairo_output_stream_get_status (surface->xml_node)) {
|
|
||||||
status = _cairo_output_stream_destroy (surface->xml_node);
|
|
||||||
surface->xml_node = NULL;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
|
||||||
if (surface->content == CAIRO_CONTENT_COLOR) {
|
|
||||||
_cairo_output_stream_printf (surface->xml_node,
|
|
||||||
"<rect "
|
|
||||||
"width=\"%f\" height=\"%f\" "
|
|
||||||
"style=\"opacity:1;"
|
|
||||||
"stroke:none;"
|
|
||||||
"fill:rgb(0,0,0);\"/>\n",
|
|
||||||
surface->width, surface->height);
|
|
||||||
}
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
case CAIRO_PAGINATED_MODE_RENDER:
|
||||||
|
status = _cairo_output_stream_destroy (surface->xml_node);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
surface->xml_node = NULL;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->xml_node = _cairo_memory_stream_create ();
|
||||||
|
if (_cairo_output_stream_get_status (surface->xml_node)) {
|
||||||
|
status = _cairo_output_stream_destroy (surface->xml_node);
|
||||||
|
surface->xml_node = NULL;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||||
|
if (surface->content == CAIRO_CONTENT_COLOR) {
|
||||||
|
_cairo_output_stream_printf (surface->xml_node,
|
||||||
|
"<rect "
|
||||||
|
"width=\"%f\" height=\"%f\" "
|
||||||
|
"style=\"opacity:1;"
|
||||||
|
"stroke:none;"
|
||||||
|
"fill:rgb(0,0,0);\"/>\n",
|
||||||
|
surface->width, surface->height);
|
||||||
|
}
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||||
|
return _cairo_svg_surface_analyze_operation (surface, op, source);
|
||||||
|
|
||||||
|
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
return _cairo_svg_surface_emit_paint (surface->xml_node,
|
return _cairo_svg_surface_emit_paint (surface->xml_node,
|
||||||
surface, op, source, 0, NULL);
|
surface, op, source, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -2161,7 +2245,7 @@ _cairo_svg_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_svg_surface_t *surface = abstract_surface;
|
cairo_svg_surface_t *surface = abstract_surface;
|
||||||
|
|
@ -2189,6 +2273,10 @@ _cairo_svg_surface_mask (void *abstract_surface,
|
||||||
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
||||||
assert (_cairo_svg_surface_operation_supported (surface, CAIRO_OPERATOR_OVER, mask));
|
assert (_cairo_svg_surface_operation_supported (surface, CAIRO_OPERATOR_OVER, mask));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||||
const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t*) mask;
|
const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t*) mask;
|
||||||
cairo_content_t content = cairo_surface_get_content (surface_pattern->surface);
|
cairo_content_t content = cairo_surface_get_content (surface_pattern->surface);
|
||||||
|
|
@ -2249,7 +2337,7 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_svg_surface_t *surface = abstract_dst;
|
cairo_svg_surface_t *surface = abstract_dst;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
@ -2259,6 +2347,10 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
||||||
|
|
||||||
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
assert (_cairo_svg_surface_operation_supported (surface, op, source));
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "<path style=\"fill:none;");
|
_cairo_output_stream_printf (surface->xml_node, "<path style=\"fill:none;");
|
||||||
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op,
|
status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op,
|
||||||
source, stroke_style, ctm_inverse);
|
source, stroke_style, ctm_inverse);
|
||||||
|
|
@ -2267,9 +2359,7 @@ _cairo_svg_surface_stroke (void *abstract_dst,
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "\" ");
|
_cairo_output_stream_printf (surface->xml_node, "\" ");
|
||||||
|
|
||||||
status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
|
_cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse);
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL);
|
_cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL);
|
||||||
_cairo_output_stream_printf (surface->xml_node, "/>\n");
|
_cairo_output_stream_printf (surface->xml_node, "/>\n");
|
||||||
|
|
@ -2284,8 +2374,8 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_svg_surface_t *surface = abstract_surface;
|
cairo_svg_surface_t *surface = abstract_surface;
|
||||||
cairo_svg_document_t *document = surface->document;
|
cairo_svg_document_t *document = surface->document;
|
||||||
|
|
@ -2302,6 +2392,10 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
|
||||||
if (num_glyphs <= 0)
|
if (num_glyphs <= 0)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
/* FIXME it's probably possible to apply a pattern of a gradient to
|
/* FIXME it's probably possible to apply a pattern of a gradient to
|
||||||
* a group of symbols, but I don't know how yet. Gradients or patterns
|
* a group of symbols, but I don't know how yet. Gradients or patterns
|
||||||
* are translated by x and y properties of use element. */
|
* are translated by x and y properties of use element. */
|
||||||
|
|
@ -2349,7 +2443,9 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface,
|
||||||
FALLBACK:
|
FALLBACK:
|
||||||
_cairo_path_fixed_init (&path);
|
_cairo_path_fixed_init (&path);
|
||||||
|
|
||||||
status = _cairo_scaled_font_glyph_path (scaled_font,(cairo_glyph_t *) glyphs, num_glyphs, &path);
|
status = _cairo_scaled_font_glyph_path (scaled_font,
|
||||||
|
(cairo_glyph_t *) glyphs,
|
||||||
|
num_glyphs, &path);
|
||||||
|
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
_cairo_path_fixed_fini (&path);
|
_cairo_path_fixed_fini (&path);
|
||||||
|
|
@ -2357,58 +2453,15 @@ FALLBACK:
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _cairo_svg_surface_fill (abstract_surface, op, pattern,
|
status = _cairo_svg_surface_fill (abstract_surface, op, pattern,
|
||||||
&path, CAIRO_FILL_RULE_WINDING, 0.0, CAIRO_ANTIALIAS_SUBPIXEL, NULL);
|
&path, CAIRO_FILL_RULE_WINDING,
|
||||||
|
0.0, CAIRO_ANTIALIAS_SUBPIXEL,
|
||||||
|
clip);
|
||||||
|
|
||||||
_cairo_path_fixed_fini (&path);
|
_cairo_path_fixed_fini (&path);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_svg_surface_intersect_clip_path (void *dst,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias)
|
|
||||||
{
|
|
||||||
cairo_svg_surface_t *surface = dst;
|
|
||||||
cairo_svg_document_t *document = surface->document;
|
|
||||||
cairo_status_t status;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
for (i = 0; i < surface->clip_level; i++)
|
|
||||||
_cairo_output_stream_printf (surface->xml_node, "</g>\n");
|
|
||||||
|
|
||||||
surface->clip_level = 0;
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (document->xml_node_defs,
|
|
||||||
"<clipPath id=\"clip%d\">\n"
|
|
||||||
" <path ",
|
|
||||||
document->clip_id);
|
|
||||||
status = _cairo_svg_surface_emit_path (document->xml_node_defs, path, NULL);
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (document->xml_node_defs,
|
|
||||||
"/>\n"
|
|
||||||
"</clipPath>\n");
|
|
||||||
|
|
||||||
_cairo_output_stream_printf (surface->xml_node,
|
|
||||||
"<g clip-path=\"url(#clip%d)\" "
|
|
||||||
"clip-rule=\"%s\">\n",
|
|
||||||
document->clip_id,
|
|
||||||
fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
|
|
||||||
"evenodd" : "nonzero");
|
|
||||||
|
|
||||||
document->clip_id++;
|
|
||||||
surface->clip_level++;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cairo_svg_surface_get_font_options (void *abstract_surface,
|
_cairo_svg_surface_get_font_options (void *abstract_surface,
|
||||||
cairo_font_options_t *options)
|
cairo_font_options_t *options)
|
||||||
|
|
@ -2422,7 +2475,7 @@ _cairo_svg_surface_get_font_options (void *abstract_surface,
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
||||||
CAIRO_SURFACE_TYPE_SVG,
|
CAIRO_SURFACE_TYPE_SVG,
|
||||||
_cairo_svg_surface_create_similar,
|
NULL, /* create_similar: handled by wrapper */
|
||||||
_cairo_svg_surface_finish,
|
_cairo_svg_surface_finish,
|
||||||
NULL, /* acquire_source_image */
|
NULL, /* acquire_source_image */
|
||||||
NULL, /* release_source_image */
|
NULL, /* release_source_image */
|
||||||
|
|
@ -2436,8 +2489,6 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
_cairo_svg_surface_copy_page,
|
_cairo_svg_surface_copy_page,
|
||||||
_cairo_svg_surface_show_page,
|
_cairo_svg_surface_show_page,
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_svg_surface_intersect_clip_path,
|
|
||||||
_cairo_svg_surface_get_extents,
|
_cairo_svg_surface_get_extents,
|
||||||
NULL, /* _cairo_svg_surface_old_show_glyphs, */
|
NULL, /* _cairo_svg_surface_old_show_glyphs, */
|
||||||
_cairo_svg_surface_get_font_options,
|
_cairo_svg_surface_get_font_options,
|
||||||
|
|
@ -2452,7 +2503,6 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
|
||||||
_cairo_svg_surface_show_glyphs,
|
_cairo_svg_surface_show_glyphs,
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
_cairo_svg_surface_fill_stroke
|
_cairo_svg_surface_fill_stroke
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2487,7 +2537,6 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
|
||||||
document->width = width;
|
document->width = width;
|
||||||
document->height = height;
|
document->height = height;
|
||||||
|
|
||||||
document->surface_id = 0;
|
|
||||||
document->linear_pattern_id = 0;
|
document->linear_pattern_id = 0;
|
||||||
document->radial_pattern_id = 0;
|
document->radial_pattern_id = 0;
|
||||||
document->pattern_id = 0;
|
document->pattern_id = 0;
|
||||||
|
|
@ -2507,9 +2556,6 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
|
||||||
|
|
||||||
document->alpha_filter = FALSE;
|
document->alpha_filter = FALSE;
|
||||||
|
|
||||||
_cairo_array_init (&document->meta_snapshots,
|
|
||||||
sizeof (cairo_meta_snapshot_t));
|
|
||||||
|
|
||||||
document->svg_version = version;
|
document->svg_version = version;
|
||||||
|
|
||||||
*document_out = document;
|
*document_out = document;
|
||||||
|
|
@ -2560,7 +2606,6 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
|
||||||
{
|
{
|
||||||
cairo_status_t status, status2;
|
cairo_status_t status, status2;
|
||||||
cairo_output_stream_t *output = document->output_stream;
|
cairo_output_stream_t *output = document->output_stream;
|
||||||
cairo_meta_snapshot_t *snapshot;
|
|
||||||
cairo_svg_page_t *page;
|
cairo_svg_page_t *page;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
|
@ -2662,16 +2707,6 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
if (status == CAIRO_STATUS_SUCCESS)
|
||||||
status = status2;
|
status = status2;
|
||||||
|
|
||||||
for (i = 0; i < document->meta_snapshots.num_elements; i++) {
|
|
||||||
snapshot = _cairo_array_index (&document->meta_snapshots, i);
|
|
||||||
cairo_surface_finish (&snapshot->meta->base);
|
|
||||||
status2 = cairo_surface_status (&snapshot->meta->base);
|
|
||||||
cairo_surface_destroy (&snapshot->meta->base);
|
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
|
||||||
status = status2;
|
|
||||||
}
|
|
||||||
_cairo_array_fini (&document->meta_snapshots);
|
|
||||||
|
|
||||||
document->finished = TRUE;
|
document->finished = TRUE;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@
|
||||||
|
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
|
|
||||||
|
#include "cairo-region-private.h"
|
||||||
|
|
||||||
/* private functions */
|
/* private functions */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -51,6 +53,8 @@ _cairo_traps_init (cairo_traps_t *traps)
|
||||||
|
|
||||||
traps->status = CAIRO_STATUS_SUCCESS;
|
traps->status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
traps->maybe_region = 1;
|
||||||
|
|
||||||
traps->num_traps = 0;
|
traps->num_traps = 0;
|
||||||
|
|
||||||
traps->traps_size = ARRAY_LENGTH (traps->traps_embedded);
|
traps->traps_size = ARRAY_LENGTH (traps->traps_embedded);
|
||||||
|
|
@ -83,6 +87,8 @@ _cairo_traps_clear (cairo_traps_t *traps)
|
||||||
{
|
{
|
||||||
traps->status = CAIRO_STATUS_SUCCESS;
|
traps->status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
traps->maybe_region = 1;
|
||||||
|
|
||||||
traps->num_traps = 0;
|
traps->num_traps = 0;
|
||||||
traps->extents.p1.x = traps->extents.p1.y = INT32_MAX;
|
traps->extents.p1.x = traps->extents.p1.y = INT32_MAX;
|
||||||
traps->extents.p2.x = traps->extents.p2.y = INT32_MIN;
|
traps->extents.p2.x = traps->extents.p2.y = INT32_MIN;
|
||||||
|
|
@ -616,14 +622,18 @@ _cairo_traps_extents (const cairo_traps_t *traps,
|
||||||
* or %CAIRO_STATUS_NO_MEMORY
|
* or %CAIRO_STATUS_NO_MEMORY
|
||||||
**/
|
**/
|
||||||
cairo_int_status_t
|
cairo_int_status_t
|
||||||
_cairo_traps_extract_region (const cairo_traps_t *traps,
|
_cairo_traps_extract_region (cairo_traps_t *traps,
|
||||||
cairo_region_t **region)
|
cairo_region_t **region)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
|
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
|
||||||
cairo_rectangle_int_t *rects = stack_rects;
|
cairo_rectangle_int_t *rects = stack_rects;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
int i, rect_count;
|
int i, rect_count;
|
||||||
|
|
||||||
|
/* we only treat this a hint... */
|
||||||
|
if (! traps->maybe_region)
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
for (i = 0; i < traps->num_traps; i++) {
|
for (i = 0; i < traps->num_traps; i++) {
|
||||||
if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x ||
|
if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x ||
|
||||||
traps->traps[i].right.p1.x != traps->traps[i].right.p2.x ||
|
traps->traps[i].right.p1.x != traps->traps[i].right.p2.x ||
|
||||||
|
|
@ -632,6 +642,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
|
||||||
! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) ||
|
! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) ||
|
||||||
! _cairo_fixed_is_integer (traps->traps[i].right.p1.x))
|
! _cairo_fixed_is_integer (traps->traps[i].right.p1.x))
|
||||||
{
|
{
|
||||||
|
traps->maybe_region = FALSE;
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -655,7 +666,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
|
||||||
*/
|
*/
|
||||||
if (x1 == x2 || y1 == y2)
|
if (x1 == x2 || y1 == y2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rects[rect_count].x = x1;
|
rects[rect_count].x = x1;
|
||||||
rects[rect_count].y = y1;
|
rects[rect_count].y = y1;
|
||||||
rects[rect_count].width = x2 - x1;
|
rects[rect_count].width = x2 - x1;
|
||||||
|
|
@ -663,18 +674,13 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
|
||||||
|
|
||||||
rect_count++;
|
rect_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*region = cairo_region_create_rectangles (rects, rect_count);
|
*region = cairo_region_create_rectangles (rects, rect_count);
|
||||||
status = cairo_region_status (*region);
|
status = (*region)->status;
|
||||||
|
|
||||||
if (rects != stack_rects)
|
if (rects != stack_rects)
|
||||||
free (rects);
|
free (rects);
|
||||||
|
|
||||||
if (unlikely (status)) {
|
|
||||||
cairo_region_destroy (*region);
|
|
||||||
*region = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
#if CAIRO_HAS_FONT_SUBSET
|
#if CAIRO_HAS_FONT_SUBSET
|
||||||
|
|
||||||
#include "cairo-surface-private.h"
|
#include "cairo-surface-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
#include "cairo-pdf-operators-private.h"
|
#include "cairo-pdf-operators-private.h"
|
||||||
|
|
||||||
typedef cairo_status_t (*cairo_type3_glyph_surface_emit_image_t) (cairo_image_surface_t *image,
|
typedef cairo_status_t (*cairo_type3_glyph_surface_emit_image_t) (cairo_image_surface_t *image,
|
||||||
|
|
@ -55,16 +56,18 @@ typedef struct cairo_type3_glyph_surface {
|
||||||
cairo_pdf_operators_t pdf_operators;
|
cairo_pdf_operators_t pdf_operators;
|
||||||
cairo_matrix_t cairo_to_pdf;
|
cairo_matrix_t cairo_to_pdf;
|
||||||
cairo_type3_glyph_surface_emit_image_t emit_image;
|
cairo_type3_glyph_surface_emit_image_t emit_image;
|
||||||
|
|
||||||
|
cairo_surface_clipper_t clipper;
|
||||||
} cairo_type3_glyph_surface_t;
|
} cairo_type3_glyph_surface_t;
|
||||||
|
|
||||||
cairo_private cairo_surface_t *
|
cairo_private cairo_surface_t *
|
||||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||||
cairo_output_stream_t *stream,
|
cairo_output_stream_t *stream,
|
||||||
cairo_type3_glyph_surface_emit_image_t emit_image,
|
cairo_type3_glyph_surface_emit_image_t emit_image,
|
||||||
cairo_scaled_font_subsets_t *font_subsets);
|
cairo_scaled_font_subsets_t *font_subsets);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface,
|
_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface,
|
||||||
cairo_pdf_operators_use_font_subset_t use_font_subset,
|
cairo_pdf_operators_use_font_subset_t use_font_subset,
|
||||||
void *closure);
|
void *closure);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,31 @@
|
||||||
#include "cairo-output-stream-private.h"
|
#include "cairo-output-stream-private.h"
|
||||||
#include "cairo-meta-surface-private.h"
|
#include "cairo-meta-surface-private.h"
|
||||||
#include "cairo-analysis-surface-private.h"
|
#include "cairo-analysis-surface-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_type3_glyph_surface_backend;
|
static const cairo_surface_backend_t cairo_type3_glyph_surface_backend;
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_type3_glyph_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias)
|
||||||
|
{
|
||||||
|
cairo_type3_glyph_surface_t *surface = cairo_container_of (clipper,
|
||||||
|
cairo_type3_glyph_surface_t,
|
||||||
|
clipper);
|
||||||
|
|
||||||
|
if (path == NULL) {
|
||||||
|
_cairo_output_stream_printf (surface->stream, "Q q\n");
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _cairo_pdf_operators_clip (&surface->pdf_operators,
|
||||||
|
path,
|
||||||
|
fill_rule);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||||
cairo_output_stream_t *stream,
|
cairo_output_stream_t *stream,
|
||||||
|
|
@ -81,6 +103,9 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||||
&surface->cairo_to_pdf,
|
&surface->cairo_to_pdf,
|
||||||
font_subsets);
|
font_subsets);
|
||||||
|
|
||||||
|
_cairo_surface_clipper_init (&surface->clipper,
|
||||||
|
_cairo_type3_glyph_surface_clipper_intersect_clip_path);
|
||||||
|
|
||||||
return &surface->base;
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,30 +180,11 @@ _cairo_type3_glyph_surface_finish (void *abstract_surface)
|
||||||
return _cairo_pdf_operators_fini (&surface->pdf_operators);
|
return _cairo_pdf_operators_fini (&surface->pdf_operators);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_type3_glyph_surface_intersect_clip_path (void *abstract_surface,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias)
|
|
||||||
{
|
|
||||||
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
|
||||||
|
|
||||||
if (path == NULL) {
|
|
||||||
_cairo_output_stream_printf (surface->stream, "Q q\n");
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _cairo_pdf_operators_clip (&surface->pdf_operators,
|
|
||||||
path,
|
|
||||||
fill_rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_cairo_type3_glyph_surface_paint (void *abstract_surface,
|
_cairo_type3_glyph_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
||||||
const cairo_surface_pattern_t *pattern;
|
const cairo_surface_pattern_t *pattern;
|
||||||
|
|
@ -189,8 +195,13 @@ _cairo_type3_glyph_surface_paint (void *abstract_surface,
|
||||||
if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
|
if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
|
||||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
pattern = (const cairo_surface_pattern_t *) source;
|
pattern = (const cairo_surface_pattern_t *) source;
|
||||||
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
|
status = _cairo_surface_acquire_source_image (pattern->surface,
|
||||||
|
&image, &image_extra);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
@ -209,9 +220,11 @@ _cairo_type3_glyph_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
return _cairo_type3_glyph_surface_paint (abstract_surface, op, mask, extents);
|
return _cairo_type3_glyph_surface_paint (abstract_surface,
|
||||||
|
op, mask,
|
||||||
|
clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -224,9 +237,14 @@ _cairo_type3_glyph_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
||||||
|
cairo_int_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
return _cairo_pdf_operators_stroke (&surface->pdf_operators,
|
return _cairo_pdf_operators_stroke (&surface->pdf_operators,
|
||||||
path,
|
path,
|
||||||
|
|
@ -243,16 +261,18 @@ _cairo_type3_glyph_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
|
||||||
status = _cairo_pdf_operators_fill (&surface->pdf_operators,
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
path,
|
if (unlikely (status))
|
||||||
fill_rule);
|
return status;
|
||||||
|
|
||||||
return status;
|
return _cairo_pdf_operators_fill (&surface->pdf_operators,
|
||||||
|
path,
|
||||||
|
fill_rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -262,8 +282,8 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
|
@ -271,8 +291,14 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_matrix_t new_ctm, ctm_inverse;
|
cairo_matrix_t new_ctm, ctm_inverse;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < num_glyphs; i++)
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
cairo_matrix_transform_point (&surface->cairo_to_pdf, &glyphs[i].x, &glyphs[i].y);
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
|
for (i = 0; i < num_glyphs; i++) {
|
||||||
|
cairo_matrix_transform_point (&surface->cairo_to_pdf,
|
||||||
|
&glyphs[i].x, &glyphs[i].y);
|
||||||
|
}
|
||||||
|
|
||||||
/* We require the matrix to be invertable. */
|
/* We require the matrix to be invertable. */
|
||||||
ctm_inverse = scaled_font->ctm;
|
ctm_inverse = scaled_font->ctm;
|
||||||
|
|
@ -316,8 +342,6 @@ static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* cairo_type3_glyph_surface_copy_page */
|
NULL, /* cairo_type3_glyph_surface_copy_page */
|
||||||
NULL, /* _cairo_type3_glyph_surface_show_page */
|
NULL, /* _cairo_type3_glyph_surface_show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_type3_glyph_surface_intersect_clip_path,
|
|
||||||
NULL, /* _cairo_type3_glyph_surface_get_extents */
|
NULL, /* _cairo_type3_glyph_surface_get_extents */
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* _cairo_type3_glyph_surface_get_font_options */
|
NULL, /* _cairo_type3_glyph_surface_get_font_options */
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
|
|
||||||
#include "cairo.h"
|
#include "cairo.h"
|
||||||
#include "cairo-fixed-type-private.h"
|
#include "cairo-fixed-type-private.h"
|
||||||
|
#include "cairo-list-private.h"
|
||||||
#include "cairo-reference-count-private.h"
|
#include "cairo-reference-count-private.h"
|
||||||
|
|
||||||
typedef struct _cairo_array cairo_array_t;
|
typedef struct _cairo_array cairo_array_t;
|
||||||
|
|
@ -63,6 +64,7 @@ typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t;
|
||||||
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
|
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
|
||||||
typedef struct _cairo_solid_pattern cairo_solid_pattern_t;
|
typedef struct _cairo_solid_pattern cairo_solid_pattern_t;
|
||||||
typedef struct _cairo_surface_backend cairo_surface_backend_t;
|
typedef struct _cairo_surface_backend cairo_surface_backend_t;
|
||||||
|
typedef struct _cairo_surface_wrapper cairo_surface_wrapper_t;
|
||||||
typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t;
|
typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t;
|
||||||
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
|
typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t;
|
||||||
|
|
||||||
|
|
@ -167,6 +169,7 @@ typedef enum _cairo_internal_surface_type {
|
||||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
||||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
|
CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
|
||||||
|
CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING,
|
||||||
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
|
CAIRO_INTERNAL_SURFACE_TYPE_NULL,
|
||||||
CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH
|
CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH
|
||||||
} cairo_internal_surface_type_t;
|
} cairo_internal_surface_type_t;
|
||||||
|
|
@ -237,12 +240,6 @@ typedef enum _cairo_direction {
|
||||||
CAIRO_DIRECTION_REVERSE
|
CAIRO_DIRECTION_REVERSE
|
||||||
} cairo_direction_t;
|
} cairo_direction_t;
|
||||||
|
|
||||||
typedef enum _cairo_clip_mode {
|
|
||||||
CAIRO_CLIP_MODE_PATH,
|
|
||||||
CAIRO_CLIP_MODE_REGION,
|
|
||||||
CAIRO_CLIP_MODE_MASK
|
|
||||||
} cairo_clip_mode_t;
|
|
||||||
|
|
||||||
typedef struct _cairo_edge {
|
typedef struct _cairo_edge {
|
||||||
cairo_line_t edge;
|
cairo_line_t edge;
|
||||||
int dir;
|
int dir;
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ _cairo_user_scaled_font_create_meta_context (cairo_user_scaled_font_t *scaled_fo
|
||||||
CAIRO_CONTENT_COLOR_ALPHA :
|
CAIRO_CONTENT_COLOR_ALPHA :
|
||||||
CAIRO_CONTENT_ALPHA;
|
CAIRO_CONTENT_ALPHA;
|
||||||
|
|
||||||
meta_surface = cairo_meta_surface_create (content, -1, -1);
|
meta_surface = cairo_meta_surface_create (content, NULL);
|
||||||
cr = cairo_create (meta_surface);
|
cr = cairo_create (meta_surface);
|
||||||
cairo_surface_destroy (meta_surface);
|
cairo_surface_destroy (meta_surface);
|
||||||
|
|
||||||
|
|
@ -114,11 +114,11 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
|
||||||
|
|
||||||
cr = _cairo_user_scaled_font_create_meta_context (scaled_font);
|
cr = _cairo_user_scaled_font_create_meta_context (scaled_font);
|
||||||
|
|
||||||
if (face->scaled_font_methods.render_glyph)
|
if (face->scaled_font_methods.render_glyph) {
|
||||||
status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font,
|
status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font,
|
||||||
_cairo_scaled_glyph_index(scaled_glyph),
|
_cairo_scaled_glyph_index(scaled_glyph),
|
||||||
cr, &extents);
|
cr, &extents);
|
||||||
else
|
} else
|
||||||
status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED;
|
status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
if (status == CAIRO_STATUS_SUCCESS)
|
if (status == CAIRO_STATUS_SUCCESS)
|
||||||
|
|
@ -141,27 +141,16 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
|
||||||
/* set metrics */
|
/* set metrics */
|
||||||
|
|
||||||
if (extents.width == 0.) {
|
if (extents.width == 0.) {
|
||||||
/* Compute extents.x/y/width/height from meta_surface, in font space */
|
|
||||||
|
|
||||||
cairo_box_t bbox;
|
cairo_box_t bbox;
|
||||||
double x1, y1, x2, y2;
|
double x1, y1, x2, y2;
|
||||||
double x_scale, y_scale;
|
double x_scale, y_scale;
|
||||||
cairo_surface_t *null_surface;
|
|
||||||
cairo_surface_t *analysis_surface;
|
|
||||||
|
|
||||||
null_surface = _cairo_null_surface_create (cairo_surface_get_content (meta_surface));
|
|
||||||
analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
|
|
||||||
cairo_surface_destroy (null_surface);
|
|
||||||
status = analysis_surface->status;
|
|
||||||
if (unlikely (status))
|
|
||||||
return status;
|
|
||||||
|
|
||||||
_cairo_analysis_surface_set_ctm (analysis_surface,
|
|
||||||
&scaled_font->extent_scale);
|
|
||||||
status = cairo_meta_surface_replay (meta_surface, analysis_surface);
|
|
||||||
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
|
|
||||||
cairo_surface_destroy (analysis_surface);
|
|
||||||
|
|
||||||
|
/* Compute extents.x/y/width/height from meta_surface,
|
||||||
|
* in font space.
|
||||||
|
*/
|
||||||
|
status = _cairo_meta_surface_get_bbox ((cairo_meta_surface_t *) meta_surface,
|
||||||
|
&bbox,
|
||||||
|
&scaled_font->extent_scale);
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -231,7 +220,6 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
status = _cairo_meta_surface_get_path (meta_surface, path);
|
status = _cairo_meta_surface_get_path (meta_surface, path);
|
||||||
|
|
||||||
if (unlikely (status)) {
|
if (unlikely (status)) {
|
||||||
_cairo_path_fixed_destroy (path);
|
_cairo_path_fixed_destroy (path);
|
||||||
return status;
|
return status;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
|
|
||||||
#include "cairo-path-fixed-private.h"
|
#include "cairo-path-fixed-private.h"
|
||||||
#include "cairo-meta-surface-private.h"
|
#include "cairo-meta-surface-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
#include "cairo-cache-private.h"
|
#include "cairo-cache-private.h"
|
||||||
|
|
||||||
#include <pixman.h>
|
#include <pixman.h>
|
||||||
|
|
@ -94,7 +95,7 @@ struct _cairo_vg_surface {
|
||||||
|
|
||||||
cairo_cache_entry_t snapshot_cache_entry;
|
cairo_cache_entry_t snapshot_cache_entry;
|
||||||
|
|
||||||
cairo_bool_t clipped;
|
cairo_surface_clipper_t clipper;
|
||||||
|
|
||||||
unsigned long target_id;
|
unsigned long target_id;
|
||||||
};
|
};
|
||||||
|
|
@ -397,21 +398,21 @@ _vg_surface_create_similar (void *abstract_surface,
|
||||||
return cairo_vg_surface_create (surface->context, content, width, height);
|
return cairo_vg_surface_create (surface->context, content, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_status_t
|
||||||
_vg_surface_intersect_clip_path (void *abstract_surface,
|
_vg_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias)
|
cairo_antialias_t antialias)
|
||||||
{
|
{
|
||||||
cairo_vg_surface_t *surface = abstract_surface;
|
cairo_vg_surface_t *surface = cairo_container_of (clipper,
|
||||||
|
cairo_vg_surface_t,
|
||||||
|
clipper);
|
||||||
cairo_vg_surface_t *mask;
|
cairo_vg_surface_t *mask;
|
||||||
cairo_rectangle_int_t extents, clip_extents;
|
|
||||||
cairo_solid_pattern_t white;
|
cairo_solid_pattern_t white;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
surface->clipped = FALSE;
|
|
||||||
vgMask (VG_INVALID_HANDLE,
|
vgMask (VG_INVALID_HANDLE,
|
||||||
VG_FILL_MASK, 0, 0, surface->width, surface->height);
|
VG_FILL_MASK, 0, 0, surface->width, surface->height);
|
||||||
vgSeti (VG_MASKING, VG_FALSE);
|
vgSeti (VG_MASKING, VG_FALSE);
|
||||||
|
|
@ -419,16 +420,6 @@ _vg_surface_intersect_clip_path (void *abstract_surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
extents.x = extents.y = 0;
|
|
||||||
extents.width = surface->width;
|
|
||||||
extents.height = surface->height;
|
|
||||||
_cairo_path_fixed_approximate_clip_extents (path, &clip_extents);
|
|
||||||
if (! _cairo_rectangle_intersect (&clip_extents, &extents))
|
|
||||||
surface->clipped = TRUE;
|
|
||||||
|
|
||||||
if (surface->clipped)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
mask = (cairo_vg_surface_t *)
|
mask = (cairo_vg_surface_t *)
|
||||||
_vg_surface_create_similar (surface, CAIRO_CONTENT_ALPHA,
|
_vg_surface_create_similar (surface, CAIRO_CONTENT_ALPHA,
|
||||||
surface->width, surface->height);
|
surface->width, surface->height);
|
||||||
|
|
@ -456,7 +447,7 @@ _vg_surface_intersect_clip_path (void *abstract_surface,
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_vg_surface_get_extents (void *abstract_surface,
|
_vg_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
|
|
@ -467,7 +458,7 @@ _vg_surface_get_extents (void *abstract_surface,
|
||||||
extents->width = surface->width;
|
extents->width = surface->width;
|
||||||
extents->height = surface->height;
|
extents->height = surface->height;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_SEG 16 /* max number of knots to upload in a batch */
|
#define MAX_SEG 16 /* max number of knots to upload in a batch */
|
||||||
|
|
@ -589,7 +580,7 @@ _vg_close_path (void *closure)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_vg_path_from_cairo (vg_path_t *vg_path,
|
_vg_path_from_cairo (vg_path_t *vg_path,
|
||||||
cairo_path_fixed_t *path)
|
const cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
|
|
@ -805,7 +796,7 @@ _vg_setup_linear_source (cairo_vg_context_t *context,
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_vg_setup_radial_source (cairo_vg_context_t *context,
|
_vg_setup_radial_source (cairo_vg_context_t *context,
|
||||||
cairo_radial_pattern_t *rpat)
|
const cairo_radial_pattern_t *rpat)
|
||||||
{
|
{
|
||||||
VGfloat radial[5];
|
VGfloat radial[5];
|
||||||
|
|
||||||
|
|
@ -832,7 +823,7 @@ _vg_setup_radial_source (cairo_vg_context_t *context,
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_vg_setup_solid_source (cairo_vg_context_t *context,
|
_vg_setup_solid_source (cairo_vg_context_t *context,
|
||||||
cairo_solid_pattern_t *spat)
|
const cairo_solid_pattern_t *spat)
|
||||||
{
|
{
|
||||||
VGfloat color[] = {
|
VGfloat color[] = {
|
||||||
spat->color.red,
|
spat->color.red,
|
||||||
|
|
@ -960,7 +951,7 @@ _vg_surface_remove_from_cache (cairo_surface_t *abstract_surface)
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_vg_setup_surface_source (cairo_vg_context_t *context,
|
_vg_setup_surface_source (cairo_vg_context_t *context,
|
||||||
cairo_surface_pattern_t *spat)
|
const cairo_surface_pattern_t *spat)
|
||||||
{
|
{
|
||||||
cairo_surface_t *snapshot;
|
cairo_surface_t *snapshot;
|
||||||
cairo_vg_surface_t *clone;
|
cairo_vg_surface_t *clone;
|
||||||
|
|
@ -1077,7 +1068,7 @@ _vg_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_vg_surface_t *surface = abstract_surface;
|
cairo_vg_surface_t *surface = abstract_surface;
|
||||||
cairo_vg_context_t *context;
|
cairo_vg_context_t *context;
|
||||||
|
|
@ -1086,9 +1077,6 @@ _vg_surface_stroke (void *abstract_surface,
|
||||||
VGfloat strokeTransform[9];
|
VGfloat strokeTransform[9];
|
||||||
vg_path_t vg_path;
|
vg_path_t vg_path;
|
||||||
|
|
||||||
if (surface->clipped)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (! _vg_is_supported_operator (op))
|
if (! _vg_is_supported_operator (op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
|
@ -1105,6 +1093,12 @@ _vg_surface_stroke (void *abstract_surface,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
_vg_context_unlock (context);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
|
vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
|
||||||
VG_PATH_DATATYPE_F,
|
VG_PATH_DATATYPE_F,
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
|
|
@ -1148,16 +1142,13 @@ _vg_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_vg_surface_t *surface = abstract_surface;
|
cairo_vg_surface_t *surface = abstract_surface;
|
||||||
cairo_vg_context_t *context;
|
cairo_vg_context_t *context;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
vg_path_t vg_path;
|
vg_path_t vg_path;
|
||||||
|
|
||||||
if (surface->clipped)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (op == CAIRO_OPERATOR_DEST)
|
if (op == CAIRO_OPERATOR_DEST)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
@ -1177,6 +1168,12 @@ _vg_surface_fill (void *abstract_surface,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
_vg_context_unlock (context);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
|
vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD,
|
||||||
VG_PATH_DATATYPE_F,
|
VG_PATH_DATATYPE_F,
|
||||||
1, 0,
|
1, 0,
|
||||||
|
|
@ -1208,15 +1205,12 @@ static cairo_int_status_t
|
||||||
_vg_surface_paint (void *abstract_surface,
|
_vg_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_vg_surface_t *surface = abstract_surface;
|
cairo_vg_surface_t *surface = abstract_surface;
|
||||||
cairo_vg_context_t *context;
|
cairo_vg_context_t *context;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
if (surface->clipped)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (op == CAIRO_OPERATOR_DEST)
|
if (op == CAIRO_OPERATOR_DEST)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
|
@ -1236,6 +1230,12 @@ _vg_surface_paint (void *abstract_surface,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (unlikely (status)) {
|
||||||
|
_vg_context_unlock (context);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
vgSeti (VG_BLEND_MODE, _vg_operator (op));
|
vgSeti (VG_BLEND_MODE, _vg_operator (op));
|
||||||
vgSetPaint (context->paint, VG_FILL_PATH);
|
vgSetPaint (context->paint, VG_FILL_PATH);
|
||||||
|
|
||||||
|
|
@ -1273,14 +1273,11 @@ _vg_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_vg_surface_t *surface = abstract_surface;
|
cairo_vg_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
if (surface->clipped)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (! _vg_is_supported_operator (op))
|
if (! _vg_is_supported_operator (op))
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
|
@ -1291,7 +1288,7 @@ _vg_surface_mask (void *abstract_surface,
|
||||||
double alpha = context->alpha;
|
double alpha = context->alpha;
|
||||||
|
|
||||||
context->alpha = solid->color.alpha;
|
context->alpha = solid->color.alpha;
|
||||||
status = _vg_surface_paint (abstract_surface, op, source, extents);
|
status = _vg_surface_paint (abstract_surface, op, source, clip);
|
||||||
context->alpha = alpha;
|
context->alpha = alpha;
|
||||||
|
|
||||||
_vg_context_unlock (context);
|
_vg_context_unlock (context);
|
||||||
|
|
@ -1312,14 +1309,14 @@ _vg_surface_get_font_options (void *abstract_surface,
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
_vg_surface_show_glyphs (void *abstract_surface,
|
_vg_surface_show_glyphs (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
cairo_path_fixed_t path;
|
cairo_path_fixed_t path;
|
||||||
|
|
@ -1342,7 +1339,7 @@ _vg_surface_show_glyphs (void *abstract_surface,
|
||||||
CAIRO_FILL_RULE_WINDING,
|
CAIRO_FILL_RULE_WINDING,
|
||||||
CAIRO_GSTATE_TOLERANCE_DEFAULT,
|
CAIRO_GSTATE_TOLERANCE_DEFAULT,
|
||||||
CAIRO_ANTIALIAS_SUBPIXEL,
|
CAIRO_ANTIALIAS_SUBPIXEL,
|
||||||
extents);
|
clip);
|
||||||
BAIL:
|
BAIL:
|
||||||
_cairo_path_fixed_fini (&path);
|
_cairo_path_fixed_fini (&path);
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -1510,12 +1507,6 @@ _vg_surface_release_dest_image (void *abstract_surface,
|
||||||
cairo_vg_surface_t *surface = abstract_surface;
|
cairo_vg_surface_t *surface = abstract_surface;
|
||||||
cairo_bool_t needs_unpremultiply;
|
cairo_bool_t needs_unpremultiply;
|
||||||
|
|
||||||
/* XXX clipping is incorrect
|
|
||||||
* We can either composite through the current clip mask using fill,
|
|
||||||
* or what for the clipping overhaul patches, due to land any time
|
|
||||||
* soon now...
|
|
||||||
*/
|
|
||||||
|
|
||||||
_vg_format_to_pixman (surface->format, &needs_unpremultiply);
|
_vg_format_to_pixman (surface->format, &needs_unpremultiply);
|
||||||
if (needs_unpremultiply) {
|
if (needs_unpremultiply) {
|
||||||
unpremultiply_argb (image->data,
|
unpremultiply_argb (image->data,
|
||||||
|
|
@ -1545,6 +1536,8 @@ _vg_surface_finish (void *abstract_surface)
|
||||||
surface->snapshot_cache_entry.hash = 0;
|
surface->snapshot_cache_entry.hash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cairo_surface_clipper_reset (&surface->clipper);
|
||||||
|
|
||||||
if (surface->own_image)
|
if (surface->own_image)
|
||||||
vgDestroyImage (surface->image);
|
vgDestroyImage (surface->image);
|
||||||
|
|
||||||
|
|
@ -1561,20 +1554,21 @@ static const cairo_surface_backend_t cairo_vg_surface_backend = {
|
||||||
CAIRO_SURFACE_TYPE_VG,
|
CAIRO_SURFACE_TYPE_VG,
|
||||||
_vg_surface_create_similar,
|
_vg_surface_create_similar,
|
||||||
_vg_surface_finish,
|
_vg_surface_finish,
|
||||||
|
|
||||||
_vg_surface_acquire_source_image,
|
_vg_surface_acquire_source_image,
|
||||||
_vg_surface_release_source_image,
|
_vg_surface_release_source_image,
|
||||||
_vg_surface_acquire_dest_image,
|
_vg_surface_acquire_dest_image,
|
||||||
_vg_surface_release_dest_image,
|
_vg_surface_release_dest_image,
|
||||||
|
|
||||||
NULL, /* clone_similar */
|
NULL, /* clone_similar */
|
||||||
NULL, /* composite */
|
NULL, /* composite */
|
||||||
NULL, /* fill_rectangles */
|
NULL, /* fill_rectangles */
|
||||||
NULL, /* composite_trapezoids */
|
NULL, /* composite_trapezoids */
|
||||||
NULL, /* create_span_renderer */
|
NULL, /* create_span_renderer */
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
|
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_vg_surface_intersect_clip_path,
|
|
||||||
_vg_surface_get_extents,
|
_vg_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
_vg_surface_get_font_options, /* get_font_options */
|
_vg_surface_get_font_options, /* get_font_options */
|
||||||
|
|
@ -1591,7 +1585,6 @@ static const cairo_surface_backend_t cairo_vg_surface_backend = {
|
||||||
|
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
|
|
@ -1617,15 +1610,14 @@ _vg_surface_create_internal (cairo_vg_context_t *context,
|
||||||
|
|
||||||
surface->width = width;
|
surface->width = width;
|
||||||
surface->height = height;
|
surface->height = height;
|
||||||
surface->clipped = FALSE;
|
|
||||||
|
_cairo_surface_clipper_init (&surface->clipper,
|
||||||
|
_vg_surface_clipper_intersect_clip_path);
|
||||||
|
|
||||||
surface->snapshot_cache_entry.hash = 0;
|
surface->snapshot_cache_entry.hash = 0;
|
||||||
|
|
||||||
surface->target_id = 0;
|
surface->target_id = 0;
|
||||||
|
|
||||||
/* Force an initial "clip", that resets the mask */
|
|
||||||
_vg_surface_intersect_clip_path (surface, NULL, 0, 0.0, 0);
|
|
||||||
|
|
||||||
CHECK_VG_ERRORS();
|
CHECK_VG_ERRORS();
|
||||||
return &surface->base;
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1360,6 +1360,7 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
|
cairo_region_t *clip_region,
|
||||||
int *remaining_glyphs)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_win32_scaled_font_t *scaled_font = abstract_font;
|
cairo_win32_scaled_font_t *scaled_font = abstract_font;
|
||||||
|
|
@ -1381,15 +1382,17 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
||||||
*/
|
*/
|
||||||
COLORREF new_color;
|
COLORREF new_color;
|
||||||
|
|
||||||
|
status = _cairo_win32_surface_set_clip_region (surface, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
return status;
|
||||||
|
|
||||||
new_color = RGB (((int)solid_pattern->color.red_short) >> 8,
|
new_color = RGB (((int)solid_pattern->color.red_short) >> 8,
|
||||||
((int)solid_pattern->color.green_short) >> 8,
|
((int)solid_pattern->color.green_short) >> 8,
|
||||||
((int)solid_pattern->color.blue_short) >> 8);
|
((int)solid_pattern->color.blue_short) >> 8);
|
||||||
|
|
||||||
status = _draw_glyphs_on_surface (surface, scaled_font, new_color,
|
return _draw_glyphs_on_surface (surface, scaled_font, new_color,
|
||||||
0, 0,
|
0, 0,
|
||||||
glyphs, num_glyphs);
|
glyphs, num_glyphs);
|
||||||
|
|
||||||
return status;
|
|
||||||
} else {
|
} else {
|
||||||
/* Otherwise, we need to draw using software fallbacks. We create a mask
|
/* Otherwise, we need to draw using software fallbacks. We create a mask
|
||||||
* surface by drawing the the glyphs onto a DIB, black-on-white then
|
* surface by drawing the the glyphs onto a DIB, black-on-white then
|
||||||
|
|
@ -1458,7 +1461,8 @@ _cairo_win32_scaled_font_show_glyphs (void *abstract_font,
|
||||||
source_x, source_y,
|
source_x, source_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
dest_x, dest_y,
|
dest_x, dest_y,
|
||||||
width, height);
|
width, height,
|
||||||
|
clip_region);
|
||||||
|
|
||||||
_cairo_pattern_fini (&mask.base);
|
_cairo_pattern_fini (&mask.base);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@
|
||||||
#include "cairo-meta-surface-private.h"
|
#include "cairo-meta-surface-private.h"
|
||||||
#include "cairo-scaled-font-subsets-private.h"
|
#include "cairo-scaled-font-subsets-private.h"
|
||||||
#include "cairo-image-info-private.h"
|
#include "cairo-image-info-private.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
@ -128,7 +129,7 @@ analyze_surface_pattern_transparency (cairo_surface_pattern_t *pattern)
|
||||||
cairo_image_surface_t *image;
|
cairo_image_surface_t *image;
|
||||||
void *image_extra;
|
void *image_extra;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
int x, y;
|
cairo_image_transparency_t transparency;
|
||||||
|
|
||||||
status = _cairo_surface_acquire_source_image (pattern->surface,
|
status = _cairo_surface_acquire_source_image (pattern->surface,
|
||||||
&image,
|
&image,
|
||||||
|
|
@ -136,38 +137,20 @@ analyze_surface_pattern_transparency (cairo_surface_pattern_t *pattern)
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (image->base.status)
|
transparency = _cairo_image_analyze_transparency (image);
|
||||||
return image->base.status;
|
switch (transparency) {
|
||||||
|
case CAIRO_IMAGE_UNKNOWN:
|
||||||
if (image->format == CAIRO_FORMAT_RGB24) {
|
ASSERT_NOT_REACHED;
|
||||||
|
case CAIRO_IMAGE_IS_OPAQUE:
|
||||||
status = CAIRO_STATUS_SUCCESS;
|
status = CAIRO_STATUS_SUCCESS;
|
||||||
goto RELEASE_SOURCE;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (image->format != CAIRO_FORMAT_ARGB32) {
|
case CAIRO_IMAGE_HAS_BILEVEL_ALPHA:
|
||||||
/* If the surface does not support the image format, assume
|
case CAIRO_IMAGE_HAS_ALPHA:
|
||||||
* that it does have alpha. The image will be converted to
|
|
||||||
* rgb24 when the surface blends the image into the page
|
|
||||||
* color to remove the transparency. */
|
|
||||||
status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
||||||
goto RELEASE_SOURCE;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 0; y < image->height; y++) {
|
|
||||||
int a;
|
|
||||||
uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
|
|
||||||
|
|
||||||
for (x = 0; x < image->width; x++, pixel++) {
|
|
||||||
a = (*pixel & 0xff000000) >> 24;
|
|
||||||
if (a != 255) {
|
|
||||||
status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
|
|
||||||
goto RELEASE_SOURCE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
status = CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
RELEASE_SOURCE:
|
|
||||||
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
|
@ -176,8 +159,6 @@ RELEASE_SOURCE:
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
surface_pattern_supported (const cairo_surface_pattern_t *pattern)
|
surface_pattern_supported (const cairo_surface_pattern_t *pattern)
|
||||||
{
|
{
|
||||||
cairo_extend_t extend;
|
|
||||||
|
|
||||||
if (_cairo_surface_is_meta (pattern->surface))
|
if (_cairo_surface_is_meta (pattern->surface))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
|
@ -187,19 +168,7 @@ surface_pattern_supported (const cairo_surface_pattern_t *pattern)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
extend = cairo_pattern_get_extend ((cairo_pattern_t*)&pattern->base);
|
return TRUE;
|
||||||
switch (extend) {
|
|
||||||
case CAIRO_EXTEND_NONE:
|
|
||||||
case CAIRO_EXTEND_REPEAT:
|
|
||||||
case CAIRO_EXTEND_REFLECT:
|
|
||||||
/* There's no point returning FALSE for EXTEND_PAD, as the image
|
|
||||||
* surface does not currently implement it either */
|
|
||||||
case CAIRO_EXTEND_PAD:
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_NOT_REACHED;
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -390,7 +359,8 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
|
||||||
XFORM xform;
|
XFORM xform;
|
||||||
int x_tile, y_tile, left, right, top, bottom;
|
int x_tile, y_tile, left, right, top, bottom;
|
||||||
RECT clip;
|
RECT clip;
|
||||||
cairo_surface_t *meta_surface = pattern->surface;
|
cairo_meta_surface_t *meta_surface = (cairo_meta_surface_t *) pattern->surface;
|
||||||
|
cairo_box_t bbox;
|
||||||
|
|
||||||
extend = cairo_pattern_get_extend (&pattern->base);
|
extend = cairo_pattern_get_extend (&pattern->base);
|
||||||
|
|
||||||
|
|
@ -406,7 +376,7 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
|
||||||
SaveDC (surface->dc);
|
SaveDC (surface->dc);
|
||||||
_cairo_matrix_to_win32_xform (&p2d, &xform);
|
_cairo_matrix_to_win32_xform (&p2d, &xform);
|
||||||
|
|
||||||
status = _cairo_surface_get_extents (meta_surface, &meta_extents);
|
status = _cairo_meta_surface_get_bbox (meta_surface, &bbox, NULL);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|
@ -415,10 +385,10 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) {
|
if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) {
|
||||||
left = (int) floor((double)clip.left/meta_extents.width);
|
left = (int) floor (clip.left / _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x));
|
||||||
right = (int) ceil((double)clip.right/meta_extents.width);
|
right = (int) ceil (clip.right / _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x));
|
||||||
top = (int) floor((double)clip.top/meta_extents.height);
|
top = (int) floor (clip.top / _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y));
|
||||||
bottom = (int) ceil((double)clip.bottom/meta_extents.height);
|
bottom = (int) ceil (clip.bottom / _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y));
|
||||||
} else {
|
} else {
|
||||||
left = 0;
|
left = 0;
|
||||||
right = 1;
|
right = 1;
|
||||||
|
|
@ -427,7 +397,7 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
|
||||||
}
|
}
|
||||||
|
|
||||||
old_content = surface->content;
|
old_content = surface->content;
|
||||||
if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) {
|
if (meta_surface->base.content == CAIRO_CONTENT_COLOR) {
|
||||||
cairo_pattern_t *source;
|
cairo_pattern_t *source;
|
||||||
cairo_solid_pattern_t black;
|
cairo_solid_pattern_t black;
|
||||||
|
|
||||||
|
|
@ -490,7 +460,8 @@ _cairo_win32_printing_surface_paint_meta_pattern (cairo_win32_surface_t *surfa
|
||||||
SelectClipPath (surface->dc, RGN_AND);
|
SelectClipPath (surface->dc, RGN_AND);
|
||||||
|
|
||||||
SaveDC (surface->dc); /* Allow clip path to be reset during replay */
|
SaveDC (surface->dc); /* Allow clip path to be reset during replay */
|
||||||
status = _cairo_meta_surface_replay_region (meta_surface, &surface->base,
|
status = _cairo_meta_surface_replay_region (&meta_surface->base,
|
||||||
|
&surface->base,
|
||||||
CAIRO_META_REGION_NATIVE);
|
CAIRO_META_REGION_NATIVE);
|
||||||
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
|
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
|
||||||
/* Restore both the clip save and our earlier path SaveDC */
|
/* Restore both the clip save and our earlier path SaveDC */
|
||||||
|
|
@ -594,7 +565,6 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
|
||||||
cairo_extend_t extend;
|
cairo_extend_t extend;
|
||||||
cairo_image_surface_t *image;
|
cairo_image_surface_t *image;
|
||||||
void *image_extra;
|
void *image_extra;
|
||||||
cairo_surface_t *opaque_surface;
|
|
||||||
cairo_image_surface_t *opaque_image = NULL;
|
cairo_image_surface_t *opaque_image = NULL;
|
||||||
BITMAPINFO bi;
|
BITMAPINFO bi;
|
||||||
cairo_matrix_t m;
|
cairo_matrix_t m;
|
||||||
|
|
@ -651,13 +621,15 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
|
||||||
&mime_size,
|
&mime_size,
|
||||||
&mime_info);
|
&mime_info);
|
||||||
}
|
}
|
||||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
if (_cairo_status_is_error (status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
use_mime = (status == CAIRO_STATUS_SUCCESS);
|
use_mime = (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
if (!use_mime && image->format != CAIRO_FORMAT_RGB24) {
|
if (!use_mime && image->format != CAIRO_FORMAT_RGB24) {
|
||||||
cairo_surface_pattern_t opaque_pattern;
|
cairo_surface_t *opaque_surface;
|
||||||
|
cairo_surface_pattern_t image_pattern;
|
||||||
|
cairo_solid_pattern_t background_pattern;
|
||||||
|
|
||||||
opaque_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
|
opaque_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
|
||||||
image->width,
|
image->width,
|
||||||
|
|
@ -667,36 +639,27 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
|
||||||
goto CLEANUP_OPAQUE_IMAGE;
|
goto CLEANUP_OPAQUE_IMAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cairo_pattern_init_for_surface (&opaque_pattern, &image->base);
|
_cairo_pattern_init_solid (&background_pattern,
|
||||||
|
background_color,
|
||||||
status = _cairo_surface_fill_rectangle (opaque_surface,
|
CAIRO_CONTENT_COLOR);
|
||||||
CAIRO_OPERATOR_SOURCE,
|
status = _cairo_surface_paint (opaque_surface,
|
||||||
background_color,
|
CAIRO_OPERATOR_SOURCE,
|
||||||
0, 0,
|
&background_pattern.base,
|
||||||
image->width, image->height);
|
NULL);
|
||||||
if (status) {
|
if (status)
|
||||||
_cairo_pattern_fini (&opaque_pattern.base);
|
|
||||||
goto CLEANUP_OPAQUE_IMAGE;
|
goto CLEANUP_OPAQUE_IMAGE;
|
||||||
}
|
|
||||||
|
|
||||||
status = _cairo_surface_composite (CAIRO_OPERATOR_OVER,
|
_cairo_pattern_init_for_surface (&image_pattern, &image->base);
|
||||||
&opaque_pattern.base,
|
status = _cairo_surface_paint (opaque_surface,
|
||||||
NULL,
|
CAIRO_OPERATOR_OVER,
|
||||||
opaque_surface,
|
&image_pattern.base,
|
||||||
0, 0,
|
NULL);
|
||||||
0, 0,
|
_cairo_pattern_fini (&image_pattern.base);
|
||||||
0, 0,
|
if (status)
|
||||||
image->width,
|
|
||||||
image->height);
|
|
||||||
if (status) {
|
|
||||||
_cairo_pattern_fini (&opaque_pattern.base);
|
|
||||||
goto CLEANUP_OPAQUE_IMAGE;
|
goto CLEANUP_OPAQUE_IMAGE;
|
||||||
}
|
|
||||||
|
|
||||||
_cairo_pattern_fini (&opaque_pattern.base);
|
|
||||||
opaque_image = (cairo_image_surface_t *) opaque_surface;
|
opaque_image = (cairo_image_surface_t *) opaque_surface;
|
||||||
} else {
|
} else {
|
||||||
opaque_surface = &image->base;
|
|
||||||
opaque_image = image;
|
opaque_image = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -767,7 +730,7 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
|
||||||
|
|
||||||
CLEANUP_OPAQUE_IMAGE:
|
CLEANUP_OPAQUE_IMAGE:
|
||||||
if (opaque_image != image)
|
if (opaque_image != image)
|
||||||
cairo_surface_destroy (opaque_surface);
|
cairo_surface_destroy (&opaque_image->base);
|
||||||
CLEANUP_IMAGE:
|
CLEANUP_IMAGE:
|
||||||
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
||||||
|
|
||||||
|
|
@ -1085,17 +1048,15 @@ _cairo_win32_printing_surface_emit_path (cairo_win32_surface_t *surface,
|
||||||
cairo_path_fixed_t *path)
|
cairo_path_fixed_t *path)
|
||||||
{
|
{
|
||||||
win32_path_info_t path_info;
|
win32_path_info_t path_info;
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
path_info.surface = surface;
|
path_info.surface = surface;
|
||||||
status = _cairo_path_fixed_interpret (path,
|
return _cairo_path_fixed_interpret (path,
|
||||||
CAIRO_DIRECTION_FORWARD,
|
CAIRO_DIRECTION_FORWARD,
|
||||||
_cairo_win32_printing_surface_path_move_to,
|
_cairo_win32_printing_surface_path_move_to,
|
||||||
_cairo_win32_printing_surface_path_line_to,
|
_cairo_win32_printing_surface_path_line_to,
|
||||||
_cairo_win32_printing_surface_path_curve_to,
|
_cairo_win32_printing_surface_path_curve_to,
|
||||||
_cairo_win32_printing_surface_path_close_path,
|
_cairo_win32_printing_surface_path_close_path,
|
||||||
&path_info);
|
&path_info);
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -1109,14 +1070,16 @@ _cairo_win32_printing_surface_show_page (void *abstract_surface)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_status_t
|
||||||
_cairo_win32_printing_surface_intersect_clip_path (void *abstract_surface,
|
_cairo_win32_printing_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias)
|
cairo_antialias_t antialias)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
cairo_win32_surface_t *surface = cairo_container_of (clipper,
|
||||||
|
cairo_win32_surface_t,
|
||||||
|
clipper);
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||||
|
|
@ -1164,10 +1127,15 @@ static cairo_int_status_t
|
||||||
_cairo_win32_printing_surface_paint (void *abstract_surface,
|
_cairo_win32_printing_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
cairo_win32_surface_t *surface = abstract_surface;
|
||||||
cairo_solid_pattern_t clear;
|
cairo_solid_pattern_t clear;
|
||||||
|
cairo_status_t status;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||||
|
|
@ -1242,7 +1210,7 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *stroke_ctm_inverse,
|
cairo_matrix_t *stroke_ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
cairo_win32_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
|
|
@ -1258,6 +1226,10 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t mat;
|
cairo_matrix_t mat;
|
||||||
double scale;
|
double scale;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||||
source = (cairo_pattern_t*) &clear;
|
source = (cairo_pattern_t*) &clear;
|
||||||
|
|
@ -1364,12 +1336,16 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
cairo_win32_surface_t *surface = abstract_surface;
|
||||||
cairo_int_status_t status;
|
cairo_int_status_t status;
|
||||||
cairo_solid_pattern_t clear;
|
cairo_solid_pattern_t clear;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||||
source = (cairo_pattern_t*) &clear;
|
source = (cairo_pattern_t*) &clear;
|
||||||
|
|
@ -1423,8 +1399,8 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
cairo_win32_surface_t *surface = abstract_surface;
|
||||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
@ -1435,6 +1411,10 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||||
cairo_bool_t old_has_ctm;
|
cairo_bool_t old_has_ctm;
|
||||||
cairo_solid_pattern_t clear;
|
cairo_solid_pattern_t clear;
|
||||||
|
|
||||||
|
status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (op == CAIRO_OPERATOR_CLEAR) {
|
if (op == CAIRO_OPERATOR_CLEAR) {
|
||||||
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
_cairo_win32_printing_surface_init_clear_color (surface, &clear);
|
||||||
source = (cairo_pattern_t*) &clear;
|
source = (cairo_pattern_t*) &clear;
|
||||||
|
|
@ -1547,8 +1527,8 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
|
||||||
status = _cairo_win32_surface_show_glyphs (surface, op,
|
status = _cairo_win32_surface_show_glyphs (surface, op,
|
||||||
source, glyphs,
|
source, glyphs,
|
||||||
num_glyphs, scaled_font,
|
num_glyphs, scaled_font,
|
||||||
remaining_glyphs,
|
clip,
|
||||||
extents);
|
remaining_glyphs);
|
||||||
if (surface->has_ctm)
|
if (surface->has_ctm)
|
||||||
cairo_scaled_font_destroy (scaled_font);
|
cairo_scaled_font_destroy (scaled_font);
|
||||||
|
|
||||||
|
|
@ -1607,7 +1587,12 @@ _cairo_win32_printing_surface_create_similar (void *abstract_surface,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
return cairo_meta_surface_create (content, width, height);
|
cairo_rectangle_t extents;
|
||||||
|
|
||||||
|
extents.x = extents.y = 0;
|
||||||
|
extents.width = width;
|
||||||
|
extents.height = height;
|
||||||
|
return cairo_meta_surface_create (content, &extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -1698,6 +1683,9 @@ cairo_win32_printing_surface_create (HDC hdc)
|
||||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cairo_surface_clipper_init (&surface->clipper,
|
||||||
|
_cairo_win32_printing_surface_clipper_intersect_clip_path);
|
||||||
|
|
||||||
surface->image = NULL;
|
surface->image = NULL;
|
||||||
surface->format = CAIRO_FORMAT_RGB24;
|
surface->format = CAIRO_FORMAT_RGB24;
|
||||||
surface->content = CAIRO_CONTENT_COLOR_ALPHA;
|
surface->content = CAIRO_CONTENT_COLOR_ALPHA;
|
||||||
|
|
@ -1725,13 +1713,12 @@ cairo_win32_printing_surface_create (HDC hdc)
|
||||||
|
|
||||||
_cairo_win32_printing_surface_init_ps_mode (surface);
|
_cairo_win32_printing_surface_init_ps_mode (surface);
|
||||||
_cairo_win32_printing_surface_init_image_support (surface);
|
_cairo_win32_printing_surface_init_image_support (surface);
|
||||||
_cairo_surface_init (&surface->base, &cairo_win32_printing_surface_backend,
|
_cairo_surface_init (&surface->base,
|
||||||
|
&cairo_win32_printing_surface_backend,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA);
|
CAIRO_CONTENT_COLOR_ALPHA);
|
||||||
|
|
||||||
paginated = _cairo_paginated_surface_create (&surface->base,
|
paginated = _cairo_paginated_surface_create (&surface->base,
|
||||||
CAIRO_CONTENT_COLOR_ALPHA,
|
CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
surface->extents.width,
|
|
||||||
surface->extents.height,
|
|
||||||
&cairo_win32_surface_paginated_backend);
|
&cairo_win32_surface_paginated_backend);
|
||||||
|
|
||||||
/* paginated keeps the only reference to surface now, drop ours */
|
/* paginated keeps the only reference to surface now, drop ours */
|
||||||
|
|
@ -1762,8 +1749,6 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
_cairo_win32_printing_surface_show_page,
|
_cairo_win32_printing_surface_show_page,
|
||||||
NULL, /* set_clip_region */
|
|
||||||
_cairo_win32_printing_surface_intersect_clip_path,
|
|
||||||
_cairo_win32_surface_get_extents,
|
_cairo_win32_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
_cairo_win32_printing_surface_get_font_options,
|
_cairo_win32_printing_surface_get_font_options,
|
||||||
|
|
@ -1779,7 +1764,6 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
|
||||||
_cairo_win32_printing_surface_show_glyphs,
|
_cairo_win32_printing_surface_show_glyphs,
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include "cairo-win32.h"
|
#include "cairo-win32.h"
|
||||||
#include "cairoint.h"
|
#include "cairoint.h"
|
||||||
|
#include "cairo-surface-clipper-private.h"
|
||||||
|
|
||||||
#ifndef SHADEBLENDCAPS
|
#ifndef SHADEBLENDCAPS
|
||||||
#define SHADEBLENDCAPS 120
|
#define SHADEBLENDCAPS 120
|
||||||
|
|
@ -81,6 +82,10 @@ typedef struct _cairo_win32_surface {
|
||||||
cairo_rectangle_int_t clip_rect;
|
cairo_rectangle_int_t clip_rect;
|
||||||
HRGN initial_clip_rgn;
|
HRGN initial_clip_rgn;
|
||||||
cairo_bool_t had_simple_clip;
|
cairo_bool_t had_simple_clip;
|
||||||
|
cairo_region_t *clip_region;
|
||||||
|
|
||||||
|
/* For path clipping to the printing-surface */
|
||||||
|
cairo_surface_clipper_t clipper;
|
||||||
|
|
||||||
/* Surface DC flags */
|
/* Surface DC flags */
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
@ -137,13 +142,17 @@ _cairo_surface_is_win32_printing (cairo_surface_t *surface);
|
||||||
cairo_status_t
|
cairo_status_t
|
||||||
_cairo_win32_surface_finish (void *abstract_surface);
|
_cairo_win32_surface_finish (void *abstract_surface);
|
||||||
|
|
||||||
cairo_int_status_t
|
cairo_bool_t
|
||||||
_cairo_win32_surface_get_extents (void *abstract_surface,
|
_cairo_win32_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle);
|
cairo_rectangle_int_t *rectangle);
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
_cairo_win32_flags_for_dc (HDC dc);
|
_cairo_win32_flags_for_dc (HDC dc);
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||||
|
cairo_region_t *region);
|
||||||
|
|
||||||
cairo_int_status_t
|
cairo_int_status_t
|
||||||
_cairo_win32_surface_show_glyphs (void *surface,
|
_cairo_win32_surface_show_glyphs (void *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
|
|
@ -151,8 +160,8 @@ _cairo_win32_surface_show_glyphs (void *surface,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents);
|
int *remaining_glyphs);
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_win32_surface_create_similar (void *abstract_src,
|
_cairo_win32_surface_create_similar (void *abstract_src,
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,8 @@ _cairo_win32_surface_clone_similar (void *abstract_surface,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
0, 0,
|
0, 0,
|
||||||
width, height);
|
width, height,
|
||||||
|
NULL);
|
||||||
|
|
||||||
_cairo_pattern_fini (&pattern.base);
|
_cairo_pattern_fini (&pattern.base);
|
||||||
|
|
||||||
|
|
@ -693,6 +694,91 @@ _cairo_win32_surface_release_dest_image (void *abstract_surfa
|
||||||
cairo_surface_destroy ((cairo_surface_t *)local);
|
cairo_surface_destroy ((cairo_surface_t *)local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_status_t
|
||||||
|
_cairo_win32_surface_set_clip_region (void *abstract_surface,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
cairo_win32_surface_t *surface = abstract_surface;
|
||||||
|
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
if (surface->clip_region == region)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
surface->clip_region = cairo_region_reference (region);
|
||||||
|
|
||||||
|
/* The semantics we want is that any clip set by cairo combines
|
||||||
|
* is intersected with the clip on device context that the
|
||||||
|
* surface was created for. To implement this, we need to
|
||||||
|
* save the original clip when first setting a clip on surface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Clear any clip set by cairo, return to the original first */
|
||||||
|
status = _cairo_win32_restore_initial_clip (surface);
|
||||||
|
|
||||||
|
/* Then combine any new region with it */
|
||||||
|
if (region) {
|
||||||
|
cairo_rectangle_int_t extents;
|
||||||
|
int num_rects;
|
||||||
|
RGNDATA *data;
|
||||||
|
size_t data_size;
|
||||||
|
RECT *rects;
|
||||||
|
int i;
|
||||||
|
HRGN gdi_region;
|
||||||
|
|
||||||
|
/* Create a GDI region for the cairo region */
|
||||||
|
|
||||||
|
cairo_region_get_extents (region, &extents);
|
||||||
|
num_rects = cairo_region_num_rectangles (region);
|
||||||
|
/* XXX see notes in _cairo_win32_save_initial_clip --
|
||||||
|
* this code will interact badly with a HDC which had an initial
|
||||||
|
* world transform -- we should probably manually transform the
|
||||||
|
* region rects, because SelectClipRgn takes device units, not
|
||||||
|
* logical units (unlike IntersectClipRect).
|
||||||
|
*/
|
||||||
|
|
||||||
|
data_size = sizeof (RGNDATAHEADER) + num_rects * sizeof (RECT);
|
||||||
|
data = malloc (data_size);
|
||||||
|
if (!data)
|
||||||
|
return _cairo_error(CAIRO_STATUS_NO_MEMORY);
|
||||||
|
rects = (RECT *)data->Buffer;
|
||||||
|
|
||||||
|
data->rdh.dwSize = sizeof (RGNDATAHEADER);
|
||||||
|
data->rdh.iType = RDH_RECTANGLES;
|
||||||
|
data->rdh.nCount = num_rects;
|
||||||
|
data->rdh.nRgnSize = num_rects * sizeof (RECT);
|
||||||
|
data->rdh.rcBound.left = extents.x;
|
||||||
|
data->rdh.rcBound.top = extents.y;
|
||||||
|
data->rdh.rcBound.right = extents.x + extents.width;
|
||||||
|
data->rdh.rcBound.bottom = extents.y + extents.height;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rects; i++) {
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
cairo_region_get_rectangle (region, i, &rect);
|
||||||
|
|
||||||
|
rects[i].left = rect.x;
|
||||||
|
rects[i].top = rect.y;
|
||||||
|
rects[i].right = rect.x + rect.width;
|
||||||
|
rects[i].bottom = rect.y + rect.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdi_region = ExtCreateRegion (NULL, data_size, data);
|
||||||
|
free (data);
|
||||||
|
|
||||||
|
if (!gdi_region)
|
||||||
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
|
/* AND the new region into our DC */
|
||||||
|
if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
|
||||||
|
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
|
||||||
|
|
||||||
|
DeleteObject (gdi_region);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(AC_SRC_OVER)
|
#if !defined(AC_SRC_OVER)
|
||||||
#define AC_SRC_OVER 0x00
|
#define AC_SRC_OVER 0x00
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
@ -889,7 +975,8 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *dst = abstract_dst;
|
cairo_win32_surface_t *dst = abstract_dst;
|
||||||
cairo_win32_surface_t *src;
|
cairo_win32_surface_t *src;
|
||||||
|
|
@ -1030,7 +1117,7 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If the src recangle doesn't wholly lie within the src extents,
|
/* If the src rectangle doesn't wholly lie within the src extents,
|
||||||
* fudge things. We really need to do fixup on the unpainted
|
* fudge things. We really need to do fixup on the unpainted
|
||||||
* region -- e.g. the SOURCE operator is broken for areas outside
|
* region -- e.g. the SOURCE operator is broken for areas outside
|
||||||
* of the extents, because it won't clear that area to transparent
|
* of the extents, because it won't clear that area to transparent
|
||||||
|
|
@ -1150,6 +1237,10 @@ _cairo_win32_surface_composite (cairo_operator_t op,
|
||||||
fflush (stderr);
|
fflush (stderr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
status = _cairo_win32_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
/* If we need to repeat, we turn the repeated blit into
|
/* If we need to repeat, we turn the repeated blit into
|
||||||
* a bunch of piece-by-piece blits.
|
* a bunch of piece-by-piece blits.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1283,7 +1374,8 @@ UNSUPPORTED:
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
mask_x, mask_y,
|
mask_x, mask_y,
|
||||||
dst_x, dst_y,
|
dst_x, dst_y,
|
||||||
width, height);
|
width, height,
|
||||||
|
clip_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
@ -1387,6 +1479,10 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface,
|
||||||
if (surface->format != CAIRO_FORMAT_RGB24)
|
if (surface->format != CAIRO_FORMAT_RGB24)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
|
status = _cairo_win32_surface_set_clip_region (surface, NULL);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
/* Optimize for no destination alpha (surface->pixman_image is non-NULL for all
|
/* Optimize for no destination alpha (surface->pixman_image is non-NULL for all
|
||||||
* surfaces with alpha.)
|
* surfaces with alpha.)
|
||||||
*/
|
*/
|
||||||
|
|
@ -1432,133 +1528,20 @@ _cairo_win32_surface_fill_rectangles (void *abstract_surface,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
cairo_bool_t
|
||||||
_cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|
||||||
cairo_region_t *region)
|
|
||||||
{
|
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
|
||||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
/* If we are in-memory, then we set the clip on the image surface
|
|
||||||
* as well as on the underlying GDI surface.
|
|
||||||
*/
|
|
||||||
if (surface->image) {
|
|
||||||
unsigned int serial;
|
|
||||||
|
|
||||||
serial = _cairo_surface_allocate_clip_serial (surface->image);
|
|
||||||
status = _cairo_surface_set_clip_region (surface->image, region, serial);
|
|
||||||
if (status)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The semantics we want is that any clip set by cairo combines
|
|
||||||
* is intersected with the clip on device context that the
|
|
||||||
* surface was created for. To implement this, we need to
|
|
||||||
* save the original clip when first setting a clip on surface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Clear any clip set by cairo, return to the original first */
|
|
||||||
status = _cairo_win32_restore_initial_clip (surface);
|
|
||||||
|
|
||||||
/* Then combine any new region with it */
|
|
||||||
if (region) {
|
|
||||||
cairo_rectangle_int_t extents;
|
|
||||||
int num_rects;
|
|
||||||
RGNDATA *data;
|
|
||||||
size_t data_size;
|
|
||||||
RECT *rects;
|
|
||||||
int i;
|
|
||||||
HRGN gdi_region;
|
|
||||||
cairo_rectangle_int_t rect0;
|
|
||||||
|
|
||||||
/* Create a GDI region for the cairo region */
|
|
||||||
|
|
||||||
cairo_region_get_extents (region, &extents);
|
|
||||||
num_rects = cairo_region_num_rectangles (region);
|
|
||||||
|
|
||||||
if (num_rects == 1)
|
|
||||||
cairo_region_get_rectangle (region, 0, &rect0);
|
|
||||||
|
|
||||||
if (num_rects == 1 &&
|
|
||||||
rect0.x == 0 &&
|
|
||||||
rect0.y == 0 &&
|
|
||||||
rect0.width == surface->extents.width &&
|
|
||||||
rect0.width == surface->extents.height)
|
|
||||||
{
|
|
||||||
gdi_region = NULL;
|
|
||||||
|
|
||||||
SelectClipRgn (surface->dc, NULL);
|
|
||||||
IntersectClipRect (surface->dc,
|
|
||||||
rect0.x,
|
|
||||||
rect0.y,
|
|
||||||
rect0.x + rect0.width,
|
|
||||||
rect0.y + rect0.height);
|
|
||||||
} else {
|
|
||||||
/* XXX see notes in _cairo_win32_save_initial_clip --
|
|
||||||
* this code will interact badly with a HDC which had an initial
|
|
||||||
* world transform -- we should probably manually transform the
|
|
||||||
* region rects, because SelectClipRgn takes device units, not
|
|
||||||
* logical units (unlike IntersectClipRect).
|
|
||||||
*/
|
|
||||||
|
|
||||||
data_size = sizeof (RGNDATAHEADER) + num_rects * sizeof (RECT);
|
|
||||||
data = malloc (data_size);
|
|
||||||
if (!data)
|
|
||||||
return _cairo_error(CAIRO_STATUS_NO_MEMORY);
|
|
||||||
rects = (RECT *)data->Buffer;
|
|
||||||
|
|
||||||
data->rdh.dwSize = sizeof (RGNDATAHEADER);
|
|
||||||
data->rdh.iType = RDH_RECTANGLES;
|
|
||||||
data->rdh.nCount = num_rects;
|
|
||||||
data->rdh.nRgnSize = num_rects * sizeof (RECT);
|
|
||||||
data->rdh.rcBound.left = extents.x;
|
|
||||||
data->rdh.rcBound.top = extents.y;
|
|
||||||
data->rdh.rcBound.right = extents.x + extents.width;
|
|
||||||
data->rdh.rcBound.bottom = extents.y + extents.height;
|
|
||||||
|
|
||||||
for (i = 0; i < num_rects; i++) {
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
|
|
||||||
cairo_region_get_rectangle (region, i, &rect);
|
|
||||||
|
|
||||||
rects[i].left = rect.x;
|
|
||||||
rects[i].top = rect.y;
|
|
||||||
rects[i].right = rect.x + rect.width;
|
|
||||||
rects[i].bottom = rect.y + rect.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
gdi_region = ExtCreateRegion (NULL, data_size, data);
|
|
||||||
free (data);
|
|
||||||
|
|
||||||
if (!gdi_region)
|
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
|
|
||||||
/* AND the new region into our DC */
|
|
||||||
if (ExtSelectClipRgn (surface->dc, gdi_region, RGN_AND) == ERROR)
|
|
||||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
|
|
||||||
|
|
||||||
DeleteObject (gdi_region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_int_status_t
|
|
||||||
_cairo_win32_surface_get_extents (void *abstract_surface,
|
_cairo_win32_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
cairo_win32_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
*rectangle = surface->extents;
|
*rectangle = surface->extents;
|
||||||
|
return TRUE;
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
static cairo_status_t
|
||||||
_cairo_win32_surface_flush (void *abstract_surface)
|
_cairo_win32_surface_flush (void *abstract_surface)
|
||||||
{
|
{
|
||||||
return _cairo_surface_reset_clip (abstract_surface);
|
return _cairo_win32_surface_set_clip_region (abstract_surface, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STACK_GLYPH_SIZE 256
|
#define STACK_GLYPH_SIZE 256
|
||||||
|
|
@ -1570,8 +1553,8 @@ _cairo_win32_surface_show_glyphs (void *surface,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
#if CAIRO_HAS_WIN32_FONT
|
#if CAIRO_HAS_WIN32_FONT
|
||||||
cairo_win32_surface_t *dst = surface;
|
cairo_win32_surface_t *dst = surface;
|
||||||
|
|
@ -1611,11 +1594,19 @@ _cairo_win32_surface_show_glyphs (void *surface,
|
||||||
/* If we have a fallback mask clip set on the dst, we have
|
/* If we have a fallback mask clip set on the dst, we have
|
||||||
* to go through the fallback path, but only if we're not
|
* to go through the fallback path, but only if we're not
|
||||||
* doing this for printing */
|
* doing this for printing */
|
||||||
if (dst->base.clip &&
|
if (clip != NULL) {
|
||||||
!(dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
|
if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) == 0) {
|
||||||
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
|
cairo_region_t *clip_region;
|
||||||
dst->base.clip->surface != NULL))
|
cairo_status_t status;
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
|
||||||
|
status = _cairo_clip_get_region (clip, &clip_region);
|
||||||
|
assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
_cairo_win32_surface_set_clip_region (surface, clip_region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
solid_pattern = (cairo_solid_pattern_t *)source;
|
solid_pattern = (cairo_solid_pattern_t *)source;
|
||||||
color = RGB(((int)solid_pattern->color.red_short) >> 8,
|
color = RGB(((int)solid_pattern->color.red_short) >> 8,
|
||||||
|
|
@ -1957,19 +1948,6 @@ _cairo_win32_surface_is_similar (void *surface_a,
|
||||||
return a->dc == b->dc;
|
return a->dc == b->dc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_cairo_win32_surface_reset (void *abstract_surface)
|
|
||||||
{
|
|
||||||
cairo_win32_surface_t *surface = abstract_surface;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_win32_surface_set_clip_region (surface, NULL);
|
|
||||||
if (status)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct _cairo_win32_surface_span_renderer {
|
typedef struct _cairo_win32_surface_span_renderer {
|
||||||
cairo_span_renderer_t base;
|
cairo_span_renderer_t base;
|
||||||
|
|
||||||
|
|
@ -1979,6 +1957,7 @@ typedef struct _cairo_win32_surface_span_renderer {
|
||||||
|
|
||||||
cairo_image_surface_t *mask;
|
cairo_image_surface_t *mask;
|
||||||
cairo_win32_surface_t *dst;
|
cairo_win32_surface_t *dst;
|
||||||
|
cairo_region_t *clip_region;
|
||||||
|
|
||||||
cairo_composite_rectangles_t composite_rectangles;
|
cairo_composite_rectangles_t composite_rectangles;
|
||||||
} cairo_win32_surface_span_renderer_t;
|
} cairo_win32_surface_span_renderer_t;
|
||||||
|
|
@ -2031,18 +2010,20 @@ _cairo_win32_surface_span_renderer_finish (void *abstract_renderer)
|
||||||
rects->src.y,
|
rects->src.y,
|
||||||
0, 0, /* mask.x, mask.y */
|
0, 0, /* mask.x, mask.y */
|
||||||
rects->dst.x, rects->dst.y,
|
rects->dst.x, rects->dst.y,
|
||||||
rects->width, rects->height);
|
rects->width, rects->height,
|
||||||
|
renderer->clip_region);
|
||||||
} else {
|
} else {
|
||||||
/* otherwise go through the fallback_composite path which
|
/* otherwise go through the fallback_composite path which
|
||||||
* will do the appropriate surface acquisition */
|
* will do the appropriate surface acquisition */
|
||||||
status = _cairo_surface_fallback_composite (
|
status = _cairo_surface_fallback_composite (
|
||||||
renderer->op,
|
renderer->op,
|
||||||
renderer->pattern, mask_pattern, dst,
|
renderer->pattern, mask_pattern, &dst->base,
|
||||||
rects->src.x,
|
rects->src.x,
|
||||||
rects->src.y,
|
rects->src.y,
|
||||||
0, 0, /* mask.x, mask.y */
|
0, 0, /* mask.x, mask.y */
|
||||||
rects->dst.x, rects->dst.y,
|
rects->dst.x, rects->dst.y,
|
||||||
rects->width, rects->height);
|
rects->width, rects->height,
|
||||||
|
renderer->clip_region);
|
||||||
}
|
}
|
||||||
cairo_pattern_destroy (mask_pattern);
|
cairo_pattern_destroy (mask_pattern);
|
||||||
|
|
||||||
|
|
@ -2073,15 +2054,16 @@ _cairo_win32_surface_create_span_renderer (cairo_operator_t op,
|
||||||
const cairo_pattern_t *pattern,
|
const cairo_pattern_t *pattern,
|
||||||
void *abstract_dst,
|
void *abstract_dst,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
const cairo_composite_rectangles_t *rects)
|
const cairo_composite_rectangles_t *rects,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_win32_surface_t *dst = abstract_dst;
|
cairo_win32_surface_t *dst = abstract_dst;
|
||||||
cairo_win32_surface_span_renderer_t *renderer
|
cairo_win32_surface_span_renderer_t *renderer;
|
||||||
= calloc(1, sizeof(*renderer));
|
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
int width = rects->width;
|
int width = rects->width;
|
||||||
int height = rects->height;
|
int height = rects->height;
|
||||||
|
|
||||||
|
renderer = calloc(1, sizeof(*renderer));
|
||||||
if (renderer == NULL)
|
if (renderer == NULL)
|
||||||
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
|
||||||
|
|
@ -2093,6 +2075,7 @@ _cairo_win32_surface_create_span_renderer (cairo_operator_t op,
|
||||||
renderer->pattern = pattern;
|
renderer->pattern = pattern;
|
||||||
renderer->antialias = antialias;
|
renderer->antialias = antialias;
|
||||||
renderer->dst = dst;
|
renderer->dst = dst;
|
||||||
|
renderer->clip_region = clip_region;
|
||||||
|
|
||||||
renderer->composite_rectangles = *rects;
|
renderer->composite_rectangles = *rects;
|
||||||
|
|
||||||
|
|
@ -2128,8 +2111,6 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
|
||||||
_cairo_win32_surface_check_span_renderer,
|
_cairo_win32_surface_check_span_renderer,
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
_cairo_win32_surface_set_clip_region,
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_win32_surface_get_extents,
|
_cairo_win32_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -2146,8 +2127,6 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
|
||||||
|
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
_cairo_win32_surface_is_similar,
|
_cairo_win32_surface_is_similar,
|
||||||
|
|
||||||
_cairo_win32_surface_reset
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Notes:
|
/* Notes:
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ typedef struct cairo_xcb_surface {
|
||||||
cairo_bool_t have_clip_rects;
|
cairo_bool_t have_clip_rects;
|
||||||
xcb_rectangle_t *clip_rects;
|
xcb_rectangle_t *clip_rects;
|
||||||
int num_clip_rects;
|
int num_clip_rects;
|
||||||
|
cairo_region_t *clip_region;
|
||||||
|
|
||||||
xcb_render_picture_t src_picture, dst_picture;
|
xcb_render_picture_t src_picture, dst_picture;
|
||||||
xcb_render_pictforminfo_t xrender_format;
|
xcb_render_pictforminfo_t xrender_format;
|
||||||
|
|
@ -166,6 +167,93 @@ _xcb_render_format_to_content (xcb_render_pictforminfo_t *xrender_format)
|
||||||
return CAIRO_CONTENT_COLOR;
|
return CAIRO_CONTENT_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface)
|
||||||
|
{
|
||||||
|
if (surface->have_clip_rects)
|
||||||
|
xcb_set_clip_rectangles(surface->dpy, XCB_CLIP_ORDERING_YX_SORTED, surface->gc,
|
||||||
|
0, 0,
|
||||||
|
surface->num_clip_rects,
|
||||||
|
surface->clip_rects );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface)
|
||||||
|
{
|
||||||
|
if (surface->have_clip_rects)
|
||||||
|
xcb_render_set_picture_clip_rectangles (surface->dpy, surface->dst_picture,
|
||||||
|
0, 0,
|
||||||
|
surface->num_clip_rects,
|
||||||
|
surface->clip_rects);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
||||||
|
cairo_region_t *region)
|
||||||
|
{
|
||||||
|
cairo_xcb_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
if (region == surface->clip_region)
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
region = cairo_region_reference (region);
|
||||||
|
|
||||||
|
if (surface->clip_rects) {
|
||||||
|
free (surface->clip_rects);
|
||||||
|
surface->clip_rects = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->have_clip_rects = FALSE;
|
||||||
|
surface->num_clip_rects = 0;
|
||||||
|
|
||||||
|
if (region == NULL) {
|
||||||
|
uint32_t none[] = { XCB_NONE };
|
||||||
|
if (surface->gc)
|
||||||
|
xcb_change_gc (surface->dpy, surface->gc, XCB_GC_CLIP_MASK, none);
|
||||||
|
|
||||||
|
if (surface->xrender_format.id != XCB_NONE && surface->dst_picture)
|
||||||
|
xcb_render_change_picture (surface->dpy, surface->dst_picture,
|
||||||
|
XCB_RENDER_CP_CLIP_MASK, none);
|
||||||
|
} else {
|
||||||
|
xcb_rectangle_t *rects = NULL;
|
||||||
|
int n_rects, i;
|
||||||
|
|
||||||
|
n_rects = cairo_region_num_rectangles (region);
|
||||||
|
|
||||||
|
if (n_rects > 0) {
|
||||||
|
rects = _cairo_malloc_ab (n_rects, sizeof(xcb_rectangle_t));
|
||||||
|
if (rects == NULL)
|
||||||
|
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||||
|
} else {
|
||||||
|
rects = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n_rects; i++) {
|
||||||
|
cairo_rectangle_int_t rect;
|
||||||
|
|
||||||
|
cairo_region_get_rectangle (region, i, &rect);
|
||||||
|
|
||||||
|
rects[i].x = rect.x;
|
||||||
|
rects[i].y = rect.y;
|
||||||
|
rects[i].width = rect.width;
|
||||||
|
rects[i].height = rect.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
surface->have_clip_rects = TRUE;
|
||||||
|
surface->clip_rects = rects;
|
||||||
|
surface->num_clip_rects = n_rects;
|
||||||
|
|
||||||
|
if (surface->gc)
|
||||||
|
_cairo_xcb_surface_set_gc_clip_rects (surface);
|
||||||
|
|
||||||
|
if (surface->dst_picture)
|
||||||
|
_cairo_xcb_surface_set_picture_clip_rects (surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_xcb_surface_create_similar (void *abstract_src,
|
_cairo_xcb_surface_create_similar (void *abstract_src,
|
||||||
cairo_content_t content,
|
cairo_content_t content,
|
||||||
|
|
@ -223,6 +311,7 @@ _cairo_xcb_surface_finish (void *abstract_surface)
|
||||||
xcb_free_gc (surface->dpy, surface->gc);
|
xcb_free_gc (surface->dpy, surface->gc);
|
||||||
|
|
||||||
free (surface->clip_rects);
|
free (surface->clip_rects);
|
||||||
|
cairo_region_destroy (surface->clip_region);
|
||||||
|
|
||||||
surface->dpy = NULL;
|
surface->dpy = NULL;
|
||||||
|
|
||||||
|
|
@ -475,26 +564,6 @@ _cairo_xcb_surface_ensure_src_picture (cairo_xcb_surface_t *surface)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface)
|
|
||||||
{
|
|
||||||
if (surface->have_clip_rects)
|
|
||||||
xcb_render_set_picture_clip_rectangles (surface->dpy, surface->dst_picture,
|
|
||||||
0, 0,
|
|
||||||
surface->num_clip_rects,
|
|
||||||
surface->clip_rects);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface)
|
|
||||||
{
|
|
||||||
if (surface->have_clip_rects)
|
|
||||||
xcb_set_clip_rectangles(surface->dpy, XCB_CLIP_ORDERING_YX_SORTED, surface->gc,
|
|
||||||
0, 0,
|
|
||||||
surface->num_clip_rects,
|
|
||||||
surface->clip_rects );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_cairo_xcb_surface_ensure_dst_picture (cairo_xcb_surface_t *surface)
|
_cairo_xcb_surface_ensure_dst_picture (cairo_xcb_surface_t *surface)
|
||||||
{
|
{
|
||||||
|
|
@ -1124,7 +1193,8 @@ _cairo_xcb_surface_composite (cairo_operator_t op,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height)
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_surface_attributes_t src_attr, mask_attr;
|
cairo_surface_attributes_t src_attr, mask_attr;
|
||||||
cairo_xcb_surface_t *dst = abstract_dst;
|
cairo_xcb_surface_t *dst = abstract_dst;
|
||||||
|
|
@ -1163,6 +1233,10 @@ _cairo_xcb_surface_composite (cairo_operator_t op,
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = _cairo_xcb_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto BAIL;
|
||||||
|
|
||||||
status = _cairo_xcb_surface_set_attributes (src, &src_attr);
|
status = _cairo_xcb_surface_set_attributes (src, &src_attr);
|
||||||
if (status)
|
if (status)
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
|
|
@ -1257,7 +1331,8 @@ _cairo_xcb_surface_composite (cairo_operator_t op,
|
||||||
mask ? mask->height : 0,
|
mask ? mask->height : 0,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
mask_x, mask_y,
|
mask_x, mask_y,
|
||||||
dst_x, dst_y, width, height);
|
dst_x, dst_y, width, height,
|
||||||
|
clip_region);
|
||||||
|
|
||||||
BAIL:
|
BAIL:
|
||||||
if (mask)
|
if (mask)
|
||||||
|
|
@ -1279,6 +1354,7 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
||||||
xcb_render_color_t render_color;
|
xcb_render_color_t render_color;
|
||||||
xcb_rectangle_t static_xrects[16];
|
xcb_rectangle_t static_xrects[16];
|
||||||
xcb_rectangle_t *xrects = static_xrects;
|
xcb_rectangle_t *xrects = static_xrects;
|
||||||
|
cairo_status_t status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))
|
if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))
|
||||||
|
|
@ -1289,6 +1365,9 @@ _cairo_xcb_surface_fill_rectangles (void *abstract_surface,
|
||||||
render_color.blue = color->blue_short;
|
render_color.blue = color->blue_short;
|
||||||
render_color.alpha = color->alpha_short;
|
render_color.alpha = color->alpha_short;
|
||||||
|
|
||||||
|
status = _cairo_xcb_surface_set_clip_region (surface, NULL);
|
||||||
|
assert (status == CAIRO_STATUS_SUCCESS);
|
||||||
|
|
||||||
if (num_rects > ARRAY_LENGTH(static_xrects)) {
|
if (num_rects > ARRAY_LENGTH(static_xrects)) {
|
||||||
xrects = _cairo_malloc_ab (num_rects, sizeof(xcb_rectangle_t));
|
xrects = _cairo_malloc_ab (num_rects, sizeof(xcb_rectangle_t));
|
||||||
if (xrects == NULL)
|
if (xrects == NULL)
|
||||||
|
|
@ -1415,7 +1494,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int num_traps)
|
int num_traps,
|
||||||
|
cairo_region_t *clip_region)
|
||||||
{
|
{
|
||||||
cairo_surface_attributes_t attributes;
|
cairo_surface_attributes_t attributes;
|
||||||
cairo_xcb_surface_t *dst = abstract_dst;
|
cairo_xcb_surface_t *dst = abstract_dst;
|
||||||
|
|
@ -1475,6 +1555,11 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
render_src_y = src_y + render_reference_y - dst_y;
|
render_src_y = src_y + render_reference_y - dst_y;
|
||||||
|
|
||||||
_cairo_xcb_surface_ensure_dst_picture (dst);
|
_cairo_xcb_surface_ensure_dst_picture (dst);
|
||||||
|
|
||||||
|
status = _cairo_xcb_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto BAIL;
|
||||||
|
|
||||||
status = _cairo_xcb_surface_set_attributes (src, &attributes);
|
status = _cairo_xcb_surface_set_attributes (src, &attributes);
|
||||||
if (status)
|
if (status)
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
|
|
@ -1516,7 +1601,8 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
width, height,
|
width, height,
|
||||||
src_x, src_y,
|
src_x, src_y,
|
||||||
0, 0,
|
0, 0,
|
||||||
dst_x, dst_y, width, height);
|
dst_x, dst_y, width, height,
|
||||||
|
clip_region);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
xcb_render_trapezoid_t xtraps_stack[16];
|
xcb_render_trapezoid_t xtraps_stack[16];
|
||||||
|
|
@ -1562,68 +1648,7 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
|
||||||
cairo_region_t *region)
|
|
||||||
{
|
|
||||||
cairo_xcb_surface_t *surface = abstract_surface;
|
|
||||||
|
|
||||||
if (surface->clip_rects) {
|
|
||||||
free (surface->clip_rects);
|
|
||||||
surface->clip_rects = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->have_clip_rects = FALSE;
|
|
||||||
surface->num_clip_rects = 0;
|
|
||||||
|
|
||||||
if (region == NULL) {
|
|
||||||
uint32_t none[] = { XCB_NONE };
|
|
||||||
if (surface->gc)
|
|
||||||
xcb_change_gc (surface->dpy, surface->gc, XCB_GC_CLIP_MASK, none);
|
|
||||||
|
|
||||||
if (surface->xrender_format.id != XCB_NONE && surface->dst_picture)
|
|
||||||
xcb_render_change_picture (surface->dpy, surface->dst_picture,
|
|
||||||
XCB_RENDER_CP_CLIP_MASK, none);
|
|
||||||
} else {
|
|
||||||
xcb_rectangle_t *rects = NULL;
|
|
||||||
int n_rects, i;
|
|
||||||
|
|
||||||
n_rects = cairo_region_num_rectangles (region);
|
|
||||||
|
|
||||||
if (n_rects > 0) {
|
|
||||||
rects = _cairo_malloc_ab (n_rects, sizeof(xcb_rectangle_t));
|
|
||||||
if (rects == NULL)
|
|
||||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
|
||||||
} else {
|
|
||||||
rects = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < n_rects; i++) {
|
|
||||||
cairo_rectangle_int_t rect;
|
|
||||||
|
|
||||||
cairo_region_get_rectangle (region, i, &rect);
|
|
||||||
|
|
||||||
rects[i].x = rect.x;
|
|
||||||
rects[i].y = rect.y;
|
|
||||||
rects[i].width = rect.width;
|
|
||||||
rects[i].height = rect.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->have_clip_rects = TRUE;
|
|
||||||
surface->clip_rects = rects;
|
|
||||||
surface->num_clip_rects = n_rects;
|
|
||||||
|
|
||||||
if (surface->gc)
|
|
||||||
_cairo_xcb_surface_set_gc_clip_rects (surface);
|
|
||||||
|
|
||||||
if (surface->dst_picture)
|
|
||||||
_cairo_xcb_surface_set_picture_clip_rects (surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_cairo_xcb_surface_get_extents (void *abstract_surface,
|
_cairo_xcb_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -1635,7 +1660,7 @@ _cairo_xcb_surface_get_extents (void *abstract_surface,
|
||||||
rectangle->width = surface->width;
|
rectangle->width = surface->width;
|
||||||
rectangle->height = surface->height;
|
rectangle->height = surface->height;
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: _cairo_xcb_surface_get_font_options */
|
/* XXX: _cairo_xcb_surface_get_font_options */
|
||||||
|
|
@ -1654,8 +1679,8 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents);
|
int *remaining_glyphs);
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
_cairo_xcb_surface_is_similar (void *surface_a,
|
_cairo_xcb_surface_is_similar (void *surface_a,
|
||||||
|
|
@ -1682,40 +1707,29 @@ _cairo_xcb_surface_is_similar (void *surface_a,
|
||||||
return a->xrender_format.id == xrender_format->id;
|
return a->xrender_format.id == xrender_format->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_status_t
|
|
||||||
_cairo_xcb_surface_reset (void *abstract_surface)
|
|
||||||
{
|
|
||||||
cairo_xcb_surface_t *surface = abstract_surface;
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
status = _cairo_xcb_surface_set_clip_region (surface, NULL);
|
|
||||||
if (status)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* XXX: move this to the bottom of the file, XCB and Xlib */
|
/* XXX: move this to the bottom of the file, XCB and Xlib */
|
||||||
|
|
||||||
static const cairo_surface_backend_t cairo_xcb_surface_backend = {
|
static const cairo_surface_backend_t cairo_xcb_surface_backend = {
|
||||||
CAIRO_SURFACE_TYPE_XCB,
|
CAIRO_SURFACE_TYPE_XCB,
|
||||||
|
|
||||||
_cairo_xcb_surface_create_similar,
|
_cairo_xcb_surface_create_similar,
|
||||||
_cairo_xcb_surface_finish,
|
_cairo_xcb_surface_finish,
|
||||||
_cairo_xcb_surface_acquire_source_image,
|
_cairo_xcb_surface_acquire_source_image,
|
||||||
_cairo_xcb_surface_release_source_image,
|
_cairo_xcb_surface_release_source_image,
|
||||||
|
|
||||||
_cairo_xcb_surface_acquire_dest_image,
|
_cairo_xcb_surface_acquire_dest_image,
|
||||||
_cairo_xcb_surface_release_dest_image,
|
_cairo_xcb_surface_release_dest_image,
|
||||||
|
|
||||||
_cairo_xcb_surface_clone_similar,
|
_cairo_xcb_surface_clone_similar,
|
||||||
_cairo_xcb_surface_composite,
|
_cairo_xcb_surface_composite,
|
||||||
_cairo_xcb_surface_fill_rectangles,
|
_cairo_xcb_surface_fill_rectangles,
|
||||||
_cairo_xcb_surface_composite_trapezoids,
|
_cairo_xcb_surface_composite_trapezoids,
|
||||||
NULL, /* create_span_renderer */
|
NULL, /* create_span_renderer */
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
|
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
_cairo_xcb_surface_set_clip_region,
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_cairo_xcb_surface_get_extents,
|
_cairo_xcb_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -1733,8 +1747,6 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = {
|
||||||
_cairo_xcb_surface_snapshot,
|
_cairo_xcb_surface_snapshot,
|
||||||
|
|
||||||
_cairo_xcb_surface_is_similar,
|
_cairo_xcb_surface_is_similar,
|
||||||
|
|
||||||
_cairo_xcb_surface_reset
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1853,8 +1865,9 @@ _cairo_xcb_surface_create_internal (xcb_connection_t *dpy,
|
||||||
surface->have_clip_rects = FALSE;
|
surface->have_clip_rects = FALSE;
|
||||||
surface->clip_rects = NULL;
|
surface->clip_rects = NULL;
|
||||||
surface->num_clip_rects = 0;
|
surface->num_clip_rects = 0;
|
||||||
|
surface->clip_region = NULL;
|
||||||
|
|
||||||
return (cairo_surface_t *) surface;
|
return &surface->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xcb_screen_t *
|
static xcb_screen_t *
|
||||||
|
|
@ -2463,8 +2476,8 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents)
|
int *remaining_glyphs)
|
||||||
{
|
{
|
||||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||||
cairo_xcb_surface_t *dst = abstract_dst;
|
cairo_xcb_surface_t *dst = abstract_dst;
|
||||||
|
|
@ -2474,6 +2487,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||||
cairo_xcb_surface_t *src = NULL;
|
cairo_xcb_surface_t *src = NULL;
|
||||||
|
|
||||||
cairo_solid_pattern_t solid_pattern;
|
cairo_solid_pattern_t solid_pattern;
|
||||||
|
cairo_region_t *clip_region = NULL;
|
||||||
|
|
||||||
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || dst->xrender_format.id == XCB_NONE)
|
if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || dst->xrender_format.id == XCB_NONE)
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
|
@ -2497,10 +2511,12 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||||
* fallback clip masking, we have to go through the full
|
* fallback clip masking, we have to go through the full
|
||||||
* fallback path.
|
* fallback path.
|
||||||
*/
|
*/
|
||||||
if (dst->base.clip &&
|
if (clip != NULL) {
|
||||||
(dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
|
status = _cairo_clip_get_region (clip, &clip_region);
|
||||||
dst->base.clip->surface != NULL))
|
assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
if (status)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
|
operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
|
||||||
if (operation == DO_UNSUPPORTED)
|
if (operation == DO_UNSUPPORTED)
|
||||||
|
|
@ -2564,6 +2580,10 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status = _cairo_xcb_surface_set_clip_region (dst, clip_region);
|
||||||
|
if (unlikely (status))
|
||||||
|
goto BAIL;
|
||||||
|
|
||||||
status = _cairo_xcb_surface_set_attributes (src, &attributes);
|
status = _cairo_xcb_surface_set_attributes (src, &attributes);
|
||||||
if (status)
|
if (status)
|
||||||
goto BAIL;
|
goto BAIL;
|
||||||
|
|
|
||||||
|
|
@ -85,11 +85,11 @@ struct _cairo_xlib_surface {
|
||||||
Picture dst_picture, src_picture;
|
Picture dst_picture, src_picture;
|
||||||
|
|
||||||
unsigned int clip_dirty;
|
unsigned int clip_dirty;
|
||||||
cairo_bool_t have_clip_rects;
|
|
||||||
cairo_bool_t gc_has_clip_rects;
|
cairo_bool_t gc_has_clip_rects;
|
||||||
XRectangle embedded_clip_rects[8];
|
XRectangle embedded_clip_rects[8];
|
||||||
XRectangle *clip_rects;
|
XRectangle *clip_rects;
|
||||||
int num_clip_rects;
|
int num_clip_rects;
|
||||||
|
cairo_region_t *clip_region;
|
||||||
|
|
||||||
XRenderPictFormat *xrender_format;
|
XRenderPictFormat *xrender_format;
|
||||||
cairo_filter_t filter;
|
cairo_filter_t filter;
|
||||||
|
|
|
||||||
83
src/cairo.c
|
|
@ -44,6 +44,10 @@
|
||||||
|
|
||||||
#define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1)
|
#define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1)
|
||||||
|
|
||||||
|
#if !defined(INFINITY)
|
||||||
|
#define INFINITY HUGE_VAL
|
||||||
|
#endif
|
||||||
|
|
||||||
static const cairo_t _cairo_nil = {
|
static const cairo_t _cairo_nil = {
|
||||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||||
|
|
@ -57,7 +61,8 @@ static const cairo_t _cairo_nil = {
|
||||||
FALSE, /* has_current_point */
|
FALSE, /* has_current_point */
|
||||||
FALSE, /* has_curve_to */
|
FALSE, /* has_curve_to */
|
||||||
FALSE, /* is_box */
|
FALSE, /* is_box */
|
||||||
FALSE, /* is_region */
|
FALSE, /* maybe_fill_region */
|
||||||
|
TRUE, /* is_empty_fill */
|
||||||
{{{NULL,NULL}}} /* link */
|
{{{NULL,NULL}}} /* link */
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
|
|
@ -496,25 +501,28 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_rectangle_int_t extents;
|
cairo_rectangle_int_t extents;
|
||||||
|
const cairo_rectangle_int_t *clip_extents;
|
||||||
cairo_surface_t *parent_surface, *group_surface = NULL;
|
cairo_surface_t *parent_surface, *group_surface = NULL;
|
||||||
|
cairo_bool_t is_empty;
|
||||||
|
|
||||||
if (unlikely (cr->status))
|
if (unlikely (cr->status))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
parent_surface = _cairo_gstate_get_target (cr->gstate);
|
parent_surface = _cairo_gstate_get_target (cr->gstate);
|
||||||
/* Get the extents that we'll use in creating our new group surface */
|
|
||||||
status = _cairo_surface_get_extents (parent_surface, &extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
goto bail;
|
|
||||||
status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents);
|
|
||||||
if (unlikely (status))
|
|
||||||
goto bail;
|
|
||||||
|
|
||||||
group_surface = cairo_surface_create_similar (parent_surface,
|
/* Get the extents that we'll use in creating our new group surface */
|
||||||
content,
|
is_empty = _cairo_surface_get_extents (parent_surface, &extents);
|
||||||
extents.width,
|
clip_extents = _cairo_clip_get_extents (_cairo_gstate_get_clip (cr->gstate));
|
||||||
extents.height);
|
if (clip_extents != NULL)
|
||||||
status = cairo_surface_status (group_surface);
|
is_empty = _cairo_rectangle_intersect (&extents, clip_extents);
|
||||||
|
|
||||||
|
group_surface = _cairo_surface_create_similar_solid (parent_surface,
|
||||||
|
content,
|
||||||
|
extents.width,
|
||||||
|
extents.height,
|
||||||
|
CAIRO_COLOR_TRANSPARENT,
|
||||||
|
TRUE);
|
||||||
|
status = group_surface->status;
|
||||||
if (unlikely (status))
|
if (unlikely (status))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
|
|
@ -2340,7 +2348,7 @@ cairo_in_stroke (cairo_t *cr, double x, double y)
|
||||||
cairo_bool_t inside = FALSE;
|
cairo_bool_t inside = FALSE;
|
||||||
|
|
||||||
if (unlikely (cr->status))
|
if (unlikely (cr->status))
|
||||||
return 0;
|
return FALSE;
|
||||||
|
|
||||||
status = _cairo_gstate_in_stroke (cr->gstate,
|
status = _cairo_gstate_in_stroke (cr->gstate,
|
||||||
cr->path,
|
cr->path,
|
||||||
|
|
@ -2370,16 +2378,10 @@ cairo_in_stroke (cairo_t *cr, double x, double y)
|
||||||
cairo_bool_t
|
cairo_bool_t
|
||||||
cairo_in_fill (cairo_t *cr, double x, double y)
|
cairo_in_fill (cairo_t *cr, double x, double y)
|
||||||
{
|
{
|
||||||
cairo_bool_t inside;
|
|
||||||
|
|
||||||
if (unlikely (cr->status))
|
if (unlikely (cr->status))
|
||||||
return 0;
|
return FALSE;
|
||||||
|
|
||||||
_cairo_gstate_in_fill (cr->gstate,
|
return _cairo_gstate_in_fill (cr->gstate, cr->path, x, y);
|
||||||
cr->path,
|
|
||||||
x, y, &inside);
|
|
||||||
|
|
||||||
return inside;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2600,8 +2602,6 @@ cairo_clip_extents (cairo_t *cr,
|
||||||
double *x1, double *y1,
|
double *x1, double *y1,
|
||||||
double *x2, double *y2)
|
double *x2, double *y2)
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
if (unlikely (cr->status)) {
|
if (unlikely (cr->status)) {
|
||||||
if (x1)
|
if (x1)
|
||||||
*x1 = 0.0;
|
*x1 = 0.0;
|
||||||
|
|
@ -2615,9 +2615,38 @@ cairo_clip_extents (cairo_t *cr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2);
|
if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) {
|
||||||
if (unlikely (status))
|
*x1 = -INFINITY;
|
||||||
_cairo_set_error (cr, status);
|
*y1 = -INFINITY;
|
||||||
|
*x2 = +INFINITY;
|
||||||
|
*y2 = +INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cairo_in_clip:
|
||||||
|
* @cr: a cairo context
|
||||||
|
* @x: X coordinate of the point to test
|
||||||
|
* @y: Y coordinate of the point to test
|
||||||
|
*
|
||||||
|
* Tests whether the given point is inside the area that would be
|
||||||
|
* visible through the current clip, i.e. the area that would be filled by
|
||||||
|
* a cairo_paint() operation.
|
||||||
|
*
|
||||||
|
* See cairo_clip(), and cairo_clip_preserve().
|
||||||
|
*
|
||||||
|
* Return value: A non-zero value if the point is inside, or zero if
|
||||||
|
* outside.
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
**/
|
||||||
|
cairo_bool_t
|
||||||
|
cairo_in_clip (cairo_t *cr, double x, double y)
|
||||||
|
{
|
||||||
|
if (unlikely (cr->status))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return _cairo_gstate_in_clip (cr->gstate, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_rectangle_list_t *
|
static cairo_rectangle_list_t *
|
||||||
|
|
|
||||||
30
src/cairo.h
|
|
@ -788,6 +788,9 @@ cairo_in_stroke (cairo_t *cr, double x, double y);
|
||||||
cairo_public cairo_bool_t
|
cairo_public cairo_bool_t
|
||||||
cairo_in_fill (cairo_t *cr, double x, double y);
|
cairo_in_fill (cairo_t *cr, double x, double y);
|
||||||
|
|
||||||
|
cairo_public cairo_bool_t
|
||||||
|
cairo_in_clip (cairo_t *cr, double x, double y);
|
||||||
|
|
||||||
/* Rectangular extents */
|
/* Rectangular extents */
|
||||||
cairo_public void
|
cairo_public void
|
||||||
cairo_stroke_extents (cairo_t *cr,
|
cairo_stroke_extents (cairo_t *cr,
|
||||||
|
|
@ -2169,8 +2172,7 @@ cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
|
||||||
|
|
||||||
cairo_public cairo_surface_t *
|
cairo_public cairo_surface_t *
|
||||||
cairo_meta_surface_create (cairo_content_t content,
|
cairo_meta_surface_create (cairo_content_t content,
|
||||||
double width_pixels,
|
const cairo_rectangle_t *extents);
|
||||||
double height_pixels);
|
|
||||||
|
|
||||||
cairo_public void
|
cairo_public void
|
||||||
cairo_meta_surface_ink_extents (cairo_surface_t *surface,
|
cairo_meta_surface_ink_extents (cairo_surface_t *surface,
|
||||||
|
|
@ -2451,39 +2453,45 @@ cairo_public cairo_region_t *
|
||||||
cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle);
|
cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle);
|
||||||
|
|
||||||
cairo_public cairo_region_t *
|
cairo_public cairo_region_t *
|
||||||
cairo_region_create_rectangles (cairo_rectangle_int_t *rects,
|
cairo_region_create_rectangles (const cairo_rectangle_int_t *rects,
|
||||||
int count);
|
int count);
|
||||||
|
|
||||||
cairo_public cairo_region_t *
|
cairo_public cairo_region_t *
|
||||||
cairo_region_copy (cairo_region_t *original);
|
cairo_region_copy (const cairo_region_t *original);
|
||||||
|
|
||||||
|
cairo_public cairo_region_t *
|
||||||
|
cairo_region_reference (cairo_region_t *);
|
||||||
|
|
||||||
cairo_public void
|
cairo_public void
|
||||||
cairo_region_destroy (cairo_region_t *region);
|
cairo_region_destroy (cairo_region_t *region);
|
||||||
|
|
||||||
|
cairo_public cairo_bool_t
|
||||||
|
cairo_region_equal (const cairo_region_t *a, const cairo_region_t *b);
|
||||||
|
|
||||||
cairo_public cairo_status_t
|
cairo_public cairo_status_t
|
||||||
cairo_region_status (cairo_region_t *region);
|
cairo_region_status (const cairo_region_t *region);
|
||||||
|
|
||||||
cairo_public void
|
cairo_public void
|
||||||
cairo_region_get_extents (cairo_region_t *region,
|
cairo_region_get_extents (const cairo_region_t *region,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
cairo_public int
|
cairo_public int
|
||||||
cairo_region_num_rectangles (cairo_region_t *region);
|
cairo_region_num_rectangles (const cairo_region_t *region);
|
||||||
|
|
||||||
cairo_public void
|
cairo_public void
|
||||||
cairo_region_get_rectangle (cairo_region_t *region,
|
cairo_region_get_rectangle (const cairo_region_t *region,
|
||||||
int nth_rectangle,
|
int nth_rectangle,
|
||||||
cairo_rectangle_int_t *rectangle);
|
cairo_rectangle_int_t *rectangle);
|
||||||
|
|
||||||
cairo_public cairo_bool_t
|
cairo_public cairo_bool_t
|
||||||
cairo_region_is_empty (cairo_region_t *region);
|
cairo_region_is_empty (const cairo_region_t *region);
|
||||||
|
|
||||||
cairo_public cairo_region_overlap_t
|
cairo_public cairo_region_overlap_t
|
||||||
cairo_region_contains_rectangle (cairo_region_t *region,
|
cairo_region_contains_rectangle (const cairo_region_t *region,
|
||||||
const cairo_rectangle_int_t *rectangle);
|
const cairo_rectangle_int_t *rectangle);
|
||||||
|
|
||||||
cairo_public cairo_bool_t
|
cairo_public cairo_bool_t
|
||||||
cairo_region_contains_point (cairo_region_t *region, int x, int y);
|
cairo_region_contains_point (const cairo_region_t *region, int x, int y);
|
||||||
|
|
||||||
cairo_public void
|
cairo_public void
|
||||||
cairo_region_translate (cairo_region_t *region, int dx, int dy);
|
cairo_region_translate (cairo_region_t *region, int dx, int dy);
|
||||||
|
|
|
||||||
325
src/cairoint.h
|
|
@ -125,7 +125,7 @@ _cairo_win32_tmpfile (void);
|
||||||
#define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string)
|
#define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string)
|
||||||
#define STRINGIFY_ARG(contents) #contents
|
#define STRINGIFY_ARG(contents) #contents
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#if defined (__GNUC__)
|
||||||
#define cairo_container_of(ptr, type, member) ({ \
|
#define cairo_container_of(ptr, type, member) ({ \
|
||||||
const __typeof__ (((type *) 0)->member) *mptr__ = (ptr); \
|
const __typeof__ (((type *) 0)->member) *mptr__ = (ptr); \
|
||||||
(type *) ((char *) mptr__ - offsetof (type, member)); \
|
(type *) ((char *) mptr__ - offsetof (type, member)); \
|
||||||
|
|
@ -252,6 +252,15 @@ cairo_private void
|
||||||
_cairo_box_round_to_rectangle (const cairo_box_t *box,
|
_cairo_box_round_to_rectangle (const cairo_box_t *box,
|
||||||
cairo_rectangle_int_t *rectangle);
|
cairo_rectangle_int_t *rectangle);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_cairo_unbounded_rectangle_init (cairo_rectangle_int_t *rect)
|
||||||
|
{
|
||||||
|
rect->x = CAIRO_RECT_INT_MIN;
|
||||||
|
rect->y = CAIRO_RECT_INT_MIN;
|
||||||
|
rect->width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
||||||
|
rect->height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_rectangle_intersect (cairo_rectangle_int_t *dst,
|
_cairo_rectangle_intersect (cairo_rectangle_int_t *dst,
|
||||||
const cairo_rectangle_int_t *src);
|
const cairo_rectangle_int_t *src);
|
||||||
|
|
@ -489,6 +498,7 @@ struct _cairo_scaled_font_backend {
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
|
cairo_region_t *clip_region,
|
||||||
int *remaining_glyphs);
|
int *remaining_glyphs);
|
||||||
|
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
|
|
@ -615,6 +625,7 @@ struct _cairo_surface_backend {
|
||||||
int *clone_offset_y,
|
int *clone_offset_y,
|
||||||
cairo_surface_t **clone_out);
|
cairo_surface_t **clone_out);
|
||||||
|
|
||||||
|
/* XXX remove to a separate cairo_surface_compositor_t */
|
||||||
/* XXX: dst should be the first argument for consistency */
|
/* XXX: dst should be the first argument for consistency */
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*composite) (cairo_operator_t op,
|
(*composite) (cairo_operator_t op,
|
||||||
|
|
@ -628,7 +639,8 @@ struct _cairo_surface_backend {
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height);
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*fill_rectangles) (void *surface,
|
(*fill_rectangles) (void *surface,
|
||||||
|
|
@ -650,14 +662,16 @@ struct _cairo_surface_backend {
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int num_traps);
|
int num_traps,
|
||||||
|
cairo_region_t *region);
|
||||||
|
|
||||||
cairo_warn cairo_span_renderer_t *
|
cairo_warn cairo_span_renderer_t *
|
||||||
(*create_span_renderer) (cairo_operator_t op,
|
(*create_span_renderer) (cairo_operator_t op,
|
||||||
const cairo_pattern_t *pattern,
|
const cairo_pattern_t *pattern,
|
||||||
void *dst,
|
void *dst,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
const cairo_composite_rectangles_t *rects);
|
const cairo_composite_rectangles_t *rects,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_warn cairo_bool_t
|
cairo_warn cairo_bool_t
|
||||||
(*check_span_renderer) (cairo_operator_t op,
|
(*check_span_renderer) (cairo_operator_t op,
|
||||||
|
|
@ -672,59 +686,15 @@ struct _cairo_surface_backend {
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*show_page) (void *surface);
|
(*show_page) (void *surface);
|
||||||
|
|
||||||
/* Set given region as the clip region for the surface, replacing
|
|
||||||
* any previously set clip region. Passing in a NULL region will
|
|
||||||
* clear the surface clip region.
|
|
||||||
*
|
|
||||||
* The surface is expected to store the clip region and clip all
|
|
||||||
* following drawing operations against it until the clip region
|
|
||||||
* is cleared of replaced by another clip region.
|
|
||||||
*
|
|
||||||
* Cairo will call this function whenever a clip path can be
|
|
||||||
* represented as a device pixel aligned set of rectangles. When
|
|
||||||
* this is not possible, cairo will use mask surfaces for
|
|
||||||
* clipping.
|
|
||||||
*/
|
|
||||||
cairo_warn cairo_int_status_t
|
|
||||||
(*set_clip_region) (void *surface,
|
|
||||||
cairo_region_t *region);
|
|
||||||
|
|
||||||
/* Intersect the given path against the clip path currently set in
|
|
||||||
* the surface, using the given fill_rule and tolerance, and set
|
|
||||||
* the result as the new clipping path for the surface. Passing
|
|
||||||
* in a NULL path will clear the surface clipping path.
|
|
||||||
*
|
|
||||||
* The surface is expected to store the resulting clip path and
|
|
||||||
* clip all following drawing operations against it until the clip
|
|
||||||
* path cleared or intersected with a new path.
|
|
||||||
*
|
|
||||||
* If a surface implements this function, set_clip_region() will
|
|
||||||
* never be called and should not be implemented. If this
|
|
||||||
* function is not implemented cairo will use set_clip_region()
|
|
||||||
* (if available) and mask surfaces for clipping.
|
|
||||||
*/
|
|
||||||
cairo_warn cairo_int_status_t
|
|
||||||
(*intersect_clip_path) (void *dst,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias);
|
|
||||||
|
|
||||||
/* Get the extents of the current surface. For many surface types
|
/* Get the extents of the current surface. For many surface types
|
||||||
* this will be as simple as { x=0, y=0, width=surface->width,
|
* this will be as simple as { x=0, y=0, width=surface->width,
|
||||||
* height=surface->height}.
|
* height=surface->height}.
|
||||||
*
|
*
|
||||||
* This function need not take account of any clipping from
|
|
||||||
* set_clip_region since the generic version of set_clip_region
|
|
||||||
* saves those, and the generic get_clip_extents will only call
|
|
||||||
* into the specific surface->get_extents if there is no current
|
|
||||||
* clip.
|
|
||||||
*
|
|
||||||
* If this function is not implemented, or if it returns
|
* If this function is not implemented, or if it returns
|
||||||
* %CAIRO_INT_STATUS_UNSUPPORTED, the surface is considered to be
|
* FALSE the surface is considered to be
|
||||||
* boundless and inifnite bounds are used for it.
|
* boundless and infinite bounds are used for it.
|
||||||
*/
|
*/
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_bool_t
|
||||||
(*get_extents) (void *surface,
|
(*get_extents) (void *surface,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
|
|
@ -745,7 +715,8 @@ struct _cairo_surface_backend {
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs);
|
int num_glyphs,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
void
|
void
|
||||||
(*get_font_options) (void *surface,
|
(*get_font_options) (void *surface,
|
||||||
|
|
@ -775,14 +746,14 @@ struct _cairo_surface_backend {
|
||||||
(*paint) (void *surface,
|
(*paint) (void *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*mask) (void *surface,
|
(*mask) (void *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*stroke) (void *surface,
|
(*stroke) (void *surface,
|
||||||
|
|
@ -794,7 +765,7 @@ struct _cairo_surface_backend {
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*fill) (void *surface,
|
(*fill) (void *surface,
|
||||||
|
|
@ -804,7 +775,7 @@ struct _cairo_surface_backend {
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*show_glyphs) (void *surface,
|
(*show_glyphs) (void *surface,
|
||||||
|
|
@ -813,8 +784,8 @@ struct _cairo_surface_backend {
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents);
|
int *remaining_glyphs);
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
(*snapshot) (void *surface);
|
(*snapshot) (void *surface);
|
||||||
|
|
@ -824,9 +795,6 @@ struct _cairo_surface_backend {
|
||||||
void *surface_b,
|
void *surface_b,
|
||||||
cairo_content_t content);
|
cairo_content_t content);
|
||||||
|
|
||||||
cairo_warn cairo_status_t
|
|
||||||
(*reset) (void *surface);
|
|
||||||
|
|
||||||
cairo_warn cairo_int_status_t
|
cairo_warn cairo_int_status_t
|
||||||
(*fill_stroke) (void *surface,
|
(*fill_stroke) (void *surface,
|
||||||
cairo_operator_t fill_op,
|
cairo_operator_t fill_op,
|
||||||
|
|
@ -842,7 +810,7 @@ struct _cairo_surface_backend {
|
||||||
cairo_matrix_t *stroke_ctm_inverse,
|
cairo_matrix_t *stroke_ctm_inverse,
|
||||||
double stroke_tolerance,
|
double stroke_tolerance,
|
||||||
cairo_antialias_t stroke_antialias,
|
cairo_antialias_t stroke_antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
(*create_solid_pattern_surface)
|
(*create_solid_pattern_surface)
|
||||||
|
|
@ -869,7 +837,7 @@ struct _cairo_surface_backend {
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "cairo-surface-private.h"
|
#include "cairo-surface-private.h"
|
||||||
|
|
@ -887,9 +855,9 @@ struct _cairo_image_surface {
|
||||||
int depth;
|
int depth;
|
||||||
|
|
||||||
pixman_image_t *pixman_image;
|
pixman_image_t *pixman_image;
|
||||||
|
cairo_region_t *clip_region;
|
||||||
|
|
||||||
unsigned owns_data : 1;
|
unsigned owns_data : 1;
|
||||||
unsigned has_clip : 1;
|
|
||||||
unsigned transparency : 2;
|
unsigned transparency : 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -983,6 +951,8 @@ typedef struct _cairo_traps {
|
||||||
|
|
||||||
cairo_box_t extents;
|
cairo_box_t extents;
|
||||||
|
|
||||||
|
unsigned int maybe_region : 1; /* hint: 0 implies that it cannot be */
|
||||||
|
|
||||||
int num_traps;
|
int num_traps;
|
||||||
int traps_size;
|
int traps_size;
|
||||||
cairo_trapezoid_t *traps;
|
cairo_trapezoid_t *traps;
|
||||||
|
|
@ -1245,12 +1215,16 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate,
|
||||||
double y,
|
double y,
|
||||||
cairo_bool_t *inside_ret);
|
cairo_bool_t *inside_ret);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private cairo_bool_t
|
||||||
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
|
_cairo_gstate_in_fill (cairo_gstate_t *gstate,
|
||||||
cairo_path_fixed_t *path,
|
cairo_path_fixed_t *path,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y);
|
||||||
cairo_bool_t *inside_ret);
|
|
||||||
|
cairo_private cairo_bool_t
|
||||||
|
_cairo_gstate_in_clip (cairo_gstate_t *gstate,
|
||||||
|
double x,
|
||||||
|
double y);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path);
|
_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path);
|
||||||
|
|
@ -1258,12 +1232,12 @@ _cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path);
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_gstate_reset_clip (cairo_gstate_t *gstate);
|
_cairo_gstate_reset_clip (cairo_gstate_t *gstate);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
_cairo_gstate_clip_extents (cairo_gstate_t *gstate,
|
||||||
double *x1,
|
double *x1,
|
||||||
double *y1,
|
double *y1,
|
||||||
double *x2,
|
double *x2,
|
||||||
double *y2);
|
double *y2);
|
||||||
|
|
||||||
cairo_private cairo_rectangle_list_t*
|
cairo_private cairo_rectangle_list_t*
|
||||||
_cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate);
|
_cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate);
|
||||||
|
|
@ -1480,19 +1454,19 @@ cairo_private void
|
||||||
_cairo_intern_string_reset_static_data (void);
|
_cairo_intern_string_reset_static_data (void);
|
||||||
|
|
||||||
/* cairo-path-fixed.c */
|
/* cairo-path-fixed.c */
|
||||||
|
cairo_private cairo_path_fixed_t *
|
||||||
|
_cairo_path_fixed_create (void);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_init (cairo_path_fixed_t *path);
|
_cairo_path_fixed_init (cairo_path_fixed_t *path);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||||
cairo_path_fixed_t *other);
|
const cairo_path_fixed_t *other);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
|
_cairo_path_fixed_is_equal (const cairo_path_fixed_t *path,
|
||||||
cairo_path_fixed_t *other);
|
const cairo_path_fixed_t *other);
|
||||||
|
|
||||||
cairo_private cairo_path_fixed_t *
|
|
||||||
_cairo_path_fixed_create (void);
|
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_fini (cairo_path_fixed_t *path);
|
_cairo_path_fixed_fini (cairo_path_fixed_t *path);
|
||||||
|
|
@ -1578,64 +1552,69 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path,
|
||||||
void *closure,
|
void *closure,
|
||||||
double tolerance);
|
double tolerance);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
|
||||||
_cairo_path_fixed_append (cairo_path_fixed_t *path,
|
|
||||||
const cairo_path_fixed_t *other,
|
|
||||||
cairo_direction_t dir);
|
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_approximate_clip_extents (cairo_path_fixed_t *path,
|
_cairo_path_fixed_approximate_clip_extents (const cairo_path_fixed_t *path,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_approximate_fill_extents (cairo_path_fixed_t *path,
|
_cairo_path_fixed_approximate_fill_extents (const cairo_path_fixed_t *path,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_approximate_stroke_extents (cairo_path_fixed_t *path,
|
_cairo_path_fixed_fill_extents (const cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
|
cairo_private void
|
||||||
|
_cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path,
|
||||||
cairo_stroke_style_t *style,
|
cairo_stroke_style_t *style,
|
||||||
const cairo_matrix_t *ctm,
|
const cairo_matrix_t *ctm,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
|
cairo_private cairo_status_t
|
||||||
|
_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t *path,
|
||||||
|
cairo_stroke_style_t *style,
|
||||||
|
const cairo_matrix_t *ctm,
|
||||||
|
const cairo_matrix_t *ctm_inverse,
|
||||||
|
double tolerance,
|
||||||
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_bounds (cairo_path_fixed_t *path,
|
_cairo_path_fixed_bounds (const cairo_path_fixed_t *path,
|
||||||
double *x1, double *y1,
|
double *x1, double *y1,
|
||||||
double *x2, double *y2);
|
double *x2, double *y2);
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
_cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
||||||
cairo_matrix_t *matrix);
|
const cairo_matrix_t *matrix);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_path_fixed_is_empty (cairo_path_fixed_t *path);
|
_cairo_path_fixed_is_box (const cairo_path_fixed_t *path,
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
|
||||||
_cairo_path_fixed_is_box (cairo_path_fixed_t *path,
|
|
||||||
cairo_box_t *box);
|
cairo_box_t *box);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
|
_cairo_path_fixed_is_rectangle (const cairo_path_fixed_t *path,
|
||||||
cairo_box_t *box);
|
cairo_box_t *box);
|
||||||
|
|
||||||
/* cairo-path-in-fill.c */
|
/* cairo-path-in-fill.c */
|
||||||
cairo_private void
|
cairo_private cairo_bool_t
|
||||||
_cairo_path_fixed_in_fill (cairo_path_fixed_t *path,
|
_cairo_path_fixed_in_fill (const cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y);
|
||||||
cairo_bool_t *is_inside);
|
|
||||||
|
|
||||||
/* cairo-path-fill.c */
|
/* cairo-path-fill.c */
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path,
|
_cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_traps_t *traps);
|
cairo_traps_t *traps);
|
||||||
|
|
||||||
/* cairo-path-stroke.c */
|
/* cairo-path-stroke.c */
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path,
|
_cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path,
|
||||||
cairo_stroke_style_t *stroke_style,
|
cairo_stroke_style_t *stroke_style,
|
||||||
const cairo_matrix_t *ctm,
|
const cairo_matrix_t *ctm,
|
||||||
const cairo_matrix_t *ctm_inverse,
|
const cairo_matrix_t *ctm_inverse,
|
||||||
|
|
@ -1707,7 +1686,8 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs);
|
int num_glyphs,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font,
|
||||||
|
|
@ -1789,11 +1769,12 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other,
|
||||||
int height);
|
int height);
|
||||||
|
|
||||||
cairo_private cairo_surface_t *
|
cairo_private cairo_surface_t *
|
||||||
_cairo_surface_create_similar_solid (cairo_surface_t *other,
|
_cairo_surface_create_similar_solid (cairo_surface_t *other,
|
||||||
cairo_content_t content,
|
cairo_content_t content,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
const cairo_color_t *color);
|
const cairo_color_t *color,
|
||||||
|
cairo_bool_t allow_fallback);
|
||||||
|
|
||||||
cairo_private cairo_surface_t *
|
cairo_private cairo_surface_t *
|
||||||
_cairo_surface_create_solid_pattern_surface (cairo_surface_t *other,
|
_cairo_surface_create_solid_pattern_surface (cairo_surface_t *other,
|
||||||
|
|
@ -1813,22 +1794,20 @@ cairo_private void
|
||||||
_cairo_surface_set_font_options (cairo_surface_t *surface,
|
_cairo_surface_set_font_options (cairo_surface_t *surface,
|
||||||
cairo_font_options_t *options);
|
cairo_font_options_t *options);
|
||||||
|
|
||||||
cairo_private cairo_clip_mode_t
|
|
||||||
_cairo_surface_get_clip_mode (cairo_surface_t *surface);
|
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_composite (cairo_operator_t op,
|
_cairo_surface_composite (cairo_operator_t op,
|
||||||
const cairo_pattern_t *src,
|
const cairo_pattern_t *src,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_surface_t *dst,
|
cairo_surface_t *dst,
|
||||||
int src_x,
|
int src_x,
|
||||||
int src_y,
|
int src_y,
|
||||||
int mask_x,
|
int mask_x,
|
||||||
int mask_y,
|
int mask_y,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height);
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
_cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
||||||
|
|
@ -1856,14 +1835,14 @@ cairo_private cairo_status_t
|
||||||
_cairo_surface_paint (cairo_surface_t *surface,
|
_cairo_surface_paint (cairo_surface_t *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_mask (cairo_surface_t *surface,
|
_cairo_surface_mask (cairo_surface_t *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fill_stroke (cairo_surface_t *surface,
|
_cairo_surface_fill_stroke (cairo_surface_t *surface,
|
||||||
|
|
@ -1880,7 +1859,7 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
|
||||||
cairo_matrix_t *stroke_ctm_inverse,
|
cairo_matrix_t *stroke_ctm_inverse,
|
||||||
double stroke_tolerance,
|
double stroke_tolerance,
|
||||||
cairo_antialias_t stroke_antialias,
|
cairo_antialias_t stroke_antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_stroke (cairo_surface_t *surface,
|
_cairo_surface_stroke (cairo_surface_t *surface,
|
||||||
|
|
@ -1892,7 +1871,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_fill (cairo_surface_t *surface,
|
_cairo_surface_fill (cairo_surface_t *surface,
|
||||||
|
|
@ -1902,7 +1881,7 @@ _cairo_surface_fill (cairo_surface_t *surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_show_text_glyphs (cairo_surface_t *surface,
|
_cairo_surface_show_text_glyphs (cairo_surface_t *surface,
|
||||||
|
|
@ -1916,7 +1895,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_composite_trapezoids (cairo_operator_t op,
|
_cairo_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
|
|
@ -1930,23 +1909,23 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_trapezoid_t *traps,
|
cairo_trapezoid_t *traps,
|
||||||
int ntraps);
|
int ntraps,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_span_renderer_t *
|
cairo_private cairo_span_renderer_t *
|
||||||
_cairo_surface_create_span_renderer (
|
_cairo_surface_create_span_renderer (cairo_operator_t op,
|
||||||
cairo_operator_t op,
|
const cairo_pattern_t *pattern,
|
||||||
const cairo_pattern_t *pattern,
|
cairo_surface_t *dst,
|
||||||
cairo_surface_t *dst,
|
cairo_antialias_t antialias,
|
||||||
cairo_antialias_t antialias,
|
const cairo_composite_rectangles_t *rects,
|
||||||
const cairo_composite_rectangles_t *rects);
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_surface_check_span_renderer (
|
_cairo_surface_check_span_renderer (cairo_operator_t op,
|
||||||
cairo_operator_t op,
|
const cairo_pattern_t *pattern,
|
||||||
const cairo_pattern_t *pattern,
|
cairo_surface_t *dst,
|
||||||
cairo_surface_t *dst,
|
cairo_antialias_t antialias,
|
||||||
cairo_antialias_t antialias,
|
const cairo_composite_rectangles_t *rects);
|
||||||
const cairo_composite_rectangles_t *rects);
|
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_acquire_source_image (cairo_surface_t *surface,
|
_cairo_surface_acquire_source_image (cairo_surface_t *surface,
|
||||||
|
|
@ -2005,37 +1984,7 @@ _cairo_surface_is_similar (cairo_surface_t *surface_a,
|
||||||
cairo_surface_t *surface_b,
|
cairo_surface_t *surface_b,
|
||||||
cairo_content_t content);
|
cairo_content_t content);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_surface_reset (cairo_surface_t *surface);
|
|
||||||
|
|
||||||
cairo_private unsigned int
|
|
||||||
_cairo_surface_get_current_clip_serial (cairo_surface_t *surface);
|
|
||||||
|
|
||||||
cairo_private unsigned int
|
|
||||||
_cairo_surface_allocate_clip_serial (cairo_surface_t *surface);
|
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
|
||||||
_cairo_surface_reset_clip (cairo_surface_t *surface);
|
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
|
||||||
_cairo_surface_set_clip_region (cairo_surface_t *surface,
|
|
||||||
cairo_region_t *region,
|
|
||||||
unsigned int serial);
|
|
||||||
|
|
||||||
cairo_private cairo_int_status_t
|
|
||||||
_cairo_surface_intersect_clip_path (cairo_surface_t *surface,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias);
|
|
||||||
|
|
||||||
cairo_private cairo_clip_t *
|
|
||||||
_cairo_surface_get_clip (cairo_surface_t *surface);
|
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
|
||||||
_cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip);
|
|
||||||
|
|
||||||
cairo_private cairo_int_status_t
|
|
||||||
_cairo_surface_get_extents (cairo_surface_t *surface,
|
_cairo_surface_get_extents (cairo_surface_t *surface,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
|
|
@ -2051,7 +2000,8 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height,
|
unsigned int height,
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs);
|
int num_glyphs,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
_cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
||||||
|
|
@ -2068,7 +2018,8 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height);
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
_cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
||||||
|
|
@ -2084,7 +2035,8 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
int dst_y,
|
int dst_y,
|
||||||
unsigned int width,
|
unsigned int width,
|
||||||
unsigned int height);
|
unsigned int height,
|
||||||
|
cairo_region_t *clip_region);
|
||||||
|
|
||||||
cairo_private cairo_bool_t
|
cairo_private cairo_bool_t
|
||||||
_cairo_surface_is_opaque (const cairo_surface_t *surface);
|
_cairo_surface_is_opaque (const cairo_surface_t *surface);
|
||||||
|
|
@ -2193,19 +2145,6 @@ _cairo_image_surface_create_for_data_with_content (unsigned char *data,
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface);
|
_cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface);
|
||||||
|
|
||||||
/* XXX: It's a nasty kludge that this appears here. Backend functions
|
|
||||||
* like this should really be static. But we're doing this to work
|
|
||||||
* around some general defects in the backend clipping interfaces,
|
|
||||||
* (see some notes in test-paginated-surface.c).
|
|
||||||
*
|
|
||||||
* I want to fix the real defects, but it's "hard" as they touch many
|
|
||||||
* backends, so doing that will require synchronizing several backend
|
|
||||||
* maintainers.
|
|
||||||
*/
|
|
||||||
cairo_private cairo_int_status_t
|
|
||||||
_cairo_image_surface_set_clip_region (void *abstract_surface,
|
|
||||||
cairo_region_t *region);
|
|
||||||
|
|
||||||
cairo_private cairo_image_surface_t *
|
cairo_private cairo_image_surface_t *
|
||||||
_cairo_image_surface_coerce (cairo_image_surface_t *surface,
|
_cairo_image_surface_coerce (cairo_image_surface_t *surface,
|
||||||
cairo_format_t format);
|
cairo_format_t format);
|
||||||
|
|
@ -2439,8 +2378,8 @@ _cairo_traps_extents (const cairo_traps_t *traps,
|
||||||
cairo_box_t *extents);
|
cairo_box_t *extents);
|
||||||
|
|
||||||
cairo_private cairo_int_status_t
|
cairo_private cairo_int_status_t
|
||||||
_cairo_traps_extract_region (const cairo_traps_t *tr,
|
_cairo_traps_extract_region (cairo_traps_t *traps,
|
||||||
cairo_region_t **region);
|
cairo_region_t **region);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private cairo_status_t
|
||||||
_cairo_traps_path (const cairo_traps_t *traps,
|
_cairo_traps_path (const cairo_traps_t *traps,
|
||||||
|
|
@ -2560,7 +2499,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
|
||||||
cairo_surface_attributes_t *src_attributes,
|
cairo_surface_attributes_t *src_attributes,
|
||||||
cairo_surface_attributes_t *mask_attributes);
|
cairo_surface_attributes_t *mask_attributes);
|
||||||
|
|
||||||
cairo_private cairo_status_t
|
cairo_private void
|
||||||
_cairo_pattern_get_extents (const cairo_pattern_t *pattern,
|
_cairo_pattern_get_extents (const cairo_pattern_t *pattern,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_rectangle_int_t *extents);
|
||||||
|
|
||||||
|
|
@ -2577,23 +2516,8 @@ _cairo_pattern_equal (const cairo_pattern_t *a,
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_pattern_reset_static_data (void);
|
_cairo_pattern_reset_static_data (void);
|
||||||
|
|
||||||
/* cairo-region.c */
|
|
||||||
|
|
||||||
struct _cairo_region {
|
|
||||||
cairo_status_t status;
|
|
||||||
|
|
||||||
pixman_region32_t rgn;
|
|
||||||
};
|
|
||||||
|
|
||||||
cairo_private void
|
cairo_private void
|
||||||
_cairo_region_init (cairo_region_t *region);
|
_cairo_clip_reset_static_data (void);
|
||||||
|
|
||||||
cairo_private void
|
|
||||||
_cairo_region_init_rectangle (cairo_region_t *region,
|
|
||||||
const cairo_rectangle_int_t *rectangle);
|
|
||||||
|
|
||||||
cairo_private void
|
|
||||||
_cairo_region_fini (cairo_region_t *region);
|
|
||||||
|
|
||||||
/* cairo-unicode.c */
|
/* cairo-unicode.c */
|
||||||
|
|
||||||
|
|
@ -2725,7 +2649,6 @@ slim_hidden_proto (cairo_status);
|
||||||
slim_hidden_proto (cairo_stroke);
|
slim_hidden_proto (cairo_stroke);
|
||||||
slim_hidden_proto (cairo_stroke_preserve);
|
slim_hidden_proto (cairo_stroke_preserve);
|
||||||
slim_hidden_proto (cairo_surface_copy_page);
|
slim_hidden_proto (cairo_surface_copy_page);
|
||||||
slim_hidden_proto (cairo_surface_create_similar);
|
|
||||||
slim_hidden_proto (cairo_surface_destroy);
|
slim_hidden_proto (cairo_surface_destroy);
|
||||||
slim_hidden_proto (cairo_surface_finish);
|
slim_hidden_proto (cairo_surface_finish);
|
||||||
slim_hidden_proto (cairo_surface_flush);
|
slim_hidden_proto (cairo_surface_flush);
|
||||||
|
|
@ -2760,7 +2683,9 @@ slim_hidden_proto (cairo_region_create);
|
||||||
slim_hidden_proto (cairo_region_create_rectangle);
|
slim_hidden_proto (cairo_region_create_rectangle);
|
||||||
slim_hidden_proto (cairo_region_create_rectangles);
|
slim_hidden_proto (cairo_region_create_rectangles);
|
||||||
slim_hidden_proto (cairo_region_copy);
|
slim_hidden_proto (cairo_region_copy);
|
||||||
|
slim_hidden_proto (cairo_region_reference);
|
||||||
slim_hidden_proto (cairo_region_destroy);
|
slim_hidden_proto (cairo_region_destroy);
|
||||||
|
slim_hidden_proto (cairo_region_equal);
|
||||||
slim_hidden_proto (cairo_region_status);
|
slim_hidden_proto (cairo_region_status);
|
||||||
slim_hidden_proto (cairo_region_get_extents);
|
slim_hidden_proto (cairo_region_get_extents);
|
||||||
slim_hidden_proto (cairo_region_num_rectangles);
|
slim_hidden_proto (cairo_region_num_rectangles);
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ _test_fallback_surface_clone_similar (void *abstract_surface,
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_test_fallback_surface_get_extents (void *abstract_surface,
|
_test_fallback_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -219,8 +219,6 @@ static const cairo_surface_backend_t test_fallback_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_test_fallback_surface_get_extents,
|
_test_fallback_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ _test_fallback16_surface_clone_similar (void *abstract_surface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_test_fallback16_surface_get_extents (void *abstract_surface,
|
_test_fallback16_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -218,8 +218,6 @@ static const cairo_surface_backend_t test_fallback16_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
NULL, /* set_clip_region */
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_test_fallback16_surface_get_extents,
|
_test_fallback16_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
|
||||||
|
|
@ -50,26 +50,17 @@ _return_success (void)
|
||||||
|
|
||||||
/* These typedefs are just to silence the compiler... */
|
/* These typedefs are just to silence the compiler... */
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_set_clip_region_func) (void *surface,
|
|
||||||
cairo_region_t *region);
|
|
||||||
typedef cairo_int_status_t
|
|
||||||
(*_intersect_clip_path_func) (void *dst,
|
|
||||||
cairo_path_fixed_t *path,
|
|
||||||
cairo_fill_rule_t fill_rule,
|
|
||||||
double tolerance,
|
|
||||||
cairo_antialias_t antialias);
|
|
||||||
typedef cairo_int_status_t
|
|
||||||
(*_paint_func) (void *surface,
|
(*_paint_func) (void *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_mask_func) (void *surface,
|
(*_mask_func) (void *surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_stroke_func) (void *surface,
|
(*_stroke_func) (void *surface,
|
||||||
|
|
@ -81,7 +72,7 @@ typedef cairo_int_status_t
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_fill_func) (void *surface,
|
(*_fill_func) (void *surface,
|
||||||
|
|
@ -91,7 +82,7 @@ typedef cairo_int_status_t
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_show_glyphs_func) (void *surface,
|
(*_show_glyphs_func) (void *surface,
|
||||||
|
|
@ -100,8 +91,8 @@ typedef cairo_int_status_t
|
||||||
cairo_glyph_t *glyphs,
|
cairo_glyph_t *glyphs,
|
||||||
int num_glyphs,
|
int num_glyphs,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
int *remaining_glyphs,
|
cairo_clip_t *clip,
|
||||||
cairo_rectangle_int_t *extents);
|
int *remaining_glyphs);
|
||||||
|
|
||||||
typedef cairo_int_status_t
|
typedef cairo_int_status_t
|
||||||
(*_show_text_glyphs_func) (void *surface,
|
(*_show_text_glyphs_func) (void *surface,
|
||||||
|
|
@ -115,7 +106,7 @@ typedef cairo_int_status_t
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *extents);
|
cairo_clip_t *clip);
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
_cairo_null_surface_create_similar (void *other,
|
_cairo_null_surface_create_similar (void *other,
|
||||||
|
|
@ -125,16 +116,11 @@ _cairo_null_surface_create_similar (void *other,
|
||||||
return _cairo_test_null_surface_create (content);
|
return _cairo_test_null_surface_create (content);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_cairo_null_surface_get_extents (void *surface,
|
_cairo_null_surface_get_extents (void *surface,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_rectangle_int_t *extents)
|
||||||
{
|
{
|
||||||
extents->x = 0;
|
return FALSE;
|
||||||
extents->y = 0;
|
|
||||||
extents->width = 0;
|
|
||||||
extents->height = 0;
|
|
||||||
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -160,8 +146,6 @@ static const cairo_surface_backend_t null_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
(_set_clip_region_func) _return_success, /* set_clip_region */
|
|
||||||
(_intersect_clip_path_func) _return_success, /* intersect_clip_path */
|
|
||||||
_cairo_null_surface_get_extents,
|
_cairo_null_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -176,7 +160,6 @@ static const cairo_surface_backend_t null_surface_backend = {
|
||||||
(_show_glyphs_func) _return_success, /* show_glyphs */
|
(_show_glyphs_func) _return_success, /* show_glyphs */
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
|
||||||
|
|
@ -61,37 +61,27 @@ static const cairo_surface_backend_t test_paginated_surface_backend;
|
||||||
static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend;
|
static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend;
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_test_paginated_surface_create_for_data (unsigned char *data,
|
_cairo_test_paginated_surface_create (cairo_surface_t *target)
|
||||||
cairo_content_t content,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int stride)
|
|
||||||
{
|
{
|
||||||
cairo_status_t status;
|
cairo_status_t status;
|
||||||
cairo_surface_t *target;
|
|
||||||
cairo_surface_t *paginated;
|
cairo_surface_t *paginated;
|
||||||
test_paginated_surface_t *surface;
|
test_paginated_surface_t *surface;
|
||||||
|
|
||||||
target = _cairo_image_surface_create_for_data_with_content (data, content,
|
|
||||||
width, height,
|
|
||||||
stride);
|
|
||||||
status = cairo_surface_status (target);
|
status = cairo_surface_status (target);
|
||||||
if (status)
|
if (unlikely (status))
|
||||||
return target;
|
return _cairo_surface_create_in_error (status);
|
||||||
|
|
||||||
surface = malloc (sizeof (test_paginated_surface_t));
|
surface = malloc (sizeof (test_paginated_surface_t));
|
||||||
if (unlikely (surface == NULL)) {
|
if (unlikely (surface == NULL))
|
||||||
cairo_surface_destroy (target);
|
|
||||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||||
}
|
|
||||||
|
|
||||||
_cairo_surface_init (&surface->base, &test_paginated_surface_backend,
|
_cairo_surface_init (&surface->base, &test_paginated_surface_backend,
|
||||||
content);
|
target->content);
|
||||||
|
|
||||||
surface->target = target;
|
surface->target = cairo_surface_reference (target);
|
||||||
|
|
||||||
paginated = _cairo_paginated_surface_create (&surface->base,
|
paginated = _cairo_paginated_surface_create (&surface->base,
|
||||||
content, width, height,
|
target->content,
|
||||||
&test_paginated_surface_paginated_backend);
|
&test_paginated_surface_paginated_backend);
|
||||||
status = paginated->status;
|
status = paginated->status;
|
||||||
if (status == CAIRO_STATUS_SUCCESS) {
|
if (status == CAIRO_STATUS_SUCCESS) {
|
||||||
|
|
@ -115,49 +105,7 @@ _test_paginated_surface_finish (void *abstract_surface)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_bool_t
|
||||||
_test_paginated_surface_set_clip_region (void *abstract_surface,
|
|
||||||
cairo_region_t *region)
|
|
||||||
{
|
|
||||||
test_paginated_surface_t *surface = abstract_surface;
|
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
|
||||||
return CAIRO_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
/* XXX: The whole surface backend clipping interface is a giant
|
|
||||||
* disaster right now. In particular, its uncleanness shows up
|
|
||||||
* when trying to implement one surface that wraps another one (as
|
|
||||||
* we are doing here).
|
|
||||||
*
|
|
||||||
* Here are two of the problems that show up:
|
|
||||||
*
|
|
||||||
* 1. The most critical piece of information in all this stuff,
|
|
||||||
* the "clip" isn't getting passed to the backend
|
|
||||||
* functions. Instead the generic surface layer is caching that as
|
|
||||||
* surface->clip. This is a problem for surfaces like this one
|
|
||||||
* that do wrapping. Our base surface will have the clip set, but
|
|
||||||
* our target's surface will not.
|
|
||||||
*
|
|
||||||
* 2. We're here in our backend's set_clip_region function, and we
|
|
||||||
* want to call into our target surface's set_clip_region.
|
|
||||||
* Generally, we would do this by calling an equivalent
|
|
||||||
* _cairo_surface function, but _cairo_surface_set_clip_region
|
|
||||||
* does not have the same signature/semantics, (it has the
|
|
||||||
* clip_serial stuff as well).
|
|
||||||
*
|
|
||||||
* We kludge around each of these by manually copying the clip
|
|
||||||
* object from our base surface into the target's base surface
|
|
||||||
* (yuck!) and by reaching directly into the image surface's
|
|
||||||
* set_clip_region instead of calling into the generic
|
|
||||||
* _cairo_surface_set_clip_region (double yuck!).
|
|
||||||
*/
|
|
||||||
|
|
||||||
surface->target->clip = surface->base.clip;
|
|
||||||
|
|
||||||
return _cairo_image_surface_set_clip_region (surface->target, region);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cairo_int_status_t
|
|
||||||
_test_paginated_surface_get_extents (void *abstract_surface,
|
_test_paginated_surface_get_extents (void *abstract_surface,
|
||||||
cairo_rectangle_int_t *rectangle)
|
cairo_rectangle_int_t *rectangle)
|
||||||
{
|
{
|
||||||
|
|
@ -170,14 +118,14 @@ static cairo_int_status_t
|
||||||
_test_paginated_surface_paint (void *abstract_surface,
|
_test_paginated_surface_paint (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
test_paginated_surface_t *surface = abstract_surface;
|
test_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
return _cairo_surface_paint (surface->target, op, source, extents);
|
return _cairo_surface_paint (surface->target, op, source, clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -185,14 +133,15 @@ _test_paginated_surface_mask (void *abstract_surface,
|
||||||
cairo_operator_t op,
|
cairo_operator_t op,
|
||||||
const cairo_pattern_t *source,
|
const cairo_pattern_t *source,
|
||||||
const cairo_pattern_t *mask,
|
const cairo_pattern_t *mask,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
test_paginated_surface_t *surface = abstract_surface;
|
test_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
|
||||||
return CAIRO_STATUS_SUCCESS;
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
|
||||||
return _cairo_surface_mask (surface->target, op, source, mask, extents);
|
return _cairo_surface_mask (surface->target,
|
||||||
|
op, source, mask, clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -205,7 +154,7 @@ _test_paginated_surface_stroke (void *abstract_surface,
|
||||||
cairo_matrix_t *ctm_inverse,
|
cairo_matrix_t *ctm_inverse,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
test_paginated_surface_t *surface = abstract_surface;
|
test_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
|
@ -215,7 +164,8 @@ _test_paginated_surface_stroke (void *abstract_surface,
|
||||||
return _cairo_surface_stroke (surface->target, op, source,
|
return _cairo_surface_stroke (surface->target, op, source,
|
||||||
path, style,
|
path, style,
|
||||||
ctm, ctm_inverse,
|
ctm, ctm_inverse,
|
||||||
tolerance, antialias, extents);
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_int_status_t
|
static cairo_int_status_t
|
||||||
|
|
@ -226,7 +176,7 @@ _test_paginated_surface_fill (void *abstract_surface,
|
||||||
cairo_fill_rule_t fill_rule,
|
cairo_fill_rule_t fill_rule,
|
||||||
double tolerance,
|
double tolerance,
|
||||||
cairo_antialias_t antialias,
|
cairo_antialias_t antialias,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
test_paginated_surface_t *surface = abstract_surface;
|
test_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
|
@ -235,7 +185,8 @@ _test_paginated_surface_fill (void *abstract_surface,
|
||||||
|
|
||||||
return _cairo_surface_fill (surface->target, op, source,
|
return _cairo_surface_fill (surface->target, op, source,
|
||||||
path, fill_rule,
|
path, fill_rule,
|
||||||
tolerance, antialias, extents);
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cairo_bool_t
|
static cairo_bool_t
|
||||||
|
|
@ -258,7 +209,7 @@ _test_paginated_surface_show_text_glyphs (void *abstract_surface,
|
||||||
int num_clusters,
|
int num_clusters,
|
||||||
cairo_text_cluster_flags_t cluster_flags,
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
cairo_scaled_font_t *scaled_font,
|
cairo_scaled_font_t *scaled_font,
|
||||||
cairo_rectangle_int_t *extents)
|
cairo_clip_t *clip)
|
||||||
{
|
{
|
||||||
test_paginated_surface_t *surface = abstract_surface;
|
test_paginated_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
|
@ -268,8 +219,10 @@ _test_paginated_surface_show_text_glyphs (void *abstract_surface,
|
||||||
return _cairo_surface_show_text_glyphs (surface->target, op, source,
|
return _cairo_surface_show_text_glyphs (surface->target, op, source,
|
||||||
utf8, utf8_len,
|
utf8, utf8_len,
|
||||||
glyphs, num_glyphs,
|
glyphs, num_glyphs,
|
||||||
clusters, num_clusters, cluster_flags,
|
clusters, num_clusters,
|
||||||
scaled_font, extents);
|
cluster_flags,
|
||||||
|
scaled_font,
|
||||||
|
clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -302,8 +255,6 @@ static const cairo_surface_backend_t test_paginated_surface_backend = {
|
||||||
NULL, /* check_span_renderer */
|
NULL, /* check_span_renderer */
|
||||||
NULL, /* copy_page */
|
NULL, /* copy_page */
|
||||||
NULL, /* show_page */
|
NULL, /* show_page */
|
||||||
_test_paginated_surface_set_clip_region,
|
|
||||||
NULL, /* intersect_clip_path */
|
|
||||||
_test_paginated_surface_get_extents,
|
_test_paginated_surface_get_extents,
|
||||||
NULL, /* old_show_glyphs */
|
NULL, /* old_show_glyphs */
|
||||||
NULL, /* get_font_options */
|
NULL, /* get_font_options */
|
||||||
|
|
@ -319,11 +270,10 @@ static const cairo_surface_backend_t test_paginated_surface_backend = {
|
||||||
_test_paginated_surface_mask,
|
_test_paginated_surface_mask,
|
||||||
_test_paginated_surface_stroke,
|
_test_paginated_surface_stroke,
|
||||||
_test_paginated_surface_fill,
|
_test_paginated_surface_fill,
|
||||||
NULL, /* show_glyphs */
|
NULL, /* replaced by show_text_glyphs */
|
||||||
|
|
||||||
NULL, /* snapshot */
|
NULL, /* snapshot */
|
||||||
NULL, /* is_similar */
|
NULL, /* is_similar */
|
||||||
NULL, /* reset */
|
|
||||||
NULL, /* fill_stroke */
|
NULL, /* fill_stroke */
|
||||||
NULL, /* create_solid_pattern_surface */
|
NULL, /* create_solid_pattern_surface */
|
||||||
NULL, /* can_repaint_solid_pattern_surface */
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
|
||||||
|
|
@ -41,11 +41,7 @@
|
||||||
CAIRO_BEGIN_DECLS
|
CAIRO_BEGIN_DECLS
|
||||||
|
|
||||||
cairo_surface_t *
|
cairo_surface_t *
|
||||||
_cairo_test_paginated_surface_create_for_data (unsigned char *data,
|
_cairo_test_paginated_surface_create (cairo_surface_t *target);
|
||||||
cairo_content_t content,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
int stride);
|
|
||||||
|
|
||||||
CAIRO_END_DECLS
|
CAIRO_END_DECLS
|
||||||
|
|
||||||
|
|
|
||||||
272
src/test-wrapping-surface.c
Normal file
|
|
@ -0,0 +1,272 @@
|
||||||
|
/* cairo - a vector graphics library with display and print output
|
||||||
|
*
|
||||||
|
* Copyright © 2005 Red Hat, Inc
|
||||||
|
* Copyright © Chris Wilson
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it either under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1 as published by the Free Software Foundation
|
||||||
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||||
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||||
|
* notice, a recipient may use your version of this file under either
|
||||||
|
* the MPL or the LGPL.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the LGPL along with this library
|
||||||
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
* You should have received a copy of the MPL along with this library
|
||||||
|
* in the file COPYING-MPL-1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||||
|
* the specific language governing rights and limitations.
|
||||||
|
*
|
||||||
|
* The Original Code is the cairo graphics library.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Carl Worth <cworth@cworth.org>
|
||||||
|
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Another mythical surface that exists to simply wrap another - do nothing
|
||||||
|
* itself but forward the calls onto a target surface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cairoint.h"
|
||||||
|
|
||||||
|
#include "test-wrapping-surface.h"
|
||||||
|
|
||||||
|
#include "cairo-surface-wrapper-private.h"
|
||||||
|
|
||||||
|
typedef struct _test_wrapping_surface {
|
||||||
|
cairo_surface_t base;
|
||||||
|
cairo_surface_wrapper_t wrapper;
|
||||||
|
} test_wrapping_surface_t;
|
||||||
|
|
||||||
|
static const cairo_surface_backend_t test_wrapping_surface_backend;
|
||||||
|
|
||||||
|
slim_hidden_proto (_cairo_test_wrapping_surface_create);
|
||||||
|
|
||||||
|
cairo_surface_t *
|
||||||
|
_cairo_test_wrapping_surface_create (cairo_surface_t *target)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface;
|
||||||
|
|
||||||
|
if (unlikely (target->status))
|
||||||
|
return _cairo_surface_create_in_error (target->status);
|
||||||
|
|
||||||
|
surface = malloc (sizeof (test_wrapping_surface_t));
|
||||||
|
if (unlikely (surface == NULL))
|
||||||
|
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||||
|
|
||||||
|
_cairo_surface_init (&surface->base,
|
||||||
|
&test_wrapping_surface_backend,
|
||||||
|
target->content);
|
||||||
|
|
||||||
|
_cairo_surface_wrapper_init (&surface->wrapper, target);
|
||||||
|
|
||||||
|
return &surface->base;
|
||||||
|
}
|
||||||
|
slim_hidden_def (_cairo_test_wrapping_surface_create);
|
||||||
|
|
||||||
|
static cairo_surface_t *
|
||||||
|
_test_wrapping_surface_create_similar (void *abstract_surface,
|
||||||
|
cairo_content_t content,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_test_wrapping_surface_create (
|
||||||
|
_cairo_surface_wrapper_create_similar (&surface->wrapper,
|
||||||
|
content, width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_test_wrapping_surface_finish (void *abstract_surface)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
_cairo_surface_wrapper_fini (&surface->wrapper);
|
||||||
|
|
||||||
|
return CAIRO_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_status_t
|
||||||
|
_test_wrapping_surface_acquire_source_image (void *abstract_surface,
|
||||||
|
cairo_image_surface_t **image_out,
|
||||||
|
void **image_extra)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_acquire_source_image (&surface->wrapper,
|
||||||
|
image_out, image_extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_test_wrapping_surface_release_source_image (void *abstract_surface,
|
||||||
|
cairo_image_surface_t *image,
|
||||||
|
void *image_extra)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
_cairo_surface_wrapper_release_source_image (&surface->wrapper,
|
||||||
|
image, image_extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
_test_wrapping_surface_get_extents (void *abstract_surface,
|
||||||
|
cairo_rectangle_int_t *rectangle)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_get_extents (&surface->wrapper, rectangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_test_wrapping_surface_paint (void *abstract_surface,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_paint (&surface->wrapper, op, source, clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_test_wrapping_surface_mask (void *abstract_surface,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
const cairo_pattern_t *mask,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_mask (&surface->wrapper,
|
||||||
|
op, source, mask, clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_test_wrapping_surface_stroke (void *abstract_surface,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_stroke_style_t *style,
|
||||||
|
cairo_matrix_t *ctm,
|
||||||
|
cairo_matrix_t *ctm_inverse,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_stroke (&surface->wrapper,
|
||||||
|
op, source,
|
||||||
|
path, style,
|
||||||
|
ctm, ctm_inverse,
|
||||||
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_test_wrapping_surface_fill (void *abstract_surface,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
cairo_path_fixed_t *path,
|
||||||
|
cairo_fill_rule_t fill_rule,
|
||||||
|
double tolerance,
|
||||||
|
cairo_antialias_t antialias,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_fill (&surface->wrapper,
|
||||||
|
op, source,
|
||||||
|
path, fill_rule,
|
||||||
|
tolerance, antialias,
|
||||||
|
clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_bool_t
|
||||||
|
_test_wrapping_surface_has_show_text_glyphs (void *abstract_surface)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_has_show_text_glyphs (&surface->wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
static cairo_int_status_t
|
||||||
|
_test_wrapping_surface_show_text_glyphs (void *abstract_surface,
|
||||||
|
cairo_operator_t op,
|
||||||
|
const cairo_pattern_t *source,
|
||||||
|
const char *utf8,
|
||||||
|
int utf8_len,
|
||||||
|
cairo_glyph_t *glyphs,
|
||||||
|
int num_glyphs,
|
||||||
|
const cairo_text_cluster_t *clusters,
|
||||||
|
int num_clusters,
|
||||||
|
cairo_text_cluster_flags_t cluster_flags,
|
||||||
|
cairo_scaled_font_t *scaled_font,
|
||||||
|
cairo_clip_t *clip)
|
||||||
|
{
|
||||||
|
test_wrapping_surface_t *surface = abstract_surface;
|
||||||
|
|
||||||
|
return _cairo_surface_wrapper_show_text_glyphs (&surface->wrapper,
|
||||||
|
op, source,
|
||||||
|
utf8, utf8_len,
|
||||||
|
glyphs, num_glyphs,
|
||||||
|
clusters, num_clusters,
|
||||||
|
cluster_flags,
|
||||||
|
scaled_font,
|
||||||
|
clip);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const cairo_surface_backend_t test_wrapping_surface_backend = {
|
||||||
|
CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING,
|
||||||
|
_test_wrapping_surface_create_similar,
|
||||||
|
_test_wrapping_surface_finish,
|
||||||
|
_test_wrapping_surface_acquire_source_image,
|
||||||
|
_test_wrapping_surface_release_source_image,
|
||||||
|
NULL, NULL, /* dest_image */
|
||||||
|
NULL, /* clone_similar */
|
||||||
|
NULL, /* composite */
|
||||||
|
NULL, /* fill_rectangles */
|
||||||
|
NULL, /* composite_trapezoids */
|
||||||
|
NULL, /* create_span_renderer */
|
||||||
|
NULL, /* check_span_renderer */
|
||||||
|
NULL, /* copy_page */
|
||||||
|
NULL, /* show_page */
|
||||||
|
_test_wrapping_surface_get_extents,
|
||||||
|
NULL, /* old_show_glyphs */
|
||||||
|
NULL, /* get_font_options */
|
||||||
|
NULL, /* flush */
|
||||||
|
NULL, /* mark_dirty_rectangle */
|
||||||
|
NULL, /* scaled_font_fini */
|
||||||
|
NULL, /* scaled_glyph_fini */
|
||||||
|
|
||||||
|
_test_wrapping_surface_paint,
|
||||||
|
_test_wrapping_surface_mask,
|
||||||
|
_test_wrapping_surface_stroke,
|
||||||
|
_test_wrapping_surface_fill,
|
||||||
|
NULL, /* replaced by show_text_glyphs */
|
||||||
|
|
||||||
|
NULL, /* snapshot */
|
||||||
|
NULL, /* is_similar */
|
||||||
|
NULL, /* fill_stroke */
|
||||||
|
NULL, /* create_solid_pattern_surface */
|
||||||
|
NULL, /* can_repaint_solid_pattern_surface */
|
||||||
|
|
||||||
|
_test_wrapping_surface_has_show_text_glyphs,
|
||||||
|
_test_wrapping_surface_show_text_glyphs
|
||||||
|
|
||||||
|
/* XXX wrap fill-stroke and show_glyphs */
|
||||||
|
};
|
||||||
51
src/test-wrapping-surface.h
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* cairo - a vector graphics library with display and print output
|
||||||
|
*
|
||||||
|
* Copyright © 2005 Red Hat, Inc
|
||||||
|
* Copyright © 2009 Chris Wilson
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it either under the terms of the GNU Lesser General Public
|
||||||
|
* License version 2.1 as published by the Free Software Foundation
|
||||||
|
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||||
|
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||||
|
* notice, a recipient may use your version of this file under either
|
||||||
|
* the MPL or the LGPL.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the LGPL along with this library
|
||||||
|
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
* You should have received a copy of the MPL along with this library
|
||||||
|
* in the file COPYING-MPL-1.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||||
|
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||||
|
* the specific language governing rights and limitations.
|
||||||
|
*
|
||||||
|
* The Original Code is the cairo graphics library.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Carl Worth <cworth@cworth.org>
|
||||||
|
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TEST_WRAPPING_SURFACE_H
|
||||||
|
#define TEST_WRAPPING_SURFACE_H
|
||||||
|
|
||||||
|
#include "cairo.h"
|
||||||
|
|
||||||
|
CAIRO_BEGIN_DECLS
|
||||||
|
|
||||||
|
cairo_surface_t *
|
||||||
|
_cairo_test_wrapping_surface_create (cairo_surface_t *target);
|
||||||
|
|
||||||
|
CAIRO_END_DECLS
|
||||||
|
|
||||||
|
#endif /* TEST_WRAPPING_SURFACE_H */
|
||||||
|
|
||||||
|
|
@ -185,8 +185,8 @@ REFERENCE_IMAGES = \
|
||||||
clip-nesting.rgb24.ref.png \
|
clip-nesting.rgb24.ref.png \
|
||||||
clip-nesting.test-paginated.rgb24.ref.png \
|
clip-nesting.test-paginated.rgb24.ref.png \
|
||||||
clip-nesting.xlib.rgb24.ref.png \
|
clip-nesting.xlib.rgb24.ref.png \
|
||||||
clip-operator.pdf.argb32.xfail.png \
|
clip-operator.pdf.argb32.ref.png \
|
||||||
clip-operator.pdf.rgb24.xfail.png \
|
clip-operator.pdf.rgb24.ref.png \
|
||||||
clip-operator.ps2.rgb24.ref.png \
|
clip-operator.ps2.rgb24.ref.png \
|
||||||
clip-operator.ps3.argb32.ref.png \
|
clip-operator.ps3.argb32.ref.png \
|
||||||
clip-operator.ps3.ref.png \
|
clip-operator.ps3.ref.png \
|
||||||
|
|
@ -198,15 +198,21 @@ REFERENCE_IMAGES = \
|
||||||
clip-operator.svg12.argb32.xfail.png \
|
clip-operator.svg12.argb32.xfail.png \
|
||||||
clip-operator.svg12.rgb24.xfail.png \
|
clip-operator.svg12.rgb24.xfail.png \
|
||||||
clip-operator.test-paginated.argb32.ref.png \
|
clip-operator.test-paginated.argb32.ref.png \
|
||||||
clip-operator.xlib-fallback.rgb24.ref.png \
|
clip-operator.xlib-fallback.ref.png \
|
||||||
clip-operator.xlib.ref.png \
|
clip-operator.xlib.ref.png \
|
||||||
clip-operator.xlib.rgb24.ref.png \
|
clip-operator.xlib.rgb24.ref.png \
|
||||||
|
clip-unbounded.ref.png \
|
||||||
|
clip-unbounded.rgb24.ref.png \
|
||||||
|
clip-unbounded.svg12.rgb24.xfail.png \
|
||||||
|
clipped-surface.ref.png \
|
||||||
|
clip-push-group.pdf.ref.png \
|
||||||
clip-push-group.ps2.argb32.ref.png \
|
clip-push-group.ps2.argb32.ref.png \
|
||||||
clip-push-group.ps2.rgb24.ref.png \
|
clip-push-group.ps2.rgb24.ref.png \
|
||||||
clip-push-group.ps3.argb32.ref.png \
|
clip-push-group.ps3.argb32.ref.png \
|
||||||
clip-push-group.ps3.rgb24.ref.png \
|
clip-push-group.ps3.rgb24.ref.png \
|
||||||
clip-push-group.quartz.ref.png \
|
clip-push-group.quartz.ref.png \
|
||||||
clip-push-group.ref.png \
|
clip-push-group.ref.png \
|
||||||
|
clip-push-group.xlib.ref.png \
|
||||||
clip-twice.pdf.argb32.ref.png \
|
clip-twice.pdf.argb32.ref.png \
|
||||||
clip-twice.ps2.argb32.ref.png \
|
clip-twice.ps2.argb32.ref.png \
|
||||||
clip-twice.ps2.rgb24.ref.png \
|
clip-twice.ps2.rgb24.ref.png \
|
||||||
|
|
@ -220,8 +226,7 @@ REFERENCE_IMAGES = \
|
||||||
clip-twice.test-paginated.rgb24.ref.png \
|
clip-twice.test-paginated.rgb24.ref.png \
|
||||||
clip-twice.xlib.ref.png \
|
clip-twice.xlib.ref.png \
|
||||||
clip-twice.xlib.rgb24.ref.png \
|
clip-twice.xlib.rgb24.ref.png \
|
||||||
clipped-group.pdf.argb32.ref.png \
|
clipped-group.pdf.ref.png \
|
||||||
clipped-group.pdf.rgb24.ref.png \
|
|
||||||
clipped-group.ps2.ref.png \
|
clipped-group.ps2.ref.png \
|
||||||
clipped-group.ps3.ref.png \
|
clipped-group.ps3.ref.png \
|
||||||
clipped-group.ref.png \
|
clipped-group.ref.png \
|
||||||
|
|
@ -240,6 +245,8 @@ REFERENCE_IMAGES = \
|
||||||
composite-integer-translate-source.ps2.ref.png \
|
composite-integer-translate-source.ps2.ref.png \
|
||||||
composite-integer-translate-source.ps3.ref.png \
|
composite-integer-translate-source.ps3.ref.png \
|
||||||
composite-integer-translate-source.ref.png \
|
composite-integer-translate-source.ref.png \
|
||||||
|
composite-integer-translate-source.svg12.argb32.xfail.png \
|
||||||
|
composite-integer-translate-source.svg12.rgb24.xfail.png \
|
||||||
copy-path.ps2.ref.png \
|
copy-path.ps2.ref.png \
|
||||||
copy-path.ps3.ref.png \
|
copy-path.ps3.ref.png \
|
||||||
copy-path.ref.png \
|
copy-path.ref.png \
|
||||||
|
|
@ -299,7 +306,7 @@ REFERENCE_IMAGES = \
|
||||||
device-offset-fractional.gl.xfail.png \
|
device-offset-fractional.gl.xfail.png \
|
||||||
device-offset-fractional.pdf.argb32.ref.png \
|
device-offset-fractional.pdf.argb32.ref.png \
|
||||||
device-offset-fractional.pdf.ref.png \
|
device-offset-fractional.pdf.ref.png \
|
||||||
device-offset-fractional.pdf.rgb24.ref.png \
|
device-offset-fractional.pdf.xfail.png \
|
||||||
device-offset-fractional.ps2.ref.png \
|
device-offset-fractional.ps2.ref.png \
|
||||||
device-offset-fractional.ps3.ref.png \
|
device-offset-fractional.ps3.ref.png \
|
||||||
device-offset-fractional.ref.png \
|
device-offset-fractional.ref.png \
|
||||||
|
|
@ -311,8 +318,12 @@ REFERENCE_IMAGES = \
|
||||||
device-offset.rgb24.ref.png \
|
device-offset.rgb24.ref.png \
|
||||||
extended-blend.argb32.ref.png \
|
extended-blend.argb32.ref.png \
|
||||||
extended-blend.rgb24.ref.png \
|
extended-blend.rgb24.ref.png \
|
||||||
|
extended-blend.svg12.argb32.xfail.png \
|
||||||
|
extended-blend.svg12.rgb24.xfail.png \
|
||||||
extended-blend-alpha.argb32.ref.png \
|
extended-blend-alpha.argb32.ref.png \
|
||||||
extended-blend-alpha.rgb24.ref.png \
|
extended-blend-alpha.rgb24.ref.png \
|
||||||
|
extended-blend-alpha.svg12.argb32.xfail.png \
|
||||||
|
extended-blend-alpha.svg12.rgb24.xfail.png \
|
||||||
extend-pad-border.ps.ref.png \
|
extend-pad-border.ps.ref.png \
|
||||||
extend-pad-border.ref.png \
|
extend-pad-border.ref.png \
|
||||||
extend-pad-border.svg.xfail.png \
|
extend-pad-border.svg.xfail.png \
|
||||||
|
|
@ -377,6 +388,9 @@ REFERENCE_IMAGES = \
|
||||||
fill-degenerate-sort-order.rgb24.ref.png \
|
fill-degenerate-sort-order.rgb24.ref.png \
|
||||||
fill-degenerate-sort-order.xlib.ref.png \
|
fill-degenerate-sort-order.xlib.ref.png \
|
||||||
fill-degenerate-sort-order.xlib.rgb24.ref.png \
|
fill-degenerate-sort-order.xlib.rgb24.ref.png \
|
||||||
|
fill-empty.argb32.ref.png \
|
||||||
|
fill-empty.rgb24.ref.png \
|
||||||
|
fill-empty.svg12.rgb24.xfail.png \
|
||||||
fill-image.ps.ref.png \
|
fill-image.ps.ref.png \
|
||||||
fill-image.ref.png \
|
fill-image.ref.png \
|
||||||
fill-image.xlib.ref.png \
|
fill-image.xlib.ref.png \
|
||||||
|
|
@ -443,17 +457,13 @@ REFERENCE_IMAGES = \
|
||||||
ft-text-antialias-none.ps2.argb32.ref.png \
|
ft-text-antialias-none.ps2.argb32.ref.png \
|
||||||
ft-text-antialias-none.ps3.argb32.ref.png \
|
ft-text-antialias-none.ps3.argb32.ref.png \
|
||||||
ft-text-antialias-none.ref.png \
|
ft-text-antialias-none.ref.png \
|
||||||
ft-text-vertical-layout-type1.pdf.argb32.ref.png \
|
|
||||||
ft-text-vertical-layout-type1.pdf.ref.png \
|
ft-text-vertical-layout-type1.pdf.ref.png \
|
||||||
ft-text-vertical-layout-type1.pdf.rgb24.ref.png \
|
|
||||||
ft-text-vertical-layout-type1.ps2.ref.png \
|
ft-text-vertical-layout-type1.ps2.ref.png \
|
||||||
ft-text-vertical-layout-type1.ps3.ref.png \
|
ft-text-vertical-layout-type1.ps3.ref.png \
|
||||||
ft-text-vertical-layout-type1.ref.png \
|
ft-text-vertical-layout-type1.ref.png \
|
||||||
ft-text-vertical-layout-type1.svg.ref.png \
|
ft-text-vertical-layout-type1.svg.ref.png \
|
||||||
ft-text-vertical-layout-type1.xlib.ref.png \
|
ft-text-vertical-layout-type1.xlib.ref.png \
|
||||||
ft-text-vertical-layout-type3.pdf.argb32.ref.png \
|
|
||||||
ft-text-vertical-layout-type3.pdf.ref.png \
|
ft-text-vertical-layout-type3.pdf.ref.png \
|
||||||
ft-text-vertical-layout-type3.pdf.rgb24.ref.png \
|
|
||||||
ft-text-vertical-layout-type3.ps2.ref.png \
|
ft-text-vertical-layout-type3.ps2.ref.png \
|
||||||
ft-text-vertical-layout-type3.ps3.ref.png \
|
ft-text-vertical-layout-type3.ps3.ref.png \
|
||||||
ft-text-vertical-layout-type3.ref.png \
|
ft-text-vertical-layout-type3.ref.png \
|
||||||
|
|
@ -498,6 +508,8 @@ REFERENCE_IMAGES = \
|
||||||
image-surface-source.ps2.ref.png \
|
image-surface-source.ps2.ref.png \
|
||||||
image-surface-source.ps3.ref.png \
|
image-surface-source.ps3.ref.png \
|
||||||
image-surface-source.ref.png \
|
image-surface-source.ref.png \
|
||||||
|
image-surface-source.svg12.argb32.xfail.png \
|
||||||
|
image-surface-source.svg12.rgb24.xfail.png \
|
||||||
infinite-join.ps2.ref.png \
|
infinite-join.ps2.ref.png \
|
||||||
infinite-join.ps3.ref.png \
|
infinite-join.ps3.ref.png \
|
||||||
infinite-join.ref.png \
|
infinite-join.ref.png \
|
||||||
|
|
@ -558,15 +570,14 @@ REFERENCE_IMAGES = \
|
||||||
mask-transformed-similar.pdf.ref.png \
|
mask-transformed-similar.pdf.ref.png \
|
||||||
mask-transformed-similar.ref.png \
|
mask-transformed-similar.ref.png \
|
||||||
mask-transformed-similar.svg.ref.png \
|
mask-transformed-similar.svg.ref.png \
|
||||||
mask.pdf.argb32.xfail.png \
|
mask.pdf.argb32.ref.png \
|
||||||
mask.pdf.rgb24.xfail.png \
|
mask.pdf.rgb24.ref.png \
|
||||||
mask.quartz.ref.png \
|
mask.quartz.ref.png \
|
||||||
mask.quartz.rgb24.ref.png \
|
mask.quartz.rgb24.ref.png \
|
||||||
mask.ref.png \
|
mask.ref.png \
|
||||||
mask.rgb24.ref.png \
|
mask.rgb24.ref.png \
|
||||||
mask.svg.argb32.xfail.png \
|
mask.svg.argb32.xfail.png \
|
||||||
mask.svg.rgb24.xfail.png \
|
mask.svg.rgb24.xfail.png \
|
||||||
mask.xlib-fallback.rgb24.ref.png \
|
|
||||||
mask.xlib.ref.png \
|
mask.xlib.ref.png \
|
||||||
mask.xlib.rgb24.ref.png \
|
mask.xlib.rgb24.ref.png \
|
||||||
meta-surface-pattern.gl.argb32.ref.png \
|
meta-surface-pattern.gl.argb32.ref.png \
|
||||||
|
|
@ -613,15 +624,16 @@ REFERENCE_IMAGES = \
|
||||||
operator-clear.rgb24.ref.png \
|
operator-clear.rgb24.ref.png \
|
||||||
operator-clear.svg12.argb32.xfail.png \
|
operator-clear.svg12.argb32.xfail.png \
|
||||||
operator-clear.svg12.rgb24.xfail.png \
|
operator-clear.svg12.rgb24.xfail.png \
|
||||||
operator-clear.xlib.ref.png \
|
operator-clear.xlib.argb32.ref.png \
|
||||||
operator-source.pdf.rgb24.xfail.png \
|
operator-clear.xlib.rgb24.ref.png \
|
||||||
|
operator-source.pdf.rgb24.ref.png \
|
||||||
operator-source.quartz.ref.png \
|
operator-source.quartz.ref.png \
|
||||||
operator-source.quartz.rgb24.ref.png \
|
operator-source.quartz.rgb24.ref.png \
|
||||||
operator-source.ref.png \
|
operator-source.ref.png \
|
||||||
operator-source.rgb24.ref.png \
|
operator-source.rgb24.ref.png \
|
||||||
operator-source.svg12.argb32.xfail.png \
|
operator-source.svg12.argb32.xfail.png \
|
||||||
operator-source.svg12.rgb24.xfail.png \
|
operator-source.svg12.rgb24.xfail.png \
|
||||||
operator-source.xlib-fallback.rgb24.ref.png \
|
operator-source.xlib-fallback.ref.png \
|
||||||
operator-source.xlib.ref.png \
|
operator-source.xlib.ref.png \
|
||||||
operator-source.xlib.rgb24.ref.png \
|
operator-source.xlib.rgb24.ref.png \
|
||||||
operator.ref.png \
|
operator.ref.png \
|
||||||
|
|
@ -682,12 +694,15 @@ REFERENCE_IMAGES = \
|
||||||
path-append.xlib.ref.png \
|
path-append.xlib.ref.png \
|
||||||
pattern-getters.ref.png \
|
pattern-getters.ref.png \
|
||||||
pdf-surface-source.ref.png \
|
pdf-surface-source.ref.png \
|
||||||
|
pdf-surface-source.svg12.argb32.xfail.png \
|
||||||
|
pdf-surface-source.svg12.rgb24.xfail.png \
|
||||||
pixman-rotate.ref.png \
|
pixman-rotate.ref.png \
|
||||||
pixman-rotate.rgb24.ref.png \
|
pixman-rotate.rgb24.ref.png \
|
||||||
ps-surface-source.ref.png \
|
ps-surface-source.ref.png \
|
||||||
|
ps-surface-source.svg12.argb32.xfail.png \
|
||||||
|
ps-surface-source.svg12.rgb24.xfail.png \
|
||||||
push-group.ref.png \
|
push-group.ref.png \
|
||||||
push-group.rgb24.ref.png \
|
push-group.rgb24.ref.png \
|
||||||
push-group.xlib-fallback.rgb24.ref.png \
|
|
||||||
push-group.xlib.ref.png \
|
push-group.xlib.ref.png \
|
||||||
push-group.xlib.rgb24.ref.png \
|
push-group.xlib.rgb24.ref.png \
|
||||||
quartz-surface-source.ps2.ref.png \
|
quartz-surface-source.ps2.ref.png \
|
||||||
|
|
@ -727,19 +742,21 @@ REFERENCE_IMAGES = \
|
||||||
rotate-image-surface-paint.svg.ref.png \
|
rotate-image-surface-paint.svg.ref.png \
|
||||||
scale-down-source-surface-paint.ref.png \
|
scale-down-source-surface-paint.ref.png \
|
||||||
scale-offset-image.gl.ref.png \
|
scale-offset-image.gl.ref.png \
|
||||||
scale-offset-image.pdf.argb32.ref.png \
|
scale-offset-image.pdf.xfail.png \
|
||||||
scale-offset-image.pdf.rgb24.ref.png \
|
|
||||||
scale-offset-image.ps.ref.png \
|
scale-offset-image.ps.ref.png \
|
||||||
scale-offset-image.ref.png \
|
scale-offset-image.ref.png \
|
||||||
scale-offset-image.xfail.png \
|
scale-offset-image.xfail.png \
|
||||||
|
scale-offset-image.meta.xfail.png \
|
||||||
scale-offset-image.xlib.xfail.png \
|
scale-offset-image.xlib.xfail.png \
|
||||||
|
scale-offset-image.xlib-fallback.xfail.png \
|
||||||
scale-offset-similar.gl.ref.png \
|
scale-offset-similar.gl.ref.png \
|
||||||
scale-offset-similar.pdf.argb32.ref.png \
|
scale-offset-similar.pdf.xfail.png \
|
||||||
scale-offset-similar.pdf.rgb24.ref.png \
|
|
||||||
scale-offset-similar.ps.ref.png \
|
scale-offset-similar.ps.ref.png \
|
||||||
scale-offset-similar.ref.png \
|
scale-offset-similar.ref.png \
|
||||||
scale-offset-similar.xfail.png \
|
scale-offset-similar.xfail.png \
|
||||||
|
scale-offset-similar.meta.xfail.png \
|
||||||
scale-offset-similar.xlib.xfail.png \
|
scale-offset-similar.xlib.xfail.png \
|
||||||
|
scale-offset-similar.xlib-fallback.xfail.png \
|
||||||
scale-source-surface-paint.ref.png \
|
scale-source-surface-paint.ref.png \
|
||||||
scale-source-surface-paint.rgb24.ref.png \
|
scale-source-surface-paint.rgb24.ref.png \
|
||||||
scale-source-surface-paint.svg.argb32.xfail.png \
|
scale-source-surface-paint.svg.argb32.xfail.png \
|
||||||
|
|
@ -773,7 +790,6 @@ REFERENCE_IMAGES = \
|
||||||
skew-extreme.ref.png \
|
skew-extreme.ref.png \
|
||||||
smask-fill.ref.png \
|
smask-fill.ref.png \
|
||||||
smask-fill.svg.ref.png \
|
smask-fill.svg.ref.png \
|
||||||
smask-fill.xlib-fallback.ref.png \
|
|
||||||
smask-fill.xlib.ref.png \
|
smask-fill.xlib.ref.png \
|
||||||
smask-image-mask.ref.png \
|
smask-image-mask.ref.png \
|
||||||
smask-mask.pdf.xfail.png \
|
smask-mask.pdf.xfail.png \
|
||||||
|
|
@ -789,11 +805,13 @@ REFERENCE_IMAGES = \
|
||||||
smask-text.ps3.ref.png \
|
smask-text.ps3.ref.png \
|
||||||
smask-text.ref.png \
|
smask-text.ref.png \
|
||||||
smask-text.svg.ref.png \
|
smask-text.svg.ref.png \
|
||||||
|
smask-text.xlib.ref.png \
|
||||||
smask.pdf.xfail.png \
|
smask.pdf.xfail.png \
|
||||||
smask.ps2.ref.png \
|
smask.ps2.ref.png \
|
||||||
smask.ps3.ref.png \
|
smask.ps3.ref.png \
|
||||||
smask.ref.png \
|
smask.ref.png \
|
||||||
smask.svg.ref.png \
|
smask.svg.ref.png \
|
||||||
|
smask.xlib.ref.png \
|
||||||
solid-pattern-cache-stress.ref.png \
|
solid-pattern-cache-stress.ref.png \
|
||||||
source-clip-scale.gl.ref.png \
|
source-clip-scale.gl.ref.png \
|
||||||
source-clip-scale.pdf.ref.png \
|
source-clip-scale.pdf.ref.png \
|
||||||
|
|
@ -821,6 +839,7 @@ REFERENCE_IMAGES = \
|
||||||
stroke-image.quartz.ref.png \
|
stroke-image.quartz.ref.png \
|
||||||
stroke-image.ref.png \
|
stroke-image.ref.png \
|
||||||
surface-pattern-big-scale-down.ref.png \
|
surface-pattern-big-scale-down.ref.png \
|
||||||
|
surface-pattern-big-scale-down.ps.xfail.png \
|
||||||
surface-pattern-scale-down.pdf.ref.png \
|
surface-pattern-scale-down.pdf.ref.png \
|
||||||
surface-pattern-scale-down.ps2.ref.png \
|
surface-pattern-scale-down.ps2.ref.png \
|
||||||
surface-pattern-scale-down.ps3.ref.png \
|
surface-pattern-scale-down.ps3.ref.png \
|
||||||
|
|
@ -835,8 +854,12 @@ REFERENCE_IMAGES = \
|
||||||
surface-pattern.ref.png \
|
surface-pattern.ref.png \
|
||||||
surface-pattern.svg.xfail.png \
|
surface-pattern.svg.xfail.png \
|
||||||
svg-surface-source.ref.png \
|
svg-surface-source.ref.png \
|
||||||
|
svg-surface-source.svg12.argb32.xfail.png \
|
||||||
|
svg-surface-source.svg12.rgb24.xfail.png \
|
||||||
test-fallback16-surface-source.ps.ref.png \
|
test-fallback16-surface-source.ps.ref.png \
|
||||||
test-fallback16-surface-source.ref.png \
|
test-fallback16-surface-source.ref.png \
|
||||||
|
test-fallback16-surface-source.svg12.argb32.xfail.png \
|
||||||
|
test-fallback16-surface-source.svg12.rgb24.xfail.png \
|
||||||
text-antialias-gray.quartz.ref.png \
|
text-antialias-gray.quartz.ref.png \
|
||||||
text-antialias-gray.ref.png \
|
text-antialias-gray.ref.png \
|
||||||
text-antialias-none.quartz.ref.png \
|
text-antialias-none.quartz.ref.png \
|
||||||
|
|
@ -846,8 +869,8 @@ REFERENCE_IMAGES = \
|
||||||
text-glyph-range.ps2.ref.png \
|
text-glyph-range.ps2.ref.png \
|
||||||
text-glyph-range.ps3.ref.png \
|
text-glyph-range.ps3.ref.png \
|
||||||
text-glyph-range.ref.png \
|
text-glyph-range.ref.png \
|
||||||
text-pattern.pdf.argb32.xfail.png \
|
text-pattern.pdf.argb32.ref.png \
|
||||||
text-pattern.pdf.rgb24.xfail.png \
|
text-pattern.pdf.rgb24.ref.png \
|
||||||
text-pattern.ps3.argb32.ref.png \
|
text-pattern.ps3.argb32.ref.png \
|
||||||
text-pattern.ps3.rgb24.ref.png \
|
text-pattern.ps3.rgb24.ref.png \
|
||||||
text-pattern.quartz.ref.png \
|
text-pattern.quartz.ref.png \
|
||||||
|
|
@ -924,6 +947,8 @@ REFERENCE_IMAGES = \
|
||||||
xlib-surface-source.ps2.ref.png \
|
xlib-surface-source.ps2.ref.png \
|
||||||
xlib-surface-source.ps3.ref.png \
|
xlib-surface-source.ps3.ref.png \
|
||||||
xlib-surface-source.ref.png \
|
xlib-surface-source.ref.png \
|
||||||
|
xlib-surface-source.svg12.argb32.xfail.png \
|
||||||
|
xlib-surface-source.svg12.rgb24.xfail.png \
|
||||||
zero-alpha.ref.png
|
zero-alpha.ref.png
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
|
|
@ -1218,7 +1243,7 @@ run:
|
||||||
|
|
||||||
# Check tests under valgrind. Saves log to valgrind-log
|
# Check tests under valgrind. Saves log to valgrind-log
|
||||||
check-valgrind:
|
check-valgrind:
|
||||||
$(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) CAIRO_TEST_MODE="$(MODE),foreground" $(top_builddir)/libtool --mode=execute valgrind $(VALGRIND_FLAGS)' 2>&1 | tee valgrind-log
|
$(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) CAIRO_TEST_MODE="$(MODE),foreground CAIRO_TEST_TIMEOUT=0" $(top_builddir)/libtool --mode=execute valgrind $(VALGRIND_FLAGS)' 2>&1 | tee valgrind-log
|
||||||
|
|
||||||
%.log: %.c cairo-test-suite
|
%.log: %.c cairo-test-suite
|
||||||
-./cairo-test-suite $(<:.c=)
|
-./cairo-test-suite $(<:.c=)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ test_sources = \
|
||||||
clip-operator.c \
|
clip-operator.c \
|
||||||
clip-push-group.c \
|
clip-push-group.c \
|
||||||
clip-twice.c \
|
clip-twice.c \
|
||||||
|
clip-unbounded.c \
|
||||||
clip-zero.c \
|
clip-zero.c \
|
||||||
clipped-group.c \
|
clipped-group.c \
|
||||||
clipped-surface.c \
|
clipped-surface.c \
|
||||||
|
|
@ -64,6 +65,7 @@ test_sources = \
|
||||||
fill-and-stroke-alpha.c \
|
fill-and-stroke-alpha.c \
|
||||||
fill-and-stroke-alpha-add.c \
|
fill-and-stroke-alpha-add.c \
|
||||||
fill-degenerate-sort-order.c \
|
fill-degenerate-sort-order.c \
|
||||||
|
fill-empty.c \
|
||||||
fill-image.c \
|
fill-image.c \
|
||||||
fill-missed-stop.c \
|
fill-missed-stop.c \
|
||||||
fill-rule.c \
|
fill-rule.c \
|
||||||
|
|
|
||||||
|
|
@ -70,13 +70,12 @@ buffer_diff_core (const unsigned char *_buf_a, int stride_a,
|
||||||
stride_a /= sizeof (uint32_t);
|
stride_a /= sizeof (uint32_t);
|
||||||
stride_b /= sizeof (uint32_t);
|
stride_b /= sizeof (uint32_t);
|
||||||
stride_diff /= sizeof (uint32_t);
|
stride_diff /= sizeof (uint32_t);
|
||||||
for (y = 0; y < height; y++)
|
for (y = 0; y < height; y++) {
|
||||||
{
|
|
||||||
const uint32_t *row_a = buf_a + y * stride_a;
|
const uint32_t *row_a = buf_a + y * stride_a;
|
||||||
const uint32_t *row_b = buf_b + y * stride_b;
|
const uint32_t *row_b = buf_b + y * stride_b;
|
||||||
uint32_t *row = buf_diff + y * stride_diff;
|
uint32_t *row = buf_diff + y * stride_diff;
|
||||||
for (x = 0; x < width; x++)
|
|
||||||
{
|
for (x = 0; x < width; x++) {
|
||||||
/* check if the pixels are the same */
|
/* check if the pixels are the same */
|
||||||
if ((row_a[x] & mask) != (row_b[x] & mask)) {
|
if ((row_a[x] & mask) != (row_b[x] & mask)) {
|
||||||
int channel;
|
int channel;
|
||||||
|
|
@ -99,6 +98,11 @@ buffer_diff_core (const unsigned char *_buf_a, int stride_a,
|
||||||
}
|
}
|
||||||
|
|
||||||
result.pixels_changed++;
|
result.pixels_changed++;
|
||||||
|
if ((diff_pixel & 0x00ffffff) == 0) {
|
||||||
|
/* alpha only difference, convert to luminance */
|
||||||
|
uint8_t alpha = diff_pixel >> 24;
|
||||||
|
diff_pixel = alpha * 0x010101;
|
||||||
|
}
|
||||||
row[x] = diff_pixel;
|
row[x] = diff_pixel;
|
||||||
} else {
|
} else {
|
||||||
row[x] = 0;
|
row[x] = 0;
|
||||||
|
|
|
||||||
|
|
@ -566,7 +566,7 @@ cairo_test_file_is_older (const char *filename,
|
||||||
|
|
||||||
while (num_ref_filenames--) {
|
while (num_ref_filenames--) {
|
||||||
struct stat ref;
|
struct stat ref;
|
||||||
char *ref_filename = ref_filenames++;
|
char *ref_filename = *ref_filenames++;
|
||||||
|
|
||||||
if (ref_filename == NULL)
|
if (ref_filename == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -912,6 +912,11 @@ REPEAT:
|
||||||
goto UNWIND_SURFACE;
|
goto UNWIND_SURFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_surface_set_user_data (surface,
|
||||||
|
&cairo_boilerplate_output_basename_key,
|
||||||
|
base_path,
|
||||||
|
NULL);
|
||||||
|
|
||||||
cairo_surface_set_device_offset (surface, dev_offset, dev_offset);
|
cairo_surface_set_device_offset (surface, dev_offset, dev_offset);
|
||||||
|
|
||||||
cr = cairo_create (surface);
|
cr = cairo_create (surface);
|
||||||
|
|
@ -1080,13 +1085,17 @@ REPEAT:
|
||||||
ctx->test->width,
|
ctx->test->width,
|
||||||
ctx->test->height);
|
ctx->test->height);
|
||||||
diff_status = cairo_surface_write_to_png (test_image, out_png_path);
|
diff_status = cairo_surface_write_to_png (test_image, out_png_path);
|
||||||
|
cairo_surface_destroy (test_image);
|
||||||
if (diff_status) {
|
if (diff_status) {
|
||||||
|
if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS)
|
||||||
|
ret = CAIRO_TEST_CRASHED;
|
||||||
|
else
|
||||||
|
ret = CAIRO_TEST_FAILURE;
|
||||||
cairo_test_log (ctx,
|
cairo_test_log (ctx,
|
||||||
"Error: Failed to write output image: %s\n",
|
"Error: Failed to write output image: %s\n",
|
||||||
cairo_status_to_string (diff_status));
|
cairo_status_to_string (diff_status));
|
||||||
}
|
}
|
||||||
have_output = TRUE;
|
have_output = TRUE;
|
||||||
cairo_surface_destroy (test_image);
|
|
||||||
|
|
||||||
ret = CAIRO_TEST_XFAILURE;
|
ret = CAIRO_TEST_XFAILURE;
|
||||||
goto UNWIND_CAIRO;
|
goto UNWIND_CAIRO;
|
||||||
|
|
@ -1167,8 +1176,11 @@ REPEAT:
|
||||||
if (cairo_surface_status (test_image)) {
|
if (cairo_surface_status (test_image)) {
|
||||||
cairo_test_log (ctx, "Error: Failed to extract image: %s\n",
|
cairo_test_log (ctx, "Error: Failed to extract image: %s\n",
|
||||||
cairo_status_to_string (cairo_surface_status (test_image)));
|
cairo_status_to_string (cairo_surface_status (test_image)));
|
||||||
|
if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS)
|
||||||
|
ret = CAIRO_TEST_CRASHED;
|
||||||
|
else
|
||||||
|
ret = CAIRO_TEST_FAILURE;
|
||||||
cairo_surface_destroy (test_image);
|
cairo_surface_destroy (test_image);
|
||||||
ret = CAIRO_TEST_FAILURE;
|
|
||||||
goto UNWIND_CAIRO;
|
goto UNWIND_CAIRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
BIN
test/clip-operator.pdf.argb32.ref.png
Normal file
|
After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 9.1 KiB |
BIN
test/clip-operator.pdf.rgb24.ref.png
Normal file
|
After Width: | Height: | Size: 5 KiB |
|
Before Width: | Height: | Size: 5 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
BIN
test/clip-operator.xlib-fallback.ref.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
BIN
test/clip-push-group.pdf.ref.png
Normal file
|
After Width: | Height: | Size: 164 B |
|
Before Width: | Height: | Size: 199 B After Width: | Height: | Size: 164 B |