Пример #1
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());
            }
        }
    }
}
Пример #2
0
void
sp_textpath_to_text(SPObject *tp)
{
    SPObject *text = SP_OBJECT_PARENT(tp);

    NRRect bbox;
    sp_item_invoke_bbox(SP_ITEM(text), &bbox, sp_item_i2doc_affine(SP_ITEM(text)), TRUE);
    Geom::Point xy(bbox.x0, bbox.y0);

    // make a list of textpath children
    GSList *tp_reprs = NULL;
    for (SPObject *o = SP_OBJECT(tp)->firstChild() ; o != NULL; o = o->next) {
        tp_reprs = g_slist_prepend(tp_reprs, SP_OBJECT_REPR(o));
    }

    for ( GSList *i = tp_reprs ; i ; i = i->next ) {
        // make a copy of each textpath child
        Inkscape::XML::Node *copy = ((Inkscape::XML::Node *) i->data)->duplicate(SP_OBJECT_REPR(text)->document());
        // remove the old repr from under textpath
        SP_OBJECT_REPR(tp)->removeChild((Inkscape::XML::Node *) i->data);
        // put its copy under text
        SP_OBJECT_REPR(text)->addChild(copy, NULL); // fixme: copy id
    }

    //remove textpath
    tp->deleteObject();
    g_slist_free(tp_reprs);

    // set x/y on text
    /* fixme: Yuck, is this really the right test? */
    if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) {
        sp_repr_set_svg_double(SP_OBJECT_REPR(text), "x", xy[Geom::X]);
        sp_repr_set_svg_double(SP_OBJECT_REPR(text), "y", xy[Geom::Y]);
    }
}
Пример #3
0
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;
}
Пример #4
0
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;
            }
        }
    }
}
Пример #5
0
void
text_unflow ()
{
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    if (!desktop)
        return;

    SPDocument *doc = sp_desktop_document (desktop);
    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);

    Inkscape::Selection *selection = sp_desktop_selection(desktop);


    if (!flowtext_in_selection(selection) || g_slist_length((GSList *) selection->itemList()) < 1) {
        sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it."));
        return;
    }

    GSList *new_objs = NULL;
    GSList *old_objs = NULL;

    for (GSList *items = g_slist_copy((GSList *) selection->itemList());
         items != NULL;
         items = items->next) {

        if (!SP_IS_FLOWTEXT(SP_OBJECT(items->data))) {
            continue;
        }

        SPItem *flowtext = SP_ITEM(items->data);

        if (sp_te_get_string_multiline(flowtext) == NULL) { // flowtext is empty
            continue;
        }

        /* Create <text> */
        Inkscape::XML::Node *rtext = xml_doc->createElement("svg:text");
        rtext->setAttribute("xml:space", "preserve"); // we preserve spaces in the text objects we create

        /* Set style */
        rtext->setAttribute("style", SP_OBJECT_REPR(flowtext)->attribute("style")); // fixme: transfer style attrs too; and from descendants

        NRRect bbox;
        sp_item_invoke_bbox(SP_ITEM(flowtext), &bbox, sp_item_i2doc_affine(SP_ITEM(flowtext)), TRUE);
        Geom::Point xy(bbox.x0, bbox.y0);
        if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) {
            sp_repr_set_svg_double(rtext, "x", xy[Geom::X]);
            sp_repr_set_svg_double(rtext, "y", xy[Geom::Y]);
        }

        /* Create <tspan> */
        Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan");
        rtspan->setAttribute("sodipodi:role", "line"); // otherwise, why bother creating the tspan?
        rtext->addChild(rtspan, NULL);

        gchar *text_string = sp_te_get_string_multiline(flowtext);
        Inkscape::XML::Node *text_repr = xml_doc->createTextNode(text_string); // FIXME: transfer all formatting!!!
        free(text_string);
        rtspan->appendChild(text_repr);

        SP_OBJECT_REPR(SP_OBJECT_PARENT(flowtext))->appendChild(rtext);
        SPObject *text_object = doc->getObjectByRepr(rtext);

        new_objs = g_slist_prepend (new_objs, text_object);
        old_objs = g_slist_prepend (old_objs, flowtext);

        Inkscape::GC::release(rtext);
        Inkscape::GC::release(rtspan);
        Inkscape::GC::release(text_repr);
    }

    selection->clear();
    selection->setList(new_objs);
    for (GSList *i = old_objs; i; i = i->next) {
        SP_OBJECT(i->data)->deleteObject (true);
    }

    g_slist_free (old_objs);
    g_slist_free (new_objs);

    sp_document_done(doc, SP_VERB_CONTEXT_TEXT, 
                     _("Unflow flowed text"));
}
Пример #6
0
static void
sp_spiral_drag(SPSpiralContext *sc, Geom::Point p, guint state)
{
    SPDesktop *desktop = SP_EVENT_CONTEXT(sc)->desktop;

    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12);

    if (!sc->item) {

        if (Inkscape::have_viable_layer(desktop, sc->_message_context) == false) {
            return;
        }

        /* Create object */
        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_EVENT_CONTEXT_DOCUMENT(sc));
        Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
        repr->setAttribute("sodipodi:type", "spiral");

        /* Set style */
        sp_desktop_apply_style_tool(desktop, repr, "/tools/shapes/spiral", false);

        sc->item = (SPItem *) desktop->currentLayer()->appendChildRepr(repr);
        Inkscape::GC::release(repr);
        sc->item->transform = sp_item_i2doc_affine(SP_ITEM(desktop->currentLayer())).inverse();
        sc->item->updateRepr();

        sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5);
    }

    SnapManager &m = desktop->namedview->snap_manager;
    m.setup(desktop, true, sc->item);
    Geom::Point pt2g = to_2geom(p);
    m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g);

    Geom::Point const p0 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, sc->center));
    Geom::Point const p1 = to_2geom(sp_desktop_dt2doc_xy_point(desktop, from_2geom(pt2g)));        
    
    SPSpiral *spiral = SP_SPIRAL(sc->item);

    Geom::Point const delta = p1 - p0;
    gdouble const rad = Geom::L2(delta);

    gdouble arg = Geom::atan2(delta) - 2.0*M_PI*spiral->revo;

    if (state & GDK_CONTROL_MASK) {
        arg = sp_round(arg, M_PI/snaps);
    }

    /* Fixme: these parameters should be got from dialog box */
    sp_spiral_position_set(spiral, p0[Geom::X], p0[Geom::Y],
                           /*expansion*/ sc->exp,
                           /*revolution*/ sc->revo,
                           rad, arg,
                           /*t0*/ sc->t0);

    /* status text */
    GString *rads = SP_PX_TO_METRIC_STRING(rad, desktop->namedview->getDefaultMetric());
    sc->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE,
                               _("<b>Spiral</b>: radius %s, angle %5g&#176;; with <b>Ctrl</b> to snap angle"),
                               rads->str, sp_round((arg + 2.0*M_PI*spiral->revo)*180/M_PI, 0.0001));
    g_string_free(rads, FALSE);
}
Пример #7
0
static void
sp_fill_style_widget_update (SPWidget *spw, SPSelection *sel)
{
	SPPaintSelector *psel;
	GtkWidget *fillrule;
	SPPaintSelectorMode pselmode;
	const GSList *objects, *l;
	SPObject *object;
	SPGradient *vector;
	gfloat c[5];
	SPLinearGradient *lg;
	SPRadialGradient *rg;
#if 0
	NRPointF p0, p1, p2;
#endif
	NRMatrixF fctm, gs2d;
	NRRectF fbb;

	if (g_object_get_data (G_OBJECT (spw), "update")) return;

	g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));

	psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector"));

	if (!sel || sp_selection_is_empty (sel)) {
		/* No objects, set empty */
		sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
		g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
		return;
	}

	objects = sp_selection_item_list (sel);
	object = SP_OBJECT (objects->data);
	pselmode = (SPPaintSelectorMode)sp_fill_style_determine_paint_selector_mode (SP_OBJECT_STYLE (object));

	for (l = objects->next; l != NULL; l = l->next) {
		SPPaintSelectorMode nextmode;
		nextmode = sp_fill_style_determine_paint_selector_mode (SP_OBJECT_STYLE (l->data));
		if (nextmode != pselmode) {
			/* Multiple styles */
			sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
			g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
			return;
		}
	}
#ifdef SP_FS_VERBOSE
	g_print ("FillStyleWidget: paint selector mode %d\n", pselmode);
#endif
	switch (pselmode) {
	case SP_PAINT_SELECTOR_MODE_NONE:
		/* No paint at all */
		sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_NONE);
		break;
	case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
		sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_COLOR_RGB);
		sp_fill_style_get_average_color_rgba (objects, c);
		sp_paint_selector_set_color_rgba_floatv (psel, c);
		break;
	case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
		sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_COLOR_CMYK);
		sp_fill_style_get_average_color_cmyka (objects, c);
		sp_paint_selector_set_color_cmyka_floatv (psel, c);
		break;
	case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
		object = SP_OBJECT (objects->data);
		/* We know that all objects have lineargradient fill style */
		vector = sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object)), FALSE);
		for (l = objects->next; l != NULL; l = l->next) {
			SPObject *next;
			next = SP_OBJECT (l->data);
			if (sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (next)), FALSE) != vector) {
				/* Multiple vectors */
				sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
				g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
				return;
			}
		}
		/* fixme: Probably we should set multiple mode here too */
		sp_paint_selector_set_gradient_linear (psel, vector);
		sp_selection_bbox_document (sel, &fbb);
		sp_paint_selector_set_gradient_bbox (psel, fbb.x0, fbb.y0, fbb.x1, fbb.y1);

		/* fixme: This is plain wrong */
		lg = SP_LINEARGRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object));
		sp_item_invoke_bbox (SP_ITEM (object), &fbb, NULL, TRUE);
		sp_item_i2doc_affine (SP_ITEM (object), &fctm);
		sp_gradient_get_gs2d_matrix_f (SP_GRADIENT (lg), &fctm, &fbb, &gs2d);
		sp_paint_selector_set_gradient_gs2d_matrix_f (psel, &gs2d);
		sp_paint_selector_set_gradient_properties (psel, SP_GRADIENT_UNITS (lg), SP_GRADIENT_SPREAD (lg));
		sp_paint_selector_set_lgradient_position (psel, lg->x1.computed, lg->y1.computed, lg->x2.computed, lg->y2.computed);
		break;
	case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
		object = SP_OBJECT (objects->data);
		/* We know that all objects have radialgradient fill style */
		vector = sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object)), FALSE);
		for (l = objects->next; l != NULL; l = l->next) {
			SPObject *next;
			next = SP_OBJECT (l->data);
			if (sp_gradient_get_vector (SP_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (next)), FALSE) != vector) {
				/* Multiple vectors */
				sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
				g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
				return;
			}
		}
		/* fixme: Probably we should set multiple mode here too */
		sp_paint_selector_set_gradient_radial (psel, vector);
		sp_selection_bbox_document (sel, &fbb);
		sp_paint_selector_set_gradient_bbox (psel, fbb.x0, fbb.y0, fbb.x1, fbb.y1);
		/* fixme: This is plain wrong */
		rg = SP_RADIALGRADIENT (SP_OBJECT_STYLE_FILL_SERVER (object));
		sp_item_invoke_bbox (SP_ITEM (object), &fbb, NULL, TRUE);
		sp_item_i2doc_affine (SP_ITEM (object), &fctm);
		sp_gradient_get_gs2d_matrix_f (SP_GRADIENT (rg), &fctm, &fbb, &gs2d);
		sp_paint_selector_set_gradient_gs2d_matrix_f (psel, &gs2d);
		sp_paint_selector_set_gradient_properties (psel, SP_GRADIENT_UNITS (rg), SP_GRADIENT_SPREAD (rg));
		sp_paint_selector_set_rgradient_position (psel, rg->cx.computed, rg->cy.computed, rg->fx.computed, rg->fy.computed, rg->r.computed);
		break;
	default:
		sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
		break;
	}

	fillrule = GTK_WIDGET(g_object_get_data (G_OBJECT (spw), "fill-rule"));
	gtk_option_menu_set_history (GTK_OPTION_MENU (fillrule), (SP_OBJECT_STYLE (object)->fill_rule.computed == ART_WIND_RULE_NONZERO) ? 0 : 1);

	g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
}