示例#1
0
static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_pv, SPItem* item,
        const Geom::Matrix& item_transform, double& intersect_pos) {

    double initial_pos = intersect_pos;
    // if this is a group...
    if (SP_IS_GROUP(item)) {
        SPGroup* group = SP_GROUP(item);

        // consider all first-order children
        double child_pos = 0.0;
        for (GSList const* i = sp_item_group_item_list(group); i != NULL; i = i->next) {
            SPItem* child_item = SP_ITEM(i->data);
            try_get_intersect_point_with_item_recursive(conn_pv, child_item,
                    item_transform * child_item->transform, child_pos);
            if (intersect_pos < child_pos)
                intersect_pos = child_pos;
        }
        return intersect_pos != initial_pos;
    }

    // if this is not a shape, nothing to be done
    if (!SP_IS_SHAPE(item)) return false;

    // make sure it has an associated curve
    SPCurve* item_curve = sp_shape_get_curve(SP_SHAPE(item));
    if (!item_curve) return false;

    // apply transformations (up to common ancestor)
    item_curve->transform(item_transform);

    const Geom::PathVector& curve_pv = item_curve->get_pathvector();
    Geom::CrossingSet cross = crossings(conn_pv, curve_pv);
    // iterate over all Crossings
    for (Geom::CrossingSet::const_iterator i = cross.begin(); i != cross.end(); i++) {
        const Geom::Crossings& cr = *i;

        for (Geom::Crossings::const_iterator i = cr.begin(); i != cr.end(); i++) {
            const Geom::Crossing& cr_pt = *i;
            if ( intersect_pos < cr_pt.ta)
                intersect_pos = cr_pt.ta;
        }
    }

    item_curve->unref();

    return intersect_pos != initial_pos;
}
示例#2
0
static void
spdc_attach_selection (SPDrawContext *dc, SPSelection *sel)
{
	SPItem *item;

	/* We reset white and forget white/start/end anchors */
	spdc_reset_white (dc);
	dc->sa = NULL;
	dc->ea = NULL;

	item = sp_selection_item (dc->selection);

	if (item && SP_IS_PATH (item)) {
		SPCurve *norm;
		NRMatrixD i2dt;
		GSList *l;
		/* Create new white data */
		/* Item */
		dc->white_item = item;
		/* Curve list */
		/* We keep it in desktop coordinates to eliminate calculation errors */
		norm = sp_shape_get_curve (SP_SHAPE (item));
		sp_item_i2d_affine_d (dc->white_item, &i2dt);
		norm = sp_curve_transform (norm, NR_MATRIX_D_TO_DOUBLE (&i2dt));
		g_return_if_fail (norm != NULL);
		dc->white_curves = sp_curve_split (norm);
		sp_curve_unref (norm);
		/* Anchor list */
		for (l = dc->white_curves; l != NULL; l = l->next) {
			SPCurve *c;
			c = (SPCurve*)l->data;
			g_return_if_fail (c->end > 1);
			if (c->bpath->code == ART_MOVETO_OPEN) {
				ArtBpath *s, *e;
				SPDrawAnchor *a;
				s = sp_curve_first_bpath (c);
				e = sp_curve_last_bpath (c);
				a = sp_draw_anchor_new (dc, c, TRUE, s->x3, s->y3);
				dc->white_anchors = g_slist_prepend (dc->white_anchors, a);
				a = sp_draw_anchor_new (dc, c, FALSE, e->x3, e->y3);
				dc->white_anchors = g_slist_prepend (dc->white_anchors, a);
			}
		}
		/* fixme: recalculate active anchor? */
	}
}
示例#3
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");
	}
}
示例#4
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;
}