Exemplo n.º 1
0
static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl )
{
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));
    if (DocumentUndo::getUndoSensitive(desktop->getDocument())) {
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        prefs->setBool("/tools/shapes/arc/open", ege_select_one_action_get_active(act) != 0);
    }

    // quit if run by the attr_changed listener
    if (g_object_get_data( tbl, "freeze" )) {
        return;
    }

    // in turn, prevent listener from responding
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );

    bool modmade = false;

    if ( ege_select_one_action_get_active(act) != 0 ) {
    	std::vector<SPItem*> itemlist=desktop->getSelection()->itemList();
        for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){
            SPItem *item = *i;
            if (SP_IS_GENERICELLIPSE(item)) {
                Inkscape::XML::Node *repr = item->getRepr();
                repr->setAttribute("sodipodi:open", "true");
                item->updateRepr();
                modmade = true;
            }
        }
    } else {
    	std::vector<SPItem*> itemlist=desktop->getSelection()->itemList();
        for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){
            SPItem *item = *i;
            if (SP_IS_GENERICELLIPSE(item)) {
                Inkscape::XML::Node *repr = item->getRepr();
                repr->setAttribute("sodipodi:open", NULL);
                item->updateRepr();
                modmade = true;
            }
        }
    }

    if (modmade) {
        DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC,
                           _("Arc: Change open/closed"));
    }

    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
Exemplo n.º 2
0
void
ExecutionEnv::reselect (void) {
    if (_doc == NULL) {
        return;
    }
    SPDocument * doc = _doc->doc();
    if (doc == NULL) {
        return;
    }

    SPDesktop *desktop = (SPDesktop *)_doc;
    sp_namedview_document_from_window(desktop);

    if (desktop == NULL) {
        return;
    }

    Inkscape::Selection * selection = desktop->getSelection();

    for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); ++i) {
        SPObject * obj = doc->getObjectById(i->c_str());
        if (obj != NULL) {
            selection->add(obj);
        }
    }

    return;
}
Exemplo n.º 3
0
/** \brief  Create an execution environment that will allow the effect
            to execute independently.
    \param effect  The effect that we should execute
    \param doc     The Document to execute on
    \param docCache  The cache created for that document
    \param show_working  Show the working dialog
    \param show_error    Show the error dialog (not working)

    Grabs the selection of the current document so that it can get
    restored.  Will generate a document cache if one isn't provided.
*/
ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Implementation::ImplementationDocumentCache * docCache, bool show_working, bool show_errors) :
    _state(ExecutionEnv::INIT),
    _visibleDialog(NULL),
    _mainloop(NULL),
    _doc(doc),
    _docCache(docCache),
    _effect(effect),
    _show_working(show_working),
    _show_errors(show_errors)
{
    SPDesktop *desktop = (SPDesktop *)_doc;
    sp_namedview_document_from_window(desktop);

    if (desktop != NULL) {
    	std::vector<SPItem*> selected = desktop->getSelection()->itemList();
        for(std::vector<SPItem*>::const_iterator x = selected.begin(); x != selected.end(); ++x){
            Glib::ustring selected_id;
            selected_id = (*x)->getId();
            _selected.insert(_selected.end(), selected_id);
            //std::cout << "Selected: " << selected_id << std::endl;
        }
    }

    genDocCache();

    return;
}
Exemplo n.º 4
0
static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj)
{
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(obj, "desktop"));
    std::vector<SPItem *> selected = desktop->getSelection()->itemList();
    for (std::vector<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it){
        SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*it);
        if (lpeitem && lpeitem->hasPathEffect()){
            PathEffectList lpelist = lpeitem->getEffectList();
            std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i;
            for (i = lpelist.begin(); i != lpelist.end(); ++i) {
                LivePathEffectObject *lpeobj = (*i)->lpeobject;
                if (lpeobj) {
                    Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe();
                    if (dynamic_cast<Inkscape::LivePathEffect::LPESimplify *>(lpe)) {
                        SPShape * shape = dynamic_cast<SPShape *>(lpeitem);
                        if(shape){
                            SPCurve * c = shape->getCurveBeforeLPE();
                            lpe->doEffect(c);
                            lpeitem->setCurrentPathEffect(*i);
                            if (lpelist.size() > 1){
                                lpeitem->removeCurrentPathEffect(true);
                                shape->setCurveBeforeLPE(c);
                            } else {
                                lpeitem->removeCurrentPathEffect(false);
                                shape->setCurve(c,0);
                            }
                            break;
                        }
                    }
                }
            }
        }
    }
}
Exemplo n.º 5
0
static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis)
{
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( dataKludge, "desktop" ));
    SPDocument *document = desktop->getDocument();

    // quit if run by the attr_changed or selection changed listener
    if (g_object_get_data( dataKludge, "freeze" )) {
        return;
    }

    // in turn, prevent listener from responding
    g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE));

    std::list<Persp3D *> sel_persps = desktop->getSelection()->perspList();
    if (sel_persps.empty()) {
        // this can happen when the document is created; we silently ignore it
        return;
    }
    Persp3D *persp = sel_persps.front();

    persp->perspective_impl->tmat.set_infinite_direction (axis,
            gtk_adjustment_get_value(adj));
    persp->updateRepr();

    // TODO: use the correct axis here, too
    DocumentUndo::maybeDone(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)"));

    g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) );
}
Exemplo n.º 6
0
void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *tool, guint event_state) {
    g_return_if_fail(!strcmp(tool, "/tools/freehand/pen") || !strcmp(tool, "/tools/freehand/pencil"));
    Glib::ustring tool_path = tool;

    SPDesktop *desktop = ec->desktop;
    Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
    Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
    repr->setAttribute("sodipodi:type", "arc");
    SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
    Inkscape::GC::release(repr);

    // apply the tool's current style
    sp_desktop_apply_style_tool(desktop, repr, tool, false);

    // find out stroke width (TODO: is there an easier way??)
    double stroke_width = 3.0;
    gchar const *style_str = repr->attribute("style");
    if (style_str) {
        SPStyle style(SP_ACTIVE_DOCUMENT);
        style.mergeString(style_str);
        stroke_width = style.stroke_width.computed;
    }

    // unset stroke and set fill color to former stroke color
    gchar * str;
    str = g_strdup_printf("fill:#%06x;stroke:none;", sp_desktop_get_color_tool(desktop, tool, false) >> 8);
    repr->setAttribute("style", str);
    g_free(str);

    // put the circle where the mouse click occurred and set the diameter to the
    // current stroke width, multiplied by the amount specified in the preferences
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    Geom::Affine const i2d (item->i2dt_affine ());
    Geom::Point pp = pt * i2d.inverse();
    double rad = 0.5 * prefs->getDouble(tool_path + "/dot-size", 3.0);
    if (event_state & GDK_MOD1_MASK) {
        // TODO: We vary the dot size between 0.5*rad and 1.5*rad, where rad is the dot size
        // as specified in prefs. Very simple, but it might be sufficient in practice. If not,
        // we need to devise something more sophisticated.
        double s = g_random_double_range(-0.5, 0.5);
        rad *= (1 + s);
    }
    if (event_state & GDK_SHIFT_MASK) {
        // double the point size
        rad *= 2;
    }

    sp_repr_set_svg_double (repr, "sodipodi:cx", pp[Geom::X]);
    sp_repr_set_svg_double (repr, "sodipodi:cy", pp[Geom::Y]);
    sp_repr_set_svg_double (repr, "sodipodi:rx", rad * stroke_width);
    sp_repr_set_svg_double (repr, "sodipodi:ry", rad * stroke_width);
    item->updateRepr();

    desktop->getSelection()->set(item);

    desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating single dot"));
    DocumentUndo::done(desktop->getDocument(), SP_VERB_NONE, _("Create single dot"));
}
Exemplo n.º 7
0
static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl)
{
    // quit if run by the attr_changed listener
    if (g_object_get_data( tbl, "freeze" )) {
        return;
    }
    // in turn, prevent listener from responding
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
    prefs->setDouble("/tools/freehand/pencil/tolerance",
            gtk_adjustment_get_value(adj));
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(tbl, "desktop"));
    std::vector<SPItem *> selected = desktop->getSelection()->itemList();
    for (std::vector<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it){
        SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*it);
        if (lpeitem && lpeitem->hasPathEffect()){
            Inkscape::LivePathEffect::Effect* simplify = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY);
            if(simplify){
                Inkscape::LivePathEffect::LPESimplify *lpe_simplify = dynamic_cast<Inkscape::LivePathEffect::LPESimplify*>(simplify->getLPEObj()->get_lpe());
                if (lpe_simplify) {
                    double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0);
                    tol = tol/(100.0*(102.0-tol));
                    std::ostringstream ss;
                    ss << tol;
                    Inkscape::LivePathEffect::Effect* powerstroke = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE);
                    bool simplified = false;
                    if(powerstroke){
                        Inkscape::LivePathEffect::LPEPowerStroke *lpe_powerstroke = dynamic_cast<Inkscape::LivePathEffect::LPEPowerStroke*>(powerstroke->getLPEObj()->get_lpe());
                        if(lpe_powerstroke){
                            lpe_powerstroke->getRepr()->setAttribute("is_visible", "false");
                            sp_lpe_item_update_patheffect(lpeitem, false, false);
                            SPShape *sp_shape = dynamic_cast<SPShape *>(lpeitem);
                            if (sp_shape) {
                                guint previous_curve_length = sp_shape->getCurve()->get_segment_count();
                                lpe_simplify->getRepr()->setAttribute("threshold", ss.str());
                                sp_lpe_item_update_patheffect(lpeitem, false, false);
                                simplified = true;
                                guint curve_length = sp_shape->getCurve()->get_segment_count();
                                std::vector<Geom::Point> ts = lpe_powerstroke->offset_points.data();
                                double factor = (double)curve_length/ (double)previous_curve_length;
                                for (size_t i = 0; i < ts.size(); i++) {
                                    ts[i][Geom::X] = ts[i][Geom::X] * factor;
                                }
                                lpe_powerstroke->offset_points.param_setValue(ts);
                            }
                            lpe_powerstroke->getRepr()->setAttribute("is_visible", "true");
                            sp_lpe_item_update_patheffect(lpeitem, false, false);
                        }
                    }
                    if(!simplified){
                        lpe_simplify->getRepr()->setAttribute("threshold", ss.str());
                    }
                }
            }
        }
    }
}
Exemplo n.º 8
0
static void
sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name)
{
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));

    if (DocumentUndo::getUndoSensitive(desktop->getDocument())) {
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, gtk_adjustment_get_value(adj));
    }

    // quit if run by the attr_changed listener
    if (g_object_get_data( tbl, "freeze" )) {
        return;
    }

    // in turn, prevent listener from responding
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );

    gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL);

    bool modmade = false;
    std::vector<SPItem*> itemlist=desktop->getSelection()->itemList();
    for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){
        SPItem *item = *i;
        if (SP_IS_GENERICELLIPSE(item)) {

            SPGenericEllipse *ge = SP_GENERICELLIPSE(item);

            if (!strcmp(value_name, "start")) {
                ge->start = (gtk_adjustment_get_value(adj) * M_PI)/ 180;
            } else {
                ge->end = (gtk_adjustment_get_value(adj) * M_PI)/ 180;
            }

            ge->normalize();
            (SP_OBJECT(ge))->updateRepr();
            (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);

            modmade = true;
        }
    }

    g_free(namespaced_name);

    GtkAdjustment *other = GTK_ADJUSTMENT( g_object_get_data( tbl, other_name ) );

    sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj), gtk_adjustment_get_value(other) );

    if (modmade) {
        DocumentUndo::maybeDone(desktop->getDocument(), value_name, SP_VERB_CONTEXT_ARC,
                                _("Arc: Change start/end"));
    }

    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
Exemplo n.º 9
0
static void
sp_selection_layout_widget_modify_selection(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data)
{
    SPDesktop *desktop = static_cast<SPDesktop *>(data);
    if ((desktop->getSelection() == selection) // only respond to changes in our desktop
        && (flags & (SP_OBJECT_MODIFIED_FLAG        |
                     SP_OBJECT_PARENT_MODIFIED_FLAG |
                     SP_OBJECT_CHILD_MODIFIED_FLAG   )))
    {
        sp_selection_layout_widget_update(spw, selection);
    }
}
Exemplo n.º 10
0
static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name,
                                 void (SPRect::*setter)(gdouble))
{
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));

    UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" ));
    Unit const *unit = tracker->getActiveUnit();
    g_return_if_fail(unit != NULL);

    if (DocumentUndo::getUndoSensitive(desktop->getDocument())) {
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        prefs->setDouble(Glib::ustring("/tools/shapes/rect/") + value_name,
            Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
    }

    // quit if run by the attr_changed listener
    if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) {
        return;
    }

    // in turn, prevent listener from responding
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE));

    bool modmade = false;
    Inkscape::Selection *selection = desktop->getSelection();
    std::vector<SPItem*> itemlist=selection->itemList();
    for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){
        if (SP_IS_RECT(*i)) {
            if (gtk_adjustment_get_value(adj) != 0) {
                (SP_RECT(*i)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
            } else {
                (*i)->getRepr()->setAttribute(value_name, NULL);
            }
            modmade = true;
        }
    }

    sp_rtb_sensitivize( tbl );

    if (modmade) {
        DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_RECT,
                           _("Change rectangle"));
    }

    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
Exemplo n.º 11
0
static void
sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection *selection, gpointer data)
{
    SPDesktop *desktop = static_cast<SPDesktop *>(data);
    if (desktop->getSelection() == selection) { // only respond to changes in our desktop
        gboolean setActive = (selection && !selection->isEmpty());
        std::vector<GtkAction*> *contextActions = reinterpret_cast<std::vector<GtkAction*> *>(g_object_get_data(G_OBJECT(spw), "contextActions"));
        if ( contextActions ) {
            for ( std::vector<GtkAction*>::iterator iter = contextActions->begin();
                  iter != contextActions->end(); ++iter) {
                if ( setActive != gtk_action_is_sensitive(*iter) ) {
                    gtk_action_set_sensitive( *iter, setActive );
                }
            }
        }

        sp_selection_layout_widget_update(spw, selection);
    }
}
Exemplo n.º 12
0
static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustring const &value_name)
{
    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));

    if (DocumentUndo::getUndoSensitive(desktop->getDocument())) {
        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
        prefs->setDouble("/tools/shapes/spiral/" + value_name,
            gtk_adjustment_get_value(adj));
    }

    // quit if run by the attr_changed listener
    if (g_object_get_data( tbl, "freeze" )) {
        return;
    }

    // in turn, prevent listener from responding
    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );

    gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL);

    bool modmade = false;
    std::vector<SPItem*> itemlist=desktop->getSelection()->itemList();
    for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){
        SPItem *item = *i;
        if (SP_IS_SPIRAL(item)) {
            Inkscape::XML::Node *repr = item->getRepr();
            sp_repr_set_svg_double( repr, namespaced_name,
                gtk_adjustment_get_value(adj) );
            item->updateRepr();
            modmade = true;
        }
    }

    g_free(namespaced_name);

    if (modmade) {
        DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL,
                           _("Change spiral"));
    }

    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
}
Exemplo n.º 13
0
void spdc_endpoint_snap_free(ToolBase const * const ec, Geom::Point& p, boost::optional<Geom::Point> &start_of_line, guint const /*state*/)
{
    SPDesktop *dt = ec->desktop;
    SnapManager &m = dt->namedview->snap_manager;
    Inkscape::Selection *selection = dt->getSelection();

    // selection->singleItem() is the item that is currently being drawn. This item will not be snapped to (to avoid self-snapping)
    // TODO: Allow snapping to the stationary parts of the item, and only ignore the last segment

    m.setup(dt, true, selection->singleItem());
    Inkscape::SnapCandidatePoint scp(p, Inkscape::SNAPSOURCE_NODE_HANDLE);
    if (start_of_line) {
        scp.addOrigin(*start_of_line);
    }

    Inkscape::SnappedPoint sp = m.freeSnap(scp);
    p = sp.getPoint();

    m.unSetup();
}
Exemplo n.º 14
0
/*
 * Core function, setup all the widgets whenever something changes on the desktop
 */
static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data)
{

    // std::cout << "ms_tb_selection_changed" << std::endl;

    if (blocked)
        return;

    GtkWidget *widget = GTK_WIDGET(data);

    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop"));
    if (!desktop) {
        return;
    }

    Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args
    if (selection) {
        // ToolBase *ev = sp_desktop_event_context(desktop);
        // GrDrag *drag = NULL;
        // if (ev) {
        //     drag = ev->get_drag();
        //     // Hide/show handles?
        // }

        SPMesh *ms_selected = 0;
        SPMeshType ms_type = SP_MESH_TYPE_COONS;
        bool ms_selected_multi = false;
        bool ms_type_multi = false; 
        ms_read_selection( selection, ms_selected, ms_selected_multi, ms_type, ms_type_multi );
        // std::cout << "   type: " << ms_type << std::endl;
        
        EgeSelectOneAction* type = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "mesh_select_type_action");
        gtk_action_set_sensitive( GTK_ACTION(type), (ms_selected && !ms_selected_multi) );
        if (ms_selected) {
            blocked = TRUE;
            ege_select_one_action_set_active( type, ms_type );
            blocked = FALSE;
        }
    }
}
Exemplo n.º 15
0
/**
 * Sets mesh type: Coons, Bicubic
 */
static void ms_type_changed(EgeSelectOneAction *act, GtkWidget *widget)
{
    // std::cout << "ms_type_changed" << std::endl;
    if (blocked) {
        return;
    }

    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop"));
    Inkscape::Selection *selection = desktop->getSelection();
    SPMesh *gradient = 0;
    ms_get_dt_selected_gradient(selection, gradient);

    if (gradient) {
        SPMeshType type = (SPMeshType) ege_select_one_action_get_active(act);
        // std::cout << "   type: " << type << std::endl;
        gradient->type = type;
        gradient->type_set = true;
        gradient->updateRepr();

        DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH,
                   _("Set mesh type"));
    }
}
Exemplo n.º 16
0
static void
sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw)
{
    if (g_object_get_data(G_OBJECT(spw), "update")) {
        return;
    }

    UnitTracker *tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(G_OBJECT(spw), "tracker"));
    if ( !tracker || tracker->isUpdating() ) {
        /*
         * When only units are being changed, don't treat changes
         * to adjuster values as object changes.
         */
        return;
    }
    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));

    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    Inkscape::Selection *selection = desktop->getSelection();
    SPDocument *document = desktop->getDocument();

    document->ensureUpToDate ();
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    Geom::OptRect bbox_vis = selection->visualBounds();
    Geom::OptRect bbox_geom = selection->geometricBounds();

    int prefs_bbox = prefs->getInt("/tools/bounding_box");
    SPItem::BBoxType bbox_type = (prefs_bbox == 0)?
        SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
    Geom::OptRect bbox_user = selection->bounds(bbox_type);

    if ( !bbox_user ) {
        g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
        return;
    }

    gdouble x0 = 0;
    gdouble y0 = 0;
    gdouble x1 = 0;
    gdouble y1 = 0;
    gdouble xrel = 0;
    gdouble yrel = 0;
    Unit const *unit = tracker->getActiveUnit();
    g_return_if_fail(unit != NULL);

    GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "X" ) );
    GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "Y" ) );
    GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "width" ) );
    GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "height" ) );

    if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) {
        x0 = Quantity::convert(gtk_adjustment_get_value(a_x), unit, "px");
        y0 = Quantity::convert(gtk_adjustment_get_value(a_y), unit, "px");
        x1 = x0 + Quantity::convert(gtk_adjustment_get_value(a_w), unit, "px");
        xrel = Quantity::convert(gtk_adjustment_get_value(a_w), unit, "px") / bbox_user->dimensions()[Geom::X];
        y1 = y0 + Quantity::convert(gtk_adjustment_get_value(a_h), unit, "px");;
        yrel = Quantity::convert(gtk_adjustment_get_value(a_h), unit, "px") / bbox_user->dimensions()[Geom::Y];
    } else {
        double const x0_propn = gtk_adjustment_get_value (a_x) / 100 / unit->factor;
        x0 = bbox_user->min()[Geom::X] * x0_propn;
        double const y0_propn = gtk_adjustment_get_value (a_y) / 100 / unit->factor;
        y0 = y0_propn * bbox_user->min()[Geom::Y];
        xrel = gtk_adjustment_get_value (a_w) / (100 / unit->factor);
        x1 = x0 + xrel * bbox_user->dimensions()[Geom::X];
        yrel = gtk_adjustment_get_value (a_h) / (100 / unit->factor);
        y1 = y0 + yrel * bbox_user->dimensions()[Geom::Y];
    }

    // Keep proportions if lock is on
    GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(G_OBJECT(spw), "lock") );
    if ( gtk_toggle_action_get_active(lock) ) {
        if (adj == a_h) {
            x1 = x0 + yrel * bbox_user->dimensions()[Geom::X];
        } else if (adj == a_w) {
            y1 = y0 + xrel * bbox_user->dimensions()[Geom::Y];
        }
    }

    // scales and moves, in px
    double mh = fabs(x0 - bbox_user->min()[Geom::X]);
    double sh = fabs(x1 - bbox_user->max()[Geom::X]);
    double mv = fabs(y0 - bbox_user->min()[Geom::Y]);
    double sv = fabs(y1 - bbox_user->max()[Geom::Y]);

    // unless the unit is %, convert the scales and moves to the unit
    if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) {
        mh = Quantity::convert(mh, "px", unit);
        sh = Quantity::convert(sh, "px", unit);
        mv = Quantity::convert(mv, "px", unit);
        sv = Quantity::convert(sv, "px", unit);
    }

    // do the action only if one of the scales/moves is greater than half the last significant
    // digit in the spinbox (currently spinboxes have 3 fractional digits, so that makes 0.0005). If
    // the value was changed by the user, the difference will be at least that much; otherwise it's
    // just rounding difference between the spinbox value and actual value, so no action is
    // performed
    char const * const actionkey = ( mh > 5e-4 ? "selector:toolbar:move:horizontal" :
                                     sh > 5e-4 ? "selector:toolbar:scale:horizontal" :
                                     mv > 5e-4 ? "selector:toolbar:move:vertical" :
                                     sv > 5e-4 ? "selector:toolbar:scale:vertical" : NULL );

    if (actionkey != NULL) {

        // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed
        desktop->getCanvas()->forceFullRedrawAfterInterruptions(0);

        bool transform_stroke = prefs->getBool("/options/transform/stroke", true);
        bool preserve = prefs->getBool("/options/preservetransform/value", false);

        Geom::Affine scaler;
        if (bbox_type == SPItem::VISUAL_BBOX) {
            scaler = get_scale_transform_for_variable_stroke (*bbox_vis, *bbox_geom, transform_stroke, preserve, x0, y0, x1, y1);
        } else {
            // 1) We could have use the newer get_scale_transform_for_variable_stroke() here, but to avoid regressions
            // we'll just use the old get_scale_transform_for_uniform_stroke() for now.
            // 2) get_scale_transform_for_uniform_stroke() is intended for visual bounding boxes, not geometrical ones!
            // we'll trick it into using a geometric bounding box though, by setting the stroke width to zero
            scaler = get_scale_transform_for_uniform_stroke (*bbox_geom, 0, 0, false, false, x0, y0, x1, y1);
        }

        sp_selection_apply_affine(selection, scaler);
        DocumentUndo::maybeDone(document, actionkey, SP_VERB_CONTEXT_SELECT,
                                _("Transform by toolbar"));

        // resume interruptibility
        desktop->getCanvas()->endForcedFullRedraws();
    }

    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
}
Exemplo n.º 17
0
Glib::RefPtr<Gdk::Pixbuf> Tracer::sioxProcessImage(SPImage *img, Glib::RefPtr<Gdk::Pixbuf>origPixbuf)
{
    if (!sioxEnabled)
        return origPixbuf;

    if (origPixbuf == lastOrigPixbuf)
        return lastSioxPixbuf;

    //g_message("siox: start");

    //Convert from gdk, so a format we know.  By design, the pixel
    //format in PackedPixelMap is identical to what is needed by SIOX
    SioxImage simage(origPixbuf->gobj());

    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    if (!desktop)
        {
        g_warning("%s", _("Trace: No active desktop"));
        return Glib::RefPtr<Gdk::Pixbuf>(NULL);
        }

    Inkscape::MessageStack *msgStack = desktop->getMessageStack();

    Inkscape::Selection *sel = desktop->getSelection();
    if (!sel)
        {
        char *msg = _("Select an <b>image</b> to trace");
        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
        //g_warning(msg);
        return Glib::RefPtr<Gdk::Pixbuf>(NULL);
        }

    Inkscape::DrawingItem *aImg = img->get_arenaitem(desktop->dkey);
    //g_message("img: %d %d %d %d\n", aImg->bbox.x0, aImg->bbox.y0,
    //                                aImg->bbox.x1, aImg->bbox.y1);

    double width  = aImg->geometricBounds()->width();
    double height = aImg->geometricBounds()->height();

    double iwidth  = simage.getWidth();
    double iheight = simage.getHeight();

    double iwscale = width  / iwidth;
    double ihscale = height / iheight;

    std::vector<Inkscape::DrawingItem *> arenaItems;
    std::vector<SPShape *>::iterator iter;
    for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; ++iter)
        {
        SPItem *item = *iter;
        Inkscape::DrawingItem *aItem = item->get_arenaitem(desktop->dkey);
        arenaItems.push_back(aItem);
        }

    //g_message("%d arena items\n", arenaItems.size());

    //PackedPixelMap *dumpMap = PackedPixelMapCreate(
    //                simage.getWidth(), simage.getHeight());

    //g_message("siox: start selection");

    for (int row=0 ; row<iheight ; row++)
        {
        double ypos = aImg->geometricBounds()->top() + ihscale * (double) row;
        for (int col=0 ; col<simage.getWidth() ; col++)
            {
            //Get absolute X,Y position
            double xpos = aImg->geometricBounds()->left() + iwscale * (double)col;
            Geom::Point point(xpos, ypos);
            point *= aImg->transform();
            //point *= imgMat;
            //point = desktop->doc2dt(point);
            //g_message("x:%f    y:%f\n", point[0], point[1]);
            bool weHaveAHit = false;
            std::vector<Inkscape::DrawingItem *>::iterator aIter;
            for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; ++aIter)
                {
                Inkscape::DrawingItem *arenaItem = *aIter;
                if (arenaItem->pick(point, 1.0f, 1))
                    {
                    weHaveAHit = true;
                    break;
                    }
                }

            if (weHaveAHit)
                {
                //g_message("hit!\n");
                //dumpMap->setPixelLong(dumpMap, col, row, 0L);
                simage.setConfidence(col, row,
                        Siox::UNKNOWN_REGION_CONFIDENCE);
                }
            else
                {
                //g_message("miss!\n");
                //dumpMap->setPixelLong(dumpMap, col, row,
                //        simage.getPixel(col, row));
                simage.setConfidence(col, row,
                        Siox::CERTAIN_BACKGROUND_CONFIDENCE);
                }
            }
        }

    //g_message("siox: selection done");

    //dumpMap->writePPM(dumpMap, "siox1.ppm");
    //dumpMap->destroy(dumpMap);

    //## ok we have our pixel buf
    TraceSioxObserver observer(this);
    Siox sengine(&observer);
    SioxImage result = sengine.extractForeground(simage, 0xffffff);
    if (!result.isValid())
        {
        g_warning("%s", _("Invalid SIOX result"));
        return Glib::RefPtr<Gdk::Pixbuf>(NULL);
        }

    //result.writePPM("siox2.ppm");

    Glib::RefPtr<Gdk::Pixbuf> newPixbuf = Glib::wrap(result.getGdkPixbuf());

    //g_message("siox: done");

    lastSioxPixbuf = newPixbuf;

    return newPixbuf;
}
Exemplo n.º 18
0
void Tracer::traceThread()
{
    //## Remember. NEVER leave this method without setting
    //## engine back to NULL

    //## Prepare our kill flag.  We will watch this later to
    //## see if the main thread wants us to stop
    keepGoing = true;

    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    if (!desktop)
        {
        g_warning("Trace: No active desktop\n");
        return;
        }

    Inkscape::MessageStack *msgStack = desktop->getMessageStack();

    Inkscape::Selection *selection = desktop->getSelection();

    if (!SP_ACTIVE_DOCUMENT)
        {
        char *msg = _("Trace: No active document");
        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
        //g_warning(msg);
        engine = NULL;
        return;
        }
    SPDocument *doc = SP_ACTIVE_DOCUMENT;
    doc->ensureUpToDate();


    SPImage *img = getSelectedSPImage();
    if (!img)
        {
        engine = NULL;
        return;
        }

    GdkPixbuf *trace_pb = gdk_pixbuf_copy(img->pixbuf->getPixbufRaw(false));
    if (img->pixbuf->pixelFormat() == Inkscape::Pixbuf::PF_CAIRO) {
        convert_pixels_argb32_to_pixbuf(
            gdk_pixbuf_get_pixels(trace_pb),
            gdk_pixbuf_get_width(trace_pb),
            gdk_pixbuf_get_height(trace_pb),
            gdk_pixbuf_get_rowstride(trace_pb));
    }

    Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(trace_pb, false);

    pixbuf = sioxProcessImage(img, pixbuf);

    if (!pixbuf)
        {
        char *msg = _("Trace: Image has no bitmap data");
        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
        //g_warning(msg);
        engine = NULL;
        return;
        }

    msgStack->flash(Inkscape::NORMAL_MESSAGE, _("Trace: Starting trace..."));
    desktop->updateCanvasNow();

    std::vector<TracingEngineResult> results =
                engine->trace(pixbuf);
    //printf("nrPaths:%d\n", results.size());
    int nrPaths = results.size();

    //### Check if we should stop
    if (!keepGoing || nrPaths<1)
        {
        engine = NULL;
        return;
        }

    //### Get pointers to the <image> and its parent
    //XML Tree being used directly here while it shouldn't be.
    Inkscape::XML::Node *imgRepr   = SP_OBJECT(img)->getRepr();
    Inkscape::XML::Node *par       = imgRepr->parent();

    //### Get some information for the new transform()
    double x      = 0.0;
    double y      = 0.0;
    double width  = 0.0;
    double height = 0.0;
    double dval   = 0.0;

    if (sp_repr_get_double(imgRepr, "x", &dval))
        x = dval;
    if (sp_repr_get_double(imgRepr, "y", &dval))
        y = dval;

    if (sp_repr_get_double(imgRepr, "width", &dval))
        width = dval;
    if (sp_repr_get_double(imgRepr, "height", &dval))
        height = dval;

    double iwidth  = (double)pixbuf->get_width();
    double iheight = (double)pixbuf->get_height();

    double iwscale = width  / iwidth;
    double ihscale = height / iheight;

    Geom::Translate trans(x, y);
    Geom::Scale scal(iwscale, ihscale);

    //# Convolve scale, translation, and the original transform
    Geom::Affine tf(scal * trans);
    tf *= img->transform;


    //#OK.  Now let's start making new nodes

    Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
    Inkscape::XML::Node *groupRepr = NULL;

    //# if more than 1, make a <g>roup of <path>s
    if (nrPaths > 1)
        {
        groupRepr = xml_doc->createElement("svg:g");
        par->addChild(groupRepr, imgRepr);
        }

    long totalNodeCount = 0L;

    for (unsigned int i=0 ; i<results.size() ; i++)
        {
        TracingEngineResult result = results[i];
        totalNodeCount += result.getNodeCount();

        Inkscape::XML::Node *pathRepr = xml_doc->createElement("svg:path");
        pathRepr->setAttribute("style", result.getStyle().c_str());
        pathRepr->setAttribute("d",     result.getPathData().c_str());

        if (nrPaths > 1)
            groupRepr->addChild(pathRepr, NULL);
        else
            par->addChild(pathRepr, imgRepr);

        //### Apply the transform from the image to the new shape
        SPObject *reprobj = doc->getObjectByRepr(pathRepr);
        if (reprobj)
            {
            SPItem *newItem = SP_ITEM(reprobj);
            newItem->doWriteTransform(pathRepr, tf, NULL);
            }
        if (nrPaths == 1)
            {
            selection->clear();
            selection->add(pathRepr);
            }
        Inkscape::GC::release(pathRepr);
        }

    // If we have a group, then focus on, then forget it
    if (nrPaths > 1)
        {
        selection->clear();
        selection->add(groupRepr);
        Inkscape::GC::release(groupRepr);
        }

    //## inform the document, so we can undo
    DocumentUndo::done(doc, SP_VERB_SELECTION_TRACE, _("Trace bitmap"));

    engine = NULL;

    char *msg = g_strdup_printf(_("Trace: Done. %ld nodes created"), totalNodeCount);
    msgStack->flash(Inkscape::NORMAL_MESSAGE, msg);
    g_free(msg);

}
Exemplo n.º 19
0
static void spdc_flush_white(FreehandBase *dc, SPCurve *gc)
{
    SPCurve *c;
    if (dc->white_curves) {
        g_assert(dc->white_item);
        c = SPCurve::concat(dc->white_curves);
        g_slist_free(dc->white_curves);
        dc->white_curves = NULL;
        if (gc) {
            c->append(gc, FALSE);
        }
    } else if (gc) {
        c = gc;
        c->ref();
    } else {
        return;
    }

    // Now we have to go back to item coordinates at last
    c->transform( dc->white_item
                            ? (dc->white_item)->dt2i_affine()
                            : dc->desktop->dt2doc() );

    SPDesktop *desktop = dc->desktop;
    SPDocument *doc = desktop->getDocument();
    Inkscape::XML::Document *xml_doc = doc->getReprDoc();

    if ( c && !c->is_empty() ) {
        // We actually have something to write

        bool has_lpe = false;
        Inkscape::XML::Node *repr;

        if (dc->white_item) {
            repr = dc->white_item->getRepr();
            has_lpe = SP_LPE_ITEM(dc->white_item)->hasPathEffectRecursive();
        } else {
            repr = xml_doc->createElement("svg:path");
            // Set style
            sp_desktop_apply_style_tool(desktop, repr, tool_name(dc).data(), false);
        }

        gchar *str = sp_svg_write_path( c->get_pathvector() );
        g_assert( str != NULL );
        if (has_lpe)
            repr->setAttribute("inkscape:original-d", str);
        else
            repr->setAttribute("d", str);
        g_free(str);

        if (!dc->white_item) {
            // Attach repr
            SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));

            spdc_check_for_and_apply_waiting_LPE(dc, item, c);
            if(previous_shape_type != BEND_CLIPBOARD){
                dc->selection->set(repr);
            }
            Inkscape::GC::release(repr);
            item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
            item->updateRepr();
            item->doWriteTransform(item->getRepr(), item->transform, NULL, true);
            if(previous_shape_type == BEND_CLIPBOARD){
                repr->parent()->removeChild(repr);
            }
        }

        DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL,
                         _("Draw path"));

        // When quickly drawing several subpaths with Shift, the next subpath may be finished and
        // flushed before the selection_modified signal is fired by the previous change, which
        // results in the tool losing all of the selected path's curve except that last subpath. To
        // fix this, we force the selection_modified callback now, to make sure the tool's curve is
        // in sync immediately.
        spdc_selection_modified(desktop->getSelection(), 0, dc);
    }

    c->unref();

    // Flush pending updates
    doc->ensureUpToDate();
}
Exemplo n.º 20
0
SPImage *Tracer::getSelectedSPImage()
{

    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    if (!desktop)
        {
        g_warning("Trace: No active desktop");
        return NULL;
        }

    Inkscape::MessageStack *msgStack = desktop->getMessageStack();

    Inkscape::Selection *sel = desktop->getSelection();
    if (!sel)
        {
        char *msg = _("Select an <b>image</b> to trace");
        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
        //g_warning(msg);
        return NULL;
        }

    if (sioxEnabled)
        {
        SPImage *img = NULL;
        std::vector<SPItem*> const list = sel->itemList();
        std::vector<SPItem *> items;
        sioxShapes.clear();

        /*
           First, things are selected top-to-bottom, so we need to invert
           them as bottom-to-top so that we can discover the image and any
           SPItems above it
        */
        for (std::vector<SPItem*>::const_iterator i=list.begin() ; list.end()!=i ; ++i)
            {
            if (!SP_IS_ITEM(*i))
                {
                continue;
                }
            SPItem *item = *i;
            items.insert(items.begin(), item);
            }
        std::vector<SPItem *>::iterator iter;
        for (iter = items.begin() ; iter!= items.end() ; ++iter)
            {
            SPItem *item = *iter;
            if (SP_IS_IMAGE(item))
                {
                if (img) //we want only one
                    {
                    char *msg = _("Select only one <b>image</b> to trace");
                    msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
                    return NULL;
                    }
                img = SP_IMAGE(item);
                }
            else // if (img) //# items -after- the image in tree (above it in Z)
                {
                if (SP_IS_SHAPE(item))
                    {
                    SPShape *shape = SP_SHAPE(item);
                    sioxShapes.push_back(shape);
                    }
                }
            }

        if (!img || sioxShapes.size() < 1)
            {
            char *msg = _("Select one image and one or more shapes above it");
            msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
            return NULL;
            }
        return img;
        }
    else
        //### SIOX not enabled.  We want exactly one image selected
        {
        SPItem *item = sel->singleItem();
        if (!item)
            {
            char *msg = _("Select an <b>image</b> to trace");  //same as above
            msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
            //g_warning(msg);
            return NULL;
            }

        if (!SP_IS_IMAGE(item))
            {
            char *msg = _("Select an <b>image</b> to trace");
            msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
            //g_warning(msg);
            return NULL;
            }

        SPImage *img = SP_IMAGE(item);

        return img;
        }

}