win32: Rebase on the new compositor infrastructure

Try and undo all the damage that has acrued over the years by plugging
into the compositor pipeline.

References: https://bugs.freedesktop.org/show_bug.cgi?id=42739
References: https://bugs.freedesktop.org/show_bug.cgi?id=42821
References: https://bugs.freedesktop.org/show_bug.cgi?id=33081
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-02-12 11:25:07 +00:00
parent 92c0b37d04
commit ae3319890e
20 changed files with 2514 additions and 2111 deletions

View file

@ -209,7 +209,6 @@ cairo_sources = \
cairo-surface-snapshot.c \
cairo-surface-subsurface.c \
cairo-surface-wrapper.c \
cairo-system.c \
cairo-time.c \
cairo-tor-scan-converter.c \
cairo-tor22-scan-converter.c \
@ -336,7 +335,12 @@ cairo_quartz_font_sources = cairo-quartz-font.c
cairo_win32_headers = cairo-win32.h
cairo_win32_private = win32/cairo-win32-private.h
cairo_win32_sources = \
win32/cairo-win32-debug.c \
win32/cairo-win32-device.c \
win32/cairo-win32-gdi-compositor.c \
win32/cairo-win32-system.c \
win32/cairo-win32-surface.c \
win32/cairo-win32-display-surface.c \
win32/cairo-win32-printing-surface.c \
$(NULL)
cairo_win32_font_sources = \

View file

@ -93,6 +93,8 @@ draw_image_boxes (void *_dst,
struct _cairo_boxes_chunk *chunk;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
for (i = 0; i < chunk->count; i++) {
cairo_box_t *b = &chunk->base[i];
@ -279,6 +281,8 @@ fill_rectangles (void *_dst,
uint32_t pixel;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (fill_reduces_to_source (op, color, dst) &&
color_to_pixel (color, dst->pixman_format, &pixel))
{
@ -321,6 +325,8 @@ fill_boxes (void *_dst,
uint32_t pixel;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (fill_reduces_to_source (op, color, dst) &&
color_to_pixel (color, dst->pixman_format, &pixel))
{
@ -379,6 +385,9 @@ composite (void *_dst,
{
cairo_image_source_t *src = (cairo_image_source_t *)abstract_src;
cairo_image_source_t *mask = (cairo_image_source_t *)abstract_mask;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (mask) {
pixman_image_composite32 (_pixman_operator (op),
src->pixman_image, mask->pixman_image, to_pixman_image (_dst),
@ -415,6 +424,8 @@ lerp (void *_dst,
cairo_image_source_t *src = (cairo_image_source_t *)abstract_src;
cairo_image_source_t *mask = (cairo_image_source_t *)abstract_mask;
TRACE ((stderr, "%s\n", __FUNCTION__));
#if PIXMAN_HAS_OP_LERP
pixman_image_composite32 (PIXMAN_OP_LERP_SRC,
src->pixman_image, mask->pixman_image, dst->pixman_image,
@ -424,6 +435,10 @@ lerp (void *_dst,
width, height);
#else
/* Punch the clip out of the destination */
TRACE ((stderr, "%s - OUT_REVERSE (mask=%d/%p, dst=%d/%p)\n",
__FUNCTION__,
mask->base.unique_id, mask->pixman_image,
dst->base.unique_id, dst->pixman_image));
pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE,
mask->pixman_image, NULL, dst->pixman_image,
mask_x, mask_y,
@ -432,6 +447,11 @@ lerp (void *_dst,
width, height);
/* Now add the two results together */
TRACE ((stderr, "%s - ADD (src=%d/%p, mask=%d/%p, dst=%d/%p)\n",
__FUNCTION__,
src->base.unique_id, src->pixman_image,
mask->base.unique_id, mask->pixman_image,
dst->base.unique_id, dst->pixman_image));
pixman_image_composite32 (PIXMAN_OP_ADD,
src->pixman_image, mask->pixman_image, dst->pixman_image,
src_x, src_y,
@ -464,6 +484,7 @@ composite_boxes (void *_dst,
int i;
/* XXX consider using a region? saves multiple prepare-composite */
TRACE ((stderr, "%s\n", __FUNCTION__));
if (((cairo_surface_t *)_dst)->is_clear &&
(op == CAIRO_OPERATOR_SOURCE ||
@ -612,6 +633,8 @@ composite_traps (void *_dst,
pixman_image_t *mask;
pixman_format_code_t format;
TRACE ((stderr, "%s\n", __FUNCTION__));
/* Special case adding trapezoids onto a mask surface; we want to avoid
* creating an intermediate temporary mask unnecessarily.
*
@ -690,6 +713,8 @@ composite_tristrip (void *_dst,
pixman_image_t *mask;
pixman_format_code_t format;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (strip->num_points < 3)
return CAIRO_STATUS_SUCCESS;
@ -745,6 +770,8 @@ composite_one_glyph (void *_dst,
cairo_status_t status;
int x, y;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_scaled_glyph_lookup (info->font,
info->glyphs[0].index,
CAIRO_SCALED_GLYPH_INFO_SURFACE,
@ -794,6 +821,8 @@ composite_glyphs_via_mask (void *_dst,
cairo_status_t status;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
/* XXX convert the glyphs to common formats a8/a8r8g8b8 to hit
* optimised paths through pixman. Should we increase the bit
* depth of the target surface, we should reconsider the appropriate
@ -916,6 +945,8 @@ composite_glyphs (void *_dst,
cairo_status_t status;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (info->num_glyphs == 1)
return composite_one_glyph(_dst, op, _src, src_x, src_y, dst_x, dst_y, info);
@ -1196,6 +1227,8 @@ span_renderer_init (cairo_abstract_span_renderer_t *_r,
int src_x, src_y;
int mask_x, mask_y;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (op == CAIRO_OPERATOR_CLEAR) {
op = PIXMAN_OP_LERP_CLEAR;
} else if (dst->base.is_clear &&
@ -1281,6 +1314,8 @@ span_renderer_fini (cairo_abstract_span_renderer_t *_r,
{
cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *) _r;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (status == CAIRO_INT_STATUS_SUCCESS && r->base.finish)
r->base.finish (r);
@ -1426,6 +1461,8 @@ span_renderer_init (cairo_abstract_span_renderer_t *_r,
const cairo_pattern_t *source = &composite->source_pattern.base;
cairo_operator_t op = composite->op;
TRACE ((stderr, "%s\n", __FUNCTION__));
r->composite = composite;
r->mask = NULL;
r->src = NULL;
@ -1531,6 +1568,8 @@ span_renderer_fini (cairo_abstract_span_renderer_t *_r,
{
cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *) _r;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
const cairo_composite_rectangles_t *composite = r->composite;

View file

@ -71,6 +71,8 @@ _pixman_transparent_image (void)
{
pixman_image_t *image;
TRACE ((stderr, "%s\n", __FUNCTION__));
image = __pixman_transparent_image;
if (unlikely (image == NULL)) {
pixman_color_t color;
@ -101,6 +103,8 @@ _pixman_black_image (void)
{
pixman_image_t *image;
TRACE ((stderr, "%s\n", __FUNCTION__));
image = __pixman_black_image;
if (unlikely (image == NULL)) {
pixman_color_t color;
@ -131,6 +135,8 @@ _pixman_white_image (void)
{
pixman_image_t *image;
TRACE ((stderr, "%s\n", __FUNCTION__));
image = __pixman_white_image;
if (unlikely (image == NULL)) {
pixman_color_t color;
@ -175,18 +181,21 @@ static int n_cached;
static pixman_image_t *
_pixman_transparent_image (void)
{
TRACE ((stderr, "%s\n", __FUNCTION__));
return _pixman_image_for_color (CAIRO_COLOR_TRANSPARENT);
}
static pixman_image_t *
_pixman_black_image (void)
{
TRACE ((stderr, "%s\n", __FUNCTION__));
return _pixman_image_for_color (CAIRO_COLOR_BLACK);
}
static pixman_image_t *
_pixman_white_image (void)
{
TRACE ((stderr, "%s\n", __FUNCTION__));
return _pixman_image_for_color (CAIRO_COLOR_WHITE);
}
#endif /* !PIXMAN_HAS_ATOMIC_OPS */
@ -294,6 +303,8 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern,
unsigned int i;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
pixman_stops = _cairo_malloc_ab (pattern->n_stops,
sizeof(pixman_gradient_stop_t));
@ -384,6 +395,8 @@ _pixman_image_for_mesh (const cairo_mesh_pattern_t *pattern,
pixman_image_t *image;
int width, height;
TRACE ((stderr, "%s\n", __FUNCTION__));
*tx = -extents->x;
*ty = -extents->y;
width = extents->width;
@ -437,6 +450,8 @@ _pixel_to_solid (cairo_image_surface_t *image, int x, int y)
uint32_t pixel;
pixman_color_t color;
TRACE ((stderr, "%s\n", __FUNCTION__));
switch (image->format) {
default:
case CAIRO_FORMAT_INVALID:
@ -607,6 +622,8 @@ _pixman_image_for_recording (cairo_image_surface_t *dst,
cairo_matrix_t *m, matrix;
int tx = 0, ty = 0;
TRACE ((stderr, "%s\n", __FUNCTION__));
*ix = *iy = 0;
source = _cairo_pattern_get_source (pattern, &limit);
@ -707,6 +724,8 @@ _pixman_image_for_surface (cairo_image_surface_t *dst,
cairo_extend_t extend = pattern->base.extend;
pixman_image_t *pixman_image;
TRACE ((stderr, "%s\n", __FUNCTION__));
*ix = *iy = 0;
pixman_image = NULL;
if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
@ -915,6 +934,8 @@ _pixman_image_for_raster (cairo_image_surface_t *dst,
cairo_status_t status;
cairo_surface_t *surface;
TRACE ((stderr, "%s\n", __FUNCTION__));
*ix = *iy = 0;
surface = _cairo_raster_source_pattern_acquire (&pattern->base,
@ -977,6 +998,8 @@ _pixman_image_for_pattern (cairo_image_surface_t *dst,
{
*tx = *ty = 0;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (pattern == NULL)
return _pixman_white_image ();
@ -1034,6 +1057,8 @@ _cairo_image_source_create_for_pattern (cairo_surface_t *dst,
{
cairo_image_source_t *source;
TRACE ((stderr, "%s\n", __FUNCTION__));
source = malloc (sizeof (cairo_image_source_t));
if (unlikely (source == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

View file

@ -50,6 +50,7 @@ struct _cairo_image_surface {
pixman_image_t *pixman_image;
const cairo_compositor_t *compositor;
cairo_surface_t *parent;
pixman_format_code_t pixman_format;
cairo_format_t format;
@ -64,6 +65,7 @@ struct _cairo_image_surface {
unsigned transparency : 2;
unsigned color : 2;
};
#define to_image_surface(S) ((cairo_image_surface_t *)(S))
/* A wrapper for holding pixman images returned by create_for_pattern */
typedef struct _cairo_image_source {
@ -201,6 +203,13 @@ _pixman_image_add_tristrip (pixman_image_t *image,
int dst_x, int dst_y,
cairo_tristrip_t *strip);
static inline void
_cairo_image_surface_set_parent (cairo_image_surface_t *image,
cairo_surface_t *parent)
{
image->parent = parent;
}
/**
* _cairo_surface_is_image:
* @surface: a #cairo_surface_t

View file

@ -147,6 +147,7 @@ _cairo_image_surface_init (cairo_image_surface_t *surface,
pixman_image_t *pixman_image,
pixman_format_code_t pixman_format)
{
surface->parent = NULL;
surface->pixman_image = pixman_image;
surface->pixman_format = pixman_format;
@ -714,7 +715,7 @@ _cairo_format_bits_per_pixel (cairo_format_t format)
}
}
static cairo_surface_t *
static cairo_surface_t *
_cairo_image_surface_create_similar (void *abstract_other,
cairo_content_t content,
int width,
@ -722,6 +723,8 @@ _cairo_image_surface_create_similar (void *abstract_other,
{
cairo_image_surface_t *other = abstract_other;
TRACE ((stderr, "%s (other=%u)\n", __FUNCTION__, other->base.unique_id));
if (! _cairo_image_surface_is_size_valid (width, height))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
@ -872,6 +875,10 @@ _cairo_image_surface_paint (void *abstract_surface,
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->base.unique_id));
return _cairo_compositor_paint (surface->compositor,
&surface->base, op, source, clip);
}
@ -884,6 +891,10 @@ _cairo_image_surface_mask (void *abstract_surface,
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->base.unique_id));
return _cairo_compositor_mask (surface->compositor,
&surface->base, op, source, mask, clip);
}
@ -901,6 +912,10 @@ _cairo_image_surface_stroke (void *abstract_surface,
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->base.unique_id));
return _cairo_compositor_stroke (surface->compositor, &surface->base,
op, source, path,
style, ctm, ctm_inverse,
@ -918,6 +933,10 @@ _cairo_image_surface_fill (void *abstract_surface,
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->base.unique_id));
return _cairo_compositor_fill (surface->compositor, &surface->base,
op, source, path,
fill_rule, tolerance, antialias,
@ -934,6 +953,10 @@ _cairo_image_surface_glyphs (void *abstract_surface,
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->base.unique_id));
return _cairo_compositor_glyphs (surface->compositor, &surface->base,
op, source,
glyphs, num_glyphs, scaled_font,

View file

@ -201,6 +201,16 @@ struct _cairo_surface_backend {
(*get_supported_mime_types) (void *surface);
};
cairo_private cairo_status_t
_cairo_surface_default_acquire_source_image (void *surface,
cairo_image_surface_t **image_out,
void **image_extra);
cairo_private void
_cairo_surface_default_release_source_image (void *surface,
cairo_image_surface_t *image,
void *image_extra);
cairo_private cairo_surface_t *
_cairo_surface_default_source (void *surface,
cairo_rectangle_int_t *extents);

View file

@ -44,6 +44,7 @@
#include "cairo-list-private.h"
#include "cairo-reference-count-private.h"
#include "cairo-clip-private.h"
#include "cairo-surface-backend-private.h"
typedef void (*cairo_surface_func_t) (cairo_surface_t *);
@ -110,4 +111,13 @@ cairo_private cairo_surface_t *
_cairo_surface_get_source (cairo_surface_t *surface,
cairo_rectangle_int_t *extents);
static inline cairo_status_t
_cairo_surface_flush (cairo_surface_t *surface)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
if (surface->backend->flush)
status = surface->backend->flush (surface);
return status;
}
#endif /* CAIRO_SURFACE_PRIVATE_H */

View file

@ -1713,6 +1713,17 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
cairo_status_t
_cairo_surface_default_acquire_source_image (void *surface,
cairo_image_surface_t **image_out,
void **image_extra)
{
*image_out = (cairo_image_surface_t *)
cairo_surface_map_to_image (surface, NULL);
*image_extra = NULL;
return (*image_out)->base.status;
}
/**
* _cairo_surface_release_source_image:
* @surface: a #cairo_surface_t
@ -1731,6 +1742,15 @@ _cairo_surface_release_source_image (cairo_surface_t *surface,
surface->backend->release_source_image (surface, image, image_extra);
}
void
_cairo_surface_default_release_source_image (void *surface,
cairo_image_surface_t *image,
void *image_extra)
{
cairo_surface_unmap_image (surface, &image->base);
}
cairo_surface_t *
_cairo_surface_get_source (cairo_surface_t *surface,
cairo_rectangle_int_t *extents)

View file

@ -167,6 +167,8 @@ combine_clip_as_traps (const cairo_traps_compositor_t *compositor,
int src_x, src_y;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_clip_get_polygon (clip, &polygon,
&fill_rule, &antialias);
if (status)
@ -209,6 +211,8 @@ traps_get_clip_surface (const cairo_traps_compositor_t *compositor,
cairo_surface_t *surface;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
surface = _cairo_surface_create_similar_solid (target,
CAIRO_CONTENT_ALPHA,
extents->width,
@ -247,6 +251,8 @@ create_composite_mask (const cairo_traps_compositor_t *compositor,
int src_x, src_y;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
surface = _cairo_surface_create_similar_solid (dst,
CAIRO_CONTENT_ALPHA,
extents->bounded.width,
@ -351,6 +357,8 @@ clip_and_composite_with_mask (const cairo_traps_compositor_t *compositor,
cairo_surface_t *dst = extents->surface;
cairo_surface_t *mask;
TRACE ((stderr, "%s\n", __FUNCTION__));
mask = create_composite_mask (compositor, dst, draw_closure,
draw_func, mask_func,
extents);
@ -396,6 +404,8 @@ clip_and_composite_combine (const cairo_traps_compositor_t *compositor,
cairo_surface_t *tmp, *clip;
cairo_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
tmp = _cairo_surface_create_similar_scratch (dst, dst->content,
extents->bounded.width,
extents->bounded.height);
@ -467,6 +477,8 @@ clip_and_composite_source (const cairo_traps_compositor_t *compositor,
{
cairo_surface_t *mask;
TRACE ((stderr, "%s\n", __FUNCTION__));
/* Create a surface that is mask IN clip */
mask = create_composite_mask (compositor, dst, draw_closure,
draw_func, mask_func,
@ -531,6 +543,8 @@ fixup_unbounded_with_mask (const cairo_traps_compositor_t *compositor,
cairo_clip_t *clip = extents->clip;
cairo_surface_t *mask;
TRACE ((stderr, "%s\n", __FUNCTION__));
/* XXX can we avoid querying the clip surface again? */
mask = traps_get_clip_surface (compositor, dst, clip, &extents->unbounded);
if (unlikely (mask->status))
@ -622,6 +636,8 @@ fixup_unbounded (const cairo_traps_compositor_t *compositor,
cairo_box_t box;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (extents->bounded.width == extents->unbounded.width &&
extents->bounded.height == extents->unbounded.height)
{
@ -772,6 +788,8 @@ clip_and_composite (const cairo_traps_compositor_t *compositor,
cairo_region_t *clip_region = NULL;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (reduce_alpha_op (extents)) {
op = CAIRO_OPERATOR_ADD;
source = NULL;
@ -882,6 +900,8 @@ composite_traps (const cairo_traps_compositor_t *compositor,
{
composite_traps_info_t *info = closure;
TRACE ((stderr, "%s\n", __FUNCTION__));
return compositor->composite_traps (dst, op, src,
src_x - dst_x, src_y - dst_y,
dst_x, dst_y,
@ -907,6 +927,8 @@ composite_tristrip (const cairo_traps_compositor_t *compositor,
{
composite_tristrip_info_t *info = closure;
TRACE ((stderr, "%s\n", __FUNCTION__));
return compositor->composite_tristrip (dst, op, src,
src_x - dst_x, src_y - dst_y,
dst_x, dst_y,
@ -985,6 +1007,8 @@ composite_aligned_boxes (const cairo_traps_compositor_t *compositor,
cairo_bool_t op_is_source;
cairo_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (need_clip_mask &&
(! extents->is_bounded || extents->op == CAIRO_OPERATOR_SOURCE))
{
@ -1107,6 +1131,8 @@ upload_boxes (const cairo_traps_compositor_t *compositor,
cairo_int_status_t status;
int tx, ty;
TRACE ((stderr, "%s\n", __FUNCTION__));
src = _cairo_pattern_get_source((cairo_surface_pattern_t *)source,
&limit);
if (!(src->type == CAIRO_SURFACE_TYPE_IMAGE || src->type == dst->type))
@ -1258,6 +1284,8 @@ clip_and_composite_polygon (const cairo_traps_compositor_t *compositor,
cairo_bool_t clip_surface = ! _cairo_clip_is_region (extents->clip);
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (polygon->num_edges == 0) {
status = CAIRO_INT_STATUS_SUCCESS;
@ -1426,6 +1454,8 @@ composite_opacity_boxes (const cairo_traps_compositor_t *compositor,
struct composite_opacity_info info;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
info.compositor = compositor;
info.op = op;
info.dst = dst;
@ -1460,6 +1490,8 @@ composite_boxes (const cairo_traps_compositor_t *compositor,
cairo_traps_t traps;
cairo_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_traps_init_boxes (&traps, closure);
if (unlikely (status))
return status;
@ -1481,6 +1513,8 @@ clip_and_composite_boxes (const cairo_traps_compositor_t *compositor,
{
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (boxes->num_boxes == 0 && extents->is_bounded)
return CAIRO_STATUS_SUCCESS;
@ -1549,6 +1583,8 @@ composite_traps_as_boxes (const cairo_traps_compositor_t *compositor,
{
cairo_boxes_t boxes;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (! _cairo_traps_to_boxes (&info->traps, info->antialias, &boxes))
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1562,6 +1598,8 @@ clip_and_composite_traps (const cairo_traps_compositor_t *compositor,
{
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = trim_extents_to_traps (extents, &info->traps);
if (unlikely (status != CAIRO_INT_STATUS_SUCCESS))
return status;
@ -1596,6 +1634,8 @@ clip_and_composite_tristrip (const cairo_traps_compositor_t *compositor,
cairo_int_status_t status;
unsigned int flags = 0;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = trim_extents_to_tristrip (extents, &info->strip);
if (unlikely (status != CAIRO_INT_STATUS_SUCCESS))
return status;
@ -1630,6 +1670,8 @@ composite_mask (const cairo_traps_compositor_t *compositor,
{
struct composite_mask *data = closure;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (src != NULL) {
compositor->composite (dst, op, src, data->mask,
extents->x + src_x, extents->y + src_y,
@ -1663,6 +1705,8 @@ static void composite_box(void *closure,
struct composite_box_info *info = closure;
const cairo_traps_compositor_t *compositor = info->compositor;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (! CAIRO_ALPHA_SHORT_IS_OPAQUE (coverage)) {
cairo_surface_t *mask;
cairo_color_t color;
@ -1712,6 +1756,8 @@ composite_mask_clip_boxes (const cairo_traps_compositor_t *compositor,
struct composite_box_info info;
int i;
TRACE ((stderr, "%s\n", __FUNCTION__));
info.compositor = compositor;
info.op = CAIRO_OPERATOR_SOURCE;
info.dst = dst;
@ -1747,6 +1793,8 @@ composite_mask_clip (const cairo_traps_compositor_t *compositor,
composite_traps_info_t info;
cairo_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_clip_get_polygon (clip, &polygon,
&fill_rule, &info.antialias);
if (unlikely (status))
@ -1781,6 +1829,8 @@ _cairo_traps_compositor_paint (const cairo_compositor_t *_compositor,
cairo_boxes_t boxes;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = compositor->check_composite (extents);
if (unlikely (status))
return status;
@ -1799,6 +1849,8 @@ _cairo_traps_compositor_mask (const cairo_compositor_t *_compositor,
const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t*)_compositor;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = compositor->check_composite (extents);
if (unlikely (status))
return status;
@ -1820,6 +1872,8 @@ _cairo_traps_compositor_mask (const cairo_compositor_t *_compositor,
&extents->mask_sample_area,
&data.mask_x,
&data.mask_y);
if (unlikely (data.mask->status))
return data.mask->status;
status = clip_and_composite (compositor, extents,
composite_mask,
@ -1845,6 +1899,8 @@ _cairo_traps_compositor_stroke (const cairo_compositor_t *_compositor,
const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t *)_compositor;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = compositor->check_composite (extents);
if (unlikely (status))
return status;
@ -1908,6 +1964,8 @@ _cairo_traps_compositor_fill (const cairo_compositor_t *_compositor,
const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t *)_compositor;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = compositor->check_composite (extents);
if (unlikely (status))
return status;
@ -1975,6 +2033,8 @@ composite_glyphs (const cairo_traps_compositor_t *compositor,
{
cairo_composite_glyphs_info_t *info = closure;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (op == CAIRO_OPERATOR_ADD && (dst->content & CAIRO_CONTENT_COLOR) == 0)
info->use_mask = 0;
@ -1995,6 +2055,8 @@ _cairo_traps_compositor_glyphs (const cairo_compositor_t *_compositor,
const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t *)_compositor;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
status = compositor->check_composite (extents);
if (unlikely (status))
return status;

View file

@ -2047,6 +2047,7 @@ cairo_device_reference (cairo_device_t *device);
* @CAIRO_DEVICE_TYPE_XLIB: The device is of type xlib
* @CAIRO_DEVICE_TYPE_XML: The device is of type XML
* @CAIRO_DEVICE_TYPE_COGL: The device is of type cogl, since 1.12
* @CAIRO_DEVICE_TYPE_WIN32: The device is of type cogl, since 1.12
* @CAIRO_DEVICE_TYPE_INVALID: The device is invalid
*
* #cairo_device_type_t is used to describe the type of a given
@ -2076,6 +2077,7 @@ typedef enum _cairo_device_type {
CAIRO_DEVICE_TYPE_XLIB,
CAIRO_DEVICE_TYPE_XML,
CAIRO_DEVICE_TYPE_COGL,
CAIRO_DEVICE_TYPE_WIN32,
CAIRO_DEVICE_TYPE_INVALID = -1
} cairo_device_type_t;

View file

@ -1984,4 +1984,10 @@ _cairo_debug_print_traps (FILE *file, const cairo_traps_t *traps);
cairo_private void
_cairo_debug_print_clip (FILE *stream, const cairo_clip_t *clip);
#if 0
#define TRACE(x) fprintf x
#else
#define TRACE(x)
#endif
#endif

View file

@ -0,0 +1,87 @@
/* -*- 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.
* Copyright © 2012 Intel Corporation
*
* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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>
* Stuart Parmenter <stuart@mozilla.com>
* Vladimir Vukicevic <vladimir@pobox.com>
*/
#define WIN32_LEAN_AND_MEAN
/* We require Windows 2000 features such as ETO_PDY */
#if !defined(WINVER) || (WINVER < 0x0500)
# define WINVER 0x0500
#endif
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
# define _WIN32_WINNT 0x0500
#endif
#include "cairoint.h"
#include "cairo-win32-private.h"
#include <wchar.h>
#include <windows.h>
void
_cairo_win32_debug_dump_hrgn (HRGN rgn, char *header)
{
RGNDATA *rd;
unsigned int z;
if (header)
fprintf (stderr, "%s\n", header);
if (rgn == NULL) {
fprintf (stderr, " NULL\n");
}
z = GetRegionData(rgn, 0, NULL);
rd = (RGNDATA*) malloc(z);
z = GetRegionData(rgn, z, rd);
fprintf (stderr, " %ld rects, bounds: %ld %ld %ld %ld\n",
rd->rdh.nCount,
rd->rdh.rcBound.left,
rd->rdh.rcBound.top,
rd->rdh.rcBound.right - rd->rdh.rcBound.left,
rd->rdh.rcBound.bottom - rd->rdh.rcBound.top);
for (z = 0; z < rd->rdh.nCount; z++) {
RECT r = ((RECT*)rd->Buffer)[z];
fprintf (stderr, " [%d]: [%ld %ld %ld %ld]\n",
z, r.left, r.top, r.right - r.left, r.bottom - r.top);
}
free(rd);
fflush (stderr);
}

View file

@ -0,0 +1,189 @@
/* -*- 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.
* Copyright © 2012 Intel Corporation
*
* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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>
* Stuart Parmenter <stuart@mozilla.com>
* Vladimir Vukicevic <vladimir@pobox.com>
*/
#define WIN32_LEAN_AND_MEAN
/* We require Windows 2000 features such as ETO_PDY */
#if !defined(WINVER) || (WINVER < 0x0500)
# define WINVER 0x0500
#endif
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500)
# define _WIN32_WINNT 0x0500
#endif
#include "cairoint.h"
#include "cairo-atomic-private.h"
#include "cairo-device-private.h"
#include "cairo-win32-private.h"
#include <wchar.h>
#include <windows.h>
static cairo_device_t *__cairo_win32_device;
static cairo_status_t
_cairo_win32_device_flush (void *device)
{
GdiFlush ();
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_win32_device_finish (void *device)
{
}
static void
_cairo_win32_device_destroy (void *device)
{
free (device);
}
static const cairo_device_backend_t _cairo_win32_device_backend = {
CAIRO_DEVICE_TYPE_WIN32,
NULL, NULL, /* lock, unlock */
_cairo_win32_device_flush,
_cairo_win32_device_finish,
_cairo_win32_device_destroy,
};
#if 0
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
hr = m_pD2DFactory->CreateDCRenderTarget(&props, &device->d2d);
#endif
static cairo_bool_t is_win98 (void)
{
OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof (os);
GetVersionEx (&os);
return (VER_PLATFORM_WIN32_WINDOWS != os.dwPlatformId &&
os.dwMajorVersion != 4 &&
os.dwMinorVersion != 10);
}
static void *
_cairo_win32_device_get_alpha_blend (cairo_win32_device_t *device)
{
void *func = NULL;
if (is_win98 ())
return NULL;
device->msimg32_dll = LoadLibraryW (L"msimg32");
if (device->msimg32_dll)
func = GetProcAddress (device->msimg32_dll, "AlphaBlend");
return func;
}
cairo_device_t *
_cairo_win32_device_get (void)
{
cairo_win32_device_t *device;
if (__cairo_win32_device)
return cairo_device_reference (__cairo_win32_device);
device = malloc (sizeof (*device));
_cairo_device_init (&device->base, &_cairo_win32_device_backend);
device->compositor = _cairo_win32_gdi_compositor_get ();
device->msimg32_dll = NULL;
device->alpha_blend = _cairo_win32_device_get_alpha_blend (device);
if (_cairo_atomic_ptr_cmpxchg ((void **)&__cairo_win32_device, NULL, device))
return cairo_device_reference(&device->base);
_cairo_win32_device_destroy (device);
return cairo_device_reference (__cairo_win32_device);
}
unsigned
_cairo_win32_flags_for_dc (HDC dc)
{
uint32_t flags = 0;
int cap;
cap = GetDeviceCaps(dc, RASTERCAPS);
if (cap & RC_BITBLT)
flags |= CAIRO_WIN32_SURFACE_CAN_BITBLT;
if (cap & RC_STRETCHBLT)
flags |= CAIRO_WIN32_SURFACE_CAN_STRETCHBLT;
if (cap & RC_STRETCHDIB)
flags |= CAIRO_WIN32_SURFACE_CAN_STRETCHDIB;
if (GetDeviceCaps(dc, TECHNOLOGY) == DT_RASDISPLAY) {
flags |= CAIRO_WIN32_SURFACE_IS_DISPLAY;
/* These will always be possible, but the actual GetDeviceCaps
* calls will return whether they're accelerated or not.
* We may want to use our own (pixman) routines sometimes
* if they're eventually faster, but for now have GDI do
* everything.
*/
#if 0
flags |= CAIRO_WIN32_SURFACE_CAN_BITBLT;
flags |= CAIRO_WIN32_SURFACE_CAN_ALPHABLEND;
flags |= CAIRO_WIN32_SURFACE_CAN_STRETCHBLT;
flags |= CAIRO_WIN32_SURFACE_CAN_STRETCHDIB;
#endif
} else {
cap = GetDeviceCaps(dc, SHADEBLENDCAPS);
if (cap != SB_NONE)
flags |= CAIRO_WIN32_SURFACE_CAN_ALPHABLEND;
}
return flags;
}

File diff suppressed because it is too large Load diff

View file

@ -236,13 +236,15 @@ _compute_transform (cairo_win32_scaled_font_t *scaled_font,
if (status)
return status;
scaled_font->logical_size = _cairo_lround (WIN32_FONT_LOGICAL_SCALE *
scaled_font->y_scale);
scaled_font->logical_scale = WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;
scaled_font->logical_size =
_cairo_lround (WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale);
scaled_font->logical_scale =
WIN32_FONT_LOGICAL_SCALE * scaled_font->y_scale;
}
cairo_matrix_scale (&scaled_font->logical_to_device,
1.0 / scaled_font->logical_scale, 1.0 / scaled_font->logical_scale);
1.0 / scaled_font->logical_scale,
1.0 / scaled_font->logical_scale);
scaled_font->device_to_logical = scaled_font->logical_to_device;
@ -1049,7 +1051,6 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
extents.y_bearing = (- extents.y_bearing - extents.height);
extents.y_advance = - extents.y_advance;
}
} else {
/* For all other transformations, we use the design metrics
* of the font.
@ -1295,6 +1296,7 @@ _draw_glyphs_on_surface (cairo_win32_surface_t *surface,
return status;
}
#if 0
/* Duplicate the green channel of a 4-channel mask in the alpha channel, then
* invert the whole mask.
*/
@ -1360,6 +1362,7 @@ _compute_a8_mask (cairo_win32_surface_t *mask_surface)
return &image8->base;
}
#endif
static cairo_int_status_t
_cairo_win32_scaled_font_glyph_init (void *abstract_font,
@ -1656,9 +1659,9 @@ _cairo_win32_scaled_font_is_synthetic (void *abstract_font)
}
static cairo_int_status_t
_cairo_win32_scaled_font_index_to_glyph_name (void *abstract_font,
_cairo_win32_scaled_font_index_to_glyph_name (void *abstract_font,
char **glyph_names,
int num_glyph_names,
int num_glyph_names,
unsigned long glyph_index,
unsigned long *glyph_array_index)
{
@ -1688,7 +1691,7 @@ _cairo_win32_scaled_font_index_to_glyph_name (void *abstract_font,
*glyph_array_index = scaled_font->type1_notdef_index;
else if (glyph_index <= scaled_font->type1_notdef_index)
*glyph_array_index = glyph_index - 1;
else if (glyph_index < num_glyph_names)
else if (glyph_index < (unsigned long)num_glyph_names)
*glyph_array_index = glyph_index;
else
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -1756,8 +1759,12 @@ _cairo_win32_scaled_font_init_glyph_surface (cairo_win32_scaled_font_t *scaled_f
GdiFlush();
#if 0
image = _compute_a8_mask (surface);
status = image->status;
#else
status = CAIRO_STATUS_NO_MEMORY;
#endif
if (status)
goto FAIL;

View file

@ -0,0 +1,646 @@
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2012 Intel Corporation
*
* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*
* The Original Code is the cairo graphics library.
*
* The Initial Developer of the Original Code is University of Southern
* California.
*
* Contributor(s):
* Carl D. Worth <cworth@cworth.org>
* Behdad Esfahbod <behdad@behdad.org>
* Chris Wilson <chris@chris-wilson.co.uk>
* Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
*/
/* The original X drawing API was very restrictive in what it could handle,
* pixel-aligned fill/blits are all that map into Cairo's drawing model.
*/
#include "cairoint.h"
#include "cairo-win32-private.h"
#include "cairo-boxes-private.h"
#include "cairo-compositor-private.h"
#include "cairo-image-surface-private.h"
#include "cairo-pattern-private.h"
#include "cairo-region-private.h"
#include "cairo-surface-offset-private.h"
#if !defined(AC_SRC_OVER)
#define AC_SRC_OVER 0x00
#pragma pack(1)
typedef struct {
BYTE BlendOp;
BYTE BlendFlags;
BYTE SourceConstantAlpha;
BYTE AlphaFormat;
}BLENDFUNCTION;
#pragma pack()
#endif
/* for compatibility with VC++ 6 */
#ifndef AC_SRC_ALPHA
#define AC_SRC_ALPHA 0x01
#endif
#define PELS_72DPI ((LONG)(72. / 0.0254))
/* the low-level interface */
struct fill_box {
HDC dc;
HBRUSH brush;
};
static cairo_bool_t fill_box (cairo_box_t *box, void *closure)
{
struct fill_box *fb = closure;
RECT rect;
rect.left = _cairo_fixed_integer_part (box->p1.x);
rect.top = _cairo_fixed_integer_part (box->p1.y);
rect.right = _cairo_fixed_integer_part (box->p2.x);
rect.bottom = _cairo_fixed_integer_part (box->p2.y);
TRACE ((stderr, "%s\n", __FUNCTION__));
return FillRect (fb->dc, &rect, fb->brush);
}
struct check_box {
cairo_rectangle_int_t limit;
int tx, ty;
};
struct copy_box {
cairo_rectangle_int_t limit;
int tx, ty;
HDC dst, src;
BLENDFUNCTION bf;
cairo_win32_alpha_blend_func_t alpha_blend;
};
static cairo_bool_t copy_box (cairo_box_t *box, void *closure)
{
const struct copy_box *cb = closure;
int x = _cairo_fixed_integer_part (box->p1.x);
int y = _cairo_fixed_integer_part (box->p1.y);
int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x);
int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y);
TRACE ((stderr, "%s\n", __FUNCTION__));
return BitBlt (cb->dst, x, y, width, height,
cb->src, x + cb->tx, y + cb->ty,
SRCCOPY);
}
static cairo_bool_t alpha_box (cairo_box_t *box, void *closure)
{
const struct copy_box *cb = closure;
int x = _cairo_fixed_integer_part (box->p1.x);
int y = _cairo_fixed_integer_part (box->p1.y);
int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x);
int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y);
TRACE ((stderr, "%s\n", __FUNCTION__));
return cb->alpha_blend (cb->dst, x, y, width, height,
cb->src, x + cb->tx, y + cb->ty, width, height,
cb->bf);
}
struct upload_box {
cairo_rectangle_int_t limit;
int tx, ty;
HDC dst;
BITMAPINFO bi;
void *data;
};
static cairo_bool_t upload_box (cairo_box_t *box, void *closure)
{
const struct upload_box *cb = closure;
int x = _cairo_fixed_integer_part (box->p1.x);
int y = _cairo_fixed_integer_part (box->p1.y);
int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x);
int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y);
TRACE ((stderr, "%s\n", __FUNCTION__));
return StretchDIBits (cb->dst, x, y + height - 1, width, -height,
x + cb->tx, height - (y + cb->ty - 1),
width, -height,
cb->data, &cb->bi,
DIB_RGB_COLORS, SRCCOPY);
}
/* the mid-level: converts boxes into drawing operations */
static COLORREF color_to_rgb(const cairo_color_t *c)
{
return RGB (c->red_short >> 8, c->green_short >> 8, c->blue_short >> 8);
}
static cairo_int_status_t
fill_boxes (cairo_win32_display_surface_t *dst,
const cairo_pattern_t *src,
cairo_boxes_t *boxes)
{
const cairo_color_t *color = &((cairo_solid_pattern_t *) src)->color;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
struct fill_box fb;
TRACE ((stderr, "%s\n", __FUNCTION__));
fb.dc = dst->win32.dc;
fb.brush = CreateSolidBrush (color_to_rgb(color));
if (!fb.brush)
return _cairo_win32_print_gdi_error (__FUNCTION__);
if (! _cairo_boxes_for_each_box (boxes, fill_box, &fb))
status = CAIRO_INT_STATUS_UNSUPPORTED;
DeleteObject (fb.brush);
return status;
}
static cairo_bool_t source_contains_box (cairo_box_t *box, void *closure)
{
struct check_box *data = closure;
/* The box is pixel-aligned so the truncation is safe. */
return
_cairo_fixed_integer_part (box->p1.x) + data->tx >= data->limit.x &&
_cairo_fixed_integer_part (box->p1.y) + data->ty >= data->limit.y &&
_cairo_fixed_integer_part (box->p2.x) + data->tx <= data->limit.x + data->limit.width &&
_cairo_fixed_integer_part (box->p2.y) + data->ty <= data->limit.y + data->limit.height;
}
static cairo_status_t
copy_boxes (cairo_win32_display_surface_t *dst,
const cairo_pattern_t *source,
cairo_boxes_t *boxes)
{
const cairo_surface_pattern_t *pattern;
struct copy_box cb;
cairo_surface_t *surface;
cairo_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
pattern = (const cairo_surface_pattern_t *) source;
surface = _cairo_surface_get_source (pattern->surface, &cb.limit);
if (surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
surface = to_image_surface(surface)->parent;
if (surface == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (surface->type != CAIRO_SURFACE_TYPE_WIN32)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (! _cairo_matrix_is_integer_translation (&source->matrix,
&cb.tx, &cb.ty))
return CAIRO_INT_STATUS_UNSUPPORTED;
cb.dst = dst->win32.dc;
cb.src = to_win32_surface(surface)->dc;
/* First check that the data is entirely within the image */
if (! _cairo_boxes_for_each_box (boxes, source_contains_box, &cb))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_surface_flush (surface);
if (status)
return status;
cb.tx += cb.limit.x;
cb.ty += cb.limit.y;
status = CAIRO_STATUS_SUCCESS;
if (! _cairo_boxes_for_each_box (boxes, copy_box, &cb))
status = CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_win32_display_surface_discard_fallback (dst);
return status;
}
static cairo_status_t
upload_boxes (cairo_win32_display_surface_t *dst,
const cairo_pattern_t *source,
cairo_boxes_t *boxes)
{
const cairo_surface_pattern_t *pattern;
struct upload_box cb;
cairo_surface_t *surface;
cairo_image_surface_t *image;
void *image_extra;
cairo_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if ((dst->win32.flags & CAIRO_WIN32_SURFACE_CAN_STRETCHDIB) == 0)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (! _cairo_matrix_is_integer_translation (&source->matrix,
&cb.tx, &cb.ty))
return CAIRO_INT_STATUS_UNSUPPORTED;
pattern = (const cairo_surface_pattern_t *) source;
surface = _cairo_surface_get_source (pattern->surface, &cb.limit);
/* First check that the data is entirely within the image */
if (! _cairo_boxes_for_each_box (boxes, source_contains_box, &cb))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (surface->type != CAIRO_SURFACE_TYPE_IMAGE) {
status = _cairo_surface_acquire_source_image (surface,
&image, &image_extra);
if (status)
return status;
} else
image = to_image_surface(surface);
status = CAIRO_INT_STATUS_UNSUPPORTED;
if (!(image->format == CAIRO_FORMAT_ARGB32 ||
image->format == CAIRO_FORMAT_RGB24))
goto err;
if (image->stride != 4*image->width)
goto err;
cb.dst = dst->win32.dc;
cb.data = image->data;
cb.bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
cb.bi.bmiHeader.biWidth = image->width;
cb.bi.bmiHeader.biHeight = -image->height;
cb.bi.bmiHeader.biSizeImage = 0;
cb.bi.bmiHeader.biXPelsPerMeter = PELS_72DPI;
cb.bi.bmiHeader.biYPelsPerMeter = PELS_72DPI;
cb.bi.bmiHeader.biPlanes = 1;
cb.bi.bmiHeader.biBitCount = 32;
cb.bi.bmiHeader.biCompression = BI_RGB;
cb.bi.bmiHeader.biClrUsed = 0;
cb.bi.bmiHeader.biClrImportant = 0;
cb.tx += cb.limit.x;
cb.ty += cb.limit.y;
status = CAIRO_STATUS_SUCCESS;
if (! _cairo_boxes_for_each_box (boxes, upload_box, &cb))
status = CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_win32_display_surface_discard_fallback (dst);
err:
if (&image->base != surface)
_cairo_surface_release_source_image (surface, image, image_extra);
return status;
}
static cairo_status_t
alpha_blend_boxes (cairo_win32_display_surface_t *dst,
const cairo_pattern_t *source,
cairo_boxes_t *boxes,
uint8_t alpha)
{
const cairo_surface_pattern_t *pattern;
struct copy_box cb;
cairo_surface_t *surface;
cairo_win32_display_surface_t *src;
cairo_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
return CAIRO_INT_STATUS_UNSUPPORTED;
pattern = (const cairo_surface_pattern_t *) source;
surface = _cairo_surface_get_source (pattern->surface, &cb.limit);
if (surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
surface = to_image_surface(surface)->parent;
if (surface == NULL)
return CAIRO_INT_STATUS_UNSUPPORTED;
}
if (pattern->surface->type != CAIRO_SURFACE_TYPE_WIN32)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (! _cairo_matrix_is_integer_translation (&source->matrix,
&cb.tx, &cb.ty))
return CAIRO_INT_STATUS_UNSUPPORTED;
src = to_win32_display_surface (surface);
cb.dst = dst->win32.dc;
cb.src = src->win32.dc;
/* First check that the data is entirely within the image */
if (! _cairo_boxes_for_each_box (boxes, source_contains_box, &cb))
return CAIRO_INT_STATUS_UNSUPPORTED;
status = _cairo_surface_flush (&src->win32.base);
if (status)
return status;
cb.bf.BlendOp = AC_SRC_OVER;
cb.bf.BlendFlags = 0;
cb.bf.SourceConstantAlpha = alpha;
cb.bf.AlphaFormat = (src->win32.format == CAIRO_FORMAT_ARGB32) ? AC_SRC_ALPHA : 0;
cb.alpha_blend = to_win32_device(dst->win32.base.device)->alpha_blend;
cb.tx += cb.limit.x;
cb.ty += cb.limit.y;
status = CAIRO_STATUS_SUCCESS;
if (! _cairo_boxes_for_each_box (boxes, alpha_box, &cb))
status = CAIRO_INT_STATUS_UNSUPPORTED;
_cairo_win32_display_surface_discard_fallback (dst);
return status;
}
static cairo_bool_t
can_alpha_blend (cairo_win32_display_surface_t *dst)
{
if ((dst->win32.flags & CAIRO_WIN32_SURFACE_CAN_ALPHABLEND) == 0)
return FALSE;
return to_win32_device(dst->win32.base.device)->alpha_blend != NULL;
}
static cairo_status_t
draw_boxes (cairo_composite_rectangles_t *composite,
cairo_boxes_t *boxes)
{
cairo_win32_display_surface_t *dst = to_win32_display_surface(composite->surface);
cairo_operator_t op = composite->op;
const cairo_pattern_t *src = &composite->source_pattern.base;
cairo_int_status_t status;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (boxes->num_boxes == 0 && composite->is_bounded)
return CAIRO_STATUS_SUCCESS;
if (!boxes->is_pixel_aligned)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (op == CAIRO_OPERATOR_CLEAR)
op = CAIRO_OPERATOR_SOURCE;
if (op == CAIRO_OPERATOR_OVER &&
_cairo_pattern_is_opaque (src, &composite->bounded))
op = CAIRO_OPERATOR_SOURCE;
if (dst->win32.base.is_clear && op == CAIRO_OPERATOR_OVER)
op = CAIRO_OPERATOR_SOURCE;
if (op == CAIRO_OPERATOR_SOURCE) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
if (src->type == CAIRO_PATTERN_TYPE_SURFACE) {
status = copy_boxes (dst, src, boxes);
if (status == CAIRO_INT_STATUS_UNSUPPORTED)
status = upload_boxes (dst, src, boxes);
} else if (src->type == CAIRO_PATTERN_TYPE_SOLID) {
status = fill_boxes (dst, src, boxes);
}
return status;
}
if (op == CAIRO_OPERATOR_OVER && can_alpha_blend (dst))
return alpha_blend_boxes (dst, src, boxes, 255);
return CAIRO_INT_STATUS_UNSUPPORTED;
}
static cairo_status_t
opacity_boxes (cairo_composite_rectangles_t *composite,
cairo_boxes_t *boxes)
{
cairo_win32_display_surface_t *dst = to_win32_display_surface(composite->surface);
cairo_operator_t op = composite->op;
const cairo_pattern_t *src = &composite->source_pattern.base;
TRACE ((stderr, "%s\n", __FUNCTION__));
if (composite->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (boxes->num_boxes == 0 && composite->is_bounded)
return CAIRO_STATUS_SUCCESS;
if (!boxes->is_pixel_aligned)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (op != CAIRO_OPERATOR_OVER)
return CAIRO_INT_STATUS_UNSUPPORTED;
if (!can_alpha_blend (dst))
return CAIRO_INT_STATUS_UNSUPPORTED;
return alpha_blend_boxes (dst, src, boxes,
composite->mask_pattern.solid.color.alpha_short >> 8);
}
/* high-level compositor interface */
static cairo_bool_t check_blit (cairo_composite_rectangles_t *composite)
{
cairo_win32_display_surface_t *dst;
if (composite->clip->path)
return FALSE;
dst = to_win32_display_surface (composite->surface);
if (dst->fallback)
return FALSE;
if (dst->win32.format != CAIRO_FORMAT_RGB24)
return FALSE;
if (dst->win32.flags & CAIRO_WIN32_SURFACE_CAN_BITBLT)
return TRUE;
return dst->image == NULL;
}
static cairo_int_status_t
_cairo_win32_gdi_compositor_paint (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *composite)
{
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
if (check_blit (composite)) {
cairo_boxes_t boxes;
TRACE ((stderr, "%s\n", __FUNCTION__));
_cairo_clip_steal_boxes (composite->clip, &boxes);
status = draw_boxes (composite, &boxes);
_cairo_clip_unsteal_boxes (composite->clip, &boxes);
}
return status;
}
static cairo_int_status_t
_cairo_win32_gdi_compositor_mask (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *composite)
{
cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
if (check_blit (composite)) {
cairo_boxes_t boxes;
TRACE ((stderr, "%s\n", __FUNCTION__));
_cairo_clip_steal_boxes (composite->clip, &boxes);
status = opacity_boxes (composite, &boxes);
_cairo_clip_unsteal_boxes (composite->clip, &boxes);
}
return status;
}
static cairo_int_status_t
_cairo_win32_gdi_compositor_stroke (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *composite,
const cairo_path_fixed_t *path,
const cairo_stroke_style_t *style,
const cairo_matrix_t *ctm,
const cairo_matrix_t *ctm_inverse,
double tolerance,
cairo_antialias_t antialias)
{
cairo_int_status_t status;
status = CAIRO_INT_STATUS_UNSUPPORTED;
if (check_blit (composite) &&
_cairo_path_fixed_stroke_is_rectilinear (path)) {
cairo_boxes_t boxes;
TRACE ((stderr, "%s\n", __FUNCTION__));
_cairo_boxes_init_with_clip (&boxes, composite->clip);
status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
style,
ctm,
antialias,
&boxes);
if (likely (status == CAIRO_INT_STATUS_SUCCESS))
status = draw_boxes (composite, &boxes);
_cairo_boxes_fini (&boxes);
}
return status;
}
static cairo_int_status_t
_cairo_win32_gdi_compositor_fill (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t *composite,
const cairo_path_fixed_t *path,
cairo_fill_rule_t fill_rule,
double tolerance,
cairo_antialias_t antialias)
{
cairo_int_status_t status;
status = CAIRO_INT_STATUS_UNSUPPORTED;
if (check_blit (composite) &&
_cairo_path_fixed_fill_is_rectilinear (path)) {
cairo_boxes_t boxes;
TRACE ((stderr, "%s\n", __FUNCTION__));
_cairo_boxes_init_with_clip (&boxes, composite->clip);
status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
fill_rule,
antialias,
&boxes);
if (likely (status == CAIRO_INT_STATUS_SUCCESS))
status = draw_boxes (composite, &boxes);
_cairo_boxes_fini (&boxes);
}
return status;
}
static cairo_bool_t check_glyphs (cairo_composite_rectangles_t *composite,
cairo_scaled_font_t *scaled_font)
{
if (! _cairo_clip_is_region (composite->clip))
return FALSE;
if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
return FALSE;
if (! _cairo_pattern_is_opaque_solid (&composite->source_pattern.base))
return FALSE;
return (composite->op == CAIRO_OPERATOR_CLEAR ||
composite->op == CAIRO_OPERATOR_SOURCE ||
composite->op == CAIRO_OPERATOR_OVER);
}
static cairo_int_status_t
_cairo_win32_gdi_compositor_glyphs (const cairo_compositor_t *compositor,
cairo_composite_rectangles_t*composite,
cairo_scaled_font_t *scaled_font,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_bool_t overlap)
{
cairo_int_status_t status;
status = CAIRO_INT_STATUS_UNSUPPORTED;
if (check_blit (composite) && check_glyphs (composite, scaled_font)) {
cairo_win32_display_surface_t *dst = to_win32_display_surface (composite->surface);
TRACE ((stderr, "%s\n", __FUNCTION__));
status = _cairo_win32_display_surface_set_clip(dst, composite->clip);
if (status)
return status;
status = _cairo_win32_surface_emit_glyphs (&dst->win32,
&composite->source_pattern.base,
glyphs,
num_glyphs,
scaled_font,
TRUE);
_cairo_win32_display_surface_unset_clip (dst);
}
return status;
}
const cairo_compositor_t *
_cairo_win32_gdi_compositor_get (void)
{
static cairo_compositor_t compositor;
if (compositor.delegate == NULL) {
compositor.delegate = &_cairo_fallback_compositor;
compositor.paint = _cairo_win32_gdi_compositor_paint;
compositor.mask = _cairo_win32_gdi_compositor_mask;
compositor.fill = _cairo_win32_gdi_compositor_fill;
compositor.stroke = _cairo_win32_gdi_compositor_stroke;
compositor.glyphs = _cairo_win32_gdi_compositor_glyphs;
}
return &compositor;
}

View file

@ -102,36 +102,36 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend;
static const cairo_paginated_surface_backend_t cairo_win32_surface_paginated_backend;
static void
_cairo_win32_printing_surface_init_ps_mode (cairo_win32_surface_t *surface)
_cairo_win32_printing_surface_init_ps_mode (cairo_win32_printing_surface_t *surface)
{
DWORD word;
INT ps_feature, ps_level;
word = PSIDENT_GDICENTRIC;
if (ExtEscape (surface->dc, POSTSCRIPT_IDENTIFY, sizeof(DWORD), (char *)&word, 0, (char *)NULL) <= 0)
if (ExtEscape (surface->win32.dc, POSTSCRIPT_IDENTIFY, sizeof(DWORD), (char *)&word, 0, (char *)NULL) <= 0)
return;
ps_feature = FEATURESETTING_PSLEVEL;
if (ExtEscape (surface->dc, GET_PS_FEATURESETTING, sizeof(INT),
if (ExtEscape (surface->win32.dc, GET_PS_FEATURESETTING, sizeof(INT),
(char *)&ps_feature, sizeof(INT), (char *)&ps_level) <= 0)
return;
if (ps_level >= 3)
surface->flags |= CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT;
surface->win32.flags |= CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT;
}
static void
_cairo_win32_printing_surface_init_image_support (cairo_win32_surface_t *surface)
_cairo_win32_printing_surface_init_image_support (cairo_win32_printing_surface_t *surface)
{
DWORD word;
word = CHECKJPEGFORMAT;
if (ExtEscape(surface->dc, QUERYESCSUPPORT, sizeof(word), (char *)&word, 0, (char *)NULL) > 0)
surface->flags |= CAIRO_WIN32_SURFACE_CAN_CHECK_JPEG;
if (ExtEscape(surface->win32.dc, QUERYESCSUPPORT, sizeof(word), (char *)&word, 0, (char *)NULL) > 0)
surface->win32.flags |= CAIRO_WIN32_SURFACE_CAN_CHECK_JPEG;
word = CHECKPNGFORMAT;
if (ExtEscape(surface->dc, QUERYESCSUPPORT, sizeof(word), (char *)&word, 0, (char *)NULL) > 0)
surface->flags |= CAIRO_WIN32_SURFACE_CAN_CHECK_PNG;
if (ExtEscape(surface->win32.dc, QUERYESCSUPPORT, sizeof(word), (char *)&word, 0, (char *)NULL) > 0)
surface->win32.flags |= CAIRO_WIN32_SURFACE_CAN_CHECK_PNG;
}
/* When creating an EMF file, ExtTextOut with ETO_GLYPH_INDEX does not
@ -152,7 +152,7 @@ _cairo_win32_printing_surface_init_image_support (cairo_win32_surface_t *surface
* and argument 0.
*/
static void
_cairo_win32_printing_surface_init_language_pack (cairo_win32_surface_t *surface)
_cairo_win32_printing_surface_init_language_pack (cairo_win32_printing_surface_t *surface)
{
typedef BOOL (WINAPI *gdi_init_lang_pack_func_t)(int);
gdi_init_lang_pack_func_t gdi_init_lang_pack;
@ -219,7 +219,7 @@ surface_pattern_supported (const cairo_surface_pattern_t *pattern)
}
static cairo_bool_t
pattern_supported (cairo_win32_surface_t *surface, const cairo_pattern_t *pattern)
pattern_supported (cairo_win32_printing_surface_t *surface, const cairo_pattern_t *pattern)
{
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID)
return TRUE;
@ -228,13 +228,13 @@ pattern_supported (cairo_win32_surface_t *surface, const cairo_pattern_t *patter
return surface_pattern_supported ((const cairo_surface_pattern_t *) pattern);
if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR)
return surface->flags & CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT;
return surface->win32.flags & CAIRO_WIN32_SURFACE_CAN_RECT_GRADIENT;
return FALSE;
}
static cairo_int_status_t
_cairo_win32_printing_surface_analyze_operation (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_analyze_operation (cairo_win32_printing_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
{
@ -280,7 +280,7 @@ _cairo_win32_printing_surface_analyze_operation (cairo_win32_surface_t *surface,
}
static cairo_bool_t
_cairo_win32_printing_surface_operation_supported (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_operation_supported (cairo_win32_printing_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *pattern)
{
@ -291,7 +291,7 @@ _cairo_win32_printing_surface_operation_supported (cairo_win32_surface_t *surfac
}
static void
_cairo_win32_printing_surface_init_clear_color (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_init_clear_color (cairo_win32_printing_surface_t *surface,
cairo_solid_pattern_t *color)
{
if (surface->content == CAIRO_CONTENT_COLOR_ALPHA)
@ -301,7 +301,7 @@ _cairo_win32_printing_surface_init_clear_color (cairo_win32_surface_t *surface,
}
static COLORREF
_cairo_win32_printing_surface_flatten_transparency (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_flatten_transparency (cairo_win32_printing_surface_t *surface,
const cairo_color_t *color)
{
COLORREF c;
@ -332,7 +332,7 @@ _cairo_win32_printing_surface_flatten_transparency (cairo_win32_surface_t *surfa
}
static cairo_status_t
_cairo_win32_printing_surface_select_solid_brush (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_select_solid_brush (cairo_win32_printing_surface_t *surface,
const cairo_pattern_t *source)
{
cairo_solid_pattern_t *pattern = (cairo_solid_pattern_t *) source;
@ -343,59 +343,59 @@ _cairo_win32_printing_surface_select_solid_brush (cairo_win32_surface_t *surface
surface->brush = CreateSolidBrush (color);
if (!surface->brush)
return _cairo_win32_print_gdi_error ("_cairo_win32_surface_select_solid_brush(CreateSolidBrush)");
surface->old_brush = SelectObject (surface->dc, surface->brush);
surface->old_brush = SelectObject (surface->win32.dc, surface->brush);
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_win32_printing_surface_done_solid_brush (cairo_win32_surface_t *surface)
_cairo_win32_printing_surface_done_solid_brush (cairo_win32_printing_surface_t *surface)
{
if (surface->old_brush) {
SelectObject (surface->dc, surface->old_brush);
SelectObject (surface->win32.dc, surface->old_brush);
DeleteObject (surface->brush);
surface->old_brush = NULL;
}
}
static cairo_status_t
_cairo_win32_printing_surface_get_ctm_clip_box (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_get_ctm_clip_box (cairo_win32_printing_surface_t *surface,
RECT *clip)
{
XFORM xform;
_cairo_matrix_to_win32_xform (&surface->ctm, &xform);
if (!ModifyWorldTransform (surface->dc, &xform, MWT_LEFTMULTIPLY))
if (!ModifyWorldTransform (surface->win32.dc, &xform, MWT_LEFTMULTIPLY))
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_get_clip_box:ModifyWorldTransform");
GetClipBox (surface->dc, clip);
GetClipBox (surface->win32.dc, clip);
_cairo_matrix_to_win32_xform (&surface->gdi_ctm, &xform);
if (!SetWorldTransform (surface->dc, &xform))
if (!SetWorldTransform (surface->win32.dc, &xform))
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_get_clip_box:SetWorldTransform");
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_win32_printing_surface_paint_solid_pattern (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_paint_solid_pattern (cairo_win32_printing_surface_t *surface,
const cairo_pattern_t *pattern)
{
RECT clip;
cairo_status_t status;
GetClipBox (surface->dc, &clip);
GetClipBox (surface->win32.dc, &clip);
status = _cairo_win32_printing_surface_select_solid_brush (surface, pattern);
if (status)
return status;
FillRect (surface->dc, &clip, surface->brush);
FillRect (surface->win32.dc, &clip, surface->brush);
_cairo_win32_printing_surface_done_solid_brush (surface);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_win32_printing_surface_paint_recording_pattern (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_paint_recording_pattern (cairo_win32_printing_surface_t *surface,
cairo_surface_pattern_t *pattern)
{
cairo_content_t old_content;
@ -422,7 +422,7 @@ _cairo_win32_printing_surface_paint_recording_pattern (cairo_win32_surface_t *
old_has_ctm = surface->has_ctm;
cairo_matrix_multiply (&p2d, &p2d, &surface->ctm);
surface->ctm = p2d;
SaveDC (surface->dc);
SaveDC (surface->win32.dc);
_cairo_matrix_to_win32_xform (&p2d, &xform);
status = _cairo_recording_surface_get_bbox (recording_surface, &bbox, NULL);
@ -461,7 +461,7 @@ _cairo_win32_printing_surface_paint_recording_pattern (cairo_win32_surface_t *
cairo_matrix_t m;
double x, y;
SaveDC (surface->dc);
SaveDC (surface->win32.dc);
m = p2d;
cairo_matrix_translate (&m,
x_tile*recording_extents.width,
@ -480,39 +480,39 @@ _cairo_win32_printing_surface_paint_recording_pattern (cairo_win32_surface_t *
surface->has_ctm = !_cairo_matrix_is_identity (&surface->ctm);
/* Set clip path around bbox of the pattern. */
BeginPath (surface->dc);
BeginPath (surface->win32.dc);
x = 0;
y = 0;
cairo_matrix_transform_point (&surface->ctm, &x, &y);
MoveToEx (surface->dc, (int) x, (int) y, NULL);
MoveToEx (surface->win32.dc, (int) x, (int) y, NULL);
x = recording_extents.width;
y = 0;
cairo_matrix_transform_point (&surface->ctm, &x, &y);
LineTo (surface->dc, (int) x, (int) y);
LineTo (surface->win32.dc, (int) x, (int) y);
x = recording_extents.width;
y = recording_extents.height;
cairo_matrix_transform_point (&surface->ctm, &x, &y);
LineTo (surface->dc, (int) x, (int) y);
LineTo (surface->win32.dc, (int) x, (int) y);
x = 0;
y = recording_extents.height;
cairo_matrix_transform_point (&surface->ctm, &x, &y);
LineTo (surface->dc, (int) x, (int) y);
LineTo (surface->win32.dc, (int) x, (int) y);
CloseFigure (surface->dc);
EndPath (surface->dc);
SelectClipPath (surface->dc, RGN_AND);
CloseFigure (surface->win32.dc);
EndPath (surface->win32.dc);
SelectClipPath (surface->win32.dc, RGN_AND);
SaveDC (surface->dc); /* Allow clip path to be reset during replay */
SaveDC (surface->win32.dc); /* Allow clip path to be reset during replay */
status = _cairo_recording_surface_replay_region (&recording_surface->base, NULL,
&surface->base,
&surface->win32.base,
CAIRO_RECORDING_REGION_NATIVE);
assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
/* Restore both the clip save and our earlier path SaveDC */
RestoreDC (surface->dc, -2);
RestoreDC (surface->win32.dc, -2);
if (status)
return status;
@ -522,13 +522,13 @@ _cairo_win32_printing_surface_paint_recording_pattern (cairo_win32_surface_t *
surface->content = old_content;
surface->ctm = old_ctm;
surface->has_ctm = old_has_ctm;
RestoreDC (surface->dc, -1);
RestoreDC (surface->win32.dc, -1);
return status;
}
static cairo_int_status_t
_cairo_win32_printing_surface_check_jpeg (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_check_jpeg (cairo_win32_printing_surface_t *surface,
cairo_surface_t *source,
const unsigned char **data,
unsigned long *length,
@ -539,7 +539,7 @@ _cairo_win32_printing_surface_check_jpeg (cairo_win32_surface_t *surface,
cairo_int_status_t status;
DWORD result;
if (!(surface->flags & CAIRO_WIN32_SURFACE_CAN_CHECK_JPEG))
if (!(surface->win32.flags & CAIRO_WIN32_SURFACE_CAN_CHECK_JPEG))
return CAIRO_INT_STATUS_UNSUPPORTED;
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
@ -552,7 +552,7 @@ _cairo_win32_printing_surface_check_jpeg (cairo_win32_surface_t *surface,
return status;
result = 0;
if (ExtEscape(surface->dc, CHECKJPEGFORMAT, mime_data_length, (char *) mime_data,
if (ExtEscape(surface->win32.dc, CHECKJPEGFORMAT, mime_data_length, (char *) mime_data,
sizeof(result), (char *) &result) <= 0)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -566,7 +566,7 @@ _cairo_win32_printing_surface_check_jpeg (cairo_win32_surface_t *surface,
}
static cairo_int_status_t
_cairo_win32_printing_surface_check_png (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_check_png (cairo_win32_printing_surface_t *surface,
cairo_surface_t *source,
const unsigned char **data,
unsigned long *length,
@ -578,7 +578,7 @@ _cairo_win32_printing_surface_check_png (cairo_win32_surface_t *surface,
cairo_int_status_t status;
DWORD result;
if (!(surface->flags & CAIRO_WIN32_SURFACE_CAN_CHECK_PNG))
if (!(surface->win32.flags & CAIRO_WIN32_SURFACE_CAN_CHECK_PNG))
return CAIRO_INT_STATUS_UNSUPPORTED;
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_PNG,
@ -591,7 +591,7 @@ _cairo_win32_printing_surface_check_png (cairo_win32_surface_t *surface,
return status;
result = 0;
if (ExtEscape(surface->dc, CHECKPNGFORMAT, mime_data_length, (char *) mime_data,
if (ExtEscape(surface->win32.dc, CHECKPNGFORMAT, mime_data_length, (char *) mime_data,
sizeof(result), (char *) &result) <= 0)
return CAIRO_INT_STATUS_UNSUPPORTED;
@ -605,7 +605,7 @@ _cairo_win32_printing_surface_check_png (cairo_win32_surface_t *surface,
}
static cairo_status_t
_cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_paint_image_pattern (cairo_win32_printing_surface_t *surface,
cairo_surface_pattern_t *pattern)
{
cairo_status_t status;
@ -629,7 +629,7 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
/* If we can't use StretchDIBits with this surface, we can't do anything
* here.
*/
if (!(surface->flags & CAIRO_WIN32_SURFACE_CAN_STRETCHDIB))
if (!(surface->win32.flags & CAIRO_WIN32_SURFACE_CAN_STRETCHDIB))
return CAIRO_INT_STATUS_UNSUPPORTED;
if (surface->content == CAIRO_CONTENT_COLOR_ALPHA)
@ -727,17 +727,17 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
assert (status == CAIRO_STATUS_SUCCESS);
cairo_matrix_multiply (&m, &m, &surface->gdi_ctm);
SaveDC (surface->dc);
SaveDC (surface->win32.dc);
_cairo_matrix_to_win32_xform (&m, &xform);
if (! SetWorldTransform (surface->dc, &xform)) {
if (! SetWorldTransform (surface->win32.dc, &xform)) {
status = _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint_image_pattern");
goto CLEANUP_OPAQUE_IMAGE;
}
oldmode = SetStretchBltMode(surface->dc, HALFTONE);
oldmode = SetStretchBltMode(surface->win32.dc, HALFTONE);
GetClipBox (surface->dc, &clip);
GetClipBox (surface->win32.dc, &clip);
if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) {
left = floor ( clip.left / (double) opaque_image->width);
right = ceil (clip.right / (double) opaque_image->width);
@ -752,7 +752,7 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
for (y_tile = top; y_tile < bottom; y_tile++) {
for (x_tile = left; x_tile < right; x_tile++) {
if (!StretchDIBits (surface->dc,
if (!StretchDIBits (surface->win32.dc,
x_tile*opaque_image->width,
y_tile*opaque_image->height,
opaque_image->width,
@ -771,8 +771,8 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf
}
}
}
SetStretchBltMode(surface->dc, oldmode);
RestoreDC (surface->dc, -1);
SetStretchBltMode(surface->win32.dc, oldmode);
RestoreDC (surface->win32.dc, -1);
CLEANUP_OPAQUE_IMAGE:
if (opaque_image != image)
@ -784,7 +784,7 @@ CLEANUP_IMAGE:
}
static cairo_status_t
_cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_paint_surface_pattern (cairo_win32_printing_surface_t *surface,
cairo_surface_pattern_t *pattern)
{
if (_cairo_surface_is_recording (pattern->surface)) {
@ -809,7 +809,7 @@ vertex_set_color (TRIVERTEX *vert, cairo_color_stop_t *color)
}
static cairo_int_status_t
_cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_printing_surface_t *surface,
cairo_linear_pattern_t *pattern)
{
TRIVERTEX *vert;
@ -825,7 +825,7 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
cairo_status_t status;
extend = cairo_pattern_get_extend (&pattern->base.base);
SaveDC (surface->dc);
SaveDC (surface->win32.dc);
mat = pattern->base.base.matrix;
status = cairo_matrix_invert (&mat);
@ -853,10 +853,10 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
_cairo_matrix_to_win32_xform (&mat, &xform);
if (!SetWorldTransform (surface->dc, &xform))
if (!SetWorldTransform (surface->win32.dc, &xform))
return _cairo_win32_print_gdi_error ("_win32_printing_surface_paint_linear_pattern:SetWorldTransform2");
GetClipBox (surface->dc, &clip);
GetClipBox (surface->win32.dc, &clip);
if (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT) {
range_start = floor (clip.left / d);
@ -939,7 +939,7 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
total_rects += 2;
}
if (!GradientFill (surface->dc,
if (!GradientFill (surface->win32.dc,
vert, total_verts,
rect, total_rects,
GRADIENT_FILL_RECT_H))
@ -947,13 +947,13 @@ _cairo_win32_printing_surface_paint_linear_pattern (cairo_win32_surface_t *surfa
free (rect);
free (vert);
RestoreDC (surface->dc, -1);
RestoreDC (surface->win32.dc, -1);
return 0;
}
static cairo_int_status_t
_cairo_win32_printing_surface_paint_pattern (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_paint_pattern (cairo_win32_printing_surface_t *surface,
const cairo_pattern_t *pattern)
{
cairo_status_t status;
@ -990,7 +990,7 @@ _cairo_win32_printing_surface_paint_pattern (cairo_win32_surface_t *surface,
}
typedef struct _win32_print_path_info {
cairo_win32_surface_t *surface;
cairo_win32_printing_surface_t *surface;
} win32_path_info_t;
static cairo_status_t
@ -1005,9 +1005,9 @@ _cairo_win32_printing_surface_path_move_to (void *closure,
x = _cairo_fixed_to_double (point->x);
y = _cairo_fixed_to_double (point->y);
cairo_matrix_transform_point (&path_info->surface->ctm, &x, &y);
MoveToEx (path_info->surface->dc, (int) x, (int) y, NULL);
MoveToEx (path_info->surface->win32.dc, (int) x, (int) y, NULL);
} else {
MoveToEx (path_info->surface->dc,
MoveToEx (path_info->surface->win32.dc,
_cairo_fixed_integer_part (point->x),
_cairo_fixed_integer_part (point->y),
NULL);
@ -1029,9 +1029,9 @@ _cairo_win32_printing_surface_path_line_to (void *closure,
x = _cairo_fixed_to_double (point->x);
y = _cairo_fixed_to_double (point->y);
cairo_matrix_transform_point (&path_info->surface->ctm, &x, &y);
LineTo (path_info->surface->dc, (int) x, (int) y);
LineTo (path_info->surface->win32.dc, (int) x, (int) y);
} else {
LineTo (path_info->surface->dc,
LineTo (path_info->surface->win32.dc,
_cairo_fixed_integer_part (point->x),
_cairo_fixed_integer_part (point->y));
}
@ -1077,7 +1077,7 @@ _cairo_win32_printing_surface_path_curve_to (void *closure,
points[2].x = _cairo_fixed_integer_part (d->x);
points[2].y = _cairo_fixed_integer_part (d->y);
}
PolyBezierTo (path_info->surface->dc, points, 3);
PolyBezierTo (path_info->surface->win32.dc, points, 3);
return CAIRO_STATUS_SUCCESS;
}
@ -1087,13 +1087,13 @@ _cairo_win32_printing_surface_path_close_path (void *closure)
{
win32_path_info_t *path_info = closure;
CloseFigure (path_info->surface->dc);
CloseFigure (path_info->surface->win32.dc);
return CAIRO_STATUS_SUCCESS;
}
static cairo_status_t
_cairo_win32_printing_surface_emit_path (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_emit_path (cairo_win32_printing_surface_t *surface,
const cairo_path_fixed_t *path)
{
win32_path_info_t path_info;
@ -1110,10 +1110,10 @@ _cairo_win32_printing_surface_emit_path (cairo_win32_surface_t *surface,
static cairo_int_status_t
_cairo_win32_printing_surface_show_page (void *abstract_surface)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_win32_printing_surface_t *surface = abstract_surface;
/* Undo both SaveDC's that we did in start_page */
RestoreDC (surface->dc, -2);
RestoreDC (surface->win32.dc, -2);
return CAIRO_STATUS_SUCCESS;
}
@ -1125,8 +1125,8 @@ _cairo_win32_printing_surface_clipper_intersect_clip_path (cairo_surface_clipper
double tolerance,
cairo_antialias_t antialias)
{
cairo_win32_surface_t *surface = cairo_container_of (clipper,
cairo_win32_surface_t,
cairo_win32_printing_surface_t *surface = cairo_container_of (clipper,
cairo_win32_printing_surface_t,
clipper);
cairo_status_t status;
@ -1134,28 +1134,28 @@ _cairo_win32_printing_surface_clipper_intersect_clip_path (cairo_surface_clipper
return CAIRO_STATUS_SUCCESS;
if (path == NULL) {
RestoreDC (surface->dc, -1);
SaveDC (surface->dc);
RestoreDC (surface->win32.dc, -1);
SaveDC (surface->win32.dc);
return CAIRO_STATUS_SUCCESS;
}
BeginPath (surface->dc);
BeginPath (surface->win32.dc);
status = _cairo_win32_printing_surface_emit_path (surface, path);
EndPath (surface->dc);
EndPath (surface->win32.dc);
switch (fill_rule) {
case CAIRO_FILL_RULE_WINDING:
SetPolyFillMode (surface->dc, WINDING);
SetPolyFillMode (surface->win32.dc, WINDING);
break;
case CAIRO_FILL_RULE_EVEN_ODD:
SetPolyFillMode (surface->dc, ALTERNATE);
SetPolyFillMode (surface->win32.dc, ALTERNATE);
break;
default:
ASSERT_NOT_REACHED;
}
SelectClipPath (surface->dc, RGN_AND);
SelectClipPath (surface->win32.dc, RGN_AND);
return status;
}
@ -1178,7 +1178,7 @@ _cairo_win32_printing_surface_paint (void *abstract_surface,
const cairo_pattern_t *source,
const cairo_clip_t *clip)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_win32_printing_surface_t *surface = abstract_surface;
cairo_solid_pattern_t clear;
cairo_status_t status;
@ -1261,7 +1261,7 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
cairo_antialias_t antialias,
const cairo_clip_t *clip)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_win32_printing_surface_t *surface = abstract_surface;
cairo_int_status_t status;
HPEN pen;
LOGBRUSH brush;
@ -1311,7 +1311,7 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
pen_style |= PS_SOLID;
}
SetMiterLimit (surface->dc, (FLOAT) (style->miter_limit), NULL);
SetMiterLimit (surface->win32.dc, (FLOAT) (style->miter_limit), NULL);
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source;
@ -1334,43 +1334,43 @@ _cairo_win32_printing_surface_stroke (void *abstract_surface,
dash_array);
if (pen == NULL)
return _cairo_win32_print_gdi_error ("_win32_surface_stroke:ExtCreatePen");
obj = SelectObject (surface->dc, pen);
obj = SelectObject (surface->win32.dc, pen);
if (obj == NULL)
return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectObject");
BeginPath (surface->dc);
BeginPath (surface->win32.dc);
status = _cairo_win32_printing_surface_emit_path (surface, path);
EndPath (surface->dc);
EndPath (surface->win32.dc);
if (status)
return status;
/*
* Switch to user space to set line parameters
*/
SaveDC (surface->dc);
SaveDC (surface->win32.dc);
_cairo_matrix_to_win32_xform (&mat, &xform);
xform.eDx = 0.0f;
xform.eDy = 0.0f;
if (!ModifyWorldTransform (surface->dc, &xform, MWT_LEFTMULTIPLY))
if (!ModifyWorldTransform (surface->win32.dc, &xform, MWT_LEFTMULTIPLY))
return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SetWorldTransform");
if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
StrokePath (surface->dc);
StrokePath (surface->win32.dc);
} else {
if (!WidenPath (surface->dc))
if (!WidenPath (surface->win32.dc))
return _cairo_win32_print_gdi_error ("_win32_surface_stroke:WidenPath");
if (!SelectClipPath (surface->dc, RGN_AND))
if (!SelectClipPath (surface->win32.dc, RGN_AND))
return _cairo_win32_print_gdi_error ("_win32_surface_stroke:SelectClipPath");
/* Return to device space to paint the pattern */
_cairo_matrix_to_win32_xform (&surface->gdi_ctm, &xform);
if (!SetWorldTransform (surface->dc, &xform))
if (!SetWorldTransform (surface->win32.dc, &xform))
return _cairo_win32_print_gdi_error ("_win32_surface_stroke:ModifyWorldTransform");
status = _cairo_win32_printing_surface_paint_pattern (surface, source);
}
RestoreDC (surface->dc, -1);
RestoreDC (surface->win32.dc, -1);
DeleteObject (pen);
free (dash_array);
@ -1387,7 +1387,7 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
cairo_antialias_t antialias,
const cairo_clip_t *clip)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_win32_printing_surface_t *surface = abstract_surface;
cairo_int_status_t status;
cairo_solid_pattern_t clear;
@ -1407,16 +1407,16 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
assert (_cairo_win32_printing_surface_operation_supported (surface, op, source));
surface->path_empty = TRUE;
BeginPath (surface->dc);
BeginPath (surface->win32.dc);
status = _cairo_win32_printing_surface_emit_path (surface, path);
EndPath (surface->dc);
EndPath (surface->win32.dc);
switch (fill_rule) {
case CAIRO_FILL_RULE_WINDING:
SetPolyFillMode (surface->dc, WINDING);
SetPolyFillMode (surface->win32.dc, WINDING);
break;
case CAIRO_FILL_RULE_EVEN_ODD:
SetPolyFillMode (surface->dc, ALTERNATE);
SetPolyFillMode (surface->win32.dc, ALTERNATE);
break;
default:
ASSERT_NOT_REACHED;
@ -1427,13 +1427,13 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
if (status)
return status;
FillPath (surface->dc);
FillPath (surface->win32.dc);
_cairo_win32_printing_surface_done_solid_brush (surface);
} else if (surface->path_empty == FALSE) {
SaveDC (surface->dc);
SelectClipPath (surface->dc, RGN_AND);
SaveDC (surface->win32.dc);
SelectClipPath (surface->win32.dc, RGN_AND);
status = _cairo_win32_printing_surface_paint_pattern (surface, source);
RestoreDC (surface->dc, -1);
RestoreDC (surface->win32.dc, -1);
}
fflush(stderr);
@ -1441,13 +1441,14 @@ _cairo_win32_printing_surface_fill (void *abstract_surface,
return status;
}
static cairo_int_status_t
_cairo_win32_printing_surface_emit_win32_glyphs (cairo_win32_surface_t *surface,
_cairo_win32_printing_surface_emit_win32_glyphs (cairo_win32_printing_surface_t *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip)
{
cairo_matrix_t ctm;
@ -1502,15 +1503,12 @@ _cairo_win32_printing_surface_emit_win32_glyphs (cairo_win32_surface_t *surface
if (i == num_glyphs - 1 ||
((unicode_glyphs[i + 1].index < 0xffff) != sequence_is_unicode))
{
status = _cairo_win32_surface_show_glyphs_internal (
surface,
op,
source,
sequence_is_unicode ? &unicode_glyphs[first] : &glyphs[first],
i - first + 1,
scaled_font,
clip,
! sequence_is_unicode);
status = _cairo_win32_surface_emit_glyphs (&surface->win32,
source,
sequence_is_unicode ? &unicode_glyphs[first] : &glyphs[first],
i - first + 1,
scaled_font,
! sequence_is_unicode);
first = i + 1;
if (i < num_glyphs - 1)
sequence_is_unicode = unicode_glyphs[i + 1].index <= 0xffff;
@ -1536,7 +1534,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_win32_printing_surface_t *surface = abstract_surface;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_scaled_glyph_t *scaled_glyph;
cairo_pattern_t *opaque = NULL;
@ -1620,12 +1618,12 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
}
#endif
SaveDC (surface->dc);
SaveDC (surface->win32.dc);
old_ctm = surface->ctm;
old_has_ctm = surface->has_ctm;
surface->has_ctm = TRUE;
surface->path_empty = TRUE;
BeginPath (surface->dc);
BeginPath (surface->win32.dc);
for (i = 0; i < num_glyphs; i++) {
status = _cairo_scaled_glyph_lookup (scaled_font,
glyphs[i].index,
@ -1637,7 +1635,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
cairo_matrix_translate (&surface->ctm, glyphs[i].x, glyphs[i].y);
status = _cairo_win32_printing_surface_emit_path (surface, scaled_glyph->path);
}
EndPath (surface->dc);
EndPath (surface->win32.dc);
surface->ctm = old_ctm;
surface->has_ctm = old_has_ctm;
if (status == CAIRO_STATUS_SUCCESS && surface->path_empty == FALSE) {
@ -1646,15 +1644,15 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac
if (status)
return status;
SetPolyFillMode (surface->dc, WINDING);
FillPath (surface->dc);
SetPolyFillMode (surface->win32.dc, WINDING);
FillPath (surface->win32.dc);
_cairo_win32_printing_surface_done_solid_brush (surface);
} else {
SelectClipPath (surface->dc, RGN_AND);
SelectClipPath (surface->win32.dc, RGN_AND);
status = _cairo_win32_printing_surface_paint_pattern (surface, source);
}
}
RestoreDC (surface->dc, -1);
RestoreDC (surface->win32.dc, -1);
if (opaque)
cairo_pattern_destroy (opaque);
@ -1668,6 +1666,17 @@ _cairo_win32_printing_surface_get_supported_mime_types (void *abstract_surface
return _cairo_win32_printing_supported_mime_types;
}
static cairo_status_t
_cairo_win32_printing_surface_finish (void *abstract_surface)
{
cairo_win32_printing_surface_t *surface = abstract_surface;
if (surface->font_subsets != NULL)
_cairo_scaled_font_subsets_destroy (surface->font_subsets);
return CAIRO_STATUS_SUCCESS;
}
static cairo_surface_t *
_cairo_win32_printing_surface_create_similar (void *abstract_surface,
cairo_content_t content,
@ -1685,13 +1694,13 @@ _cairo_win32_printing_surface_create_similar (void *abstract_surface,
static cairo_int_status_t
_cairo_win32_printing_surface_start_page (void *abstract_surface)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_win32_printing_surface_t *surface = abstract_surface;
XFORM xform;
double x_res, y_res;
cairo_matrix_t inverse_ctm;
cairo_status_t status;
SaveDC (surface->dc); /* Save application context first, before doing MWT */
SaveDC (surface->win32.dc); /* Save application context first, before doing MWT */
/* As the logical coordinates used by GDI functions (eg LineTo)
* are integers we need to do some additional work to prevent
@ -1730,8 +1739,8 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
* To support allowing the user to set a GDI CTM with scale < 1,
* we avoid switching to an identity CTM if the CTM xx and yy is < 1.
*/
SetGraphicsMode (surface->dc, GM_ADVANCED);
GetWorldTransform(surface->dc, &xform);
SetGraphicsMode (surface->win32.dc, GM_ADVANCED);
GetWorldTransform(surface->win32.dc, &xform);
if (xform.eM11 < 1 && xform.eM22 < 1) {
cairo_matrix_init_identity (&surface->ctm);
surface->gdi_ctm.xx = xform.eM11;
@ -1748,7 +1757,7 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
surface->ctm.x0 = xform.eDx;
surface->ctm.y0 = xform.eDy;
cairo_matrix_init_identity (&surface->gdi_ctm);
if (!ModifyWorldTransform (surface->dc, NULL, MWT_IDENTITY))
if (!ModifyWorldTransform (surface->win32.dc, NULL, MWT_IDENTITY))
return _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_start_page:ModifyWorldTransform");
}
@ -1759,12 +1768,12 @@ _cairo_win32_printing_surface_start_page (void *abstract_surface)
if (status)
return status;
x_res = GetDeviceCaps (surface->dc, LOGPIXELSX);
y_res = GetDeviceCaps (surface->dc, LOGPIXELSY);
x_res = GetDeviceCaps (surface->win32.dc, LOGPIXELSX);
y_res = GetDeviceCaps (surface->win32.dc, LOGPIXELSY);
cairo_matrix_transform_distance (&inverse_ctm, &x_res, &y_res);
_cairo_surface_set_resolution (&surface->base, x_res, y_res);
_cairo_surface_set_resolution (&surface->win32.base, x_res, y_res);
SaveDC (surface->dc); /* Then save Cairo's known-good clip state, so the clip path can be reset */
SaveDC (surface->win32.dc); /* Then save Cairo's known-good clip state, so the clip path can be reset */
return CAIRO_STATUS_SUCCESS;
}
@ -1773,7 +1782,7 @@ static void
_cairo_win32_printing_surface_set_paginated_mode (void *abstract_surface,
cairo_paginated_mode_t paginated_mode)
{
cairo_win32_surface_t *surface = abstract_surface;
cairo_win32_printing_surface_t *surface = abstract_surface;
surface->paginated_mode = paginated_mode;
}
@ -1805,30 +1814,29 @@ _cairo_win32_printing_surface_supports_fine_grained_fallbacks (void *abstract_su
cairo_surface_t *
cairo_win32_printing_surface_create (HDC hdc)
{
cairo_win32_surface_t *surface;
cairo_win32_printing_surface_t *surface;
cairo_surface_t *paginated;
RECT rect;
surface = malloc (sizeof (cairo_win32_surface_t));
surface = malloc (sizeof (cairo_win32_printing_surface_t));
if (surface == NULL)
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
#if 0
if (_cairo_win32_save_initial_clip (hdc, surface) != CAIRO_STATUS_SUCCESS) {
free (surface);
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
#endif
_cairo_surface_clipper_init (&surface->clipper,
_cairo_win32_printing_surface_clipper_intersect_clip_path);
surface->image = NULL;
surface->format = CAIRO_FORMAT_RGB24;
surface->content = CAIRO_CONTENT_COLOR_ALPHA;
surface->win32.format = CAIRO_FORMAT_RGB24;
surface->win32.base.content = CAIRO_CONTENT_COLOR_ALPHA;
surface->win32.dc = hdc;
surface->dc = hdc;
surface->bitmap = NULL;
surface->is_dib = FALSE;
surface->saved_dc_bitmap = NULL;
surface->brush = NULL;
surface->old_brush = NULL;
surface->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
@ -1838,41 +1846,35 @@ cairo_win32_printing_surface_create (HDC hdc)
}
GetClipBox(hdc, &rect);
surface->extents.x = rect.left;
surface->extents.y = rect.top;
surface->extents.width = rect.right - rect.left;
surface->extents.height = rect.bottom - rect.top;
surface->win32.extents.x = rect.left;
surface->win32.extents.y = rect.top;
surface->win32.extents.width = rect.right - rect.left;
surface->win32.extents.height = rect.bottom - rect.top;
surface->flags = _cairo_win32_flags_for_dc (surface->dc);
surface->flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING;
surface->win32.flags = _cairo_win32_flags_for_dc (surface->win32.dc);
surface->win32.flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING;
_cairo_win32_printing_surface_init_ps_mode (surface);
_cairo_win32_printing_surface_init_image_support (surface);
_cairo_win32_printing_surface_init_language_pack (surface);
_cairo_surface_init (&surface->base,
_cairo_surface_init (&surface->win32.base,
&cairo_win32_printing_surface_backend,
NULL, /* device */
CAIRO_CONTENT_COLOR_ALPHA);
paginated = _cairo_paginated_surface_create (&surface->base,
paginated = _cairo_paginated_surface_create (&surface->win32.base,
CAIRO_CONTENT_COLOR_ALPHA,
&cairo_win32_surface_paginated_backend);
/* paginated keeps the only reference to surface now, drop ours */
cairo_surface_destroy (&surface->base);
cairo_surface_destroy (&surface->win32.base);
return paginated;
}
cairo_bool_t
_cairo_surface_is_win32_printing (cairo_surface_t *surface)
{
return surface->backend == &cairo_win32_printing_surface_backend;
}
static const cairo_surface_backend_t cairo_win32_printing_surface_backend = {
CAIRO_SURFACE_TYPE_WIN32_PRINTING,
_cairo_win32_surface_finish,
_cairo_win32_printing_surface_finish,
_cairo_default_context_create,

View file

@ -37,8 +37,12 @@
#define CAIRO_WIN32_PRIVATE_H
#include "cairo-win32.h"
#include "cairoint.h"
#include "cairo-device-private.h"
#include "cairo-surface-clipper-private.h"
#include "cairo-surface-private.h"
#ifndef SHADEBLENDCAPS
#define SHADEBLENDCAPS 120
@ -49,68 +53,6 @@
#define WIN32_FONT_LOGICAL_SCALE 32
typedef struct _cairo_win32_surface {
cairo_surface_t base;
cairo_format_t format;
HDC dc;
/* We create off-screen surfaces as DIBs or DDBs, based on what we created
* originally*/
HBITMAP bitmap;
cairo_bool_t is_dib;
/* Used to save the initial 1x1 monochrome bitmap for the DC to
* select back into the DC before deleting the DC and our
* bitmap. For Windows XP, this doesn't seem to be necessary
* ... we can just delete the DC and that automatically unselects
* out bitmap. But it's standard practice so apparently is needed
* on some versions of Windows.
*/
HBITMAP saved_dc_bitmap;
cairo_surface_t *image;
/* We use the x and y parts of extents for situations where
* we're not supposed to draw to the entire surface.
* For example, during a paint event a program will get
* a DC that has been clipped to the dirty region.
* A cairo surface constructed for that DC will have extents
* that match bounds of the clipped region.
*
* jrmuizel: I'm not sure if storing these extents instead
* of just using the size is better... */
cairo_rectangle_int_t extents;
/* Initial clip bits
* We need these kept around so that we maintain
* whatever clip was set on the original DC at creation
* time when cairo is asked to reset the surface clip.
*/
cairo_rectangle_int_t clip_rect;
HRGN initial_clip_rgn;
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 */
uint32_t flags;
/* printing surface bits */
cairo_paginated_mode_t paginated_mode;
cairo_content_t content;
cairo_bool_t path_empty;
cairo_bool_t has_ctm;
cairo_matrix_t ctm;
cairo_bool_t has_gdi_ctm;
cairo_matrix_t gdi_ctm;
HBRUSH brush, old_brush;
cairo_scaled_font_subsets_t *font_subsets;
} cairo_win32_surface_t;
/* Surface DC flag values */
enum {
/* If this is a surface created for printing or not */
@ -141,17 +83,102 @@ enum {
CAIRO_WIN32_SURFACE_CAN_CHECK_PNG = (1<<8),
};
typedef struct _cairo_win32_surface {
cairo_surface_t base;
cairo_format_t format;
HDC dc;
/* Surface DC flags */
unsigned flags;
/* We use the x and y parts of extents for situations where
* we're not supposed to draw to the entire surface.
* For example, during a paint event a program will get
* a DC that has been clipped to the dirty region.
* A cairo surface constructed for that DC will have extents
* that match bounds of the clipped region.
*/
cairo_rectangle_int_t extents;
} cairo_win32_surface_t;
#define to_win32_surface(S) ((cairo_win32_surface_t *)(S))
typedef struct _cairo_win32_display_surface {
cairo_win32_surface_t win32;
/* We create off-screen surfaces as DIBs or DDBs, based on what we created
* originally*/
HBITMAP bitmap;
cairo_bool_t is_dib;
/* Used to save the initial 1x1 monochrome bitmap for the DC to
* select back into the DC before deleting the DC and our
* bitmap. For Windows XP, this doesn't seem to be necessary
* ... we can just delete the DC and that automatically unselects
* out bitmap. But it's standard practice so apparently is needed
* on some versions of Windows.
*/
HBITMAP saved_dc_bitmap;
cairo_surface_t *image;
cairo_surface_t *fallback;
HRGN initial_clip_rgn;
cairo_bool_t had_simple_clip;
} cairo_win32_display_surface_t;
#define to_win32_display_surface(S) ((cairo_win32_display_surface_t *)(S))
typedef struct _cairo_win32_printing_surface {
cairo_win32_surface_t win32;
cairo_surface_clipper_t clipper;
cairo_paginated_mode_t paginated_mode;
cairo_content_t content;
cairo_bool_t path_empty;
cairo_bool_t has_ctm;
cairo_matrix_t ctm;
cairo_bool_t has_gdi_ctm;
cairo_matrix_t gdi_ctm;
HBRUSH brush, old_brush;
cairo_scaled_font_subsets_t *font_subsets;
} cairo_win32_printing_surface_t;
#define to_win32_printing_surface(S) ((cairo_win32_printing_surface_t *)(S))
typedef BOOL (WINAPI *cairo_win32_alpha_blend_func_t) (HDC hdcDest,
int nXOriginDest,
int nYOriginDest,
int nWidthDest,
int hHeightDest,
HDC hdcSrc,
int nXOriginSrc,
int nYOriginSrc,
int nWidthSrc,
int nHeightSrc,
BLENDFUNCTION blendFunction);
typedef struct _cairo_win32_device {
cairo_device_t base;
HMODULE msimg32_dll;
const cairo_compositor_t *compositor;
cairo_win32_alpha_blend_func_t alpha_blend;
} cairo_win32_device_t;
#define to_win32_device(D) ((cairo_win32_device_t *)(D))
#define to_win32_device_from_surface(S) to_win32_device(((cairo_surface_t *)(S))->device)
cairo_private cairo_device_t *
_cairo_win32_device_get (void);
const cairo_compositor_t *
_cairo_win32_gdi_compositor_get (void);
cairo_status_t
_cairo_win32_print_gdi_error (const char *context);
cairo_bool_t
_cairo_surface_is_win32 (cairo_surface_t *surface);
cairo_bool_t
_cairo_surface_is_win32_printing (cairo_surface_t *surface);
cairo_status_t
_cairo_win32_surface_finish (void *abstract_surface);
cairo_private void
_cairo_win32_display_surface_discard_fallback (cairo_win32_display_surface_t *surface);
cairo_bool_t
_cairo_win32_surface_get_extents (void *abstract_surface,
@ -160,34 +187,13 @@ _cairo_win32_surface_get_extents (void *abstract_surface,
uint32_t
_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_win32_surface_show_glyphs_internal (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip,
cairo_bool_t glyph_indices);
cairo_int_status_t
_cairo_win32_surface_show_glyphs (void *surface,
cairo_operator_t op,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
const cairo_clip_t *clip);
cairo_surface_t *
_cairo_win32_surface_create_similar (void *abstract_src,
cairo_content_t content,
int width,
int height);
_cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst,
const cairo_pattern_t *source,
cairo_glyph_t *glyphs,
int num_glyphs,
cairo_scaled_font_t *scaled_font,
cairo_bool_t glyph_indexing);
static inline void
_cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
@ -201,11 +207,12 @@ _cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
xform->eDy = (FLOAT) m->y0;
}
cairo_int_status_t
_cairo_win32_save_initial_clip (HDC dc, cairo_win32_surface_t *surface);
cairo_status_t
_cairo_win32_display_surface_set_clip (cairo_win32_display_surface_t *surface,
cairo_clip_t *clip);
cairo_int_status_t
_cairo_win32_restore_initial_clip (cairo_win32_surface_t *surface);
void
_cairo_win32_display_surface_unset_clip (cairo_win32_display_surface_t *surface);
void
_cairo_win32_debug_dump_hrgn (HRGN rgn, char *header);

File diff suppressed because it is too large Load diff

View file

@ -47,8 +47,6 @@
#include "cairoint.h"
#if CAIRO_MUTEX_IMPL_WIN32
#if !CAIRO_WIN32_STATIC_BUILD
@ -61,11 +59,6 @@
# define _WIN32_WINNT 0x0500
#endif
#include "cairo-clip-private.h"
#include "cairo-paginated-private.h"
#include "cairo-win32-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include <windows.h>
/* declare to avoid "no previous prototype for 'DllMain'" warning */
@ -94,4 +87,3 @@ DllMain (HINSTANCE hinstDLL,
#endif
#endif