static cairo_int_status_t
_cairo_qt_surface_set_clip (cairo_qt_surface_t *qs,
			    const cairo_clip_t *clip)
{
    cairo_int_status_t status;

    D(fprintf(stderr, "q[%p] intersect_clip_path %s\n", abstract_surface, path ? "(path)" : "(clear)"));

    if (clip == NULL) {
	_cairo_surface_clipper_reset (&qs->clipper);
        // How the clip path is reset depends on whether we own p or not
        if (qs->pixmap || qs->image) {
            // we own p
            qs->p->setClipping (false);
        } else {
            qs->p->restore ();
            qs->p->save ();
        }

        return CAIRO_INT_STATUS_SUCCESS;
    }

#if ENABLE_FAST_CLIP
    // Qt will implicitly enable clipping, and will use ReplaceClip
    // instead of IntersectClip if clipping was disabled before

    // Note: Qt is really bad at dealing with clip paths.  It doesn't
    // seem to usefully recognize rectangular paths, instead going down
    // extremely slow paths whenever a clip path is set.  So,
    // we do a bunch of work here to try to get rectangles or regions
    // down to Qt for clipping.

    cairo_region_t *clip_region = NULL;

    status = _cairo_clip_get_region (clip, &clip_region);
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	// We weren't able to extract a region from the traps.
	// Just hand the path down to QPainter.
	status = (cairo_int_status_t)
	    _cairo_surface_clipper_set_clip (&qs->clipper, clip);
    } else if (status == CAIRO_INT_STATUS_SUCCESS) {
	_cairo_qt_surface_set_clip_region (qs, clip_region);
	status = CAIRO_INT_STATUS_SUCCESS;
    }
#else
    status = (cairo_int_status_t)
	_cairo_surface_clipper_set_clip (&qs->clipper, clip);
#endif

    return status;
}
Esempio n. 2
0
static cairo_int_status_t
_cairo_type3_glyph_surface_stroke (void			*abstract_surface,
				   cairo_operator_t	 op,
				   const cairo_pattern_t *source,
				   cairo_path_fixed_t	*path,
				   const cairo_stroke_style_t	*style,
				   const cairo_matrix_t	*ctm,
				   const cairo_matrix_t	*ctm_inverse,
				   double		 tolerance,
				   cairo_antialias_t	 antialias,
				   cairo_clip_t		*clip)
{
    cairo_type3_glyph_surface_t *surface = abstract_surface;
    cairo_int_status_t status;

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

    return _cairo_pdf_operators_stroke (&surface->pdf_operators,
					path,
					style,
					ctm,
					ctm_inverse);
}
Esempio n. 3
0
static cairo_int_status_t
_cairo_type3_glyph_surface_paint (void			*abstract_surface,
				  cairo_operator_t	 op,
				  const cairo_pattern_t	*source,
				  cairo_clip_t		*clip)
{
    cairo_type3_glyph_surface_t *surface = abstract_surface;
    const 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;

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

    pattern = (const cairo_surface_pattern_t *) source;
    status = _cairo_surface_acquire_source_image (pattern->surface,
						  &image, &image_extra);
    if (unlikely (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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
static cairo_int_status_t
_cairo_type3_glyph_surface_show_glyphs (void		     *abstract_surface,
					cairo_operator_t      op,
					const cairo_pattern_t *source,
					cairo_glyph_t        *glyphs,
					int		      num_glyphs,
					cairo_scaled_font_t  *scaled_font,
					cairo_clip_t	     *clip,
					int		     *remaining_glyphs)
{
    cairo_type3_glyph_surface_t *surface = abstract_surface;
    cairo_int_status_t status;
    cairo_scaled_font_t *font;
    cairo_matrix_t new_ctm, invert_y_axis;

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

    cairo_matrix_init_scale (&invert_y_axis, 1, -1);
    cairo_matrix_multiply (&new_ctm, &invert_y_axis, &scaled_font->ctm);
    cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &new_ctm);
    font = cairo_scaled_font_create (scaled_font->font_face,
				     &scaled_font->font_matrix,
				     &new_ctm,
				     &scaled_font->options);
    if (unlikely (font->status))
	return font->status;

    status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
						    NULL, 0,
						    glyphs, num_glyphs,
						    NULL, 0,
						    FALSE,
						    font);

    cairo_scaled_font_destroy (font);

    return status;
}
Esempio n. 7
0
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;
}