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; }
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? */ } }
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"); } }
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; }