/** * Return a vector of PathVectors which contain all helperpaths that should be drawn by the effect. * This is the function called by external code like SPLPEItem. */ std::vector<Geom::PathVector> Effect::getHelperPaths(SPLPEItem *lpeitem) { std::vector<Geom::PathVector> hp_vec; if (!SP_IS_SHAPE(lpeitem)) { // g_print ("How to handle helperpaths for non-shapes?\n"); // non-shapes are for example SPGroups. return hp_vec; } // TODO: we can probably optimize this by using a lot more references // rather than copying PathVectors all over the place if (show_orig_path) { // add original path to helperpaths SPCurve* curve = sp_shape_get_curve (SP_SHAPE(lpeitem)); hp_vec.push_back(curve->get_pathvector()); } // add other helperpaths provided by the effect itself addCanvasIndicators(lpeitem, hp_vec); // add helperpaths provided by the effect's parameters for (std::vector<Parameter *>::iterator p = param_vector.begin(); p != param_vector.end(); ++p) { (*p)->addCanvasIndicators(lpeitem, hp_vec); } return hp_vec; }
static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(group)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast<SPObject *>(iter->data); if (SP_IS_GROUP(subitem)) { sp_group_perform_patheffect(SP_GROUP(subitem), topgroup, write); } else if (SP_IS_SHAPE(subitem)) { SPCurve * c = NULL; if (SP_IS_PATH(subitem)) { c = SP_PATH(subitem)->get_original_curve(); } else { c = SP_SHAPE(subitem)->getCurve(); } // only run LPEs when the shape has a curve defined if (c) { sp_lpe_item_perform_path_effect(SP_LPE_ITEM(topgroup), c); SP_SHAPE(subitem)->setCurve(c, TRUE); if (write) { Inkscape::XML::Node *repr = subitem->getRepr(); gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif g_free(str); } c->unref(); } } } }
void lpetool_update_measuring_items(LpeTool *lc) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); for ( std::map<SPPath *, SPCanvasItem*>::iterator i = lc->measuring_items->begin(); i != lc->measuring_items->end(); ++i ) { SPPath *path = i->first; SPCurve *curve = path->getCurve(); Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = Geom::paths_to_pw(curve->get_pathvector()); Inkscape::Util::Unit const * unit = NULL; if (prefs->getString("/tools/lpetool/unit").compare("")) { unit = unit_table.getUnit(prefs->getString("/tools/lpetool/unit")); } else { unit = unit_table.getUnit("px"); } double lengthval = Geom::length(pwd2); lengthval = Inkscape::Util::Quantity::convert(lengthval, "px", unit); gchar *arc_length = g_strdup_printf("%.2f %s", lengthval, unit->abbr.c_str()); sp_canvastext_set_text (SP_CANVASTEXT(i->second), arc_length); set_pos_and_anchor(SP_CANVASTEXT(i->second), pwd2, 0.5, 10); // TODO: must we free arc_length? } }
void SPConnEndPair::reroutePath(void) { if (!isAutoRoutingConn()) { // Do nothing return; } SPCurve *curve = _path->curve; Geom::Point endPt[2]; getEndpoints(endPt); Avoid::Point src(endPt[0][Geom::X], endPt[0][Geom::Y]); Avoid::Point dst(endPt[1][Geom::X], endPt[1][Geom::Y]); _connRef->updateEndPoint(Avoid::VertID::src, src); _connRef->updateEndPoint(Avoid::VertID::tar, dst); _connRef->generatePath(src, dst); Avoid::PolyLine route = _connRef->route(); _connRef->calcRouteDist(); curve->reset(); curve->moveto(endPt[0]); for (int i = 1; i < route.pn; ++i) { Geom::Point p(route.ps[i].x, route.ps[i].y); curve->lineto(p); } }
void SPUsePath::refresh_source() { sourceDirty = false; delete originalPath; originalPath = NULL; // le mauvais cas: pas d'attribut d => il faut verifier que c'est une SPShape puis prendre le contour // [tr: The bad case: no d attribute. Must check that it's a SPShape and then take the outline.] SPObject *refobj = sourceObject; if ( refobj == NULL ) return; SPItem *item = SP_ITEM(refobj); SPCurve *curve = NULL; if (SP_IS_SHAPE(item)) { curve = SP_SHAPE(item)->getCurve(); } else if (SP_IS_TEXT(item)) { curve = SP_TEXT(item)->getNormalizedBpath(); } else { return; } if (curve == NULL) return; originalPath = new Path; originalPath->LoadPathVector(curve->get_pathvector(), item->transform, true); curve->unref(); }
void SPConnEndPair::getEndpoints(Geom::Point endPts[]) const { SPCurve *curve = _path->curve; SPItem *h2attItem[2]; getAttachedItems(h2attItem); for (unsigned h = 0; h < 2; ++h) { if ( h2attItem[h] ) { Geom::OptRect bbox = h2attItem[h]->getBounds(sp_item_i2doc_affine(h2attItem[h])); if (bbox) { endPts[h] = bbox->midpoint(); } else { // FIXME endPts[h] = Geom::Point(0, 0); } } else { if (h == 0) { endPts[h] = *(curve->first_point()); } else { endPts[h] = *(curve->last_point()); } } } }
void SPPolyLine::set(SPObject *object, unsigned int key, const gchar *value) { SPPolyLine *polyline = SP_POLYLINE(object); switch (key) { case SP_ATTR_POINTS: { SPCurve * curve; const gchar * cptr; char * eptr; gboolean hascpt; if (!value) break; curve = new SPCurve (); hascpt = FALSE; cptr = value; eptr = NULL; while (TRUE) { gdouble x, y; while (*cptr != '\0' && (*cptr == ',' || *cptr == '\x20' || *cptr == '\x9' || *cptr == '\xD' || *cptr == '\xA')) { cptr++; } if (!*cptr) break; x = g_ascii_strtod (cptr, &eptr); if (eptr == cptr) break; cptr = eptr; while (*cptr != '\0' && (*cptr == ',' || *cptr == '\x20' || *cptr == '\x9' || *cptr == '\xD' || *cptr == '\xA')) { cptr++; } if (!*cptr) break; y = g_ascii_strtod (cptr, &eptr); if (eptr == cptr) break; cptr = eptr; if (hascpt) { curve->lineto(x, y); } else { curve->moveto(x, y); hascpt = TRUE; } } (SP_SHAPE (polyline))->setCurve (curve, TRUE); curve->unref(); break; } default: if (((SPObjectClass *) SPPolyLineClass::static_parent_class)->set) { ((SPObjectClass *) SPPolyLineClass::static_parent_class)->set (object, key, value); } break; } }
void sp_selected_path_reverse(SPDesktop *desktop) { Inkscape::Selection *selection = desktop->getSelection(); std::vector<SPItem*> items = selection->itemList(); if (items.empty()) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse.")); return; } // set "busy" cursor desktop->setWaitingCursor(); bool did = false; desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Reversing paths...")); for (std::vector<SPItem*>::const_iterator i = items.begin(); i != items.end(); ++i){ SPPath *path = dynamic_cast<SPPath *>(*i); if (!path) { continue; } did = true; SPCurve *rcurve = path->get_curve_reference()->create_reverse(); gchar *str = sp_svg_write_path(rcurve->get_pathvector()); if ( path->hasPathEffectRecursive() ) { path->getRepr()->setAttribute("inkscape:original-d", str); } else { path->getRepr()->setAttribute("d", str); } g_free(str); rcurve->unref(); // reverse nodetypes order (Bug #179866) gchar *nodetypes = g_strdup(path->getRepr()->attribute("sodipodi:nodetypes")); if ( nodetypes ) { path->getRepr()->setAttribute("sodipodi:nodetypes", g_strreverse(nodetypes)); g_free(nodetypes); } } desktop->clearWaitingCursor(); if (did) { DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_REVERSE, _("Reverse path")); } else { desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to reverse in the selection.")); } }
void sp_selected_path_reverse(SPDesktop *desktop) { Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList *items = (GSList *) selection->itemList(); if (!items) { sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse.")); return; } // set "busy" cursor desktop->setWaitingCursor(); bool did = false; desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Reversing paths...")); for (GSList *i = items; i != NULL; i = i->next) { if (!SP_IS_PATH(i->data)) { continue; } did = true; SPPath *path = SP_PATH(i->data); SPCurve *rcurve = path->get_curve_reference()->create_reverse(); gchar *str = sp_svg_write_path(rcurve->get_pathvector()); if ( path->hasPathEffectRecursive() ) { path->getRepr()->setAttribute("inkscape:original-d", str); } else { path->getRepr()->setAttribute("d", str); } g_free(str); rcurve->unref(); // reverse nodetypes order (Bug #179866) gchar *nodetypes = g_strdup(path->getRepr()->attribute("sodipodi:nodetypes")); if ( nodetypes ) { path->getRepr()->setAttribute("sodipodi:nodetypes", g_strreverse(nodetypes)); g_free(nodetypes); } } desktop->clearWaitingCursor(); if (did) { DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_REVERSE, _("Reverse path")); } else { sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No paths</b> to reverse in the selection.")); } }
/** * Sets a value in the path object given by 'key', to 'value'. This is used * for setting attributes and markers on a path object. */ static void sp_path_set(SPObject *object, unsigned int key, gchar const *value) { SPPath *path = (SPPath *) object; switch (key) { case SP_ATTR_INKSCAPE_ORIGINAL_D: if (value) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *curve = new SPCurve(pv); if (curve) { path->set_original_curve(curve, TRUE, true); curve->unref(); } } else { path->set_original_curve(NULL, TRUE, true); } object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_D: if (value) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *curve = new SPCurve(pv); if (curve) { ((SPShape *) path)->setCurve(curve, TRUE); curve->unref(); } } else { ((SPShape *) path)->setCurve(NULL, TRUE); } object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_PROP_MARKER: case SP_PROP_MARKER_START: case SP_PROP_MARKER_MID: case SP_PROP_MARKER_END: sp_shape_set_marker(object, key, value); object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); break; case SP_ATTR_CONNECTOR_TYPE: case SP_ATTR_CONNECTOR_CURVATURE: case SP_ATTR_CONNECTION_START: case SP_ATTR_CONNECTION_END: case SP_ATTR_CONNECTION_START_POINT: case SP_ATTR_CONNECTION_END_POINT: path->connEndPair.setAttr(key, value); break; default: if (((SPObjectClass *) parent_class)->set) { ((SPObjectClass *) parent_class)->set(object, key, value); } break; } }
/** * Return new curve that is the concatenation of all curves in list. */ SPCurve * SPCurve::concat(GSList const *list) { SPCurve *new_curve = new SPCurve(); for (GSList const *l = list; l != NULL; l = l->next) { SPCurve *c = static_cast<SPCurve *>(l->data); new_curve->_pathv.insert( new_curve->_pathv.end(), c->get_pathvector().begin(), c->get_pathvector().end() ); } return new_curve; }
static void fit_and_split(SPPencilContext *pc) { g_assert( pc->npoints > 1 ); double const tolerance_sq = 0; Geom::Point b[4]; g_assert(is_zero(pc->req_tangent) || is_unit_vector(pc->req_tangent)); Geom::Point const tHatEnd(0, 0); int const n_segs = Geom::bezier_fit_cubic_full(b, NULL, pc->p, pc->npoints, pc->req_tangent, tHatEnd, tolerance_sq, 1); if ( n_segs > 0 && unsigned(pc->npoints) < G_N_ELEMENTS(pc->p) ) { /* Fit and draw and reset state */ pc->red_curve->reset(); pc->red_curve->moveto(b[0]); pc->red_curve->curveto(b[1], b[2], b[3]); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); pc->red_curve_is_valid = true; } else { /* Fit and draw and copy last point */ g_assert(!pc->red_curve->is_empty()); /* Set up direction of next curve. */ { Geom::CubicBezier const * last_seg = dynamic_cast<Geom::CubicBezier const *>(pc->red_curve->last_segment()); g_assert( last_seg ); // Relevance: validity of (*last_seg)[2] pc->p[0] = last_seg->finalPoint(); pc->npoints = 1; Geom::Point const req_vec( pc->p[0] - (*last_seg)[2] ); pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) ) ? Geom::Point(0, 0) : Geom::unit_vector(req_vec) ); } pc->green_curve->append_continuous(pc->red_curve, 0.0625); SPCurve *curve = pc->red_curve->copy(); /// \todo fixme: SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), curve); curve->unref(); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); pc->red_curve_is_valid = false; } }
/** * Computes a point on the offset; used to set a "seed" position for * the control knot. * * \return the topmost point on the offset. */ void sp_offset_top_point (SPOffset const * offset, Geom::Point *px) { (*px) = Geom::Point(0, 0); if (offset == NULL) { return; } if (offset->knotSet) { (*px) = offset->knot; return; } SPCurve *curve = SP_SHAPE (offset)->getCurve(); if (curve == NULL) { // CPPIFY //offset->set_shape(); const_cast<SPOffset*>(offset)->set_shape(); curve = SP_SHAPE (offset)->getCurve(); if (curve == NULL) return; } if (curve->is_empty()) { curve->unref(); return; } Path *finalPath = new Path; finalPath->LoadPathVector(curve->get_pathvector()); Shape *theShape = new Shape; finalPath->Convert (1.0); finalPath->Fill (theShape, 0); if (theShape->hasPoints()) { theShape->SortPoints (); *px = theShape->getPoint(0).x; } delete theShape; delete finalPath; curve->unref(); }
void SPLPEItem::apply_to_clippath(SPItem *item) { SPClipPath *clipPath = item->clip_ref->getObject(); if(clipPath) { SPObject * clip_data = clipPath->firstChild(); SPCurve * clip_curve = NULL; if (SP_IS_PATH(clip_data)) { clip_curve = SP_PATH(clip_data)->get_original_curve(); } else if(SP_IS_SHAPE(clip_data)) { clip_curve = SP_SHAPE(clip_data)->getCurve(); } else if(SP_IS_GROUP(clip_data)) { apply_to_clip_or_mask_group(SP_ITEM(clip_data), item); return; } if(clip_curve) { bool success = false; if(SP_IS_GROUP(this)){ clip_curve->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this))); success = this->performPathEffect(clip_curve); clip_curve->transform(i2anc_affine(SP_GROUP(item), SP_GROUP(this)).inverse()); } else { success = this->performPathEffect(clip_curve); } Inkscape::XML::Node *reprClip = clip_data->getRepr(); if (success) { gchar *str = sp_svg_write_path(clip_curve->get_pathvector()); reprClip->setAttribute("d", str); g_free(str); } else { // LPE was unsuccesfull. Read the old 'd'-attribute. if (gchar const * value = reprClip->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new SPCurve(pv); if (oldcurve) { SP_SHAPE(clip_data)->setCurve(oldcurve, TRUE); oldcurve->unref(); } } } clip_curve->unref(); } } if(SP_IS_GROUP(item)){ GSList const *item_list = sp_item_group_item_list(SP_GROUP(item)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast<SPObject *>(iter->data); apply_to_clippath(SP_ITEM(subitem)); } } }
void SPLine::set_shape() { SPCurve *c = new SPCurve(); c->moveto(this->x1.computed, this->y1.computed); c->lineto(this->x2.computed, this->y2.computed); this->setCurveInsync(c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update this->setCurveBeforeLPE(c); // LPE's cannot be applied to lines. (the result can (generally) not be represented as SPLine) c->unref(); }
static void sp_dropper_context_setup(SPEventContext *ec) { SPDropperContext *dc = SP_DROPPER_CONTEXT(ec); if (((SPEventContextClass *) parent_class)->setup) { ((SPEventContextClass *) parent_class)->setup(ec); } /* TODO: have a look at sp_dyna_draw_context_setup where the same is done.. generalize? at least make it an arcto! */ SPCurve *c = new SPCurve(); const double C1 = 0.552; c->moveto(-1,0); c->curveto(-1, C1, -C1, 1, 0, 1 ); c->curveto(C1, 1, 1, C1, 1, 0 ); c->curveto(1, -C1, C1, -1, 0, -1 ); c->curveto(-C1, -1, -1, -C1, -1, 0 ); c->closepath(); dc->area = sp_canvas_bpath_new(sp_desktop_controls(ec->desktop), c); c->unref(); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(dc->area), 0x00000000,(SPWindRule)0); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->area), 0x0000007f, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_item_hide(dc->area); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/dropper/selcue")) { ec->enableSelectionCue(); } if (prefs->getBool("/tools/dropper/gradientdrag")) { ec->enableGrDrag(); } }
static void sp_line_set_shape (SPShape *shape) { SPLine *line = SP_LINE (shape); SPCurve *c = new SPCurve (); c->moveto(line->x1.computed, line->y1.computed); c->lineto(line->x2.computed, line->y2.computed); sp_shape_set_curve_insync (shape, c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update c->unref(); }
bool SPConnEndPair::reroutePathFromLibavoid(void) { if (!isAutoRoutingConn()) { // Do nothing return false; } SPCurve *curve = _path->original_curve ?_path->original_curve : _path->curve; recreateCurve( curve, _connRef, _connCurvature ); Geom::Matrix doc2item = sp_item_i2doc_affine(SP_ITEM(_path)).inverse(); curve->transform(doc2item); return true; }
static void sp_path_update_patheffect(SPLPEItem *lpeitem, bool write) { SPShape * const shape = (SPShape *) lpeitem; Inkscape::XML::Node *repr = shape->getRepr(); #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect"); #endif if (shape->_curve_before_lpe && sp_lpe_item_has_path_effect_recursive(lpeitem)) { SPCurve *curve = shape->_curve_before_lpe->copy(); /* if a path has an lpeitem applied, then reset the curve to the _curve_before_lpe. * This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/ shape->setCurveInsync(curve, TRUE); bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve); if (success && write) { // could also do shape->getRepr()->updateRepr(); but only the d attribute needs updating. #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); #endif if ( shape->_curve != NULL ) { gchar *str = sp_svg_write_path(shape->_curve->get_pathvector()); repr->setAttribute("d", str); g_free(str); } else { repr->setAttribute("d", NULL); } } else if (!success) { // LPE was unsuccesfull. Read the old 'd'-attribute. if (gchar const * value = repr->attribute("d")) { Geom::PathVector pv = sp_svg_read_pathv(value); SPCurve *oldcurve = new SPCurve(pv); if (oldcurve) { shape->setCurve(oldcurve, TRUE); oldcurve->unref(); } } } shape->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); curve->unref(); } }
void lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection) { if (!selection) { selection = lc->desktop->getSelection(); } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool show = prefs->getBool("/tools/lpetool/show_measuring_info", true); SPPath *path; SPCurve *curve; SPCanvasText *canvas_text; SPCanvasGroup *tmpgrp = lc->desktop->getTempGroup(); gchar *arc_length; double lengthval; std::vector<SPItem*> items=selection->itemList(); for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ if (SP_IS_PATH(*i)) { path = SP_PATH(*i); curve = path->getCurve(); Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = paths_to_pw(curve->get_pathvector()); canvas_text = (SPCanvasText *) sp_canvastext_new(tmpgrp, lc->desktop, Geom::Point(0,0), ""); if (!show) sp_canvas_item_hide(SP_CANVAS_ITEM(canvas_text)); Inkscape::Util::Unit const * unit = NULL; if (prefs->getString("/tools/lpetool/unit").compare("")) { unit = unit_table.getUnit(prefs->getString("/tools/lpetool/unit")); } else { unit = unit_table.getUnit("px"); } lengthval = Geom::length(pwd2); lengthval = Inkscape::Util::Quantity::convert(lengthval, "px", unit); arc_length = g_strdup_printf("%.2f %s", lengthval, unit->abbr.c_str()); sp_canvastext_set_text (canvas_text, arc_length); set_pos_and_anchor(canvas_text, pwd2, 0.5, 10); // TODO: must we free arc_length? (*lc->measuring_items)[path] = SP_CANVAS_ITEM(canvas_text); } } }
static void sp_spray_context_setup(SPEventContext *ec) { SPSprayContext *tc = SP_SPRAY_CONTEXT(ec); if (((SPEventContextClass *) parent_class)->setup) { ((SPEventContextClass *) parent_class)->setup(ec); } { /* TODO: have a look at sp_dyna_draw_context_setup where the same is done.. generalize? at least make it an arcto! */ SPCurve *c = new SPCurve(); const double C1 = 0.552; c->moveto(-1,0); c->curveto(-1, C1, -C1, 1, 0, 1 ); c->curveto(C1, 1, 1, C1, 1, 0 ); c->curveto(1, -C1, C1, -1, 0, -1 ); c->curveto(-C1, -1, -1, -C1, -1, 0 ); c->closepath(); tc->dilate_area = sp_canvas_bpath_new(sp_desktop_controls(ec->desktop), c); c->unref(); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(tc->dilate_area), 0x00000000,(SPWindRule)0); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(tc->dilate_area), 0xff9900ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_item_hide(tc->dilate_area); } tc->is_drawing = false; tc->_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack()); sp_event_context_read(ec, "distrib"); sp_event_context_read(ec, "width"); sp_event_context_read(ec, "ratio"); sp_event_context_read(ec, "tilt"); sp_event_context_read(ec, "rotation_variation"); sp_event_context_read(ec, "scale_variation"); sp_event_context_read(ec, "mode"); sp_event_context_read(ec, "population"); sp_event_context_read(ec, "force"); sp_event_context_read(ec, "mean"); sp_event_context_read(ec, "standard_deviation"); sp_event_context_read(ec, "usepressure"); sp_event_context_read(ec, "Scale"); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/tools/spray/selcue")) { ec->enableSelectionCue(); } if (prefs->getBool("/tools/spray/gradientdrag")) { ec->enableGrDrag(); } }
static void sp_image_set_curve( SPImage *image ) { //create a curve at the image's boundary for snapping if ((image->height.computed < MAGIC_EPSILON_TOO) || (image->width.computed < MAGIC_EPSILON_TOO) || (image->clip_ref->getObject())) { if (image->curve) { image->curve = image->curve->unref(); } } else { Geom::OptRect rect = image->bbox(Geom::identity(), SPItem::VISUAL_BBOX); SPCurve *c = SPCurve::new_from_rect(*rect, true); if (image->curve) { image->curve = image->curve->unref(); } if (c) { image->curve = c->ref(); c->unref(); } } }
void lpetool_create_measuring_items(SPLPEToolContext *lc, Inkscape::Selection *selection) { if (!selection) { selection = sp_desktop_selection(lc->desktop); } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool show = prefs->getBool("/tools/lpetool/show_measuring_info", true); SPPath *path; SPCurve *curve; SPCanvasText *canvas_text; SPCanvasGroup *tmpgrp = sp_desktop_tempgroup(lc->desktop); gchar *arc_length; double lengthval; for (GSList const *i = selection->itemList(); i != NULL; i = i->next) { if (SP_IS_PATH(i->data)) { path = SP_PATH(i->data); curve = sp_shape_get_curve(SP_SHAPE(path)); Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = paths_to_pw(curve->get_pathvector()); canvas_text = (SPCanvasText *) sp_canvastext_new(tmpgrp, lc->desktop, Geom::Point(0,0), ""); if (!show) sp_canvas_item_hide(SP_CANVAS_ITEM(canvas_text)); SPUnitId unitid = static_cast<SPUnitId>(prefs->getInt("/tools/lpetool/unitid", SP_UNIT_PX)); SPUnit unit = sp_unit_get_by_id(unitid); lengthval = Geom::length(pwd2); gboolean success; success = sp_convert_distance(&lengthval, &sp_unit_get_by_id(SP_UNIT_PX), &unit); arc_length = g_strdup_printf("%.2f %s", lengthval, success ? sp_unit_get_abbreviation(&unit) : "px"); sp_canvastext_set_text (canvas_text, arc_length); set_pos_and_anchor(canvas_text, pwd2, 0.5, 10); // TODO: must we free arc_length? (*lc->measuring_items)[path] = SP_CANVAS_ITEM(canvas_text); } } }
void OriginalPathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) { SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); } if (SP_IS_TEXT(linked_obj)) { curve = SP_TEXT(linked_obj)->getNormalizedBpath(); } if (curve == NULL) { // curve invalid, set empty pathvector _pathvector = Geom::PathVector(); } else { _pathvector = curve->get_pathvector(); curve->unref(); } must_recalculate_pwd2 = true; emit_changed(); SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); }
void PathParam::linked_modified_callback(SPObject *linked_obj, guint /*flags*/) { SPCurve *curve = NULL; if (SP_IS_SHAPE(linked_obj)) { curve = SP_SHAPE(linked_obj)->getCurve(); } if (SP_IS_TEXT(linked_obj)) { curve = SP_TEXT(linked_obj)->getNormalizedBpath(); } if (curve == NULL) { // curve invalid, set default value _pathvector = sp_svg_read_pathv(defvalue); } else { _pathvector = curve->get_pathvector(); curve->unref(); } must_recalculate_pwd2 = true; emit_changed(); SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); }
void KnotHolderEntityAttachPt::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) { using namespace Geom; LPETangentToCurve* lpe = dynamic_cast<LPETangentToCurve *>(_effect); Geom::Point const s = snap_knot_position(p, state); // FIXME: There must be a better way of converting the path's SPCurve* to pwd2. SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); Geom::PathVector pathv = curve->get_pathvector(); Piecewise<D2<SBasis> > pwd2; for (unsigned int i=0; i < pathv.size(); i++) { pwd2.concat(pathv[i].toPwSb()); } double t0 = nearest_point(s, pwd2); lpe->t_attach.param_set_value(t0); // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); }
void SPConnEndPair::getEndpoints(Geom::Point endPts[]) const { SPCurve *curve = _path->original_curve ? _path->original_curve : _path->curve; SPItem *h2attItem[2]; getAttachedItems(h2attItem); Geom::Matrix i2d = sp_item_i2doc_affine(SP_ITEM(_path)); for (unsigned h = 0; h < 2; ++h) { if ( h2attItem[h] ) { g_assert(h2attItem[h]->avoidRef); endPts[h] = h2attItem[h]->avoidRef->getConnectionPointPos(_connEnd[h]->type, _connEnd[h]->id); } else if (!curve->is_empty()) { if (h == 0) { endPts[h] = *(curve->first_point())*i2d; } else { endPts[h] = *(curve->last_point())*i2d; } } } }
void lpetool_update_measuring_items(SPLPEToolContext *lc) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); SPPath *path; SPCurve *curve; double lengthval; gchar *arc_length; std::map<SPPath *, SPCanvasItem*>::iterator i; for (i = lc->measuring_items->begin(); i != lc->measuring_items->end(); ++i) { path = i->first; curve = sp_shape_get_curve(SP_SHAPE(path)); Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = Geom::paths_to_pw(curve->get_pathvector()); SPUnitId unitid = static_cast<SPUnitId>(prefs->getInt("/tools/lpetool/unitid", SP_UNIT_PX)); SPUnit unit = sp_unit_get_by_id(unitid); lengthval = Geom::length(pwd2); gboolean success; success = sp_convert_distance(&lengthval, &sp_unit_get_by_id(SP_UNIT_PX), &unit); arc_length = g_strdup_printf("%.2f %s", lengthval, success ? sp_unit_get_abbreviation(&unit) : "px"); sp_canvastext_set_text (SP_CANVASTEXT(i->second), arc_length); set_pos_and_anchor(SP_CANVASTEXT(i->second), pwd2, 0.5, 10); // TODO: must we free arc_length? } }
SPCurve * SPCurve::new_from_rect(Geom::Rect const &rect, bool all_four_sides) { SPCurve *c = new SPCurve(); Geom::Point p = rect.corner(0); c->moveto(p); for (int i=3; i>=1; i--) { c->lineto(rect.corner(i)); } if (all_four_sides) { // When _constrained_ snapping to a path, the 2geom::SimpleCrosser will be invoked which doesn't consider the closing segment. // of a path. Consequently, in case we want to snap to for example the page border, we must provide all four sides of the // rectangle explicitly c->lineto(rect.corner(0)); } else { // ... instead of just three plus a closing segment c->closepath(); } return c; }
static void spdc_attach_selection(FreehandBase *dc, Inkscape::Selection */*sel*/) { // We reset white and forget white/start/end anchors spdc_reset_white(dc); dc->sa = NULL; dc->ea = NULL; SPItem *item = dc->selection ? dc->selection->singleItem() : NULL; if ( item && SP_IS_PATH(item) ) { // Create new white data // Item dc->white_item = item; // Curve list // We keep it in desktop coordinates to eliminate calculation errors SPCurve *norm = SP_PATH(item)->get_curve_for_edit(); norm->transform((dc->white_item)->i2dt_affine()); g_return_if_fail( norm != NULL ); dc->white_curves = g_slist_reverse(norm->split()); norm->unref(); // Anchor list for (GSList *l = dc->white_curves; l != NULL; l = l->next) { SPCurve *c; c = static_cast<SPCurve*>(l->data); g_return_if_fail( c->get_segment_count() > 0 ); if ( !c->is_closed() ) { SPDrawAnchor *a; a = sp_draw_anchor_new(dc, c, TRUE, *(c->first_point())); if (a) dc->white_anchors = g_slist_prepend(dc->white_anchors, a); a = sp_draw_anchor_new(dc, c, FALSE, *(c->last_point())); if (a) dc->white_anchors = g_slist_prepend(dc->white_anchors, a); } } // fixme: recalculate active anchor? } }