mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice-common
synced 2026-01-01 12:42:00 +00:00
libspice: add off screens support
Signed-off-by: Izik Eidus <ieidus@redhat.com>
This commit is contained in:
parent
998bf873bf
commit
e66440d563
@ -51,11 +51,18 @@ static pixman_image_t *canvas_get_pixman_brush(CairoCanvas *canvas,
|
||||
|
||||
return pixman_image_create_solid_fill(&c);
|
||||
}
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
CairoCanvas *surface_canvas;
|
||||
pixman_image_t* surface;
|
||||
pixman_transform_t t;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
|
||||
surface_canvas = (CairoCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
|
||||
if (surface_canvas) {
|
||||
surface = surface_canvas->image;
|
||||
surface = pixman_image_ref(surface);
|
||||
} else {
|
||||
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
|
||||
}
|
||||
pixman_transform_init_translate(&t,
|
||||
pixman_int_to_fixed(-brush->u.pattern.pos.x),
|
||||
pixman_int_to_fixed(-brush->u.pattern.pos.y));
|
||||
@ -70,6 +77,14 @@ static pixman_image_t *canvas_get_pixman_brush(CairoCanvas *canvas,
|
||||
}
|
||||
}
|
||||
|
||||
static pixman_image_t *get_image(SpiceCanvas *canvas)
|
||||
{
|
||||
CairoCanvas *cairo_canvas = (CairoCanvas *)canvas;
|
||||
|
||||
pixman_image_ref(cairo_canvas->image);
|
||||
|
||||
return cairo_canvas->image;
|
||||
}
|
||||
|
||||
static void copy_region(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *dest_region,
|
||||
@ -194,16 +209,16 @@ static void fill_solid_rects_rop(SpiceCanvas *spice_canvas,
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_tiled_rects(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y)
|
||||
static void __fill_tiled_rects(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
spice_pixman_tile_rect(canvas->image,
|
||||
rects[i].x1, rects[i].y1,
|
||||
rects[i].x2 - rects[i].x1,
|
||||
@ -212,17 +227,37 @@ static void fill_tiled_rects(SpiceCanvas *spice_canvas,
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
static void fill_tiled_rects(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y)
|
||||
{
|
||||
__fill_tiled_rects(spice_canvas, rects, n_rects, tile, offset_x, offset_y);
|
||||
}
|
||||
|
||||
static void fill_tiled_rects_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int offset_x, int offset_y)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__fill_tiled_rects(spice_canvas, rects, n_rects, cairo_surface_canvas->image, offset_x,
|
||||
offset_y);
|
||||
}
|
||||
|
||||
static void __fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
spice_pixman_tile_rect_rop(canvas->image,
|
||||
rects[i].x1, rects[i].y1,
|
||||
rects[i].x2 - rects[i].x1,
|
||||
@ -231,11 +266,32 @@ static void fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
|
||||
rop);
|
||||
}
|
||||
}
|
||||
static void fill_tiled_rects_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
{
|
||||
__fill_tiled_rects_rop(spice_canvas, rects, n_rects, tile, offset_x, offset_y, rop);
|
||||
}
|
||||
|
||||
static void blit_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y)
|
||||
static void fill_tiled_rects_rop_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__fill_tiled_rects_rop(spice_canvas, rects, n_rects, cairo_surface_canvas->image, offset_x,
|
||||
offset_y, rop);
|
||||
}
|
||||
|
||||
static void __blit_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_box32_t *rects;
|
||||
@ -262,11 +318,28 @@ static void blit_image(SpiceCanvas *spice_canvas,
|
||||
}
|
||||
}
|
||||
|
||||
static void blit_image_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
static void blit_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y)
|
||||
{
|
||||
__blit_image(spice_canvas, region, src_image, offset_x, offset_y);
|
||||
}
|
||||
|
||||
static void blit_image_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int offset_x, int offset_y)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__blit_image(spice_canvas, region, cairo_surface_canvas->image, offset_x, offset_y);
|
||||
}
|
||||
|
||||
static void __blit_image_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_box32_t *rects;
|
||||
@ -293,14 +366,35 @@ static void blit_image_rop(SpiceCanvas *spice_canvas,
|
||||
}
|
||||
}
|
||||
|
||||
static void scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode)
|
||||
static void blit_image_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
{
|
||||
__blit_image_rop(spice_canvas, region, src_image, offset_x, offset_y, rop);
|
||||
}
|
||||
|
||||
static void blit_image_rop_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__blit_image_rop(spice_canvas, region, cairo_surface_canvas->image, offset_x, offset_y, rop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void __scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_transform_t transform;
|
||||
@ -337,14 +431,41 @@ static void scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_image_set_clip_region32(canvas->image, NULL);
|
||||
}
|
||||
|
||||
static void scale_image_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode, SpiceROP rop)
|
||||
static void scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode)
|
||||
{
|
||||
__scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x, dest_y,
|
||||
dest_width,dest_height,scale_mode);
|
||||
}
|
||||
|
||||
static void scale_image_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__scale_image(spice_canvas, region, cairo_surface_canvas->image, src_x, src_y, src_width,
|
||||
src_height, dest_x, dest_y, dest_width,dest_height,scale_mode);
|
||||
}
|
||||
|
||||
static void __scale_image_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode, SpiceROP rop)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_transform_t transform;
|
||||
@ -407,13 +528,40 @@ static void scale_image_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_image_unref(scaled);
|
||||
}
|
||||
|
||||
static void blend_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int dest_x, int dest_y,
|
||||
int width, int height,
|
||||
int overall_alpha)
|
||||
static void scale_image_rop(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode, SpiceROP rop)
|
||||
{
|
||||
__scale_image_rop(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
|
||||
dest_y, dest_width, dest_height, scale_mode, rop);
|
||||
}
|
||||
|
||||
static void scale_image_rop_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode, SpiceROP rop)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__scale_image_rop(spice_canvas, region, cairo_surface_canvas->image, src_x, src_y, src_width,
|
||||
src_height, dest_x, dest_y, dest_width, dest_height, scale_mode, rop);
|
||||
}
|
||||
|
||||
static void __blend_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int dest_x, int dest_y,
|
||||
int width, int height,
|
||||
int overall_alpha)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_image_t *mask;
|
||||
@ -444,15 +592,40 @@ static void blend_image(SpiceCanvas *spice_canvas,
|
||||
pixman_image_set_clip_region32(canvas->image, NULL);
|
||||
}
|
||||
|
||||
static void blend_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode,
|
||||
int overall_alpha)
|
||||
static void blend_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int dest_x, int dest_y,
|
||||
int width, int height,
|
||||
int overall_alpha)
|
||||
{
|
||||
__blend_image(spice_canvas, region, src, src_x, src_y, dest_x, dest_y, width, height,
|
||||
overall_alpha);
|
||||
}
|
||||
|
||||
static void blend_image_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int src_x, int src_y,
|
||||
int dest_x, int dest_y,
|
||||
int width, int height,
|
||||
int overall_alpha)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__blend_image(spice_canvas, region, cairo_surface_canvas->image, src_x, src_y, dest_x, dest_y,
|
||||
width, height, overall_alpha);
|
||||
}
|
||||
|
||||
static void __blend_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode,
|
||||
int overall_alpha)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_transform_t transform;
|
||||
@ -501,11 +674,41 @@ static void blend_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_image_set_clip_region32(canvas->image, NULL);
|
||||
}
|
||||
|
||||
static void colorkey_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
uint32_t transparent_color)
|
||||
static void blend_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode,
|
||||
int overall_alpha)
|
||||
{
|
||||
__blend_scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
|
||||
dest_y, dest_width, dest_height, scale_mode, overall_alpha);
|
||||
}
|
||||
|
||||
static void blend_scale_image_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode,
|
||||
int overall_alpha)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__blend_scale_image(spice_canvas, region, cairo_surface_canvas->image, src_x, src_y, src_width,
|
||||
src_height, dest_x, dest_y, dest_width, dest_height, scale_mode,
|
||||
overall_alpha);
|
||||
}
|
||||
|
||||
static void __colorkey_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
uint32_t transparent_color)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_box32_t *rects;
|
||||
@ -533,14 +736,34 @@ static void colorkey_image(SpiceCanvas *spice_canvas,
|
||||
}
|
||||
}
|
||||
|
||||
static void colorkey_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
uint32_t transparent_color)
|
||||
static void colorkey_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
uint32_t transparent_color)
|
||||
{
|
||||
__colorkey_image(spice_canvas, region, src_image, offset_x, offset_y, transparent_color);
|
||||
}
|
||||
|
||||
static void colorkey_image_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int offset_x, int offset_y,
|
||||
uint32_t transparent_color)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__colorkey_image(spice_canvas, region, cairo_surface_canvas->image, offset_x, offset_y,
|
||||
transparent_color);
|
||||
}
|
||||
|
||||
static void __colorkey_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
uint32_t transparent_color)
|
||||
{
|
||||
CairoCanvas *canvas = (CairoCanvas *)spice_canvas;
|
||||
pixman_transform_t transform;
|
||||
@ -600,6 +823,34 @@ static void colorkey_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_image_unref(scaled);
|
||||
}
|
||||
|
||||
static void colorkey_scale_image(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
uint32_t transparent_color)
|
||||
{
|
||||
__colorkey_scale_image(spice_canvas, region, src, src_x, src_y, src_width, src_height, dest_x,
|
||||
dest_y, dest_width, dest_height, transparent_color);
|
||||
}
|
||||
|
||||
static void colorkey_scale_image_from_surface(SpiceCanvas *spice_canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *surface_canvas,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
uint32_t transparent_color)
|
||||
{
|
||||
CairoCanvas *cairo_surface_canvas = (CairoCanvas *)surface_canvas;
|
||||
__colorkey_scale_image(spice_canvas, region, cairo_surface_canvas->image, src_x, src_y,
|
||||
src_width, src_height, dest_x, dest_y, dest_width, dest_height,
|
||||
transparent_color);
|
||||
}
|
||||
|
||||
static void canvas_put_image(SpiceCanvas *spice_canvas,
|
||||
#ifdef WIN32
|
||||
HDC dc,
|
||||
@ -803,6 +1054,7 @@ SpiceCanvas *canvas_create(pixman_image_t *image, int bits
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, SpiceImageCache *bits_cache
|
||||
#endif
|
||||
, SpiceImageSurfaces *surfaces
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
#ifndef CAIRO_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
@ -826,6 +1078,7 @@ SpiceCanvas *canvas_create(pixman_image_t *image, int bits
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, bits_cache
|
||||
#endif
|
||||
, surfaces
|
||||
, glz_decoder
|
||||
#ifndef CAIRO_CANVAS_NO_CHUNKS
|
||||
, virt_mapping
|
||||
@ -858,15 +1111,26 @@ void cairo_canvas_init() //unsafe global function
|
||||
cairo_canvas_ops.fill_solid_rects = fill_solid_rects;
|
||||
cairo_canvas_ops.fill_solid_rects_rop = fill_solid_rects_rop;
|
||||
cairo_canvas_ops.fill_tiled_rects = fill_tiled_rects;
|
||||
cairo_canvas_ops.fill_tiled_rects_from_surface = fill_tiled_rects_from_surface;
|
||||
cairo_canvas_ops.fill_tiled_rects_rop = fill_tiled_rects_rop;
|
||||
cairo_canvas_ops.fill_tiled_rects_rop_from_surface = fill_tiled_rects_rop_from_surface;
|
||||
cairo_canvas_ops.blit_image = blit_image;
|
||||
cairo_canvas_ops.blit_image_from_surface = blit_image_from_surface;
|
||||
cairo_canvas_ops.blit_image_rop = blit_image_rop;
|
||||
cairo_canvas_ops.blit_image_rop_from_surface = blit_image_rop_from_surface;
|
||||
cairo_canvas_ops.scale_image = scale_image;
|
||||
cairo_canvas_ops.scale_image_from_surface = scale_image_from_surface;
|
||||
cairo_canvas_ops.scale_image_rop = scale_image_rop;
|
||||
cairo_canvas_ops.scale_image_rop_from_surface = scale_image_rop_from_surface;
|
||||
cairo_canvas_ops.blend_image = blend_image;
|
||||
cairo_canvas_ops.blend_image_from_surface = blend_image_from_surface;
|
||||
cairo_canvas_ops.blend_scale_image = blend_scale_image;
|
||||
cairo_canvas_ops.blend_scale_image_from_surface = blend_scale_image_from_surface;
|
||||
cairo_canvas_ops.colorkey_image = colorkey_image;
|
||||
cairo_canvas_ops.colorkey_image_from_surface = colorkey_image_from_surface;
|
||||
cairo_canvas_ops.colorkey_scale_image = colorkey_scale_image;
|
||||
cairo_canvas_ops.colorkey_scale_image_from_surface = colorkey_scale_image_from_surface;
|
||||
cairo_canvas_ops.copy_region = copy_region;
|
||||
cairo_canvas_ops.get_image = get_image;
|
||||
rop3_init();
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ SpiceCanvas *canvas_create(pixman_image_t *image, int bits
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, SpiceImageCache *bits_cache
|
||||
#endif
|
||||
, SpiceImageSurfaces *surfaces
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
#ifndef CAIRO_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
|
||||
@ -190,6 +190,8 @@ typedef struct CanvasBase {
|
||||
HDC dc;
|
||||
#endif
|
||||
|
||||
SpiceImageSurfaces *surfaces;
|
||||
|
||||
LzData lz_data;
|
||||
GlzData glz_data;
|
||||
|
||||
@ -948,6 +950,34 @@ static void dump_surface(pixman_image_t *surface, int cache)
|
||||
|
||||
#endif
|
||||
|
||||
static SpiceCanvas *canvas_get_surface_internal(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
|
||||
|
||||
if (descriptor->type == SPICE_IMAGE_TYPE_SURFACE) {
|
||||
SpiceSurfaceImage *surface = (SpiceSurfaceImage *)descriptor;
|
||||
access_test(canvas, descriptor, sizeof(SpiceSurfaceImage));
|
||||
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface.surface_id);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SpiceCanvas *canvas_get_surface_mask_internal(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
SpiceImageDescriptor *descriptor;
|
||||
|
||||
descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(addr);
|
||||
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
|
||||
|
||||
if (descriptor->type == SPICE_IMAGE_TYPE_SURFACE) {
|
||||
SpiceSurfaceImage *surface = (SpiceSurfaceImage *)descriptor;
|
||||
access_test(canvas, descriptor, sizeof(SpiceSurfaceImage));
|
||||
return canvas->surfaces->ops->get(canvas->surfaces, surface->surface.surface_id);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(CAIRO_CANVAS_CACHE) || defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
|
||||
//#define DEBUG_LZ
|
||||
@ -1065,6 +1095,16 @@ static pixman_image_t *canvas_get_image_internal(CanvasBase *canvas, SPICE_ADDRE
|
||||
|
||||
#endif
|
||||
|
||||
static SpiceCanvas *canvas_get_surface_mask(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
return canvas_get_surface_mask_internal(canvas, addr);
|
||||
}
|
||||
|
||||
static SpiceCanvas *canvas_get_surface(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
return canvas_get_surface_internal(canvas, addr);
|
||||
}
|
||||
|
||||
static pixman_image_t *canvas_get_image(CanvasBase *canvas, SPICE_ADDRESS addr)
|
||||
{
|
||||
return canvas_get_image_internal(canvas, addr, TRUE);
|
||||
@ -1318,10 +1358,6 @@ static pixman_image_t *canvas_get_mask(CanvasBase *canvas, SpiceQMask *mask, int
|
||||
*needs_invert_out = 0;
|
||||
}
|
||||
|
||||
if (!mask->bitmap) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
descriptor = (SpiceImageDescriptor *)SPICE_GET_ADDRESS(mask->bitmap);
|
||||
access_test(canvas, descriptor, sizeof(SpiceImageDescriptor));
|
||||
need_invers = mask->flags & SPICE_MASK_FLAGS_INVERS;
|
||||
@ -1807,6 +1843,7 @@ static void canvas_mask_pixman(CanvasBase *canvas,
|
||||
pixman_region32_t *dest_region,
|
||||
SpiceQMask *mask, int x, int y)
|
||||
{
|
||||
SpiceCanvas *surface_canvas;
|
||||
pixman_image_t *image, *subimage;
|
||||
int needs_invert;
|
||||
pixman_region32_t mask_region;
|
||||
@ -1815,13 +1852,19 @@ static void canvas_mask_pixman(CanvasBase *canvas,
|
||||
int mask_width, mask_height, mask_stride;
|
||||
pixman_box32_t extents;
|
||||
|
||||
needs_invert = FALSE;
|
||||
image = canvas_get_mask(canvas,
|
||||
mask,
|
||||
&needs_invert);
|
||||
if (!mask->bitmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (image == NULL) {
|
||||
return; /* no mask */
|
||||
surface_canvas = canvas_get_surface_mask(canvas, mask->bitmap);
|
||||
if (surface_canvas) {
|
||||
needs_invert = mask->flags & SPICE_MASK_FLAGS_INVERS;
|
||||
image = surface_canvas->ops->get_image(surface_canvas);
|
||||
} else {
|
||||
needs_invert = FALSE;
|
||||
image = canvas_get_mask(canvas,
|
||||
mask,
|
||||
&needs_invert);
|
||||
}
|
||||
|
||||
mask_data = pixman_image_get_data(image);
|
||||
@ -1921,20 +1964,35 @@ static void draw_brush(SpiceCanvas *canvas,
|
||||
canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, color, rop);
|
||||
}
|
||||
break;
|
||||
case SPICE_BRUSH_TYPE_PATTERN:
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
SpiceCanvas *surface_canvas;
|
||||
|
||||
pattern = &brush->u.pattern;
|
||||
tile = canvas_get_image(canvas_base, pattern->pat);
|
||||
offset_x = pattern->pos.x;
|
||||
offset_y = pattern->pos.y;
|
||||
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
canvas->ops->fill_tiled_rects(canvas, rects, n_rects, tile, offset_x, offset_y);
|
||||
surface_canvas = canvas_get_surface(canvas_base, pattern->pat);
|
||||
if (surface_canvas) {
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
canvas->ops->fill_tiled_rects_from_surface(canvas, rects, n_rects, surface_canvas,
|
||||
offset_x, offset_y);
|
||||
} else {
|
||||
canvas->ops->fill_tiled_rects_rop_from_surface(canvas, rects, n_rects,
|
||||
surface_canvas, offset_x, offset_y,
|
||||
rop);
|
||||
}
|
||||
} else {
|
||||
canvas->ops->fill_tiled_rects_rop(canvas, rects, n_rects,
|
||||
tile, offset_x, offset_y, rop);
|
||||
tile = canvas_get_image(canvas_base, pattern->pat);
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
canvas->ops->fill_tiled_rects(canvas, rects, n_rects, tile, offset_x, offset_y);
|
||||
} else {
|
||||
canvas->ops->fill_tiled_rects_rop(canvas, rects, n_rects,
|
||||
tile, offset_x, offset_y, rop);
|
||||
}
|
||||
pixman_image_unref(tile);
|
||||
}
|
||||
pixman_image_unref(tile);
|
||||
break;
|
||||
}
|
||||
case SPICE_BRUSH_TYPE_NONE:
|
||||
/* Still need to do *something* here, because rop could be e.g invert dest */
|
||||
canvas->ops->fill_solid_rects_rop(canvas, rects, n_rects, 0, rop);
|
||||
@ -1991,6 +2049,7 @@ static void canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceCl
|
||||
{
|
||||
CanvasBase *canvas = (CanvasBase *)spice_canvas;
|
||||
pixman_region32_t dest_region;
|
||||
SpiceCanvas *surface_canvas;
|
||||
pixman_image_t *src_image;
|
||||
SpiceROP rop;
|
||||
|
||||
@ -2013,36 +2072,67 @@ static void canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceCl
|
||||
return;
|
||||
}
|
||||
|
||||
src_image = canvas_get_image(canvas, copy->src_bitmap);
|
||||
|
||||
if (rect_is_same_size(bbox, ©->src_area)) {
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->blit_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - copy->src_area.left,
|
||||
bbox->top - copy->src_area.top);
|
||||
surface_canvas = canvas_get_surface(canvas, copy->src_bitmap);
|
||||
if (surface_canvas) {
|
||||
if (rect_is_same_size(bbox, ©->src_area)) {
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
bbox->left - copy->src_area.left,
|
||||
bbox->top - copy->src_area.top);
|
||||
} else {
|
||||
spice_canvas->ops->blit_image_rop_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
bbox->left - copy->src_area.left,
|
||||
bbox->top - copy->src_area.top,
|
||||
rop);
|
||||
}
|
||||
} else {
|
||||
spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - copy->src_area.left,
|
||||
bbox->top - copy->src_area.top,
|
||||
rop);
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
copy->src_area.left,
|
||||
copy->src_area.top,
|
||||
copy->src_area.right - copy->src_area.left,
|
||||
copy->src_area.bottom - copy->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
copy->scale_mode);
|
||||
} else {
|
||||
spice_canvas->ops->scale_image_rop_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
copy->src_area.left,
|
||||
copy->src_area.top,
|
||||
copy->src_area.right - copy->src_area.left,
|
||||
copy->src_area.bottom - copy->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
copy->scale_mode,
|
||||
rop);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
copy->src_area.left,
|
||||
copy->src_area.top,
|
||||
copy->src_area.right - copy->src_area.left,
|
||||
copy->src_area.bottom - copy->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
copy->scale_mode);
|
||||
src_image = canvas_get_image(canvas, copy->src_bitmap);
|
||||
if (rect_is_same_size(bbox, ©->src_area)) {
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->blit_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - copy->src_area.left,
|
||||
bbox->top - copy->src_area.top);
|
||||
} else {
|
||||
spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - copy->src_area.left,
|
||||
bbox->top - copy->src_area.top,
|
||||
rop);
|
||||
}
|
||||
} else {
|
||||
spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
copy->src_area.left,
|
||||
copy->src_area.top,
|
||||
@ -2052,18 +2142,31 @@ static void canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceCl
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
copy->scale_mode,
|
||||
rop);
|
||||
copy->scale_mode);
|
||||
} else {
|
||||
spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
copy->src_area.left,
|
||||
copy->src_area.top,
|
||||
copy->src_area.right - copy->src_area.left,
|
||||
copy->src_area.bottom - copy->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
copy->scale_mode,
|
||||
rop);
|
||||
}
|
||||
}
|
||||
pixman_image_unref(src_image);
|
||||
}
|
||||
|
||||
pixman_image_unref(src_image);
|
||||
pixman_region32_fini(&dest_region);
|
||||
}
|
||||
|
||||
static void canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceTransparent* transparent)
|
||||
{
|
||||
CanvasBase *canvas = (CanvasBase *)spice_canvas;
|
||||
SpiceCanvas *surface_canvas;
|
||||
pixman_image_t *src_image;
|
||||
pixman_region32_t dest_region;
|
||||
|
||||
@ -2080,29 +2183,50 @@ static void canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
return;
|
||||
}
|
||||
|
||||
src_image = canvas_get_image(canvas, transparent->src_bitmap);
|
||||
|
||||
if (rect_is_same_size(bbox, &transparent->src_area)) {
|
||||
spice_canvas->ops->colorkey_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - transparent->src_area.left,
|
||||
bbox->top - transparent->src_area.top,
|
||||
transparent->true_color);
|
||||
surface_canvas = canvas_get_surface(canvas, transparent->src_bitmap);
|
||||
if (surface_canvas) {
|
||||
if (rect_is_same_size(bbox, &transparent->src_area)) {
|
||||
spice_canvas->ops->colorkey_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
bbox->left - transparent->src_area.left,
|
||||
bbox->top - transparent->src_area.top,
|
||||
transparent->true_color);
|
||||
} else {
|
||||
spice_canvas->ops->colorkey_scale_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
transparent->src_area.left,
|
||||
transparent->src_area.top,
|
||||
transparent->src_area.right - transparent->src_area.left,
|
||||
transparent->src_area.bottom - transparent->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
transparent->true_color);
|
||||
}
|
||||
} else {
|
||||
spice_canvas->ops->colorkey_scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
transparent->src_area.left,
|
||||
transparent->src_area.top,
|
||||
transparent->src_area.right - transparent->src_area.left,
|
||||
transparent->src_area.bottom - transparent->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
transparent->true_color);
|
||||
src_image = canvas_get_image(canvas, transparent->src_bitmap);
|
||||
if (rect_is_same_size(bbox, &transparent->src_area)) {
|
||||
spice_canvas->ops->colorkey_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - transparent->src_area.left,
|
||||
bbox->top - transparent->src_area.top,
|
||||
transparent->true_color);
|
||||
} else {
|
||||
spice_canvas->ops->colorkey_scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
transparent->src_area.left,
|
||||
transparent->src_area.top,
|
||||
transparent->src_area.right - transparent->src_area.left,
|
||||
transparent->src_area.bottom - transparent->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
transparent->true_color);
|
||||
}
|
||||
pixman_image_unref(src_image);
|
||||
}
|
||||
|
||||
pixman_image_unref(src_image);
|
||||
pixman_region32_fini(&dest_region);
|
||||
}
|
||||
|
||||
@ -2110,6 +2234,7 @@ static void canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
{
|
||||
CanvasBase *canvas = (CanvasBase *)spice_canvas;
|
||||
pixman_region32_t dest_region;
|
||||
SpiceCanvas *surface_canvas;
|
||||
pixman_image_t *src_image;
|
||||
|
||||
pixman_region32_init_rect(&dest_region,
|
||||
@ -2126,34 +2251,62 @@ static void canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
return;
|
||||
}
|
||||
|
||||
src_image = canvas_get_image(canvas, alpha_blend->src_bitmap);
|
||||
|
||||
if (rect_is_same_size(bbox, &alpha_blend->src_area)) {
|
||||
spice_canvas->ops->blend_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
alpha_blend->alpha);
|
||||
} else {
|
||||
spice_canvas->ops->blend_scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.top,
|
||||
alpha_blend->src_area.right - alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.bottom - alpha_blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
SPICE_IMAGE_SCALE_MODE_NEAREST,
|
||||
alpha_blend->alpha);
|
||||
surface_canvas = canvas_get_surface(canvas, alpha_blend->src_bitmap);
|
||||
if (surface_canvas) {
|
||||
if (rect_is_same_size(bbox, &alpha_blend->src_area)) {
|
||||
spice_canvas->ops->blend_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
alpha_blend->alpha);
|
||||
} else {
|
||||
spice_canvas->ops->blend_scale_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.top,
|
||||
alpha_blend->src_area.right - alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.bottom - alpha_blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
SPICE_IMAGE_SCALE_MODE_NEAREST,
|
||||
alpha_blend->alpha);
|
||||
}
|
||||
} else {
|
||||
src_image = canvas_get_image(canvas, alpha_blend->src_bitmap);
|
||||
if (rect_is_same_size(bbox, &alpha_blend->src_area)) {
|
||||
spice_canvas->ops->blend_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
alpha_blend->alpha);
|
||||
} else {
|
||||
spice_canvas->ops->blend_scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.top,
|
||||
alpha_blend->src_area.right - alpha_blend->src_area.left,
|
||||
alpha_blend->src_area.bottom - alpha_blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
SPICE_IMAGE_SCALE_MODE_NEAREST,
|
||||
alpha_blend->alpha);
|
||||
}
|
||||
|
||||
pixman_image_unref(src_image);
|
||||
}
|
||||
|
||||
pixman_image_unref(src_image);
|
||||
pixman_region32_fini(&dest_region);
|
||||
}
|
||||
|
||||
@ -2214,6 +2367,7 @@ static void canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, Spice
|
||||
static void canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
|
||||
{
|
||||
CanvasBase *canvas = (CanvasBase *)spice_canvas;
|
||||
SpiceCanvas *surface_canvas;
|
||||
pixman_image_t *src_image;
|
||||
pixman_region32_t dest_region;
|
||||
SpiceROP rop;
|
||||
@ -2237,40 +2391,74 @@ static void canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceC
|
||||
return;
|
||||
}
|
||||
|
||||
src_image = canvas_get_image(canvas, blend->src_bitmap);
|
||||
|
||||
if (rect_is_same_size(bbox, &blend->src_area)) {
|
||||
if (rop == SPICE_ROP_COPY)
|
||||
spice_canvas->ops->blit_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - blend->src_area.left,
|
||||
bbox->top - blend->src_area.top);
|
||||
else
|
||||
spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
|
||||
surface_canvas = canvas_get_surface(canvas, blend->src_bitmap);
|
||||
if (surface_canvas) {
|
||||
if (rect_is_same_size(bbox, &blend->src_area)) {
|
||||
if (rop == SPICE_ROP_COPY)
|
||||
spice_canvas->ops->blit_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
bbox->left - blend->src_area.left,
|
||||
bbox->top - blend->src_area.top);
|
||||
else
|
||||
spice_canvas->ops->blit_image_rop_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
bbox->left - blend->src_area.left,
|
||||
bbox->top - blend->src_area.top,
|
||||
rop);
|
||||
} else {
|
||||
double sx, sy;
|
||||
|
||||
sx = (double)(blend->src_area.right - blend->src_area.left) / (bbox->right - bbox->left);
|
||||
sy = (double)(blend->src_area.bottom - blend->src_area.top) / (bbox->bottom - bbox->top);
|
||||
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->scale_image_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
blend->src_area.left,
|
||||
blend->src_area.top,
|
||||
blend->src_area.right - blend->src_area.left,
|
||||
blend->src_area.bottom - blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
blend->scale_mode);
|
||||
} else {
|
||||
spice_canvas->ops->scale_image_rop_from_surface(spice_canvas, &dest_region,
|
||||
surface_canvas,
|
||||
blend->src_area.left,
|
||||
blend->src_area.top,
|
||||
blend->src_area.right - blend->src_area.left,
|
||||
blend->src_area.bottom - blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
blend->scale_mode, rop);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
src_image = canvas_get_image(canvas, blend->src_bitmap);
|
||||
if (rect_is_same_size(bbox, &blend->src_area)) {
|
||||
if (rop == SPICE_ROP_COPY)
|
||||
spice_canvas->ops->blit_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - blend->src_area.left,
|
||||
bbox->top - blend->src_area.top,
|
||||
rop);
|
||||
} else {
|
||||
double sx, sy;
|
||||
|
||||
sx = (double)(blend->src_area.right - blend->src_area.left) / (bbox->right - bbox->left);
|
||||
sy = (double)(blend->src_area.bottom - blend->src_area.top) / (bbox->bottom - bbox->top);
|
||||
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
blend->src_area.left,
|
||||
blend->src_area.top,
|
||||
blend->src_area.right - blend->src_area.left,
|
||||
blend->src_area.bottom - blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
blend->scale_mode);
|
||||
bbox->top - blend->src_area.top);
|
||||
else
|
||||
spice_canvas->ops->blit_image_rop(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
bbox->left - blend->src_area.left,
|
||||
bbox->top - blend->src_area.top,
|
||||
rop);
|
||||
} else {
|
||||
spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
|
||||
double sx, sy;
|
||||
|
||||
sx = (double)(blend->src_area.right - blend->src_area.left) / (bbox->right - bbox->left);
|
||||
sy = (double)(blend->src_area.bottom - blend->src_area.top) / (bbox->bottom - bbox->top);
|
||||
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
spice_canvas->ops->scale_image(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
blend->src_area.left,
|
||||
blend->src_area.top,
|
||||
@ -2280,11 +2468,23 @@ static void canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceC
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
blend->scale_mode, rop);
|
||||
blend->scale_mode);
|
||||
} else {
|
||||
spice_canvas->ops->scale_image_rop(spice_canvas, &dest_region,
|
||||
src_image,
|
||||
blend->src_area.left,
|
||||
blend->src_area.top,
|
||||
blend->src_area.right - blend->src_area.left,
|
||||
blend->src_area.bottom - blend->src_area.top,
|
||||
bbox->left,
|
||||
bbox->top,
|
||||
bbox->right - bbox->left,
|
||||
bbox->bottom - bbox->top,
|
||||
blend->scale_mode, rop);
|
||||
}
|
||||
}
|
||||
pixman_image_unref(src_image);
|
||||
}
|
||||
|
||||
pixman_image_unref(src_image);
|
||||
pixman_region32_fini(&dest_region);
|
||||
}
|
||||
|
||||
@ -2382,7 +2582,11 @@ typedef struct {
|
||||
SpiceROP back_rop;
|
||||
int solid;
|
||||
uint32_t color;
|
||||
pixman_image_t *tile;
|
||||
int use_surface_canvas;
|
||||
union {
|
||||
SpiceCanvas *surface_canvas;
|
||||
pixman_image_t *tile;
|
||||
};
|
||||
int tile_offset_x;
|
||||
int tile_offset_y;
|
||||
} StrokeGC;
|
||||
@ -2505,16 +2709,31 @@ static void stroke_fill_rects(lineGC * pGC,
|
||||
}
|
||||
} else {
|
||||
if (rop == SPICE_ROP_COPY) {
|
||||
canvas->ops->fill_tiled_rects(canvas, area_rects, n_area_rects,
|
||||
strokeGC->tile,
|
||||
strokeGC->tile_offset_x,
|
||||
strokeGC->tile_offset_y);
|
||||
} else {
|
||||
canvas->ops->fill_tiled_rects_rop(canvas, area_rects, n_area_rects,
|
||||
if (strokeGC->use_surface_canvas) {
|
||||
canvas->ops->fill_tiled_rects_from_surface(canvas, area_rects, n_area_rects,
|
||||
strokeGC->surface_canvas,
|
||||
strokeGC->tile_offset_x,
|
||||
strokeGC->tile_offset_y);
|
||||
} else {
|
||||
canvas->ops->fill_tiled_rects(canvas, area_rects, n_area_rects,
|
||||
strokeGC->tile,
|
||||
strokeGC->tile_offset_x,
|
||||
strokeGC->tile_offset_y,
|
||||
rop);
|
||||
strokeGC->tile_offset_y);
|
||||
}
|
||||
} else {
|
||||
if (strokeGC->use_surface_canvas) {
|
||||
canvas->ops->fill_tiled_rects_rop_from_surface(canvas, area_rects, n_area_rects,
|
||||
strokeGC->surface_canvas,
|
||||
strokeGC->tile_offset_x,
|
||||
strokeGC->tile_offset_y,
|
||||
rop);
|
||||
} else {
|
||||
canvas->ops->fill_tiled_rects_rop(canvas, area_rects, n_area_rects,
|
||||
strokeGC->tile,
|
||||
strokeGC->tile_offset_x,
|
||||
strokeGC->tile_offset_y,
|
||||
rop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2661,6 +2880,7 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
SpiceClip *clip, SpiceStroke *stroke)
|
||||
{
|
||||
CanvasBase *canvas = (CanvasBase *)spice_canvas;
|
||||
SpiceCanvas *surface_canvas = NULL;
|
||||
StrokeGC gc = { { 0 } };
|
||||
lineGCOps ops = {
|
||||
stroke_fill_spans,
|
||||
@ -2754,8 +2974,16 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
break;
|
||||
case SPICE_BRUSH_TYPE_PATTERN:
|
||||
gc.solid = FALSE;
|
||||
gc.tile = canvas_get_image(canvas,
|
||||
stroke->brush.u.pattern.pat);
|
||||
surface_canvas = canvas_get_surface(canvas,
|
||||
stroke->brush.u.pattern.pat);
|
||||
if (surface_canvas) {
|
||||
gc.use_surface_canvas = TRUE;
|
||||
gc.surface_canvas = surface_canvas;
|
||||
} else {
|
||||
gc.use_surface_canvas = FALSE;
|
||||
gc.tile = canvas_get_image(canvas,
|
||||
stroke->brush.u.pattern.pat);
|
||||
}
|
||||
gc.tile_offset_x = stroke->brush.u.pattern.pos.x;
|
||||
gc.tile_offset_y = stroke->brush.u.pattern.pos.y;
|
||||
break;
|
||||
@ -2817,17 +3045,20 @@ static void canvas_draw_stroke(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
}
|
||||
stroke_lines_free(&lines);
|
||||
|
||||
if (!gc.solid && gc.tile) {
|
||||
if (!gc.solid && gc.tile && !surface_canvas) {
|
||||
pixman_image_unref(gc.tile);
|
||||
}
|
||||
|
||||
pixman_region32_fini(&gc.dest_region);
|
||||
}
|
||||
|
||||
|
||||
//need surfaces handling here !!!
|
||||
static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
SpiceClip *clip, SpiceRop3 *rop3)
|
||||
{
|
||||
CanvasBase *canvas = (CanvasBase *)spice_canvas;
|
||||
SpiceCanvas *surface_canvas;
|
||||
pixman_region32_t dest_region;
|
||||
pixman_image_t *d;
|
||||
pixman_image_t *s;
|
||||
@ -2848,7 +3079,12 @@ static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
heigth = bbox->bottom - bbox->top;
|
||||
|
||||
d = canvas_get_image_from_self(spice_canvas, bbox->left, bbox->top, width, heigth);
|
||||
s = canvas_get_image(canvas, rop3->src_bitmap);
|
||||
surface_canvas = canvas_get_surface(canvas, rop3->src_bitmap);
|
||||
if (surface_canvas) {
|
||||
s = surface_canvas->ops->get_image(surface_canvas);
|
||||
} else {
|
||||
s = canvas_get_image(canvas, rop3->src_bitmap);
|
||||
}
|
||||
|
||||
if (!rect_is_same_size(bbox, &rop3->src_area)) {
|
||||
pixman_image_t *scaled_s = canvas_scale_surface(s, &rop3->src_area, width, heigth,
|
||||
@ -2866,7 +3102,15 @@ static void canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox,
|
||||
CANVAS_ERROR("bad src bitmap size");
|
||||
}
|
||||
if (rop3->brush.type == SPICE_BRUSH_TYPE_PATTERN) {
|
||||
pixman_image_t *p = canvas_get_image(canvas, rop3->brush.u.pattern.pat);
|
||||
SpiceCanvas *_surface_canvas;
|
||||
pixman_image_t *p;
|
||||
|
||||
_surface_canvas = canvas_get_surface(canvas, rop3->brush.u.pattern.pat);
|
||||
if (_surface_canvas) {
|
||||
p = _surface_canvas->ops->get_image(_surface_canvas);
|
||||
} else {
|
||||
p = canvas_get_image(canvas, rop3->brush.u.pattern.pat);
|
||||
}
|
||||
SpicePoint pat_pos;
|
||||
|
||||
pat_pos.x = (bbox->left - rop3->brush.u.pattern.pos.x) % pixman_image_get_width(p);
|
||||
@ -2988,6 +3232,7 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, SpiceImageCache *bits_cache
|
||||
#endif
|
||||
, SpiceImageSurfaces *surfaces
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
#ifndef CAIRO_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
@ -3020,6 +3265,7 @@ static int canvas_base_init(CanvasBase *canvas, SpiceCanvasOps *ops,
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
canvas->surfaces = surfaces;
|
||||
canvas->glz_data.decoder = glz_decoder;
|
||||
|
||||
if (depth == 16) {
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
typedef void (*spice_destroy_fn_t)(void *data);
|
||||
|
||||
typedef struct _SpiceImageCache SpiceImageCache;
|
||||
typedef struct _SpiceImageSurfaces SpiceImageSurfaces;
|
||||
typedef struct _SpicePaletteCache SpicePaletteCache;
|
||||
typedef struct _SpiceGlzDecoder SpiceGlzDecoder;
|
||||
typedef struct _SpiceVirtMapping SpiceVirtMapping;
|
||||
@ -45,6 +46,15 @@ struct _SpiceImageCache {
|
||||
SpiceImageCacheOps *ops;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
SpiceCanvas *(*get)(SpiceImageSurfaces *surfaces,
|
||||
uint32_t surface_id);
|
||||
} SpiceImageSurfacesOps;
|
||||
|
||||
struct _SpiceImageSurfaces {
|
||||
SpiceImageSurfacesOps *ops;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void (*put)(SpicePaletteCache *cache,
|
||||
SpicePalette *palette);
|
||||
@ -127,21 +137,41 @@ typedef struct {
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y);
|
||||
void (*fill_tiled_rects_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
SpiceCanvas *tile,
|
||||
int offset_x, int offset_y);
|
||||
void (*fill_tiled_rects_rop)(SpiceCanvas *canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
pixman_image_t *tile,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop);
|
||||
void (*fill_tiled_rects_rop_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_box32_t *rects,
|
||||
int n_rects,
|
||||
SpiceCanvas *tile,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop);
|
||||
void (*blit_image)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y);
|
||||
void (*blit_image_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int offset_x, int offset_y);
|
||||
void (*blit_image_rop)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop);
|
||||
void (*blit_image_rop_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int offset_x, int offset_y,
|
||||
SpiceROP rop);
|
||||
void (*scale_image)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
@ -150,6 +180,14 @@ typedef struct {
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode);
|
||||
void (*scale_image_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode);
|
||||
void (*scale_image_rop)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
@ -158,6 +196,14 @@ typedef struct {
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode, SpiceROP rop);
|
||||
void (*scale_image_rop_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode, SpiceROP rop);
|
||||
void (*blend_image)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
@ -165,6 +211,13 @@ typedef struct {
|
||||
int dest_x, int dest_y,
|
||||
int width, int height,
|
||||
int overall_alpha);
|
||||
void (*blend_image_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int src_x, int src_y,
|
||||
int dest_x, int dest_y,
|
||||
int width, int height,
|
||||
int overall_alpha);
|
||||
void (*blend_scale_image)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
@ -174,11 +227,25 @@ typedef struct {
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode,
|
||||
int overall_alpha);
|
||||
void (*blend_scale_image_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
int scale_mode,
|
||||
int overall_alpha);
|
||||
void (*colorkey_image)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
int offset_x, int offset_y,
|
||||
uint32_t transparent_color);
|
||||
void (*colorkey_image_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int offset_x, int offset_y,
|
||||
uint32_t transparent_color);
|
||||
void (*colorkey_scale_image)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
pixman_image_t *src_image,
|
||||
@ -187,9 +254,18 @@ typedef struct {
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
uint32_t transparent_color);
|
||||
void (*colorkey_scale_image_from_surface)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *region,
|
||||
SpiceCanvas *src_image,
|
||||
int src_x, int src_y,
|
||||
int src_width, int src_height,
|
||||
int dest_x, int dest_y,
|
||||
int dest_width, int dest_height,
|
||||
uint32_t transparent_color);
|
||||
void (*copy_region)(SpiceCanvas *canvas,
|
||||
pixman_region32_t *dest_region,
|
||||
int dx, int dy);
|
||||
pixman_image_t *(*get_image)(SpiceCanvas *canvas);
|
||||
} SpiceCanvasOps;
|
||||
|
||||
void spice_canvas_set_usr_data(SpiceCanvas *canvas, void *data, spice_destroy_fn_t destroy_fn);
|
||||
|
||||
@ -42,6 +42,7 @@ struct BitmapData {
|
||||
uint8_t flags;
|
||||
HDC dc;
|
||||
int cache;
|
||||
int from_surface;
|
||||
};
|
||||
|
||||
#define _rop3_brush 0xf0
|
||||
@ -644,7 +645,8 @@ static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush)
|
||||
CANVAS_ERROR("CreateSolidBrush failed");
|
||||
}
|
||||
return hbrush;
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
case SPICE_BRUSH_TYPE_PATTERN: {
|
||||
GdiCanvas *gdi_surface = NULL;
|
||||
GdiImage image;
|
||||
HBRUSH hbrush;
|
||||
pixman_image_t *surface;
|
||||
@ -652,21 +654,31 @@ static HBRUSH get_brush(GdiCanvas *canvas, SpiceBrush *brush)
|
||||
HBITMAP bitmap;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
|
||||
surface_to_image(surface, &image);
|
||||
|
||||
if (!create_bitmap(&bitmap, &prev_bitmap, &dc, image.pixels, image.width,
|
||||
image.height, image.stride, 32, 0)) {
|
||||
CANVAS_ERROR("create_bitmap failed");
|
||||
return NULL;
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, brush->u.pattern.pat);
|
||||
if (gdi_surface) {
|
||||
bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
|
||||
if (!bitmap) {
|
||||
CANVAS_ERROR("GetCurrentObject failed");
|
||||
}
|
||||
} else {
|
||||
surface = canvas_get_image(&canvas->base, brush->u.pattern.pat);
|
||||
surface_to_image(surface, &image);
|
||||
|
||||
if (!create_bitmap(&bitmap, &prev_bitmap, &dc, image.pixels, image.width,
|
||||
image.height, image.stride, 32, 0)) {
|
||||
CANVAS_ERROR("create_bitmap failed");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(hbrush = CreatePatternBrush(bitmap))) {
|
||||
CANVAS_ERROR("CreatePatternBrush failed");
|
||||
}
|
||||
|
||||
release_bitmap(dc, bitmap, prev_bitmap, 0);
|
||||
pixman_image_unref(surface);
|
||||
if (!gdi_surface) {
|
||||
release_bitmap(dc, bitmap, prev_bitmap, 0);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
return hbrush;
|
||||
}
|
||||
case SPICE_BRUSH_TYPE_NONE:
|
||||
@ -781,30 +793,53 @@ uint8_t calc_rop3_src_brush(uint16_t rop3_bits)
|
||||
|
||||
static struct BitmapData get_mask_bitmap(struct GdiCanvas *canvas, struct SpiceQMask *mask)
|
||||
{
|
||||
GdiCanvas *gdi_surface;
|
||||
pixman_image_t *surface;
|
||||
struct BitmapData bitmap;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
bitmap.hbitmap = NULL;
|
||||
if (!(surface = canvas_get_mask(&canvas->base, mask, NULL))) {
|
||||
if (!mask->bitmap) {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data (surface);
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
bitmap.dc = create_compatible_dc();
|
||||
bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap);
|
||||
bitmap.hbitmap = pixman_data->bitmap;
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
bitmap.cache = 1;
|
||||
} else if (!create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap, &bitmap.dc,
|
||||
(uint8_t *)pixman_image_get_data(surface),
|
||||
pixman_image_get_width(surface),
|
||||
pixman_image_get_height(surface),
|
||||
pixman_image_get_stride(surface), 1, 0)) {
|
||||
bitmap.hbitmap = NULL;
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface_mask(&canvas->base, mask->bitmap);
|
||||
if (gdi_surface) {
|
||||
HBITMAP _bitmap;
|
||||
|
||||
_bitmap = (HBITMAP)GetCurrentObject(gdi_surface->dc, OBJ_BITMAP);
|
||||
if (!_bitmap) {
|
||||
CANVAS_ERROR ("GetCurrentObject failed");
|
||||
}
|
||||
bitmap.dc = gdi_surface->dc;
|
||||
bitmap.hbitmap = _bitmap;
|
||||
bitmap.prev_hbitmap = (HBITMAP)0;
|
||||
bitmap.cache = 0;
|
||||
bitmap.from_surface = 1;
|
||||
} else {
|
||||
bitmap.cache = 0;
|
||||
|
||||
if (!(surface = canvas_get_mask(&canvas->base, mask, NULL))) {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data (surface);
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
bitmap.dc = create_compatible_dc();
|
||||
bitmap.prev_hbitmap = (HBITMAP)SelectObject(bitmap.dc, pixman_data->bitmap);
|
||||
bitmap.hbitmap = pixman_data->bitmap;
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
bitmap.cache = 1;
|
||||
} else if (!create_bitmap(&bitmap.hbitmap, &bitmap.prev_hbitmap, &bitmap.dc,
|
||||
(uint8_t *)pixman_image_get_data(surface),
|
||||
pixman_image_get_width(surface),
|
||||
pixman_image_get_height(surface),
|
||||
pixman_image_get_stride(surface), 1, 0)) {
|
||||
bitmap.hbitmap = NULL;
|
||||
} else {
|
||||
bitmap.cache = 0;
|
||||
}
|
||||
|
||||
bitmap.from_surface = 0;
|
||||
}
|
||||
|
||||
bitmap.flags = mask->flags;
|
||||
@ -859,7 +894,9 @@ static void gdi_draw_bitmap_redrop(HDC dest_dc, const SpiceRect *src, const Spic
|
||||
static void free_mask(struct BitmapData *bitmap)
|
||||
{
|
||||
if (bitmap->hbitmap) {
|
||||
release_bitmap(bitmap->dc, bitmap->hbitmap, bitmap->prev_hbitmap, bitmap->cache);
|
||||
if (!bitmap->from_surface) {
|
||||
release_bitmap(bitmap->dc, bitmap->hbitmap, bitmap->prev_hbitmap, bitmap->cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -985,13 +1022,15 @@ static void gdi_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, Spi
|
||||
HBRUSH brush;
|
||||
struct BitmapData bitmapmask;
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
|
||||
if (!(brush = get_brush(canvas, &fill->brush))) {
|
||||
CANVAS_ERROR("no braash");
|
||||
return;
|
||||
}
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, &fill->mask);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, brush, &fill->brush);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask,
|
||||
@ -1004,40 +1043,51 @@ static void gdi_canvas_draw_fill(SpiceCanvas *spice_canvas, SpiceRect *bbox, Spi
|
||||
static void gdi_canvas_draw_copy(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceCopy *copy)
|
||||
{
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
GdiCanvas *gdi_surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
struct BitmapData bitmapmask;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, ©->mask);
|
||||
surface = canvas_get_image(&canvas->base, copy->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_scale_mode(canvas, copy->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, dc,
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, copy->src_bitmap);
|
||||
if (gdi_surface) {
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, ©->mask);
|
||||
set_scale_mode(canvas, copy->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, gdi_surface->dc,
|
||||
&bitmapmask, copy->rop_decriptor, 0);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image(canvas->dc, ©->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height, &bitmapmask,
|
||||
copy->rop_decriptor, 0);
|
||||
surface = canvas_get_image(&canvas->base, copy->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, ©->mask);
|
||||
set_scale_mode(canvas, copy->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, ©->src_area, bbox, dc,
|
||||
&bitmapmask, copy->rop_decriptor, 0);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image(canvas->dc, ©->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height, &bitmapmask,
|
||||
copy->rop_decriptor, 0);
|
||||
}
|
||||
|
||||
pixman_image_unref(surface);
|
||||
|
||||
}
|
||||
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
static void gdi_canvas_put_image(SpiceCanvas *spice_canvas, HDC dc, const SpiceRect *dest, const uint8_t *src_data,
|
||||
@ -1136,34 +1186,43 @@ static void gdi_canvas_draw_transparent(SpiceCanvas *spice_canvas, SpiceRect *bb
|
||||
SpiceTransparent* transparent)
|
||||
{
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
GdiCanvas *gdi_surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, transparent->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, dc,
|
||||
transparent->true_color);
|
||||
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, transparent->src_bitmap);
|
||||
if (gdi_surface) {
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox,
|
||||
gdi_surface->dc, transparent->true_color);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_transparent(canvas, canvas->dc, &transparent->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height,
|
||||
transparent->true_color, 0);
|
||||
surface = canvas_get_image(&canvas->base, transparent->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_transparent(canvas, canvas->dc, &transparent->src_area, bbox, dc,
|
||||
transparent->true_color);
|
||||
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_transparent(canvas, canvas->dc, &transparent->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height,
|
||||
transparent->true_color, 0);
|
||||
}
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
static void gdi_draw_bitmap_alpha(HDC dest_dc, const SpiceRect *src, const SpiceRect *dest,
|
||||
@ -1208,40 +1267,51 @@ static void gdi_draw_image_alpha(HDC dest_dc, const SpiceRect *src, const SpiceR
|
||||
static void gdi_canvas_draw_alpha_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceAlphaBlnd* alpha_blend)
|
||||
{
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
GdiCanvas *gdi_surface;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
PixmanData *pixman_data;
|
||||
int use_bitmap_alpha;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap);
|
||||
use_bitmap_alpha = pixman_image_get_depth(surface) == 32;
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, dc, alpha_blend->alpha,
|
||||
use_bitmap_alpha);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, alpha_blend->src_bitmap);
|
||||
if (gdi_surface) {
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
use_bitmap_alpha = 0;
|
||||
gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, gdi_surface->dc,
|
||||
alpha_blend->alpha, use_bitmap_alpha);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_alpha(canvas->dc, &alpha_blend->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height,
|
||||
alpha_blend->alpha, 0, use_bitmap_alpha);
|
||||
surface = canvas_get_image(&canvas->base, alpha_blend->src_bitmap);
|
||||
use_bitmap_alpha = pixman_image_get_depth(surface) == 32;
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_clip(canvas, clip);
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_alpha(canvas->dc, &alpha_blend->src_area, bbox, dc, alpha_blend->alpha,
|
||||
use_bitmap_alpha);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_alpha(canvas->dc, &alpha_blend->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height,
|
||||
alpha_blend->alpha, 0, use_bitmap_alpha);
|
||||
}
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
static void gdi_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceOpaque *opaque)
|
||||
{
|
||||
GdiCanvas *gdi_surface;
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
@ -1251,77 +1321,98 @@ static void gdi_canvas_draw_opaque(SpiceCanvas *spice_canvas, SpiceRect *bbox, S
|
||||
HBRUSH hbrush;
|
||||
uint8_t rop3;
|
||||
|
||||
surface = canvas_get_image(&canvas->base, opaque->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
|
||||
rop3 = calc_rop3_src_brush(opaque->rop_decriptor);
|
||||
hbrush = get_brush(canvas, &opaque->brush);
|
||||
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_scale_mode(canvas, opaque->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, opaque->src_bitmap);
|
||||
if (gdi_surface) {
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
|
||||
hbrush = get_brush(canvas, &opaque->brush);
|
||||
set_scale_mode(canvas, opaque->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
|
||||
gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, gdi_surface->dc, &bitmapmask, rop3);
|
||||
unset_brush(canvas->dc, prev_hbrush);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height, &bitmapmask, rop3, 0);
|
||||
surface = canvas_get_image(&canvas->base, opaque->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, &opaque->mask);
|
||||
hbrush = get_brush(canvas, &opaque->brush);
|
||||
set_scale_mode(canvas, opaque->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &opaque->brush);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap(canvas->dc, &opaque->src_area, bbox, dc, &bitmapmask, rop3);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_rop3(canvas->dc, &opaque->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height, &bitmapmask, rop3, 0);
|
||||
}
|
||||
unset_brush(canvas->dc, prev_hbrush);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
unset_brush(canvas->dc, prev_hbrush);
|
||||
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
static void gdi_canvas_draw_blend(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlend *blend)
|
||||
{
|
||||
GdiCanvas *gdi_surface;
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
struct BitmapData bitmapmask;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, &blend->mask);
|
||||
surface = canvas_get_image(&canvas->base, blend->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_scale_mode(canvas, blend->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, dc,
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, blend->src_bitmap);
|
||||
if (gdi_surface) {
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, &blend->mask);
|
||||
set_scale_mode(canvas, blend->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, gdi_surface->dc,
|
||||
&bitmapmask, blend->rop_decriptor, 0);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image(canvas->dc, &blend->src_area, bbox, image.pixels, image.stride, image.width,
|
||||
image.height, &bitmapmask, blend->rop_decriptor, 0);
|
||||
} else {
|
||||
surface = canvas_get_image(&canvas->base, blend->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, &blend->mask);
|
||||
set_scale_mode(canvas, blend->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, &blend->src_area, bbox, dc,
|
||||
&bitmapmask, blend->rop_decriptor, 0);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image(canvas->dc, &blend->src_area, bbox, image.pixels, image.stride, image.width,
|
||||
image.height, &bitmapmask, blend->rop_decriptor, 0);
|
||||
}
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
static void gdi_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceBlackness *blackness)
|
||||
@ -1329,9 +1420,8 @@ static void gdi_canvas_draw_blackness(SpiceCanvas *spice_canvas, SpiceRect *bbox
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
struct BitmapData bitmapmask;
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, &blackness->mask);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, &blackness->mask);
|
||||
set_clip(canvas, clip);
|
||||
gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x0);
|
||||
|
||||
@ -1343,9 +1433,8 @@ static void gdi_canvas_draw_invers(SpiceCanvas *spice_canvas, SpiceRect *bbox, S
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
struct BitmapData bitmapmask;
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, &invers->mask);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, &invers->mask);
|
||||
set_clip(canvas, clip);
|
||||
gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0x55);
|
||||
|
||||
@ -1357,9 +1446,8 @@ static void gdi_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
struct BitmapData bitmapmask;
|
||||
|
||||
bitmapmask = get_mask_bitmap(canvas, &whiteness->mask);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
bitmapmask = get_mask_bitmap(canvas, &whiteness->mask);
|
||||
set_clip(canvas, clip);
|
||||
gdi_draw_bitmap(canvas->dc, bbox, bbox, canvas->dc, &bitmapmask, 0xff);
|
||||
|
||||
@ -1368,6 +1456,7 @@ static void gdi_canvas_draw_whiteness(SpiceCanvas *spice_canvas, SpiceRect *bbox
|
||||
|
||||
static void gdi_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpiceRop3 *rop3)
|
||||
{
|
||||
GdiCanvas *gdi_surface;
|
||||
GdiCanvas *canvas = (GdiCanvas *)spice_canvas;
|
||||
pixman_image_t *surface;
|
||||
GdiImage image;
|
||||
@ -1376,37 +1465,49 @@ static void gdi_canvas_draw_rop3(SpiceCanvas *spice_canvas, SpiceRect *bbox, Spi
|
||||
HBRUSH hbrush;
|
||||
PixmanData *pixman_data;
|
||||
|
||||
hbrush = get_brush(canvas, &rop3->brush);
|
||||
surface = canvas_get_image(&canvas->base, rop3->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
|
||||
|
||||
Lock lock(*canvas->lock);
|
||||
set_scale_mode(canvas, rop3->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
|
||||
gdi_surface = (GdiCanvas *)canvas_get_surface(&canvas->base, rop3->src_bitmap);
|
||||
if (gdi_surface) {
|
||||
Lock lock(*canvas->lock);
|
||||
hbrush = get_brush(canvas, &rop3->brush);
|
||||
bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
|
||||
set_scale_mode(canvas, rop3->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
|
||||
gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, gdi_surface->dc,
|
||||
&bitmapmask, rop3->rop3);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
unset_brush(canvas->dc, prev_hbrush);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height, &bitmapmask, rop3->rop3, 0);
|
||||
surface = canvas_get_image(&canvas->base, rop3->src_bitmap);
|
||||
pixman_data = (PixmanData *)pixman_image_get_destroy_data(surface);
|
||||
Lock lock(*canvas->lock);
|
||||
hbrush = get_brush(canvas, &rop3->brush);
|
||||
bitmapmask = get_mask_bitmap(canvas, &rop3->mask);
|
||||
set_scale_mode(canvas, rop3->scale_mode);
|
||||
set_clip(canvas, clip);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &rop3->brush);
|
||||
|
||||
if (pixman_data && (WaitForSingleObject(pixman_data->mutex, INFINITE) != WAIT_FAILED)) {
|
||||
HDC dc;
|
||||
HBITMAP prev_bitmap;
|
||||
|
||||
dc = create_compatible_dc();
|
||||
prev_bitmap = (HBITMAP)SelectObject(dc, pixman_data->bitmap);
|
||||
gdi_draw_bitmap(canvas->dc, &rop3->src_area, bbox, dc,
|
||||
&bitmapmask, rop3->rop3);
|
||||
SelectObject(dc, prev_bitmap);
|
||||
DeleteObject(dc);
|
||||
ReleaseMutex(pixman_data->mutex);
|
||||
} else {
|
||||
surface_to_image(surface, &image);
|
||||
gdi_draw_image_rop3(canvas->dc, &rop3->src_area, bbox, image.pixels,
|
||||
image.stride, image.width, image.height, &bitmapmask, rop3->rop3, 0);
|
||||
}
|
||||
|
||||
unset_brush(canvas->dc, prev_hbrush);
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
unset_brush(canvas->dc, prev_hbrush);
|
||||
free_mask(&bitmapmask);
|
||||
|
||||
pixman_image_unref(surface);
|
||||
}
|
||||
|
||||
static void gdi_canvas_copy_bits(SpiceCanvas *spice_canvas, SpiceRect *bbox, SpiceClip *clip, SpicePoint *src_pos)
|
||||
@ -1433,8 +1534,8 @@ static void gdi_canvas_draw_text(SpiceCanvas *spice_canvas, SpiceRect *bbox, Spi
|
||||
HBRUSH prev_hbrush;
|
||||
HBRUSH hbrush;
|
||||
|
||||
hbrush = get_brush(canvas, &text->back_brush);
|
||||
Lock lock(*canvas->lock);
|
||||
hbrush = get_brush(canvas, &text->back_brush);
|
||||
prev_hbrush = set_brush(canvas->dc, hbrush, &text->back_brush);
|
||||
gdi_draw_bitmap_redrop(canvas->dc, bbox, bbox, canvas->dc, NULL,
|
||||
text->back_mode, 1);
|
||||
@ -1724,6 +1825,7 @@ SpiceCanvas *gdi_canvas_create(int width, int height,
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, SpiceImageCache *bits_cache
|
||||
#endif
|
||||
, SpiceImageSurfaces *surfaces
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
)
|
||||
{
|
||||
@ -1742,6 +1844,7 @@ SpiceCanvas *gdi_canvas_create(int width, int height,
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, bits_cache
|
||||
#endif
|
||||
, surfaces
|
||||
, glz_decoder);
|
||||
canvas->dc = dc;
|
||||
canvas->lock = lock;
|
||||
|
||||
@ -37,6 +37,7 @@ SpiceCanvas *gdi_canvas_create(int width, int height,
|
||||
HDC dc, class Mutex *lock, int bits,
|
||||
SpiceImageCache *bits_cache,
|
||||
SpicePaletteCache *palette_cache,
|
||||
SpiceImageSurfaces *surfaces,
|
||||
SpiceGlzDecoder *glz_decoder);
|
||||
|
||||
void gdi_canvas_init();
|
||||
|
||||
@ -828,6 +828,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, int depth
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, SpiceImageCache *bits_cache
|
||||
#endif
|
||||
, SpiceImageSurfaces *surfaces
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
#ifndef CAIRO_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
@ -854,6 +855,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, int depth
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, bits_cache
|
||||
#endif
|
||||
, surfaces
|
||||
, glz_decoder
|
||||
#ifndef CAIRO_CANVAS_NO_CHUNKS
|
||||
, virt_mapping
|
||||
|
||||
@ -28,6 +28,7 @@ SpiceCanvas *gl_canvas_create(int width, int height, int depth
|
||||
#elif defined(CAIRO_CANVAS_IMAGE_CACHE)
|
||||
, SpiceImageCache *bits_cache
|
||||
#endif
|
||||
, SpiceImageSurfaces *surfaces
|
||||
, SpiceGlzDecoder *glz_decoder
|
||||
#ifndef CAIRO_CANVAS_NO_CHUNKS
|
||||
, SpiceVirtMapping *virt_mapping
|
||||
|
||||
Loading…
Reference in New Issue
Block a user