void Context::copyPathFlat( cinder::Shape2d *resultPath ) { resultPath->clear(); cairo_path_t *path = cairo_copy_path_flat( mCairo ); convertCairoToCinderPath( path, resultPath ); cairo_path_destroy( path ); }
// cairo_public cairo_path_t * // cairo_copy_path_flat (cairo_t *cr); static int l_cairo_copy_path_flat(lua_State* L) { cairo_t *cr = get_cairo_t (L, 1); cairo_path_t *v = cairo_copy_path_flat (cr); lua_pushlightuserdata(L, v); return 1; }
static PyObject * pycairo_copy_path_flat (PycairoContext *o) { cairo_path_t *cp; Py_BEGIN_ALLOW_THREADS; cp = cairo_copy_path_flat (o->ctx); Py_END_ALLOW_THREADS; return PycairoPath_FromPath (cp); }
already_AddRefed<gfxFlattenedPath> gfxContext::GetFlattenedPath() { gfxFlattenedPath *path = new gfxFlattenedPath(cairo_copy_path_flat(mCairo)); NS_IF_ADDREF(path); return path; }
static VALUE cr_copy_path_flat (VALUE self) { cairo_path_t *path; path = cairo_copy_path_flat (_SELF); rb_cairo_check_status (path->status); return CRPATH2RVAL (path); }
void cairo_to_clipper(cairo_t* cr, Polygons &pg, int scaling_factor, Transform transform) { if (scaling_factor > 8 || scaling_factor < 0) throw clipperCairoException("cairo_to_clipper: invalid scaling factor"); double scaling = std::pow((double)10, scaling_factor); pg.clear(); cairo_path_t *path = cairo_copy_path_flat(cr); int poly_count = 0; for (int i = 0; i < path->num_data; i += path->data[i].header.length) { if( path->data[i].header.type == CAIRO_PATH_CLOSE_PATH) poly_count++; } pg.resize(poly_count); int i = 0, pc = 0; while (pc < poly_count) { int vert_count = 1; int j = i; while(j < path->num_data && path->data[j].header.type != CAIRO_PATH_CLOSE_PATH) { if (path->data[j].header.type == CAIRO_PATH_LINE_TO) vert_count++; j += path->data[j].header.length; } pg[pc].resize(vert_count); if (path->data[i].header.type != CAIRO_PATH_MOVE_TO) { pg.resize(pc); break; } pg[pc][0].X = Round(path->data[i+1].point.x *scaling); pg[pc][0].Y = Round(path->data[i+1].point.y *scaling); if (transform != tNone) transform_point(cr, transform, &pg[pc][0].X, &pg[pc][0].Y); i += path->data[i].header.length; j = 1; while (j < vert_count && i < path->num_data && path->data[i].header.type == CAIRO_PATH_LINE_TO) { pg[pc][j].X = Round(path->data[i+1].point.x *scaling); pg[pc][j].Y = Round(path->data[i+1].point.y *scaling); if (transform != tNone) transform_point(cr, transform, &pg[pc][j].X, &pg[pc][j].Y); j++; i += path->data[i].header.length; } pc++; i += path->data[i].header.length; } cairo_path_destroy(path); }
static void _rsvg_node_text_type_text_path (RsvgNodeTextPath * self, RsvgDrawingCtx * ctx, gdouble * x, gdouble * y, gboolean * lastwasspace, gboolean usetextonly) { if (self->link && self->link->type == RSVG_NODE_TYPE_PATH) { guint i; // Resolve the xlink:href id and get its cairo path object cairo_path_t *path = ((RsvgNodePath *)self->link)->path; // Get the cairo_t context RsvgCairoRender *render = RSVG_CAIRO_RENDER (ctx->render); cairo_t *cr = render->cr; // Flatten path cairo_save(cr); cairo_new_path(cr); cairo_append_path(cr, path); path = cairo_copy_path_flat (cr); cairo_restore(cr); // TODO recursively draw children rsvg_push_discrete_layer (ctx); for (i = 0; i < self->super.children->len; i++) { RsvgNode *node = g_ptr_array_index (self->super.children, i); RsvgNodeType type = RSVG_NODE_TYPE (node); if (type == RSVG_NODE_TYPE_CHARS) { RsvgNodeChars *chars = (RsvgNodeChars *) node; GString *str = _rsvg_text_chomp (rsvg_current_state (ctx), chars->contents, lastwasspace); double offset = 0; // Factor in start offset // Handle percentages as percent of path length if (self->startOffset.factor == 'p') { offset = self->startOffset.length *_rsvg_path_length(path); } else { offset = _rsvg_css_normalize_length (&self->startOffset, ctx, 'h'); } if (PANGO_GRAVITY_IS_VERTICAL (rsvg_current_state(ctx)->text_gravity)) *y += offset; else *x += offset; draw_twisted (ctx, cr, path, x, y, str->str); g_string_free (str, TRUE); } } rsvg_pop_discrete_layer (ctx); cairo_path_destroy (path); } }
static int cr_copy_path_flat (lua_State *L) { cairo_t **obj = luaL_checkudata(L, 1, OOCAIRO_MT_NAME_CONTEXT); cairo_path_t **path = lua_newuserdata(L, sizeof(cairo_path_t *)); *path = 0; luaL_getmetatable(L, OOCAIRO_MT_NAME_PATH); lua_setmetatable(L, -2); *path = cairo_copy_path_flat(*obj); return 1; }
/* Returns length of a Bezier curve. Seems like computing that analytically is not easy. The * code just flattens the curve using cairo and adds the length of segments. */ static double curve_length( double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3 ) { cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_A8, 0, 0); cairo_t* cr = cairo_create(surface); double length = 0; cairo_path_t* path; cairo_path_data_t* data; cairo_path_data_t current_point; int i; current_point.point.x = 0.0; current_point.point.y = 0.0; cairo_surface_destroy(surface); cairo_move_to(cr, x0, y0); cairo_curve_to(cr, x1, y1, x2, y2, x3, y3); path = cairo_copy_path_flat(cr); for(i = 0; i < path->num_data; i += path->data[i].header.length) { data = &path->data[i]; switch (data->header.type) { case CAIRO_PATH_MOVE_TO: current_point = data[1]; break; case CAIRO_PATH_LINE_TO: length += two_points_distance(¤t_point, &data[1]); current_point = data[1]; break; default: break; } } cairo_path_destroy(path); cairo_destroy(cr); return length; }
static bool copyPathFlat_func(JSContext *context, unsigned argc, JS::Value *vp) { GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv); cairo_path_t *path; cairo_t *cr = priv ? priv->cr : NULL; if (!gjs_parse_call_args(context, "", argv, "")) return false; path = cairo_copy_path_flat(cr); argv.rval().setObjectOrNull(gjs_cairo_path_from_path(context, path)); return true; }
static JSBool copyPathFlat_func(JSContext *context, uintN argc, jsval *vp) { jsval *argv = JS_ARGV(context, vp); JSObject *obj = JS_THIS_OBJECT(context, vp); cairo_path_t *path; cairo_t *cr; if (!gjs_parse_args(context, "", "", argc, argv)) return JS_FALSE; cr = gjs_cairo_context_get_context(context, obj); path = cairo_copy_path_flat(cr); JS_SET_RVAL(context, vp, OBJECT_TO_JSVAL(gjs_cairo_path_from_path(context, path))); return JS_TRUE; }
static JSBool copyPathFlat_func(JSContext *context, unsigned argc, jsval *vp) { JS::CallArgs argv = JS::CallArgsFromVp (argc, vp); JSObject *obj = JSVAL_TO_OBJECT(argv.thisv()); cairo_path_t *path; cairo_t *cr; if (!gjs_parse_call_args(context, "", "", argv)) return JS_FALSE; cr = gjs_cairo_context_get_context(context, obj); path = cairo_copy_path_flat(cr); argv.rval().set(OBJECT_TO_JSVAL(gjs_cairo_path_from_path(context, path))); return JS_TRUE; }
static void draw_twisted (RsvgDrawingCtx * ctx, cairo_t *cr, cairo_path_t *path, double *x, double *y, const char *text) { cairo_path_t *path_copy; cairo_save (cr); /* Decrease tolerance a bit, since it's going to be magnified */ cairo_set_tolerance (cr, 0.01); /* Using cairo_copy_path() here shows our deficiency in handling * Bezier curves, specially around sharper curves. * * Using cairo_copy_path_flat() on the other hand, magnifies the * flattening error with large off-path values. We decreased * tolerance for that reason. Increase tolerance to see that * artifact. */ // Load the previously drawn path in order to make a copy cairo_new_path(cr); cairo_append_path(cr, path); path_copy = cairo_copy_path_flat (cr); // Draw the text cairo_new_path (cr); draw_text (ctx, cr, x, y, text); map_path_onto (cr, path_copy); cairo_path_destroy (path_copy); // Render the text path using current text settings //cairo_fill_preserve (cr); path_copy = cairo_copy_path(cr); ctx->render->render_path(ctx, path_copy); cairo_path_destroy (path_copy); cairo_restore (cr); }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_path_t *path; cairo_t *cr_error; /* Ensure that calling cairo_copy_path on an in-error cairo_t will * propagate the error. */ cr_error = cairo_create (NULL); path = cairo_copy_path (cr_error); if (path->status != CAIRO_STATUS_NULL_POINTER) { cairo_test_log (ctx, "Error: cairo_copy_path returned status of %s rather than propagating %s\n", cairo_status_to_string (path->status), cairo_status_to_string (CAIRO_STATUS_NULL_POINTER)); cairo_path_destroy (path); cairo_destroy (cr_error); return CAIRO_TEST_FAILURE; } cairo_path_destroy (path); path = cairo_copy_path_flat (cr_error); if (path->status != CAIRO_STATUS_NULL_POINTER) { cairo_test_log (ctx, "Error: cairo_copy_path_flat returned status of %s rather than propagating %s\n", cairo_status_to_string (path->status), cairo_status_to_string (CAIRO_STATUS_NULL_POINTER)); cairo_path_destroy (path); cairo_destroy (cr_error); return CAIRO_TEST_FAILURE; } cairo_path_destroy (path); cairo_destroy (cr_error); /* first check that we can copy an empty path */ cairo_new_path (cr); path = cairo_copy_path (cr); if (path->status != CAIRO_STATUS_SUCCESS) { cairo_status_t status = path->status; cairo_test_log (ctx, "Error: cairo_copy_path returned status of %s\n", cairo_status_to_string (status)); cairo_path_destroy (path); return cairo_test_status_from_status (ctx, status); } if (path->num_data != 0) { cairo_test_log (ctx, "Error: cairo_copy_path did not copy an empty path, returned path contains %d elements\n", path->num_data); cairo_path_destroy (path); return CAIRO_TEST_FAILURE; } cairo_append_path (cr, path); cairo_path_destroy (path); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { cairo_test_log (ctx, "Error: cairo_append_path failed with a copy of an empty path, returned status of %s\n", cairo_status_to_string (cairo_status (cr))); return cairo_test_status_from_status (ctx, cairo_status (cr)); } /* We draw in the default black, so paint white first. */ cairo_save (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); cairo_restore (cr); /* copy path, munge, and fill */ cairo_translate (cr, 5, 5); make_path (cr); path = cairo_copy_path (cr); cairo_new_path (cr); munge_and_set_path (cr, path, scale_by_two); cairo_path_destroy (path); cairo_fill (cr); /* copy flattened path, munge, and fill */ cairo_translate (cr, 0, 15); make_path (cr); path = cairo_copy_path_flat (cr); cairo_new_path (cr); munge_and_set_path (cr, path, scale_by_two); cairo_path_destroy (path); cairo_fill (cr); /* append two copies of path, and fill */ cairo_translate (cr, 0, 15); cairo_scale (cr, 2.0, 2.0); make_path (cr); path = cairo_copy_path (cr); cairo_new_path (cr); cairo_append_path (cr, path); cairo_translate (cr, 2.5, 2.5); cairo_append_path (cr, path); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_fill (cr); cairo_path_destroy (path); return CAIRO_TEST_SUCCESS; }
static PyObject * pycairo_copy_path_flat (PycairoContext *o) { return PycairoPath_FromPath (cairo_copy_path_flat (o->ctx)); }
void drawPie(cairo_t* c, int w, int h) { double w2 = w / 2.0f; double h2 = h / 2.0f; double r = h2 * 0.8f; double seg = (2.0f * osg::PI) / 8.0f; double top = osg::PI + (osg::PI / 2.0f); // each "tier" or level or an arc double lvl[] = { 0.0f, 0.25f, 0.50f, 0.75f, 1.0f }; const char* atts[] = { "Milk", "Horns", "Beefiness", "Moo/HR", "Grazing", "Sleeping", "Cowpower!", "s p o t s" }; double attl[] = { 0.25f, 0.0f, 0.50f, 1.0f, 0.0f, 0.25f, 0.75f, 1.0f }; cairo_set_line_width(c, ((w + h) / 2.0f) * 0.003f); cairo_select_font_face(c, "SegoeUI", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(c, ((w + h) / 2.0f) * 0.05f); cairo_translate(c, w2, h2); cairo_rotate(c, -seg / 2.0f); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); for(unsigned int i = 0; i < 8; i++) { // Pick a random level... cairo_move_to(c, 0.0f, 0.0f); cairo_line_to(c, 0.0f, -r); cairo_arc(c, 0.0f, 0.0f, attl[i] * r, top, top + seg); cairo_line_to(c, 0.0f, 0.0f); cairo_set_source_rgba(c, 0.2f, 0.8f, 0.2f, 0.5f); cairo_fill(c); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); // Do the various levels... cairo_move_to(c, 0.0f, 0.0f); cairo_line_to(c, 0.0f, -r); cairo_stroke(c); for(unsigned int l = 0; l < 5; l++) { cairo_arc(c, 0.0f, 0.0f, lvl[l] * r, top, top + seg); cairo_stroke(c); } cairo_text_extents_t extents; cairo_text_extents(c, atts[i], &extents); double arcsize = r * seg; // ------------------------------------ cairo_save(c); double tr = extents.width / r; double aa = ((arcsize - extents.width) / 2.0f) / r; cairo_arc(c, 0.0f, 0.0f, h2 * 0.85f, top + aa, top + aa + tr); cairo_set_tolerance(c, 0.01f); cairo_path_t* path = cairo_copy_path_flat(c); cairo_new_path(c); cairo_text_path(c, atts[i]); osgCairo::mapPathOnto(c, path); cairo_path_destroy(path); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); cairo_set_line_width(c, 1.0f); cairo_stroke_preserve(c); cairo_set_source_rgba(c, 0.8f, 0.5f, 0.1f, 0.7f); cairo_fill(c); cairo_restore(c); // ------------------------------------ // Pick a random level... cairo_move_to(c, 0.0f, 0.0f); cairo_line_to(c, 0.0f, -r); cairo_arc(c, 0.0f, 0.0f, r, top, top + seg); cairo_line_to(c, 0.0f, 0.0f); cairo_set_source_rgba(c, 1.0f, 1.0f, 1.0f, 1.0f); cairo_stroke(c); cairo_rotate(c, seg); } }