Beispiel #1
0
static cairo_status_t
cpc_line_to (void *closure, const cairo_point_t *point)
{
    struct cpc *cpc = static_cast <struct cpc *> (closure);
    if (cpc->matrix) {
	double x = _cairo_fixed_to_double (point->x);
	double y = _cairo_fixed_to_double (point->y);
	cairo_matrix_transform_point (cpc->matrix, &x, &y);
	cpc->skPath.lineTo (SkFloatToScalar (x), SkFloatToScalar (y));
    } else {
	cpc->skPath.lineTo (CAIRO_FIXED_TO_SK_SCALAR (point->x),
			    CAIRO_FIXED_TO_SK_SCALAR (point->y));
    }
    return CAIRO_STATUS_SUCCESS;
}
Beispiel #2
0
static cairo_status_t
cpc_curve_to (void *closure,
	      const cairo_point_t *p0,
	      const cairo_point_t *p1,
	      const cairo_point_t *p2)
{
    struct cpc *cpc = static_cast <struct cpc *> (closure);
    if (cpc->matrix) {
	double x0 = _cairo_fixed_to_double (p0->x);
	double y0 = _cairo_fixed_to_double (p0->y);
	double x1 = _cairo_fixed_to_double (p1->x);
	double y1 = _cairo_fixed_to_double (p1->y);
	double x2 = _cairo_fixed_to_double (p2->x);
	double y2 = _cairo_fixed_to_double (p2->y);
	cairo_matrix_transform_point (cpc->matrix, &x0, &y0);
	cairo_matrix_transform_point (cpc->matrix, &x1, &y1);
	cairo_matrix_transform_point (cpc->matrix, &x2, &y2);

	cpc->skPath.cubicTo (SkFloatToScalar (x0),
			     SkFloatToScalar (y0),
			     SkFloatToScalar (x1),
			     SkFloatToScalar (y1),
			     SkFloatToScalar (x2),
			     SkFloatToScalar (y2));
    } else {
	cpc->skPath.cubicTo (CAIRO_FIXED_TO_SK_SCALAR (p0->x),
			     CAIRO_FIXED_TO_SK_SCALAR (p0->y),
			     CAIRO_FIXED_TO_SK_SCALAR (p1->x),
			     CAIRO_FIXED_TO_SK_SCALAR (p1->y),
			     CAIRO_FIXED_TO_SK_SCALAR (p2->x),
			     CAIRO_FIXED_TO_SK_SCALAR (p2->y));
    }
    return CAIRO_STATUS_SUCCESS;
}
static SkShader*
source_to_sk_shader (cairo_skia_context_t *cr,
		     const cairo_pattern_t *pattern)
{
    SkShader *shader = NULL;

    if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
	cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
	return new SkColorShader (color_to_sk (solid->color));
    } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
	cairo_surface_t *surface = surface_from_pattern (pattern);

	cr->source = cairo_surface_reference (surface);

	if (surface->type == CAIRO_SURFACE_TYPE_SKIA) {
	    cairo_skia_surface_t *esurf = (cairo_skia_surface_t *) surface;

	    shader = SkShader::CreateBitmapShader (*esurf->bitmap,
						   extend_to_sk (pattern->extend),
						   extend_to_sk (pattern->extend));
	} else {
	    SkBitmap bitmap;

	    if (! _cairo_surface_is_image (surface)) {
		cairo_status_t status;

		status = _cairo_surface_acquire_source_image (surface,
							      &cr->source_image,
							      &cr->source_extra);
		if (status)
		    return NULL;

		surface = &cr->source_image->base;
	    }

	    if (unlikely (! surface_to_sk_bitmap (surface, bitmap)))
		return NULL;

	    shader = SkShader::CreateBitmapShader (bitmap,
						   extend_to_sk (pattern->extend),
						   extend_to_sk (pattern->extend));
	}
    } else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR
	       /* || pattern->type == CAIRO_PATTERN_TYPE_RADIAL */)
    {
	cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern;
	SkColor colors_stack[10];
	SkScalar pos_stack[10];
	SkColor *colors = colors_stack;
	SkScalar *pos = pos_stack;

	if (gradient->n_stops > 10) {
	    colors = new SkColor[gradient->n_stops];
	    pos = new SkScalar[gradient->n_stops];
	}

	for (unsigned int i = 0; i < gradient->n_stops; i++) {
	    pos[i] = CAIRO_FIXED_TO_SK_SCALAR (gradient->stops[i].offset);
	    colors[i] = color_stop_to_sk (gradient->stops[i].color);
	}

	if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
	    cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient;
	    SkPoint points[2];

	    points[0].set (SkFloatToScalar (linear->pd1.x),
			   SkFloatToScalar (linear->pd1.y));
	    points[1].set (SkFloatToScalar (linear->pd2.x),
			   SkFloatToScalar (linear->pd2.y));
	    shader = SkGradientShader::CreateLinear (points, colors, pos, gradient->n_stops,
						     extend_to_sk (pattern->extend));
	} else {
	    // XXX todo -- implement real radial shaders in Skia
	}

	if (gradient->n_stops > 10) {
	    delete [] colors;
	    delete [] pos;
	}
    }

    if (shader && ! _cairo_matrix_is_identity (&pattern->matrix))
	shader->setLocalMatrix (matrix_inverse_to_sk (pattern->matrix));

    return shader;
}