Exemple #1
0
/**
 * 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;
}
Exemple #2
0
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();
            }
        }
    }
}
Exemple #3
0
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?
    }
}
Exemple #4
0
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();
}
Exemple #6
0
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());
            }
        }
    }
}
Exemple #7
0
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."));
    }
}
Exemple #10
0
/**
 *  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;
    }
}
Exemple #11
0
/**
 * 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;
}
Exemple #12
0
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();
}
Exemple #14
0
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));
        }
    }
}
Exemple #15
0
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();
    }
}
Exemple #17
0
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;
}
Exemple #19
0
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();
    }
}
Exemple #20
0
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);
        }
    }
}
Exemple #21
0
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);
        }
    }
}
Exemple #24
0
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);
}
Exemple #25
0
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?
    }
}
Exemple #29
0
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?
    }
}