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; }
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; }
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; }
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; }