Пример #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
/**
 * return true if this gradient is "aligned" to that gradient.
 * Aligned means that they have exactly the same coordinates and transform.
 * @param that - A gradient to compare this to
 */
bool SPGradient::isAligned(SPGradient *that)
{
    bool status = false;
    
   /*  Some gradients have coordinates/other values specified, some don't.  
           yes/yes check the coordinates/other values
           no/no   aligned (because both have all default values)
           yes/no  not aligned
           no/yes  not aligned
       It is NOT safe to just compare the computed values because if that field has
       not been set the computed value could be full of garbage.
       
       In theory the yes/no and no/yes cases could be aligned if the specified value
       matches the default value.
    */

    while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function
        if(this->gradientTransform_set != that->gradientTransform_set) { break; }
        if(this->gradientTransform_set && 
            (this->gradientTransform != that->gradientTransform)) { break; }
        if (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) {
            SPLinearGradient *sg=SP_LINEARGRADIENT(this);
            SPLinearGradient *tg=SP_LINEARGRADIENT(that);
 
            if( sg->x1._set != tg->x1._set) { break; }
            if( sg->y1._set != tg->y1._set) { break; }
            if( sg->x2._set != tg->x2._set) { break; }
            if( sg->y2._set != tg->y2._set) { break; }
            if( sg->x1._set && sg->y1._set && sg->x2._set && sg->y2._set) {
                if( (sg->x1.computed != tg->x1.computed) ||
                    (sg->y1.computed != tg->y1.computed) ||
                    (sg->x2.computed != tg->x2.computed) ||
                    (sg->y2.computed != tg->y2.computed) )  { break; }
            } else if( sg->x1._set || sg->y1._set || sg->x2._set || sg->y2._set) { break; } // some mix of set and not set
            // none set? assume aligned and fall through
        } else if (SP_IS_RADIALGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) {
            SPRadialGradient *sg=SP_RADIALGRADIENT(this);
            SPRadialGradient *tg=SP_RADIALGRADIENT(that);

            if( sg->cx._set != tg->cx._set) { break; }
            if( sg->cy._set != tg->cy._set) { break; }
            if( sg->r._set  != tg->r._set)  { break; }
            if( sg->fx._set != tg->fx._set) { break; }
            if( sg->fy._set != tg->fy._set) { break; }
            if( sg->cx._set && sg->cy._set && sg->fx._set && sg->fy._set && sg->r._set) {
                if( (sg->cx.computed != tg->cx.computed) ||
                    (sg->cy.computed != tg->cy.computed) ||
                    (sg->r.computed  != tg->r.computed ) ||
                    (sg->fx.computed != tg->fx.computed) ||
                    (sg->fy.computed != tg->fy.computed)  ) { break; }
            } else if(  sg->cx._set || sg->cy._set || sg->fx._set || sg->fy._set || sg->r._set ) { break; } // some mix of set and not set
            // none set? assume aligned and fall through
        } else if (SP_IS_MESH(this) && SP_IS_MESH(that)) {
            SPMesh *sg=SP_MESH(this);
            SPMesh *tg=SP_MESH(that);
 
            if( sg->x._set  !=  !tg->x._set) { break; }
            if( sg->y._set  !=  !tg->y._set) { break; }
            if( sg->x._set  &&  sg->y._set) { 
                if( (sg->x.computed != tg->x.computed) ||
                    (sg->y.computed != tg->y.computed) ) { break; }
            } else if( sg->x._set || sg->y._set) { break; } // some mix of set and not set
            // none set? assume aligned and fall through
         } else {
            break;
        }
        status = true;
        break;
    }
    return status;
}
Пример #3
0
static void
sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw)
{
	const GSList *items, *i, *r;
	GSList *reprs;
	SPCSSAttr *css;
	gfloat rgba[4], cmyka[5];
	SPGradient *vector;
	gchar b[64];

	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 changed\n");
#endif
	if (spw->inkscape) {
		/* fixme: */
		if (!SP_WIDGET_DOCUMENT (spw)) {
			g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
			return;
		}
		reprs = NULL;
		items = sp_widget_get_item_list (spw);
		for (i = items; i != NULL; i = i->next) {
			reprs = g_slist_prepend (reprs, SP_OBJECT_REPR (i->data));
		}
	} else {
		reprs = g_slist_prepend (NULL, spw->repr);
		items = NULL;
	}

	switch (psel->mode) {
	case SP_PAINT_SELECTOR_MODE_EMPTY:
	case SP_PAINT_SELECTOR_MODE_MULTIPLE:
		g_warning ("file %s: line %d: Paint %d should not emit 'changed'", __FILE__, __LINE__, psel->mode);
		break;
	case SP_PAINT_SELECTOR_MODE_NONE:
		css = sp_repr_css_attr_new ();
		sp_repr_css_set_property (css, "fill", "none");
		for (r = reprs; r != NULL; r = r->next) {
			sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style");
			sp_repr_set_attr_recursive ((SPRepr *) r->data, "sodipodi:fill-cmyk", NULL);
		}
		sp_repr_css_attr_unref (css);
		if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw));
		break;
	case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
		css = sp_repr_css_attr_new ();
		sp_paint_selector_get_rgba_floatv (psel, rgba);
		sp_svg_write_color (b, 64, SP_RGBA32_F_COMPOSE (rgba[0], rgba[1], rgba[2], 0.0));
		sp_repr_css_set_property (css, "fill", b);
		g_snprintf (b, 64, "%g", rgba[3]);
		sp_repr_css_set_property (css, "fill-opacity", b);
		for (r = reprs; r != NULL; r = r->next) {
			sp_repr_set_attr_recursive ((SPRepr *) r->data, "sodipodi:fill-cmyk", NULL);
			sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style");
		}
		sp_repr_css_attr_unref (css);
		if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw));
		break;
	case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
		css = sp_repr_css_attr_new ();
		sp_paint_selector_get_cmyka_floatv (psel, cmyka);
		sp_color_cmyk_to_rgb_floatv (rgba, cmyka[0], cmyka[1], cmyka[2], cmyka[3]);
		sp_svg_write_color (b, 64, SP_RGBA32_F_COMPOSE (rgba[0], rgba[1], rgba[2], 0.0));
		sp_repr_css_set_property (css, "fill", b);
		g_snprintf (b, 64, "%g", cmyka[4]);
		sp_repr_css_set_property (css, "fill-opacity", b);
		g_snprintf (b, 64, "(%g %g %g %g)", cmyka[0], cmyka[1], cmyka[2], cmyka[3]);
		for (r = reprs; r != NULL; r = r->next) {
			sp_repr_set_attr_recursive ((SPRepr *) r->data, "sodipodi:fill-cmyk", b);
			sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style");
		}
		sp_repr_css_attr_unref (css);
		if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw));
		break;
	case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
		if (items) {
			vector = sp_paint_selector_get_gradient_vector (psel);
			if (!vector) {
				/* No vector in paint selector should mean that we just changed mode */
				vector = sp_document_default_gradient_vector (SP_WIDGET_DOCUMENT (spw));
				for (i = items; i != NULL; i = i->next) {
					sp_item_force_fill_lineargradient_vector (SP_ITEM (i->data), vector);
				}
			} else {
				vector = sp_gradient_ensure_vector_normalized (vector);
				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));
					sp_object_invoke_write (SP_OBJECT (lg), SP_OBJECT_REPR (lg), SP_OBJECT_WRITE_EXT);
				}
			}
			sp_document_done (SP_WIDGET_DOCUMENT (spw));
		}
		break;
	case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
		if (items) {
			vector = sp_paint_selector_get_gradient_vector (psel);
			if (!vector) {
				/* No vector in paint selector should mean that we just changed mode */
				vector = sp_document_default_gradient_vector (SP_WIDGET_DOCUMENT (spw));
				for (i = items; i != NULL; i = i->next) {
					sp_item_force_fill_radialgradient_vector (SP_ITEM (i->data), vector);
				}
			} else {
				vector = sp_gradient_ensure_vector_normalized (vector);
				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));
					sp_object_invoke_write (SP_OBJECT (rg), SP_OBJECT_REPR (rg), SP_OBJECT_WRITE_EXT);
				}
			}
			sp_document_done (SP_WIDGET_DOCUMENT (spw));
		}
		break;
	default:
		g_warning ("file %s: line %d: Paint selector should not be in mode %d", __FILE__, __LINE__, psel->mode);
		break;
	}

	g_slist_free (reprs);

	g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
}
Пример #4
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));
}