summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2011-04-01 22:59:01 +0000
committerJohan Engelen <goejendaagh@zonnet.nl>2011-04-01 22:59:01 +0000
commitd6978fcea4a2ccd2d9cccefabc6558a74f332a6d (patch)
tree98ea2cff482d6b2196e4bffa4fab3a7a4d5aead0 /src
parentGerman translation update. (diff)
downloadinkscape-d6978fcea4a2ccd2d9cccefabc6558a74f332a6d.tar.gz
inkscape-d6978fcea4a2ccd2d9cccefabc6558a74f332a6d.zip
add curve before LPE to SPShape. this is useful for helperpath display. It was inspired from fixing bug 407008
Fixed bugs: - https://launchpad.net/bugs/407008 (bzr r10142)
Diffstat (limited to 'src')
-rw-r--r--src/sp-ellipse.cpp4
-rw-r--r--src/sp-line.cpp3
-rw-r--r--src/sp-offset.cpp2
-rw-r--r--src/sp-path.cpp1
-rw-r--r--src/sp-rect.cpp5
-rw-r--r--src/sp-shape.cpp36
-rw-r--r--src/sp-shape.h5
-rw-r--r--src/sp-spiral.cpp2
-rw-r--r--src/sp-star.cpp2
-rw-r--r--src/splivarot.cpp75
-rw-r--r--src/splivarot.h2
11 files changed, 115 insertions, 22 deletions
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index 4ebbe6287..cb8c1699b 100644
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
@@ -256,9 +256,11 @@ static void sp_genericellipse_set_shape(SPShape *shape)
Geom::Affine aff = Geom::Scale(rx, ry) * Geom::Translate(ellipse->cx.computed, ellipse->cy.computed);
curve->transform(aff);
- /* Reset the shape'scurve to the "original_curve"
+ /* Reset the shape's curve to the "original_curve"
* This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
shape->setCurveInsync( curve, TRUE);
+ shape->setCurveBeforeLPE(curve);
+
if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) {
SPCurve *c_lpe = curve->copy();
bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe);
diff --git a/src/sp-line.cpp b/src/sp-line.cpp
index 100eefe87..72fe2cfa2 100644
--- a/src/sp-line.cpp
+++ b/src/sp-line.cpp
@@ -221,6 +221,9 @@ void SPLine::setShape(SPShape *shape)
c->lineto(line->x2.computed, line->y2.computed);
shape->setCurveInsync(c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update
+ shape->setCurveBeforeLPE(c);
+
+ // LPE's cannot be applied to lines. (the result can (generally) not be represented as SPLine)
c->unref();
}
diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp
index 57c04f31f..3fb9441a3 100644
--- a/src/sp-offset.cpp
+++ b/src/sp-offset.cpp
@@ -463,6 +463,7 @@ sp_offset_set_shape(SPShape *shape)
SPCurve *c = new SPCurve(pv);
g_assert(c != NULL);
((SPShape *) offset)->setCurveInsync (c, TRUE);
+ ((SPShape *) offset)->setCurveBeforeLPE(c);
c->unref();
}
return;
@@ -712,6 +713,7 @@ sp_offset_set_shape(SPShape *shape)
SPCurve *c = new SPCurve(pv);
g_assert(c != NULL);
((SPShape *) offset)->setCurveInsync (c, TRUE);
+ ((SPShape *) offset)->setCurveBeforeLPE(c);
c->unref();
free (res_d);
diff --git a/src/sp-path.cpp b/src/sp-path.cpp
index 16e2fcc1b..9a27af2f0 100644
--- a/src/sp-path.cpp
+++ b/src/sp-path.cpp
@@ -425,6 +425,7 @@ g_message("sp_path_update_patheffect");
/* if a path does not have an lpeitem applied, then reset the curve to the original_curve.
* This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
shape->setCurveInsync(curve, TRUE);
+ shape->setCurveBeforeLPE(path->original_curve);
bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve);
if (success && write) {
diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp
index fd44f64df..e8f79e6ed 100644
--- a/src/sp-rect.cpp
+++ b/src/sp-rect.cpp
@@ -232,6 +232,7 @@ sp_rect_set_shape(SPShape *shape)
if ((rect->height.computed < 1e-18) || (rect->width.computed < 1e-18)) {
SP_SHAPE(rect)->setCurveInsync( NULL, TRUE);
+ SP_SHAPE(rect)->setCurveBeforeLPE( NULL );
return;
}
@@ -282,6 +283,10 @@ sp_rect_set_shape(SPShape *shape)
c->closepath();
SP_SHAPE(rect)->setCurveInsync( c, TRUE);
+ SP_SHAPE(rect)->setCurveBeforeLPE( c );
+
+ // LPE is not applied because result can generally not be represented as SPRect
+
c->unref();
}
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index e9b0909ed..72559c63f 100644
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
@@ -126,6 +126,7 @@ void SPShape::sp_shape_init(SPShape *shape)
shape->marker[i] = NULL;
}
shape->curve = NULL;
+ shape->curve_before_lpe = NULL;
}
void SPShape::sp_shape_finalize(GObject *object)
@@ -195,6 +196,9 @@ void SPShape::sp_shape_release(SPObject *object)
if (shape->curve) {
shape->curve = shape->curve->unref();
}
+ if (shape->curve_before_lpe) {
+ shape->curve_before_lpe = shape->curve_before_lpe->unref();
+ }
if (((SPObjectClass *) SPShapeClass::parent_class)->release) {
((SPObjectClass *) SPShapeClass::parent_class)->release (object);
@@ -1115,6 +1119,20 @@ void SPShape::setCurve(SPCurve *curve, unsigned int owner)
}
/**
+ * Sets curve_before_lpe to refer to the curve.
+ */
+void
+SPShape::setCurveBeforeLPE (SPCurve *curve)
+{
+ if (this->curve_before_lpe) {
+ this->curve_before_lpe = this->curve_before_lpe->unref();
+ }
+ if (curve) {
+ this->curve_before_lpe = curve->ref();
+ }
+}
+
+/**
* Return duplicate of curve (if any exists) or NULL if there is no curve
*/
SPCurve * SPShape::getCurve()
@@ -1126,6 +1144,24 @@ SPCurve * SPShape::getCurve()
}
/**
+ * Return duplicate of curve *before* LPE (if any exists) or NULL if there is no curve
+ */
+SPCurve *
+SPShape::getCurveBeforeLPE()
+{
+ if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(this))) {
+ if (this->curve_before_lpe) {
+ return this->curve_before_lpe->copy();
+ }
+ } else {
+ if (this->curve) {
+ return this->curve->copy();
+ }
+ }
+ return NULL;
+}
+
+/**
* Same as sp_shape_set_curve but without updating the display
*/
void SPShape::setCurveInsync(SPCurve *curve, unsigned int owner)
diff --git a/src/sp-shape.h b/src/sp-shape.h
index b29b0c50b..b91850d1f 100644
--- a/src/sp-shape.h
+++ b/src/sp-shape.h
@@ -44,11 +44,16 @@ public:
static GType getType (void);
void setShape ();
SPCurve * getCurve ();
+ SPCurve * getCurveBeforeLPE ();
void setCurve (SPCurve *curve, unsigned int owner);
void setCurveInsync (SPCurve *curve, unsigned int owner);
+ void setCurveBeforeLPE (SPCurve *curve);
int hasMarkers () const;
int numberOfMarkers (int type);
+protected:
+ SPCurve *curve_before_lpe;
+
private:
static void sp_shape_init (SPShape *shape);
static void sp_shape_finalize (GObject *object);
diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp
index e4bd0fa21..05c6bc9cd 100644
--- a/src/sp-spiral.cpp
+++ b/src/sp-spiral.cpp
@@ -427,6 +427,7 @@ sp_spiral_set_shape (SPShape *shape)
Geom::PathVector pv = sp_svg_read_pathv(shape->getRepr()->attribute("d"));
SPCurve *cold = new SPCurve(pv);
shape->setCurveInsync( cold, TRUE);
+ shape->setCurveBeforeLPE( cold );
cold->unref();
}
return;
@@ -470,6 +471,7 @@ sp_spiral_set_shape (SPShape *shape)
/* Reset the shape'scurve to the "original_curve"
* This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
shape->setCurveInsync( c, TRUE);
+ shape->setCurveBeforeLPE( c );
if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) {
SPCurve *c_lpe = c->copy();
bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe);
diff --git a/src/sp-star.cpp b/src/sp-star.cpp
index 200217ba2..92d8cd7a5 100644
--- a/src/sp-star.cpp
+++ b/src/sp-star.cpp
@@ -439,6 +439,7 @@ sp_star_set_shape (SPShape *shape)
Geom::PathVector pv = sp_svg_read_pathv(shape->getRepr()->attribute("d"));
SPCurve *cold = new SPCurve(pv);
shape->setCurveInsync( cold, TRUE);
+ shape->setCurveBeforeLPE(cold);
cold->unref();
}
return;
@@ -509,6 +510,7 @@ sp_star_set_shape (SPShape *shape)
/* Reset the shape'scurve to the "original_curve"
* This is very important for LPEs to work properly! (the bbox might be recalculated depending on the curve in shape)*/
shape->setCurveInsync( c, TRUE);
+ shape->setCurveBeforeLPE( c );
if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(shape)) && sp_lpe_item_path_effects_enabled(SP_LPE_ITEM(shape))) {
SPCurve *c_lpe = c->copy();
bool success = sp_lpe_item_perform_path_effect(SP_LPE_ITEM (shape), c_lpe);
diff --git a/src/splivarot.cpp b/src/splivarot.cpp
index 9c2fc8ff9..0e27ce26d 100644
--- a/src/splivarot.cpp
+++ b/src/splivarot.cpp
@@ -1804,19 +1804,10 @@ sp_selected_path_simplify_item(SPDesktop *desktop,
false);
}
-
- SPCurve *curve = NULL;
-
- if (SP_IS_SHAPE(item)) {
- curve = SP_SHAPE(item)->getCurve();
- if (!curve)
- return false;
- }
-
- if (SP_IS_TEXT(item)) {
- curve = SP_TEXT(item)->getNormalizedBpath();
- if (!curve)
- return false;
+ // get path to simplify (note that the path *before* LPE calculation is needed)
+ Path *orig = Path_for_item_before_LPE(item, false);
+ if (orig == NULL) {
+ return false;
}
// correct virtual size by full transform (bug #166937)
@@ -1836,14 +1827,6 @@ sp_selected_path_simplify_item(SPDesktop *desktop,
gchar *mask = g_strdup(item->getRepr()->attribute("mask"));
gchar *clip_path = g_strdup(item->getRepr()->attribute("clip-path"));
- Path *orig = Path_for_item(item, false);
- if (orig == NULL) {
- g_free(style);
- curve->unref();
- return false;
- }
-
- curve->unref();
// remember the position of the item
gint pos = item->getRepr()->position();
// remember parent
@@ -2106,6 +2089,27 @@ Path_for_item(SPItem *item, bool doTransformation, bool transformFull)
return dest;
}
+/**
+ * Obtains an item's Path before the LPE stack has been applied.
+ */
+Path *
+Path_for_item_before_LPE(SPItem *item, bool doTransformation, bool transformFull)
+{
+ SPCurve *curve = curve_for_item_before_LPE(item);
+
+ if (curve == NULL)
+ return NULL;
+
+ Geom::PathVector *pathv = pathvector_for_curve(item, curve, doTransformation, transformFull, Geom::identity(), Geom::identity());
+ curve->unref();
+
+ Path *dest = new Path;
+ dest->LoadPathVector(*pathv);
+ delete pathv;
+
+ return dest;
+}
+
/*
* NOTE: Returns empty pathvector if curve == NULL
* TODO: see if calling this method can be optimized. All the pathvector copying might be slow.
@@ -2132,6 +2136,10 @@ pathvector_for_curve(SPItem *item, SPCurve *curve, bool doTransformation, bool t
return dest;
}
+/**
+ * Obtains an item's curve. For SPPath, it is the path *before* LPE. For SPShapes other than path, it is the path *after* LPE.
+ * So the result is somewhat ill-defined, and probably this method should not be used... See curve_for_item_before_LPE.
+ */
SPCurve* curve_for_item(SPItem *item)
{
if (!item)
@@ -2157,6 +2165,31 @@ SPCurve* curve_for_item(SPItem *item)
return curve; // do not forget to unref the curve at some point!
}
+/**
+ * Obtains an item's curve *before* LPE.
+ * The returned SPCurve should be unreffed by the caller.
+ */
+SPCurve* curve_for_item_before_LPE(SPItem *item)
+{
+ if (!item)
+ return NULL;
+
+ SPCurve *curve = NULL;
+ if (SP_IS_SHAPE(item)) {
+ curve = SP_SHAPE(item)->getCurveBeforeLPE();
+ }
+ else if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item))
+ {
+ curve = te_get_layout(item)->convertToCurves();
+ }
+ else if (SP_IS_IMAGE(item))
+ {
+ curve = sp_image_get_curve(SP_IMAGE(item));
+ }
+
+ return curve; // do not forget to unref the curve at some point!
+}
+
boost::optional<Path::cut_position> get_nearest_position_on_Path(Path *path, Geom::Point p, unsigned seg)
{
//get nearest position on path
diff --git a/src/splivarot.h b/src/splivarot.h
index ea8183b67..40089ad71 100644
--- a/src/splivarot.h
+++ b/src/splivarot.h
@@ -49,8 +49,10 @@ Geom::PathVector* item_outline(SPItem const *item);
void sp_selected_path_simplify (SPDesktop *desktop);
Path *Path_for_item(SPItem *item, bool doTransformation, bool transformFull = true);
+Path *Path_for_item_before_LPE(SPItem *item, bool doTransformation, bool transformFull = true);
Geom::PathVector* pathvector_for_curve(SPItem *item, SPCurve *curve, bool doTransformation, bool transformFull, Geom::Affine extraPreAffine, Geom::Affine extraPostAffine);
SPCurve *curve_for_item(SPItem *item);
+SPCurve *curve_for_item_before_LPE(SPItem *item);
boost::optional<Path::cut_position> get_nearest_position_on_Path(Path *path, Geom::Point p, unsigned seg = 0);
Geom::Point get_point_on_Path(Path *path, int piece, double t);