Exemple #1
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]);
    }
}
Exemple #2
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"));
}
Exemple #3
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));
}