Пример #1
0
static void
sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw)
{
	const GSList *items, *i;
	SPGradient *vector;
	gfloat c[5];

	if (!spw->inkscape) return;
	if (g_object_get_data (G_OBJECT (spw), "update")) return;
	g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
#ifdef SP_FS_VERBOSE
	g_print ("FillStyleWidget: paint dragged\n");
#endif
	switch (psel->mode) {
	case SP_PAINT_SELECTOR_MODE_EMPTY:
	case SP_PAINT_SELECTOR_MODE_MULTIPLE:
	case SP_PAINT_SELECTOR_MODE_NONE:
		g_warning ("file %s: line %d: Paint %d should not emit 'dragged'", __FILE__, __LINE__, psel->mode);
		break;
	case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
		sp_paint_selector_get_rgba_floatv (psel, c);
		items = sp_widget_get_item_list (spw);
		for (i = items; i != NULL; i = i->next) {
			sp_style_set_fill_color_rgba (SP_OBJECT_STYLE (i->data), c[0], c[1], c[2], c[3], TRUE, TRUE);
		}
		break;
	case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
		sp_paint_selector_get_cmyka_floatv (psel, c);
		items = sp_widget_get_item_list (spw);
		for (i = items; i != NULL; i = i->next) {
			sp_style_set_fill_color_cmyka (SP_OBJECT_STYLE (i->data), c[0], c[1], c[2], c[3], c[4], TRUE, TRUE);
		}
		break;
	case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
		vector = sp_paint_selector_get_gradient_vector (psel);
		vector = sp_gradient_ensure_vector_normalized (vector);
		items = sp_widget_get_item_list (spw);
		for (i = items; i != NULL; i = i->next) {
			SPGradient *lg;
			lg = sp_item_force_fill_lineargradient_vector (SP_ITEM (i->data), vector);
			sp_paint_selector_write_lineargradient (psel, SP_LINEARGRADIENT (lg), SP_ITEM (i->data));
		}
		break;
	case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
		vector = sp_paint_selector_get_gradient_vector (psel);
		vector = sp_gradient_ensure_vector_normalized (vector);
		items = sp_widget_get_item_list (spw);
		for (i = items; i != NULL; i = i->next) {
			SPGradient *rg;
			rg = sp_item_force_fill_radialgradient_vector (SP_ITEM (i->data), vector);
			sp_paint_selector_write_radialgradient (psel, SP_RADIALGRADIENT (rg), SP_ITEM (i->data));
		}
		break;
	default:
		g_warning ("file %s: line %d: Paint selector should not be in mode %d", __FILE__, __LINE__, psel->mode);
		break;
	}
	g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
}
Пример #2
0
void
gr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke)
{
    SPStyle *style = SP_OBJECT_STYLE (item);

    if (do_fill) {
        if (style && (style->fill.isPaintserver()) &&
            SP_IS_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (item))) {
            SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
            if (SP_IS_LINEARGRADIENT (server)) {
                sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true);
            } else if (SP_IS_RADIALGRADIENT (server)) {
                sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true);
            }
        } else if (new_fill) {
            sp_item_set_gradient(item, gr, new_type, true);
        }
    }

    if (do_stroke) {
        if (style && (style->stroke.isPaintserver()) &&
            SP_IS_GRADIENT (SP_OBJECT_STYLE_STROKE_SERVER (item))) {
            SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
            if (SP_IS_LINEARGRADIENT (server)) {
                sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false);
            } else if (SP_IS_RADIALGRADIENT (server)) {
                sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false);
            }
        } else if (!new_fill) {
            sp_item_set_gradient(item, gr, new_type, false);
        }
    }
}
Пример #3
0
static void sp_tspan_bbox(SPItem const *item, NRRect *bbox, Geom::Matrix const &transform, unsigned const /*flags*/)
{
    // find out the ancestor text which holds our layout
    SPObject *parent_text = SP_OBJECT(item);
    for (; parent_text != NULL && !SP_IS_TEXT(parent_text); parent_text = SP_OBJECT_PARENT (parent_text)){};
    if (parent_text == NULL) return;

    // get the bbox of our portion of the layout
    SP_TEXT(parent_text)->layout.getBoundingBox(bbox, transform, sp_text_get_length_upto(parent_text, item), sp_text_get_length_upto(item, NULL) - 1);

    // Add stroke width
    SPStyle* style=SP_OBJECT_STYLE (item);
    if (!style->stroke.isNone()) {
        double const scale = transform.descrim();
        if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord
            double const width = MAX(0.125, style->stroke_width.computed * scale);
            if ( fabs(bbox->x1 - bbox->x0) > -0.00001 && fabs(bbox->y1 - bbox->y0) > -0.00001 ) {
                bbox->x0-=0.5*width;
                bbox->x1+=0.5*width;
                bbox->y0-=0.5*width;
                bbox->y1+=0.5*width;
            }
        }
    }
}
Пример #4
0
/**
 * Writes the given transform into the repr for the given item.
 */
static void
sp_path_write_transform (SPItem *item, SPRepr *repr, NRMatrixF *transform)
{
	SPPath *path;
	SPShape *shape;
	NRBPath dpath, spath;
	double ex;
	gchar *svgpath;
	SPStyle *style;

	path = (SPPath *) item;
	shape = (SPShape *) item;

	/* Calculate the DF */
	ex = NR_MATRIX_DF_EXPANSION (transform);

	/* Take the path for the shape, write it as an svgpath, and add it to the repr */
	spath.path = shape->curve->bpath;
	nr_path_duplicate_transform (&dpath, &spath, transform);
	svgpath = sp_svg_write_path (dpath.path);
	sp_repr_set_attr (repr, "d", svgpath);
	g_free (svgpath);
	nr_free (dpath.path);

	/* Wrte the style info into the repr */
	style = SP_OBJECT_STYLE (item);
	if (style->stroke.type != SP_PAINT_TYPE_NONE) {
		if (!NR_DF_TEST_CLOSE (ex, 1.0, NR_EPSILON_D)) {
			gchar *str;
			/* Scale changed, so we have to adjust stroke width */
			style->stroke_width.computed *= ex;
			if (style->stroke_dash.n_dash != 0) {
				int i;
				for (i = 0; i < style->stroke_dash.n_dash; i++) style->stroke_dash.dash[i] *= ex;
				style->stroke_dash.offset *= ex;
			}
			str = sp_style_write_difference (style, SP_OBJECT_STYLE (SP_OBJECT_PARENT (item)));
			sp_repr_set_attr (repr, "style", str);
			g_free (str);
		}
	}
	sp_repr_set_attr (repr, "transform", NULL);
}
Пример #5
0
static void         GetDest(SPObject* child,Shape **computed)
{
	if ( child == NULL ) return;

	SPCurve *curve=NULL;
	Geom::Matrix tr_mat;

	SPObject* u_child=child;
	if ( SP_IS_USE(u_child) ) {
		u_child=SP_USE(u_child)->child;
		tr_mat = SP_ITEM(u_child)->getRelativeTransform(SP_OBJECT_PARENT(child));
	} else {
		tr_mat = SP_ITEM(u_child)->transform;
	}
	if ( SP_IS_SHAPE (u_child) ) {
		curve = sp_shape_get_curve (SP_SHAPE (u_child));
	} else if ( SP_IS_TEXT (u_child) ) {
	curve = SP_TEXT (u_child)->getNormalizedBpath ();
	}

	if ( curve ) {
		Path*   temp=new Path;
        temp->LoadPathVector(curve->get_pathvector(), tr_mat, true);
		Shape*  n_shp=new Shape;
		temp->Convert(0.25);
		temp->Fill(n_shp,0);
		Shape*  uncross=new Shape;
		SPStyle* style=SP_OBJECT_STYLE(u_child);
		if ( style && style->fill_rule.computed == SP_WIND_RULE_EVENODD ) {
			uncross->ConvertToShape(n_shp,fill_oddEven);
		} else {
			uncross->ConvertToShape(n_shp,fill_nonZero);
		}
		UnionShape(computed, uncross);
		delete uncross;
		delete n_shp;
		delete temp;
		curve->unref();
	} else {
//		printf("no curve\n");
	}
}
Пример #6
0
static void
sp_text_edit_dialog_read_selection (GtkWidget *dlg, gboolean dostyle, gboolean docontent)
{
	GtkWidget *notebook, *textw, *fontsel, *preview, *apply, *def;
	GtkTextBuffer *tb;
	SPText *text;
	SPRepr *repr;
	SPStyle *style;
	unsigned items;

	if (g_object_get_data (G_OBJECT (dlg), "blocked")) return;
	g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (TRUE));

	notebook = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "notebook");
	textw = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "textw");
	tb = (GtkTextBuffer*)g_object_get_data (G_OBJECT (dlg), "text");
	fontsel = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "fontsel");
	preview = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "preview");
	apply = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "apply");
	def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default");

	text = sp_ted_get_selected_text_item ();

	if (text) {
		items = sp_ted_get_selected_text_count ();
		if (items == 1) {
			gtk_widget_set_sensitive (textw, TRUE);
		} else {
			gtk_widget_set_sensitive (textw, FALSE);
		}
		gtk_widget_set_sensitive (apply, FALSE);
		gtk_widget_set_sensitive (def, TRUE);
		style = SP_OBJECT_STYLE (text);
		if (docontent) {
			gchar *str;
			str = sp_text_get_string_multiline (text);
			if (str) {
				int pos;
				pos = 0;
				if (items == 1) {
					gtk_text_buffer_set_text (tb, str, strlen (str));
				}
				sp_font_preview_set_phrase (SP_FONT_PREVIEW (preview), str);
				g_free (str);
			} else {
				gtk_text_buffer_set_text (tb, "", 0);
				sp_font_preview_set_phrase (SP_FONT_PREVIEW (preview), NULL);
			}
		}
		repr = SP_OBJECT_REPR (text);
	} else {
		gtk_widget_set_sensitive (textw, FALSE);
		gtk_widget_set_sensitive (apply, FALSE);
		gtk_widget_set_sensitive (def, FALSE);
		repr = inkscape_get_repr (INKSCAPE, "tools.text");
		if (repr) {
			gtk_widget_set_sensitive (notebook, TRUE);
			style = sp_style_new ();
			sp_style_read_from_repr (style, repr);
		} else {
			gtk_widget_set_sensitive (notebook, FALSE);
			style = sp_style_new ();
		}
	}

	if (dostyle) {
		NRTypeFace *tf;
		NRFont *font;
		GtkWidget *b, *combo;
		gchar *c;
		const gchar *sstr;

		c = sp_text_edit_dialog_font_style_to_lookup (style);
		tf = nr_type_directory_lookup_fuzzy ((gchar*)style->text->font_family.value, c);
		font = nr_font_new_default (tf, NR_TYPEFACE_METRICS_HORIZONTAL, style->font_size.computed);
		nr_typeface_unref (tf);

		if (font) {
			sp_font_selector_set_font (SP_FONT_SELECTOR (fontsel), font);
			sp_font_preview_set_font (SP_FONT_PREVIEW (preview), font);
			nr_font_unref (font);
		}

		if (style->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) {
			b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_start");
		} else if (style->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) {
			b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_middle");
		} else {
			b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_end");
		}
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b), TRUE);
		if (style->writing_mode.computed == SP_CSS_WRITING_MODE_LR) {
			b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "writing_mode_lr");
		} else {
			b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "writing_mode_tb");
		}
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b), TRUE);
		combo = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "line_spacing");
		sstr = (repr) ? sp_repr_attr (repr, "sodipodi:linespacing") : NULL;
		gtk_entry_set_text ((GtkEntry *) ((GtkCombo *) (combo))->entry, (sstr) ? sstr : (const gchar *) "100%");
	}

	g_object_set_data (G_OBJECT (dlg), "blocked", NULL);
}
Пример #7
0
void
gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi)
{
    if (drag && drag->selected) {
        // GRADIENTFIXME: make this work for more than one selected dragger?
        GrDragger *dragger = (GrDragger*) drag->selected->data;
        for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
            GrDraggable *draggable = (GrDraggable *) i->data;
            SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
            SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);

            if (gradient != *gr_selected) {
                if (*gr_selected != NULL) {
                    *gr_multi = true;
                } else {
                    *gr_selected = gradient;
                }
            }
            if (spread != *spr_selected) {
                if (*spr_selected != INT_MAX) {
                    *spr_multi = true;
                } else {
                    *spr_selected = spread;
                }
            }
         }
        return;
    }

   // If no selected dragger, read desktop selection
   for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
        SPItem *item = SP_ITEM(i->data);
        SPStyle *style = SP_OBJECT_STYLE (item);

        if (style && (style->fill.isPaintserver())) {
            SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
            if (SP_IS_GRADIENT (server)) {
                SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
                SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
                if (gradient != *gr_selected) {
                    if (*gr_selected != NULL) {
                        *gr_multi = true;
                    } else {
                        *gr_selected = gradient;
                    }
                }
                if (spread != *spr_selected) {
                    if (*spr_selected != INT_MAX) {
                        *spr_multi = true;
                    } else {
                        *spr_selected = spread;
                    }
                }
            }
        }
        if (style && (style->stroke.isPaintserver())) {
            SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
            if (SP_IS_GRADIENT (server)) {
                SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
                SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
                if (gradient != *gr_selected) {
                    if (*gr_selected != NULL) {
                        *gr_multi = true;
                    } else {
                        *gr_selected = gradient;
                    }
                }
                if (spread != *spr_selected) {
                    if (*spr_selected != INT_MAX) {
                        *spr_multi = true;
                    } else {
                        *spr_selected = spread;
                    }
                }
            }
        }
    }
 }
Пример #8
0
Inkscape::XML::Node *
sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/)
{
    if (!item)
        return NULL;

    Inkscape::XML::Document *xml_doc = SP_OBJECT_REPR(item)->document();

    if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
        // Special treatment for text: convert each glyph to separate path, then group the paths
        Inkscape::XML::Node *g_repr = xml_doc->createElement("svg:g");
        g_repr->setAttribute("transform", SP_OBJECT_REPR(item)->attribute("transform"));
        /* Mask */
        gchar *mask_str = (gchar *) SP_OBJECT_REPR(item)->attribute("mask");
        if ( mask_str )
            g_repr->setAttribute("mask", mask_str);
        /* Clip path */
        gchar *clip_path_str = (gchar *) SP_OBJECT_REPR(item)->attribute("clip-path");
        if ( clip_path_str )
            g_repr->setAttribute("clip-path", clip_path_str);
        /* Rotation center */
        g_repr->setAttribute("inkscape:transform-center-x", SP_OBJECT_REPR(item)->attribute("inkscape:transform-center-x"), false);
        g_repr->setAttribute("inkscape:transform-center-y", SP_OBJECT_REPR(item)->attribute("inkscape:transform-center-y"), false);
        /* Whole text's style */
        gchar *style_str = sp_style_write_difference(SP_OBJECT_STYLE(item),
                                             SP_OBJECT_STYLE(SP_OBJECT_PARENT(item)));
        g_repr->setAttribute("style", style_str);
        g_free(style_str);
        Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); 
        do {
            Inkscape::Text::Layout::iterator iter_next = iter;
            iter_next.nextGlyph(); // iter_next is one glyph ahead from iter
            if (iter == iter_next)
                break;

            /* This glyph's style */
            SPObject const *pos_obj = 0;
            void *rawptr = 0;
            te_get_layout(item)->getSourceOfCharacter(iter, &rawptr);
            if (!rawptr || !SP_IS_OBJECT(rawptr)) // no source for glyph, abort
                break;
            pos_obj = SP_OBJECT(rawptr);
            while (SP_IS_STRING(pos_obj) && SP_OBJECT_PARENT(pos_obj)) {
               pos_obj = SP_OBJECT_PARENT(pos_obj);   // SPStrings don't have style
            }
            gchar *style_str = sp_style_write_difference(SP_OBJECT_STYLE(pos_obj),
                                                 SP_OBJECT_STYLE(SP_OBJECT_PARENT(pos_obj)));

            // get path from iter to iter_next:
            SPCurve *curve = te_get_layout(item)->convertToCurves(iter, iter_next);
            iter = iter_next; // shift to next glyph
            if (!curve) { // error converting this glyph
                g_free (style_str);
                continue;
            }
            if (curve->is_empty()) { // whitespace glyph?
                curve->unref();
                g_free (style_str);
                continue;
            }

            Inkscape::XML::Node *p_repr = xml_doc->createElement("svg:path");

            gchar *def_str = sp_svg_write_path(curve->get_pathvector());
            p_repr->setAttribute("d", def_str);
            g_free(def_str);
            curve->unref();

            p_repr->setAttribute("style", style_str);
            g_free(style_str);

            g_repr->appendChild(p_repr);
            Inkscape::GC::release(p_repr);

            if (iter == te_get_layout(item)->end())
                break;

        } while (true);

        return g_repr;
    }

    SPCurve *curve = NULL;
    if (SP_IS_SHAPE(item)) {
        curve = sp_shape_get_curve(SP_SHAPE(item));
    } 

    if (!curve)
        return NULL;

    // Prevent empty paths from being added to the document
    // otherwise we end up with zomby markup in the SVG file
    if(curve->is_empty())
    {
        curve->unref();
        return NULL;
    }

    Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
    /* Transformation */
    repr->setAttribute("transform", SP_OBJECT_REPR(item)->attribute("transform"));
    /* Style */
    gchar *style_str = sp_style_write_difference(SP_OBJECT_STYLE(item),
                                                 SP_OBJECT_STYLE(SP_OBJECT_PARENT(item)));
    repr->setAttribute("style", style_str);
    g_free(style_str);

    /* Mask */
    gchar *mask_str = (gchar *) SP_OBJECT_REPR(item)->attribute("mask");
    if ( mask_str )
        repr->setAttribute("mask", mask_str);

    /* Clip path */
    gchar *clip_path_str = (gchar *) SP_OBJECT_REPR(item)->attribute("clip-path");
    if ( clip_path_str )
        repr->setAttribute("clip-path", clip_path_str);

    /* Rotation center */
    repr->setAttribute("inkscape:transform-center-x", SP_OBJECT_REPR(item)->attribute("inkscape:transform-center-x"), false);
    repr->setAttribute("inkscape:transform-center-y", SP_OBJECT_REPR(item)->attribute("inkscape:transform-center-y"), false);

    /* Definition */
    gchar *def_str = sp_svg_write_path(curve->get_pathvector());
    repr->setAttribute("d", def_str);
    g_free(def_str);
    curve->unref();
    return repr;
}
Пример #9
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));
}