=== modified file 'src/splivarot.cpp'
--- src/splivarot.cpp 2016-02-13 01:41:52 +0000
+++ src/splivarot.cpp 2016-03-13 12:45:08 +0000
@@ -849,7 +849,8 @@
static
void sp_selected_path_outline_add_marker( SPObject *marker_object, Geom::Affine marker_transform,
Geom::Scale stroke_scale, Geom::Affine transform,
- Inkscape::XML::Node *g_repr, Inkscape::XML::Document *xml_doc, SPDocument * doc )
+ Inkscape::XML::Node *g_repr, Inkscape::XML::Document *xml_doc, SPDocument * doc,
+ SPDesktop *desktop)
{
SPMarker* marker = SP_MARKER (marker_object);
SPItem* marker_item = sp_item_first_item_child(marker_object);
@@ -869,8 +870,11 @@
if (marker_item->getRepr()) {
Inkscape::XML::Node *m_repr = marker_item->getRepr()->duplicate(xml_doc);
g_repr->appendChild(m_repr);
+ //There is a special group to markers whith this reverse the order in clussion
+ m_repr->setPosition(0);
SPItem *marker_item = (SPItem *) doc->getObjectByRepr(m_repr);
marker_item->doWriteTransform(m_repr, tr);
+ sp_item_path_outline(marker_item, desktop);
}
}
@@ -1144,74 +1148,86 @@
return ret_pathv;
}
-void
-sp_selected_path_outline(SPDesktop *desktop)
+bool
+sp_item_path_outline(SPItem *item, SPDesktop *desktop)
{
+ bool did = false;
Inkscape::Selection *selection = desktop->getSelection();
-
- if (selection->isEmpty()) {
- desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select stroked path(s) to convert stroke to path."));
- return;
- }
-
- bool did = false;
- std::vector il(selection->itemList());
- for (std::vector::const_iterator l = il.begin(); l != il.end(); l++){
- SPItem *item = *l;
-
- if (!SP_IS_SHAPE(item) && !SP_IS_TEXT(item))
- continue;
-
- SPCurve *curve = NULL;
- if (SP_IS_SHAPE(item)) {
- curve = SP_SHAPE(item)->getCurve();
- if (curve == NULL)
- continue;
- }
- if (SP_IS_TEXT(item)) {
- curve = SP_TEXT(item)->getNormalizedBpath();
- if (curve == NULL)
- continue;
- }
-
- g_assert(curve != NULL);
-
- if (curve->get_pathvector().empty()) {
- continue;
- }
-
- // pas de stroke pas de chocolat
- if (!item->style || item->style->stroke.noneSet) {
- curve->unref();
- continue;
- }
-
- // remember old stroke style, to be set on fill
- SPStyle *i_style = item->style;
- SPCSSAttr *ncss = 0;
- {
- ncss = sp_css_attr_from_style(i_style, SP_STYLE_FLAG_ALWAYS);
- gchar const *s_val = sp_repr_css_property(ncss, "stroke", NULL);
- gchar const *s_opac = sp_repr_css_property(ncss, "stroke-opacity", NULL);
-
- sp_repr_css_set_property(ncss, "stroke", "none");
- sp_repr_css_set_property(ncss, "stroke-opacity", "1.0");
- sp_repr_css_set_property(ncss, "fill", s_val);
- if ( s_opac ) {
- sp_repr_css_set_property(ncss, "fill-opacity", s_opac);
- } else {
- sp_repr_css_set_property(ncss, "fill-opacity", "1.0");
- }
- sp_repr_css_unset_property(ncss, "marker-start");
- sp_repr_css_unset_property(ncss, "marker-mid");
- sp_repr_css_unset_property(ncss, "marker-end");
- }
-
- Geom::Affine const transform(item->transform);
- float const scale = transform.descrim();
- gchar const *mask = item->getRepr()->attribute("mask");
- gchar const *clip_path = item->getRepr()->attribute("clip-path");
-
+ if (!SP_IS_SHAPE(item) && !SP_IS_TEXT(item))
+ return did;
+
+ SPCurve *curve = NULL;
+ if (SP_IS_SHAPE(item)) {
+ curve = SP_SHAPE(item)->getCurve();
+ if (curve == NULL)
+ return did;
+ }
+ if (SP_IS_TEXT(item)) {
+ curve = SP_TEXT(item)->getNormalizedBpath();
+ if (curve == NULL)
+ return did;
+ }
+
+ g_assert(curve != NULL);
+
+ if (curve->get_pathvector().empty()) {
+ return did;
+ }
+
+ // pas de stroke pas de chocolat
+ if (!item->style) {
+ curve->unref();
+ return did;
+ }
+
+ // remember old stroke style, to be set on fill
+ SPStyle *i_style = item->style;
+ //Stroke - and markers
+ SPCSSAttr *ncss = 0;
+ {
+ ncss = sp_css_attr_from_style(i_style, SP_STYLE_FLAG_ALWAYS);
+ gchar const *s_val = sp_repr_css_property(ncss, "stroke", NULL);
+ gchar const *s_opac = sp_repr_css_property(ncss, "stroke-opacity", NULL);
+
+ sp_repr_css_set_property(ncss, "stroke", "none");
+ sp_repr_css_set_property(ncss, "stroke-opacity", "1.0");
+ sp_repr_css_set_property(ncss, "fill", s_val);
+ if ( s_opac ) {
+ sp_repr_css_set_property(ncss, "fill-opacity", s_opac);
+ } else {
+ sp_repr_css_set_property(ncss, "fill-opacity", "1.0");
+ }
+ sp_repr_css_unset_property(ncss, "marker-start");
+ sp_repr_css_unset_property(ncss, "marker-mid");
+ sp_repr_css_unset_property(ncss, "marker-end");
+ }
+ //fill
+ SPCSSAttr *ncsf = 0;
+ {
+ ncsf = sp_css_attr_from_style(i_style, SP_STYLE_FLAG_ALWAYS);
+ sp_repr_css_set_property(ncsf, "stroke", "none");
+ sp_repr_css_set_property(ncsf, "stroke-opacity", "1.0");
+ sp_repr_css_unset_property(ncsf, "marker-start");
+ sp_repr_css_unset_property(ncsf, "marker-mid");
+ sp_repr_css_unset_property(ncsf, "marker-end");
+ }
+
+ Geom::Affine const transform(item->transform);
+ float const scale = transform.descrim();
+ gchar const *mask = item->getRepr()->attribute("mask");
+ gchar const *clip_path = item->getRepr()->attribute("clip-path");
+
+ Path *orig = new Path;
+ Path *res = new Path;
+ SPCurve *curvetemp = curve_for_item(item);
+ if (curvetemp == NULL) {
+ curve->unref();
+ return did;
+ }
+ // Livarot's outline of arcs is broken. So convert the path to linear and cubics only, for which the outline is created correctly.
+ Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curvetemp->get_pathvector() );
+ curvetemp->unref();
+ if ( !item->style->stroke.noneSet ) {
float o_width, o_miter;
JoinType o_join;
ButtType o_butt;
@@ -1252,19 +1268,8 @@
o_miter = i_style->stroke_miterlimit.value * o_width;
}
- SPCurve *curvetemp = curve_for_item(item);
- if (curvetemp == NULL) {
- curve->unref();
- continue;
- }
- // Livarot's outline of arcs is broken. So convert the path to linear and cubics only, for which the outline is created correctly.
- Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers( curvetemp->get_pathvector() );
- curvetemp->unref();
- Path *orig = new Path;
orig->LoadPathVector(pathv);
-
- Path *res = new Path;
res->SetBackData(false);
if (!i_style->stroke_dasharray.values.empty()) {
@@ -1318,75 +1323,99 @@
// ca a merdĀ, ou bien le resultat est vide
delete res;
delete orig;
- continue;
+ return did;
}
-
- did = true;
-
- // remember the position of the item
- gint pos = item->getRepr()->position();
- // remember parent
- Inkscape::XML::Node *parent = item->getRepr()->parent();
- // remember id
- char const *id = item->getRepr()->attribute("id");
- // remember title
- gchar *title = item->title();
- // remember description
- gchar *desc = item->desc();
-
- if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether
-
+ }
+ // remember the position of the item
+ gint pos = item->getRepr()->position();
+ // remember parent
+ Inkscape::XML::Node *parent = item->getRepr()->parent();
+ // remember id
+ char const *id = item->getRepr()->attribute("id");
+ // remember title
+ gchar *title = item->title();
+ // remember description
+ gchar *desc = item->desc();
+
+ if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether
+
+ //The stroke
+ Inkscape::XML::Node *stroke = NULL;
+ if( !item->style->stroke.noneSet ){
SPDocument * doc = desktop->getDocument();
Inkscape::XML::Document *xml_doc = doc->getReprDoc();
- Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
+ stroke = xml_doc->createElement("svg:path");
// restore old style, but set old stroke style on fill
- sp_repr_css_change(repr, ncss, "style");
+ sp_repr_css_change(stroke, ncss, "style");
sp_repr_css_attr_unref(ncss);
gchar *str = orig->svg_dump_path();
- repr->setAttribute("d", str);
+ stroke->setAttribute("d", str);
g_free(str);
if (mask)
- repr->setAttribute("mask", mask);
+ stroke->setAttribute("mask", mask);
if (clip_path)
- repr->setAttribute("clip-path", clip_path);
-
- if (SP_IS_SHAPE(item) && SP_SHAPE(item)->hasMarkers ()) {
-
- Inkscape::XML::Document *xml_doc = doc->getReprDoc();
- Inkscape::XML::Node *g_repr = xml_doc->createElement("svg:g");
-
- // add the group to the parent
- parent->appendChild(g_repr);
- // move to the saved position
- g_repr->setPosition(pos > 0 ? pos : 0);
-
- g_repr->appendChild(repr);
- // restore title, description, id, transform
- repr->setAttribute("id", id);
- SPItem *newitem = (SPItem *) doc->getObjectByRepr(repr);
- newitem->doWriteTransform(repr, transform);
- if (title) {
- newitem->setTitle(title);
- }
- if (desc) {
- newitem->setDesc(desc);
- }
-
- SPShape *shape = SP_SHAPE(item);
-
- Geom::PathVector const & pathv = curve->get_pathvector();
-
+ stroke->setAttribute("clip-path", clip_path);
+ }
+
+ if (SP_IS_SHAPE(item)) {
+ SPDocument * doc = desktop->getDocument();
+ Inkscape::XML::Document *xml_doc = doc->getReprDoc();
+ Inkscape::XML::Node *g_repr = xml_doc->createElement("svg:g");
+
+ // add the group to the parent
+ parent->appendChild(g_repr);
+ // move to the saved position
+ g_repr->setPosition(pos > 0 ? pos : 0);
+
+ //The fill
+
+ Inkscape::XML::Node *fill = NULL;
+ gchar const *f_val = sp_repr_css_property(ncsf, "fill", NULL);
+ if (f_val) {
+ fill = xml_doc->createElement("svg:path");
+ sp_repr_css_change(fill, ncsf, "style");
+
+ sp_repr_css_attr_unref(ncsf);
+
+ gchar *str = sp_svg_write_path( pathv );
+ fill->setAttribute("d", str);
+ g_free(str);
+
+ if (mask)
+ fill->setAttribute("mask", mask);
+ if (clip_path)
+ fill->setAttribute("clip-path", clip_path);
+ }
+ // restore title, description, id, transform
+ g_repr->setAttribute("id", id);
+ SPItem *newitem = (SPItem *) doc->getObjectByRepr(g_repr);
+ newitem->doWriteTransform(g_repr, transform);
+ if (title) {
+ newitem->setTitle(title);
+ }
+ if (desc) {
+ newitem->setDesc(desc);
+ }
+
+ SPShape *shape = SP_SHAPE(item);
+
+ Geom::PathVector const & pathv = curve->get_pathvector();
+ Inkscape::XML::Node *markers = NULL;
+ if(SP_SHAPE(item)->hasMarkers ()) {
+ markers = xml_doc->createElement("svg:g");
+ g_repr->appendChild(markers);
+ markers->setPosition(pos > 0 ? pos : 0);
// START marker
for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START
if ( SPObject *marker_obj = shape->_marker[i] ) {
Geom::Affine const m (sp_shape_marker_get_transform_at_start(pathv.front().front()));
sp_selected_path_outline_add_marker( marker_obj, m,
Geom::Scale(i_style->stroke_width.computed), transform,
- g_repr, xml_doc, doc );
+ markers, xml_doc, doc, desktop );
}
}
// MID marker
@@ -1401,7 +1430,7 @@
Geom::Affine const m (sp_shape_marker_get_transform_at_start(path_it->front()));
sp_selected_path_outline_add_marker( midmarker_obj, m,
Geom::Scale(i_style->stroke_width.computed), transform,
- g_repr, xml_doc, doc );
+ markers, xml_doc, doc, desktop );
}
// MID position
if (path_it->size_default() > 1) {
@@ -1414,9 +1443,9 @@
* there should be a midpoint marker between last segment and closing straight line segment
*/
Geom::Affine const m (sp_shape_marker_get_transform(*curve_it1, *curve_it2));
- sp_selected_path_outline_add_marker(midmarker_obj, m,
- Geom::Scale(i_style->stroke_width.computed), transform,
- g_repr, xml_doc, doc);
+ sp_selected_path_outline_add_marker( midmarker_obj, m,
+ Geom::Scale(i_style->stroke_width.computed), transform,
+ markers, xml_doc, doc, desktop );
++curve_it1;
++curve_it2;
@@ -1428,7 +1457,7 @@
Geom::Affine const m = sp_shape_marker_get_transform_at_end(lastcurve);
sp_selected_path_outline_add_marker( midmarker_obj, m,
Geom::Scale(i_style->stroke_width.computed), transform,
- g_repr, xml_doc, doc );
+ markers, xml_doc, doc, desktop );
}
}
}
@@ -1447,61 +1476,157 @@
Geom::Affine const m = sp_shape_marker_get_transform_at_end(lastcurve);
sp_selected_path_outline_add_marker( marker_obj, m,
Geom::Scale(i_style->stroke_width.computed), transform,
- g_repr, xml_doc, doc );
- }
- }
- //bug lp:1290573 : completely destroy the old object first
- curve->unref();
+ markers, xml_doc, doc, desktop );
+ }
+ }
+ if (mask)
+ markers->setAttribute("mask", mask);
+ if (clip_path)
+ markers->setAttribute("clip-path", clip_path);
+ }
+ gchar const *paint_order = sp_repr_css_property(ncss, "paint-order", NULL);
+ SPIPaintOrder temp;
+ temp.read( paint_order );
+ if (temp.layer[0] != SP_CSS_PAINT_ORDER_NORMAL) {
+
+ if (temp.layer[0] == SP_CSS_PAINT_ORDER_FILL) {
+ if (temp.layer[1] == SP_CSS_PAINT_ORDER_STROKE) {
+ if ( fill ) {
+ g_repr->appendChild(fill);
+ }
+ if ( stroke ) {
+ g_repr->appendChild(stroke);
+ }
+ if ( markers ) {
+ markers->setPosition(2);
+ }
+ } else {
+ if ( fill ) {
+ g_repr->appendChild(fill);
+ }
+ if ( markers ) {
+ markers->setPosition(1);
+ }
+ if ( stroke ) {
+ g_repr->appendChild(stroke);
+ }
+ }
+ } else if (temp.layer[0] == SP_CSS_PAINT_ORDER_STROKE) {
+ if (temp.layer[1] == SP_CSS_PAINT_ORDER_FILL) {
+ if ( stroke ) {
+ g_repr->appendChild(stroke);
+ }
+ if ( fill ) {
+ g_repr->appendChild(fill);
+ }
+ if ( markers ) {
+ markers->setPosition(2);
+ }
+ } else {
+ if ( stroke ) {
+ g_repr->appendChild(stroke);
+ }
+ if ( markers ) {
+ markers->setPosition(1);
+ }
+ if ( fill ) {
+ g_repr->appendChild(fill);
+ }
+ }
+ } else {
+ if (temp.layer[1] == SP_CSS_PAINT_ORDER_STROKE) {
+ if ( markers ) {
+ markers->setPosition(0);
+ }
+ if ( stroke ) {
+ g_repr->appendChild(stroke);
+ }
+ if ( fill ) {
+ g_repr->appendChild(fill);
+ }
+ } else {
+ if ( markers ) {
+ markers->setPosition(0);
+ }
+ if ( fill ) {
+ g_repr->appendChild(fill);
+ }
+ if ( stroke ) {
+ g_repr->appendChild(stroke);
+ }
+ }
+ }
+
+ } else {
+ if ( fill ) {
+ g_repr->appendChild(fill);
+ }
+ if ( stroke ) {
+ g_repr->appendChild(stroke);
+ }
+ if ( markers ) {
+ markers->setPosition(2);
+ }
+ }
+ if( fill || stroke || markers ) {
+ did = true;
+ }
+ if (!fill && !markers) {
+ g_repr = stroke;
+ }
+ if (!fill && !stroke) {
+ g_repr = markers;
+ }
+ if (!markers && !stroke) {
+ g_repr = fill;
+ }
+
+ //bug lp:1290573 : completely destroy the old object first
+ curve->unref();
+ //Check for recursive markers to path
+ if( selection->includes(item) ){
selection->remove(item);
item->deleteObject(false);
-
selection->add(g_repr);
-
- Inkscape::GC::release(g_repr);
-
- } else
- {
- //lp:1290573
- curve->unref();
- selection->remove(item);
+ } else {
item->deleteObject(false);
-
- // add the new repr to the parent
- parent->appendChild(repr);
-
- // move to the saved position
- repr->setPosition(pos > 0 ? pos : 0);
-
- // restore title, description, id, transform
- repr->setAttribute("id", id);
-
- SPItem *newitem = (SPItem *) desktop->getDocument()->getObjectByRepr(repr);
- newitem->doWriteTransform(repr, transform);
- if (title) {
- newitem->setTitle(title);
- }
- if (desc) {
- newitem->setDesc(desc);
- }
-
- selection->add(repr);
-
}
-
- Inkscape::GC::release(repr);
-
- }
- if (title) {
- g_free(title);
- title = 0;
- }
- if (desc) {
- g_free(desc);
- desc = 0;
- }
-
- delete res;
- delete orig;
+ Inkscape::GC::release(g_repr);
+
+ }
+ }
+
+ if (title) {
+ g_free(title);
+ title = 0;
+ }
+ if (desc) {
+ g_free(desc);
+ desc = 0;
+ }
+
+ delete res;
+ delete orig;
+
+
+ return did;
+}
+
+void
+sp_selected_path_outline(SPDesktop *desktop)
+{
+ Inkscape::Selection *selection = desktop->getSelection();
+
+ if (selection->isEmpty()) {
+ desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select stroked path(s) to convert stroke to path."));
+ return;
+ }
+
+ bool did = false;
+ std::vector il(selection->itemList());
+ for (std::vector::const_iterator l = il.begin(); l != il.end(); l++){
+ SPItem *item = *l;
+ did = sp_item_path_outline(item, desktop);
}
if (did) {
=== modified file 'src/splivarot.h'
--- src/splivarot.h 2016-02-13 01:41:52 +0000
+++ src/splivarot.h 2016-03-13 09:55:55 +0000
@@ -53,6 +53,7 @@
// outline of a curve
// uses the stroke-width
+bool sp_item_path_outline (SPItem *item, SPDesktop *desktop);
void sp_selected_path_outline (SPDesktop *desktop);
Geom::PathVector* item_outline(SPItem const *item, bool bbox_only = false);