static cairo_status_t _cairo_skia_context_set_dash (void *abstract_cr, const double *dashes, int num_dashes, double offset) { cairo_skia_context_t *cr = (cairo_skia_context_t *) abstract_cr; SkScalar intervals_static[20]; SkScalar *intervals = intervals_static; if (num_dashes == 0) { cr->paint->setPathEffect (NULL); return CAIRO_STATUS_SUCCESS; } int loop = 0; if ((num_dashes & 1) != 0) { loop = 1; num_dashes <<= 1; } if (num_dashes > 20) intervals = new SkScalar[num_dashes]; int i = 0; do { for (int j = 0; i < num_dashes; j++) intervals[i++] = SkFloatToScalar (dashes[j]); } while (loop--); SkDashPathEffect *dash = new SkDashPathEffect (intervals, num_dashes, SkFloatToScalar (offset)); cr->paint->setPathEffect (dash); dash->unref (); return CAIRO_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; }