コード例 #1
0
cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface)
{
    cairo_surface_t *snapshot;
    cairo_status_t status;
    cairo_pattern_union_t pattern;
    cairo_image_surface_t *image;
    void *image_extra;

    status = _cairo_surface_acquire_source_image (surface,
						  &image, &image_extra);
    if (status)
	return _cairo_surface_create_in_error (status);

    snapshot = cairo_image_surface_create (image->format,
					   image->width,
					   image->height);
    if (cairo_surface_status (snapshot)) {
	_cairo_surface_release_source_image (surface,
					     image, image_extra);
	return snapshot;
    }

    _cairo_pattern_init_for_surface (&pattern.surface, &image->base);

    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
			               &pattern.base,
				       NULL,
				       snapshot,
				       0, 0,
				       0, 0,
				       0, 0,
				       image->width,
				       image->height);

    _cairo_pattern_fini (&pattern.base);
    _cairo_surface_release_source_image (surface,
					 image, image_extra);

    if (status) {
	cairo_surface_destroy (snapshot);
	return _cairo_surface_create_in_error (status);
    }

    snapshot->device_transform = surface->device_transform;
    snapshot->device_transform_inverse = surface->device_transform_inverse;

    snapshot->is_snapshot = TRUE;

    return snapshot;
}
コード例 #2
0
cairo_surface_t *
_cairo_surface_fallback_snapshot (cairo_surface_t *surface)
{
    cairo_surface_t *snapshot;
    cairo_status_t status;
    cairo_format_t format;
    cairo_surface_pattern_t pattern;
    cairo_image_surface_t *image;
    void *image_extra;

    status = _cairo_surface_acquire_source_image (surface,
						  &image, &image_extra);
    if (unlikely (status))
	return _cairo_surface_create_in_error (status);

    format = image->format;
    if (format == CAIRO_FORMAT_INVALID) {
	/* Non-standard images formats can be generated when retrieving
	 * images from unusual xservers, for example.
	 */
	format = _cairo_format_from_content (image->base.content);
    }
    snapshot = cairo_image_surface_create (format,
					   image->width,
					   image->height);
    if (cairo_surface_status (snapshot)) {
	_cairo_surface_release_source_image (surface, image, image_extra);
	return snapshot;
    }

    _cairo_pattern_init_for_surface (&pattern, &image->base);
    status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
			               &pattern.base,
				       NULL,
				       snapshot,
				       0, 0,
				       0, 0,
				       0, 0,
				       image->width,
				       image->height);
    _cairo_pattern_fini (&pattern.base);
    _cairo_surface_release_source_image (surface, image, image_extra);
    if (unlikely (status)) {
	cairo_surface_destroy (snapshot);
	return _cairo_surface_create_in_error (status);
    }

    return snapshot;
}
コード例 #3
0
static cairo_status_t
_cairo_skia_context_set_source (void *abstract_cr,
				cairo_pattern_t *source)
{
    cairo_skia_context_t *cr = (cairo_skia_context_t *) abstract_cr;
    SkColor color;

    if (cr->source != NULL) {
	if (cr->source_image != NULL) {
	    _cairo_surface_release_source_image (cr->source, cr->source_image, cr->source_extra);
	    cr->source_image = NULL;
	}
	cairo_surface_destroy (cr->source);
	cr->source = NULL;
    }

    if (pattern_to_sk_color (source, color)) {
	cr->paint->setColor (color);
    } else {
	SkShader *shader = source_to_sk_shader (cr, source);
	if (shader == NULL) {
	    UNSUPPORTED;
	    return CAIRO_STATUS_SUCCESS;
	}

	cr->paint->setShader (shader);
	shader->unref ();

	cr->paint->setFilterBitmap (pattern_filter_to_sk (source));
    }

    /* XXX change notification */
    return CAIRO_STATUS_SUCCESS;
}
コード例 #4
0
static cairo_int_status_t
_cairo_type3_glyph_surface_paint (void			*abstract_surface,
				  cairo_operator_t	 op,
				  cairo_pattern_t	*source)
{
    cairo_type3_glyph_surface_t *surface = abstract_surface;
    cairo_surface_pattern_t *pattern;
    cairo_image_surface_t *image;
    void *image_extra;
    cairo_status_t status;

    if (source->type != CAIRO_PATTERN_TYPE_SURFACE)
	return CAIRO_INT_STATUS_IMAGE_FALLBACK;

    pattern = (cairo_surface_pattern_t *) source;
    status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
    if (status)
	goto fail;

    status = _cairo_type3_glyph_surface_emit_image_pattern (surface,
							    image,
							    &pattern->base.matrix);

fail:
    _cairo_surface_release_source_image (pattern->surface, image, image_extra);

    return status;
}
コード例 #5
0
static void
_cairo_skia_context_destroy (void *abstract_cr)
{
    cairo_skia_context_t *cr = (cairo_skia_context_t *) abstract_cr;

    cr->path->reset ();
    cr->paint->reset ();

    delete cr->canvas;

    cairo_surface_destroy (&cr->target->image.base);
    cairo_surface_destroy (&cr->original->image.base);

    if (cr->source != NULL) {
	if (cr->source_image != NULL) {
	    _cairo_surface_release_source_image (cr->source, cr->source_image, cr->source_extra);
	    cr->source_image = NULL;
	}
	cairo_surface_destroy (cr->source);
	cr->source = NULL;
    }

    _cairo_fini (&cr->base);

    _freed_pool_put (&context_pool, cr);
}
コード例 #6
0
ファイル: cairo-surface-wrapper.c プロジェクト: igagis/cairo
void
_cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper,
					     cairo_image_surface_t  *image,
					     void                   *image_extra)
{
    _cairo_surface_release_source_image (wrapper->target, image, image_extra);
}
コード例 #7
0
static cairo_status_t
_cairo_xml_emit_surface (cairo_xml_t *xml,
			 const cairo_surface_pattern_t *pattern)
{
    cairo_surface_t *source = pattern->surface;
    cairo_status_t status;

    if (_cairo_surface_is_recording (source)) {
	status = cairo_xml_for_recording_surface (&xml->base, source);
    } else {
	cairo_image_surface_t *image;
	void *image_extra;

	status = _cairo_surface_acquire_source_image (source,
						      &image, &image_extra);
	if (unlikely (status))
	    return status;

	status = _cairo_xml_emit_image (xml, image);

	_cairo_surface_release_source_image (source, image, image_extra);
    }

    return status;
}
コード例 #8
0
static void
_cairo_surface_snapshot_release_source_image (void                   *abstract_surface,
					      cairo_image_surface_t  *image,
					      void                   *extra)
{
    cairo_surface_snapshot_t *surface = abstract_surface;

    _cairo_surface_release_source_image (surface->target, image, extra);
}
コード例 #9
0
static void
_test_fallback_surface_release_source_image (void	     *abstract_surface,
					     cairo_image_surface_t	*image,
					     void		  *image_extra)
{
    test_fallback_surface_t *surface = abstract_surface;

    _cairo_surface_release_source_image (surface->backing,
					 image, image_extra);
}
コード例 #10
0
ファイル: cairo-skia-surface.cpp プロジェクト: AZed/cairo
static cairo_int_status_t
_cairo_skia_surface_paint (void *asurface,
			   cairo_operator_t op,
			   const cairo_pattern_t *source,
			   cairo_clip_t *clip)
{
    cairo_skia_surface_t *surface = (cairo_skia_surface_t *) asurface;
    cairo_image_surface_t *image = NULL;
    cairo_status_t status;
    void *image_extra;
    SkColor color;

    status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
    if (unlikely (status))
	return (cairo_int_status_t) status;

    if (pattern_to_sk_color (source, color)) {
	surface->canvas->drawColor (color, operator_to_sk (op));
	return CAIRO_INT_STATUS_SUCCESS;
    }

    SkMatrix bitmapMatrix;
    SkBitmap *bitmap = pattern_to_sk_bitmap (surface, source, &bitmapMatrix,
					     &image, &image_extra);
    SkShader *shader = NULL;
    if (!bitmap)
	shader = pattern_to_sk_shader (surface, source, &image, &image_extra);

    if (!bitmap && !shader)
	return UNSUPPORTED("pattern to bitmap and shader conversion");

    SkPaint paint;
    paint.setFilterBitmap (pattern_filter_to_sk (source));
    paint.setXfermodeMode (operator_to_sk (op));

    if (shader) {
	paint.setShader (shader);
	surface->canvas->drawPaint (paint);
    } else {
	surface->canvas->drawBitmapMatrix (*bitmap, bitmapMatrix, &paint);
    }

    if (bitmap)
	delete bitmap;
    if (shader)
	shader->unref ();

    if (image != NULL) {
	_cairo_surface_release_source_image (&surface->base,
					     image, image_extra);
    }

    return CAIRO_INT_STATUS_SUCCESS;
}
コード例 #11
0
static void
_cairo_surface_snapshot_release_source_image (void                   *abstract_surface,
					      cairo_image_surface_t  *image,
					      void                   *_extra)
{
    struct snapshot_extra *extra = _extra;

    _cairo_surface_release_source_image (extra->target, image, extra->extra);
    cairo_surface_destroy (extra->target);
    free (extra);
}
コード例 #12
0
static void
_cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
{
    cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface;
    cairo_image_surface_t *image;
    cairo_image_surface_t *clone;
    void *extra;
    cairo_status_t status;

    /* We need to make an image copy of the original surface since the
     * snapshot may exceed the lifetime of the original device, i.e.
     * when we later need to use the snapshot the data may have already
     * been lost.
     */

    status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
    if (unlikely (status)) {
	snapshot->target = _cairo_surface_create_in_error (status);
	status = _cairo_surface_set_error (surface, status);
	return;
    }

    clone = (cairo_image_surface_t *)
	_cairo_image_surface_create_with_pixman_format (NULL,
							image->pixman_format,
							image->width,
							image->height,
							0);
    if (likely (clone->base.status == CAIRO_STATUS_SUCCESS)) {
	if (clone->stride == image->stride) {
	    memcpy (clone->data, image->data, image->stride * image->height);
	} else {
	    pixman_image_composite32 (PIXMAN_OP_SRC,
				      image->pixman_image, NULL, clone->pixman_image,
				      0, 0,
				      0, 0,
				      0, 0,
				      image->width, image->height);
	}
	clone->base.is_clear = FALSE;

	snapshot->clone = &clone->base;
    } else {
	snapshot->clone = &clone->base;
	status = _cairo_surface_set_error (surface, clone->base.status);
    }

    _cairo_surface_release_source_image (snapshot->target, image, extra);
    snapshot->target = snapshot->clone;
    snapshot->base.type = snapshot->target->type;
}
コード例 #13
0
ファイル: cairo-xcb-surface.c プロジェクト: ghub/NVprSDK
static void
_cairo_xcb_surface_release_source_image (void *abstract_surface,
					 cairo_image_surface_t *image,
					 void *image_extra)
{
    cairo_xcb_surface_t *surface = abstract_surface;

    if (surface->drm != NULL && ! surface->marked_dirty) {
	return _cairo_surface_release_source_image (surface->drm,
						    image, image_extra);
    }

    cairo_surface_destroy (&image->base);
}
コード例 #14
0
ファイル: cairo-skia-surface.cpp プロジェクト: AZed/cairo
static cairo_int_status_t
_cairo_skia_surface_fill (void *asurface,
			  cairo_operator_t op,
			  const cairo_pattern_t *source,
			  cairo_path_fixed_t *path,
			  cairo_fill_rule_t fill_rule,
			  double tolerance,
			  cairo_antialias_t antialias,
			  cairo_clip_t *clip)
{
    cairo_skia_surface_t *surface = (cairo_skia_surface_t *) asurface;
    cairo_image_surface_t *image = NULL;
    cairo_status_t status;
    void *image_extra;

    status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
    if (unlikely (status))
	return (cairo_int_status_t) status;


    SkPaint paint;
    paint.setStyle (SkPaint::kFill_Style);

    SkColor color;
    if (pattern_to_sk_color (source, color)) {
	paint.setColor (color);
    } else {
	SkShader *shader = pattern_to_sk_shader (surface,
						 source, &image, &image_extra);
	if (shader == NULL)
	    return UNSUPPORTED("pattern to shader conversion");

	paint.setShader (shader);
	shader->unref ();

	paint.setFilterBitmap (pattern_filter_to_sk (source));
    }

    paint.setXfermodeMode (operator_to_sk (op));
    paint.setAntiAlias (antialias != CAIRO_ANTIALIAS_NONE);

    surface->canvas->drawPath (path_to_sk (path, fill_rule), paint);

    if (image != NULL) {
	_cairo_surface_release_source_image (&surface->base,
					     image, image_extra);
    }

    return CAIRO_INT_STATUS_SUCCESS;
}
コード例 #15
0
static void
_cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface)
{
    cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface;
    cairo_image_surface_t *image;
    cairo_surface_t *clone;
    void *extra;
    cairo_status_t status;

    TRACE ((stderr, "%s: target=%d\n",
	    __FUNCTION__, snapshot->target->unique_id));

    /* We need to make an image copy of the original surface since the
     * snapshot may exceed the lifetime of the original device, i.e.
     * when we later need to use the snapshot the data may have already
     * been lost.
     */

    CAIRO_MUTEX_LOCK (snapshot->mutex);

    if (snapshot->target->backend->snapshot != NULL) {
	clone = snapshot->target->backend->snapshot (snapshot->target);
	if (clone != NULL) {
	    assert (clone->status || ! _cairo_surface_is_snapshot (clone));
	    goto done;
	}
    }

    /* XXX copy to a similar surface, leave acquisition till later?
     * We should probably leave such decisions to the backend in case we
     * rely upon devices/connections like Xlib.
    */
    status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra);
    if (unlikely (status)) {
	snapshot->target = _cairo_surface_create_in_error (status);
	status = _cairo_surface_set_error (surface, status);
	goto unlock;
    }
    clone = image->base.backend->snapshot (&image->base);
    _cairo_surface_release_source_image (snapshot->target, image, extra);

done:
    status = _cairo_surface_set_error (surface, clone->status);
    snapshot->target = snapshot->clone = clone;
    snapshot->base.type = clone->type;
unlock:
    CAIRO_MUTEX_UNLOCK (snapshot->mutex);
}
コード例 #16
0
ファイル: cairo-skia-surface.cpp プロジェクト: AZed/cairo
static cairo_int_status_t
_cairo_skia_surface_stroke (void *asurface,
			    cairo_operator_t op,
			    const cairo_pattern_t *source,
			    cairo_path_fixed_t *path,
			    cairo_stroke_style_t *style,
			    cairo_matrix_t *ctm,
			    cairo_matrix_t *ctm_inverse,
			    double tolerance,
			    cairo_antialias_t antialias,
			    cairo_clip_t *clip)
{
    cairo_skia_surface_t *surface = (cairo_skia_surface_t *) asurface;
    cairo_image_surface_t *image = NULL;
    cairo_status_t status;
    void *image_extra;

    status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
    if (unlikely (status))
	return (cairo_int_status_t) status;

    SkPaint paint;
    paint.setStyle (SkPaint::kStroke_Style);

    SkColor color;
    if (pattern_to_sk_color (source, color)) {
	paint.setColor (color);
    } else {
	SkShader *shader = pattern_to_sk_shader (surface,
						 source, &image, &image_extra);
	if (shader == NULL)
	    return UNSUPPORTED("pattern to shader conversion");

	paint.setShader (shader);
	shader->unref ();

	paint.setFilterBitmap (pattern_filter_to_sk (source));
    }

    paint.setXfermodeMode (operator_to_sk (op));
    paint.setAntiAlias (antialias != CAIRO_ANTIALIAS_NONE);

    /* Convert the various stroke rendering bits */
    paint.setStrokeWidth (SkFloatToScalar (style->line_width));
    paint.setStrokeMiter (SkFloatToScalar (style->miter_limit));

    static const SkPaint::Cap capMap[] = {
	SkPaint::kButt_Cap,
	SkPaint::kRound_Cap,
	SkPaint::kSquare_Cap
    };
    paint.setStrokeCap (capMap[style->line_cap]);

    static const SkPaint::Join joinMap[] = {
	SkPaint::kMiter_Join,
	SkPaint::kRound_Join,
	SkPaint::kBevel_Join
    };
    paint.setStrokeJoin (joinMap[style->line_join]);

    /* If we have a dash pattern, we need to
     * create a SkDashPathEffect and set it on the Paint.
     */
    if (style->dash != NULL) {
	SkScalar intervals_static[20];
	SkScalar *intervals = intervals_static;

	int loop = 0;
	unsigned int dash_count = style->num_dashes;
	if ((dash_count & 1) != 0) {
	    loop = 1;
	    dash_count <<= 1;
	}

	if (dash_count > 20)
	    intervals = new SkScalar[dash_count];

	unsigned int i = 0;
	do {
	    for (unsigned int j = 0; i < style->num_dashes; j++)
		intervals[i++] = SkFloatToScalar (style->dash[j]);
	} while (loop--);

	SkDashPathEffect *dash = new SkDashPathEffect (intervals,
						       dash_count,
						       SkFloatToScalar (style->dash_offset));

	paint.setPathEffect (dash);
	dash->unref ();
    }

    surface->canvas->save (SkCanvas::kMatrix_SaveFlag);
    surface->canvas->concat (matrix_to_sk (*ctm));
    surface->canvas->drawPath (path_to_sk (path, ctm_inverse), paint);
    surface->canvas->restore ();

    if (image != NULL) {
	_cairo_surface_release_source_image (&surface->base,
					     image, image_extra);
    }

    return CAIRO_INT_STATUS_SUCCESS;
}
コード例 #17
0
    ~PatternToBrushConverter () {
	if (mAcquiredImageParent)
	    _cairo_surface_release_source_image (mAcquiredImageParent, mAcquiredImage, mAcquiredImageExtra);
    }
コード例 #18
0
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;
}