Ejemplo n.º 1
0
/**
 * cairo_win32_surface_get_dc:
 * @surface: a #cairo_surface_t
 *
 * Returns the HDC associated with this surface, or %NULL if none.
 * Also returns %NULL if the surface is not a win32 surface.
 *
 * A call to cairo_surface_flush() is required before using the HDC to
 * ensure that all pending drawing operations are finished and to
 * restore any temporary modification cairo has made to its state. A
 * call to cairo_surface_mark_dirty() is required after the state or
 * the content of the HDC has been modified.
 *
 * Return value: HDC or %NULL if no HDC available.
 *
 * Since: 1.2
 **/
HDC
cairo_win32_surface_get_dc (cairo_surface_t *surface)
{
    if (surface->backend->type == CAIRO_SURFACE_TYPE_WIN32)
        return to_win32_surface(surface)->dc;

    if (_cairo_surface_is_paginated (surface)) {
        cairo_surface_t *target = _cairo_paginated_surface_get_target (surface);
        if (target->backend->type == CAIRO_SURFACE_TYPE_WIN32_PRINTING)
            return to_win32_surface(target)->dc;
    }

    return NULL;
}
static cairo_int_status_t
_cairo_win32_display_surface_unmap_image (void                    *abstract_surface,
					  cairo_image_surface_t   *image)
{
    cairo_win32_display_surface_t *surface = abstract_surface;

    /* Delay the download until the next flush, which means we also need
     * to make sure our sources rare flushed.
     */
    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, to_win32_surface(surface)->base.unique_id));

    if (surface->fallback) {
	cairo_rectangle_int_t r;

	r.x = image->base.device_transform_inverse.x0;
	r.y = image->base.device_transform_inverse.y0;
	r.width  = image->width;
	r.height = image->height;

	TRACE ((stderr, "%s: adding damage (%d,%d)x(%d,%d)\n",
		__FUNCTION__, r.x, r.y, r.width, r.height));
	surface->fallback->damage =
	    _cairo_damage_add_rectangle (surface->fallback->damage, &r);
	surface = to_win32_display_surface (surface->fallback);
    }

    return _cairo_surface_unmap_image (surface->image, image);
}
Ejemplo n.º 3
0
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;
    cairo_win32_surface_t *src;

    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;

    src = to_win32_surface(surface);

    if (src->format != dst->win32.format &&
	!(src->format == CAIRO_FORMAT_ARGB32 && dst->win32.format == CAIRO_FORMAT_RGB24))
    {
	/* forbid copy different surfaces unless it is from argb32 to
	 * rgb (dropping alpha) */
        return CAIRO_INT_STATUS_UNSUPPORTED;
    }
    cb.dst = dst->win32.dc;
    cb.src = src->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, 0);
    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_image_surface_t *
_cairo_win32_display_surface_map_to_image (void                    *abstract_surface,
					   const cairo_rectangle_int_t   *extents)
{
    cairo_win32_display_surface_t *surface = abstract_surface;
    cairo_status_t status;

    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, surface->win32.base.unique_id));

    if (surface->image)
	goto done;

    if (surface->fallback == NULL) {
	surface->fallback =
	    _cairo_win32_display_surface_create_for_dc (surface->win32.dc,
							surface->win32.format,
							surface->win32.extents.width,
							surface->win32.extents.height);
	if (unlikely (status = surface->fallback->status))
	    goto err;

	if (!BitBlt (to_win32_surface(surface->fallback)->dc,
		     0, 0,
		     surface->win32.extents.width,
		     surface->win32.extents.height,
		     surface->win32.dc,
		     0, 0,
		     SRCCOPY)) {
	    status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
	    goto err;
	}
    }

    surface = to_win32_display_surface (surface->fallback);
done:
    GdiFlush();
    return _cairo_surface_map_to_image (surface->image, extents);

err:
    cairo_surface_destroy (surface->fallback);
    surface->fallback = NULL;

    return _cairo_image_surface_create_in_error (status);
}
static cairo_int_status_t
_cairo_win32_display_surface_mask (void				*surface,
				   cairo_operator_t		 op,
				   const cairo_pattern_t	*source,
				   const cairo_pattern_t	*mask,
				   const cairo_clip_t		*clip)
{
    cairo_win32_device_t *device = to_win32_device_from_surface (surface);

    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, to_win32_surface(surface)->base.unique_id));

    if (clip == NULL && op == CAIRO_OPERATOR_SOURCE)
	_cairo_win32_display_surface_discard_fallback (surface);

    return _cairo_compositor_mask (device->compositor,
				   surface, op, source, mask, clip);
}
static cairo_int_status_t
_cairo_win32_display_surface_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_win32_device_t *device = to_win32_device_from_surface (surface);

    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, to_win32_surface(surface)->base.unique_id));

    return _cairo_compositor_glyphs (device->compositor, surface,
				     op, source,
				     glyphs, num_glyphs, scaled_font,
				     clip);
}
static cairo_int_status_t
_cairo_win32_display_surface_fill (void				*surface,
				   cairo_operator_t		 op,
				   const cairo_pattern_t	*source,
				   const cairo_path_fixed_t	*path,
				   cairo_fill_rule_t		 fill_rule,
				   double			 tolerance,
				   cairo_antialias_t		 antialias,
				   const cairo_clip_t		*clip)
{
    cairo_win32_device_t *device = to_win32_device_from_surface (surface);

    TRACE ((stderr, "%s (surface=%d)\n",
	    __FUNCTION__, to_win32_surface(surface)->base.unique_id));

    return _cairo_compositor_fill (device->compositor, surface,
				   op, source, path,
				   fill_rule, tolerance, antialias,
				   clip);
}