static cairo_status_t _cairo_skia_context_rel_curve_to (void *abstract_cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3) { cairo_skia_context_t *cr = (cairo_skia_context_t *) abstract_cr; user_to_device_distance (cr, &dx1, &dy1); user_to_device_distance (cr, &dx2, &dy2); user_to_device_distance (cr, &dx3, &dy3); cr->path->rCubicTo (SkFloatToScalar (dx1), SkFloatToScalar (dy1), SkFloatToScalar (dx2), SkFloatToScalar (dy2), SkFloatToScalar (dx3), SkFloatToScalar (dy3)); return CAIRO_STATUS_SUCCESS; }
void snap_line_width(std::shared_ptr< cairo_t>& cr) { double x_width = line_width(cr); double y_width = x_width; user_to_device_distance(cr, x_width, y_width); /* If the line width is less than 1 then it will round to 0 and * disappear. Instead, we clamp it to 1.0, but we must preserve * its sign for the case of a reflecting transformation. */ double x_width_snapped = floor(x_width + 0.5); if (fabs(x_width_snapped) < 1.0) { if (x_width > 0) x_width_snapped = 1.0; else x_width_snapped = -1.0; } double y_width_snapped = floor(y_width + 0.5); if (fabs(y_width_snapped) < 1.0) { if (y_width > 0) y_width_snapped = 1.0; else y_width_snapped = -1.0; } double x_error = fabs(x_width - x_width_snapped); double y_error = fabs(y_width - y_width_snapped); device_to_user_distance(cr, x_width_snapped, y_width_snapped); if (x_error > y_error) line_width(cr, x_width_snapped); else line_width(cr, y_width_snapped); }
static cairo_status_t _cairo_skia_context_rel_line_to (void *abstract_cr, double dx, double dy) { cairo_skia_context_t *cr = (cairo_skia_context_t *) abstract_cr; user_to_device_distance (cr, &dx, &dy); cr->path->rLineTo (SkFloatToScalar (dx), SkFloatToScalar (dy)); return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _cairo_skia_context_rel_arc_to (void *abstract_cr, double dx1, double dy1, double dx2, double dy2, double radius) { cairo_skia_context_t *cr = (cairo_skia_context_t *) abstract_cr; #if 0 user_to_device_point (cr, &x1, &y1); user_to_device_point (cr, &x2, &y2); user_to_device_distance (cr, &radius, &radius); #endif cr->path->arcTo (SkFloatToScalar (dx1), SkFloatToScalar (dy1), SkFloatToScalar (dx2), SkFloatToScalar (dy2), SkFloatToScalar (radius)); return CAIRO_STATUS_SUCCESS; }
void snap_point_for_stroke(std::shared_ptr< cairo_t>& cr, double& x, double& y) { /* * Round in device space after adding the fractional portion of * one-half the (device space) line width. */ double x_width_dev_2 = line_width(cr); double y_width_dev_2 = x_width_dev_2; user_to_device_distance(cr, x_width_dev_2, y_width_dev_2); x_width_dev_2 *= 0.5; y_width_dev_2 *= 0.5; double x_offset = x_width_dev_2 - (int)(x_width_dev_2); double y_offset = y_width_dev_2 - (int)(y_width_dev_2); user_to_device(cr, x, y); x = floor(x + x_offset + 0.5); y = floor(y + y_offset + 0.5); x -= x_offset; y -= y_offset; device_to_user(cr, x, y); }