summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e884573)
raw | patch | inline | side by side (parent: e884573)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Fri, 6 Jun 2008 01:43:35 +0000 (01:43 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Fri, 6 Jun 2008 01:43:35 +0000 (01:43 +0000) |
48 files changed:
index 7957ef56c594e43f51e856e64334f99b1a7b77da..b01e31b1411581945919753002c9a60241387264 100644 (file)
@@ -148,8 +148,8 @@ copy_without_nans_or_adjacent_duplicates(NR::Point const src[], unsigned src_len
if ( si == src_len ) {
return 0;
}
- if (!isNaN(src[si][NR::X]) &&
- !isNaN(src[si][NR::Y])) {
+ if (!IS_NAN(src[si][NR::X]) &&
+ !IS_NAN(src[si][NR::Y])) {
dest[0] = NR::Point(src[si]);
++si;
break;
@@ -160,8 +160,8 @@ copy_without_nans_or_adjacent_duplicates(NR::Point const src[], unsigned src_len
for (; si < src_len; ++si) {
NR::Point const src_pt = NR::Point(src[si]);
if ( src_pt != dest[di]
- && !isNaN(src_pt[NR::X])
- && !isNaN(src_pt[NR::Y])) {
+ && !IS_NAN(src_pt[NR::X])
+ && !IS_NAN(src_pt[NR::Y])) {
dest[++di] = src_pt;
}
}
double const dist = ( L2( data[len - 1]
- data[0] )
/ 3.0 );
- if (isNaN(dist)) {
+ if (IS_NAN(dist)) {
/* Numerical problem, fall back to straight line segment. */
bezier[1] = bezier[0];
bezier[2] = bezier[3];
}
}
- if (!isFinite(improved_u)) {
+ if (!IS_FINITE(improved_u)) {
improved_u = u;
} else if ( improved_u < 0.0 ) {
improved_u = 0.0;
/* Then scale to [0.0 .. 1.0]. */
gdouble tot_len = u[len - 1];
g_return_if_fail( tot_len != 0 );
- if (isFinite(tot_len)) {
+ if (IS_FINITE(tot_len)) {
for (unsigned i = 1; i < len; ++i) {
u[i] /= tot_len;
}
/** \todo
* It's been reported that u[len - 1] can differ from 1.0 on some
* systems (amd64), despite it having been calculated as x / x where x
- * is isFinite and non-zero.
+ * is IS_FINITE and non-zero.
*/
if (u[len - 1] != 1) {
double const diff = u[len - 1] - 1;
index a3327308c6e1eb7a58f6c57f509fd42537d0b569..3c46a9049d6c4fbf824c607fdd1cb240847c17bc 100644 (file)
@@ -142,7 +142,7 @@ sp_canvas_bpath_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned i
Path* thePath=new Path;
thePath->LoadArtBPath(SP_CURVE_BPATH(cbp->curve), affine, true);
thePath->Convert(0.25);
- if ((cbp->fill_rgba & 0xff) && (cbp->curve->_end > 2)) {
+ if ((cbp->fill_rgba & 0xff) && (cbp->curve->get_length() > 2)) {
Shape* theShape=new Shape;
thePath->Fill(theShape,0);
if ( cbp->fill_shp == NULL ) cbp->fill_shp=new Shape;
@@ -165,7 +165,7 @@ sp_canvas_bpath_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned i
}
}
}
- if ((cbp->stroke_rgba & 0xff) && (cbp->curve->_end > 1)) {
+ if ((cbp->stroke_rgba & 0xff) && (cbp->curve->get_length() > 1)) {
JoinType join=join_straight;
// Shape* theShape=new Shape;
ButtType butt=butt_straight;
diff --git a/src/display/curve.cpp b/src/display/curve.cpp
index 966a35f5bd01ddf01f0e08c4b01c6773adda09f8..eb86773f91dbdf76b5bced293e25063e71377274 100644 (file)
--- a/src/display/curve.cpp
+++ b/src/display/curve.cpp
#include <libnr/n-art-bpath.h>
#include <libnr/nr-point-matrix-ops.h>
#include <libnr/nr-translate-ops.h>
+#include <libnr/n-art-bpath-2geom.h>
+#include <libnr/nr-convert2geom.h>
#include <cstring>
#include <string>
+#include <2geom/pathvector.h>
+#include <2geom/sbasis-geometric.h>
+#include <2geom/sbasis-to-bezier.h>
+#include "svg/svg.h"
static unsigned sp_bpath_length(NArtBpath const bpath[]);
static bool sp_bpath_closed(NArtBpath const bpath[]);
+#define NO_CHECKS
+
+static void debug_out( char const * text, Geom::PathVector const & pathv) {
+#ifndef NO_CHECKS
+ char * str = sp_svg_write_path(pathv);
+ g_message("%s : %s", text, str);
+ g_free(str);
+#endif
+}
+static void debug_out( char const * text, NArtBpath const * bpath) {
+#ifndef NO_CHECKS
+ char * str = sp_svg_write_path(bpath);
+ g_message("%s : %s", text, str);
+ g_free(str);
+#endif
+}
+void SPCurve::debug_check( char const * text, SPCurve const * curve) {
+#ifndef NO_CHECKS
+ char * pathv_str = sp_svg_write_path(curve->_pathv);
+ char * bpath_str = sp_svg_write_path(curve->_bpath);
+ if ( strcmp(pathv_str, bpath_str) ) {
+ g_message("%s : unequal paths", text);
+ g_message("bpath : %s", bpath_str);
+ g_message("pathv : %s", pathv_str);
+ }
+ g_free(pathv_str);
+ g_free(bpath_str);
+#endif
+}
+void SPCurve::debug_check( char const * text, bool a) {
+#ifndef NO_CHECKS
+ if ( !a ) {
+ g_message("%s : bool fail", text);
+ }
+#endif
+}
+
/* Constructors */
/**
* The returned curve's state is as if SPCurve::reset has just been called on it.
* \param length Initial number of NArtBpath elements allocated for bpath (including NR_END
* element).
+ * 2GEOMproof
*/
SPCurve::SPCurve(guint length)
- : _end(0),
+ : _refcount(1),
+ _bpath(NULL),
+ _pathv(),
+ _end(0),
_length(length),
_substart(0),
_hascpt(false),
_posSet(false),
_moving(false),
- _closed(false),
- _refcount(1),
- _bpath(NULL)
+ _closed(false)
{
if (length <= 0) {
g_error("SPCurve::SPCurve called with invalid length parameter");
_bpath = g_new(NArtBpath, length);
_bpath->code = NR_END;
+
+ _pathv.clear();
+
+ debug_check("SPCurve::SPCurve(guint length)", this);
}
+SPCurve::SPCurve(Geom::PathVector const& pathv)
+ : _refcount(1),
+ _bpath(NULL),
+ _pathv(pathv),
+ _end(0),
+ _length(0),
+ _substart(0),
+ _hascpt(false),
+ _posSet(false),
+ _moving(false),
+ _closed(false)
+{
+ // temporary code to convert to _bpath as well:
+ _bpath = BPath_from_2GeomPath(_pathv);
+ unsigned const len = sp_bpath_length(_bpath);
+ _length = len;
+ _end = _length - 1;
+ gint i = _end;
+ for (; i > 0; i--)
+ if ((_bpath[i].code == NR_MOVETO) ||
+ (_bpath[i].code == NR_MOVETO_OPEN))
+ break;
+ _substart = i;
+ _closed = sp_bpath_closed(_bpath);
+
+ debug_check("SPCurve::SPCurve(Geom::PathVector const& pathv)", this);
+}
+
+// * 2GEOMproof
SPCurve *
SPCurve::new_from_foreign_bpath(NArtBpath const *bpath)
{
curve->_substart = i;
curve->_closed = sp_bpath_closed(new_bpath);
+ curve->_pathv = BPath_to_2GeomPath(curve->_bpath);
+
+ debug_check("SPCurve::new_from_foreign_bpath", curve);
+
return curve;
}
* Convert NArtBpath object to SPCurve object.
*
* \return new SPCurve, or NULL if the curve was not created for some reason.
+ * 2GEOMproof
*/
SPCurve *
SPCurve::new_from_bpath(NArtBpath *bpath)
SPCurve *curve = SPCurve::new_from_foreign_bpath(bpath);
g_free(bpath);
+
+ debug_check("SPCurve::new_from_bpath", curve);
+
return curve;
}
+// * 2GEOMproof
SPCurve *
SPCurve::new_from_rect(NR::Maybe<NR::Rect> const &rect)
{
}
c->closepath_current();
+ debug_check("SPCurve::new_from_rect", c);
+
return c;
}
+// * 2GEOMproof
SPCurve::~SPCurve()
{
if (_bpath) {
/* Methods */
-/**
- * Frees old path and sets new path
- * This does not copy the bpath, so the new_bpath should not be deleted by caller
- */
void
-SPCurve::set_bpath(NArtBpath * new_bpath)
+SPCurve::set_pathv(Geom::PathVector const & new_pathv)
{
- if (new_bpath && new_bpath != _bpath) { // FIXME, add function to SPCurve to change bpath? or a copy function?
- if (_bpath) {
- g_free(_bpath); //delete old bpath
- }
- _bpath = new_bpath;
+ _pathv = new_pathv;
+
+ _hascpt = false;
+ _posSet = false;
+ _moving = false;
+
+ // temporary code to convert to _bpath as well:
+ if (_bpath) {
+ g_free(_bpath);
+ _bpath = NULL;
}
+ _bpath = BPath_from_2GeomPath(_pathv);
+ unsigned const len = sp_bpath_length(_bpath);
+ _length = len;
+ _end = _length - 1;
+ gint i = _end;
+ for (; i > 0; i--)
+ if ((_bpath[i].code == NR_MOVETO) ||
+ (_bpath[i].code == NR_MOVETO_OPEN))
+ break;
+ _substart = i;
+ _closed = sp_bpath_closed(_bpath);
+
+ debug_check("SPCurve::set_pathv", this);
}
/**
{
return _bpath;
};
-/*
-NArtBpath *
-SPCurve::get_bpath()
+
+Geom::PathVector const &
+SPCurve::get_pathvector() const
{
- return _bpath;
-};
-*/
+ return _pathv;
+}
+
+/**
+ *Returns index in bpath[] of NR_END element.
+ * remove for 2geom
+ */
+guint
+SPCurve::get_length() const
+{
+// g_message("SPCurve::get_length must be removed");
+
+ return _end;
+}
/**
* Increase _refcount of curve.
*
* \todo should this be shared with other refcounting code?
+ * 2GEOMproof
*/
SPCurve *
SPCurve::ref()
* Decrease refcount of curve, with possible destruction.
*
* \todo should this be shared with other refcounting code?
+ * 2GEOMproof
*/
SPCurve *
SPCurve::unref()
_refcount -= 1;
if (_refcount < 1) {
- if (_bpath) {
- g_free(_bpath);
- _bpath = NULL;
- }
delete this;
}
/**
* Add space for more paths in curve.
+ * This function has no meaning for 2geom representation, other than maybe for optimization issues (enlargening the vector for what is to come)
+ * 2GEOMproof
*/
void
SPCurve::ensure_space(guint space)
/**
* Create new curve from its own bpath array.
+ * 2GEOMproof
*/
SPCurve *
SPCurve::copy() const
/**
* Return new curve that is the concatenation of all curves in list.
+ * 2GEOMified
*/
SPCurve *
SPCurve::concat(GSList const *list)
new_curve->_substart = i;
+ for (GSList const *l = list; l != NULL; l = l->next) {
+ SPCurve *c = (SPCurve *) l->data;
+ new_curve->_pathv.insert( new_curve->_pathv.end(), c->get_pathvector().begin(), c->get_pathvector().end() );
+ }
+
+ debug_check("SPCurve::concat", new_curve);
+
return new_curve;
}
/**
* Returns a list of new curves corresponding to the subpaths in \a curve.
+ * 2geomified
*/
GSList *
SPCurve::split() const
guint p = 0;
GSList *l = NULL;
+ gint pathnr = 0;
while (p < _end) {
gint i = 1;
while ((_bpath[p + i].code == NR_LINETO) ||
new_curve->_substart = 0;
new_curve->_closed = (new_curve->_bpath->code == NR_MOVETO);
new_curve->_hascpt = (new_curve->_bpath->code == NR_MOVETO_OPEN);
+ new_curve->_pathv = Geom::PathVector(1, _pathv[pathnr]);
l = g_slist_prepend(l, new_curve);
p += i;
+ pathnr++;
}
return l;
*/
template<class M>
static void
-tmpl_curve_transform(SPCurve *const curve, M const &m)
+tmpl_curve_transform(SPCurve * curve, M const &m)
{
g_return_if_fail(curve != NULL);
/**
* Transform all paths in curve using matrix.
+ * 2GEOMified, can be deleted when completely 2geom
*/
void
SPCurve::transform(NR::Matrix const &m)
{
tmpl_curve_transform<NR::Matrix>(this, m);
+
+ transform(to_2geom(m));
+
+ debug_check("SPCurve::transform", this);
+}
+
+/**
+ * Transform all paths in curve using matrix.
+ */
+void
+SPCurve::transform(Geom::Matrix const &m)
+{
+ _pathv = _pathv * m;
}
/**
* Transform all paths in curve using NR::translate.
+ * 2GEOMified, can be deleted when completely 2geom
*/
void
SPCurve::transform(NR::translate const &m)
{
tmpl_curve_transform<NR::translate>(this, m);
+
+ transform(to_2geom(m));
+
+ debug_check("SPCurve::transform translate", this);
}
/**
* Set curve to empty curve.
+ * 2GEOMified
*/
void
SPCurve::reset()
_posSet = false;
_moving = false;
_closed = false;
+
+ _pathv.clear();
+
+ debug_check("SPCurve::reset", this);
}
/* Several consecutive movetos are ALLOWED */
{
moveto(NR::Point(x, y));
}
-
+/**
+ * Calls SPCurve::moveto() with point made of given coordinates.
+ */
+void
+SPCurve::moveto(Geom::Point const &p)
+{
+ moveto(from_2geom(p));
+}
/**
* Perform a moveto to a point, thus starting a new subpath.
+ * 2GEOMified
*/
void
SPCurve::moveto(NR::Point const &p)
_hascpt = true;
_posSet = true;
_movePos = p;
+ _pathv.push_back( Geom::Path() ); // for some reason Geom::Path(p) does not work...
+ _pathv.back().start(to_2geom(p));
+
+ // the output is not the same. This is because SPCurve *incorrectly* coaslesces multiple moveto's into one for NArtBpath.
+// debug_check("SPCurve::moveto", this);
}
+/**
+ * Calls SPCurve::lineto() with a point's coordinates.
+ */
+void
+SPCurve::lineto(Geom::Point const &p)
+{
+ lineto(p[Geom::X], p[Geom::Y]);
+}
/**
* Calls SPCurve::lineto() with a point's coordinates.
*/
{
lineto(p[NR::X], p[NR::Y]);
}
-
/**
* Adds a line to the current subpath.
+ * 2GEOMified
*/
void
SPCurve::lineto(gdouble x, gdouble y)
bp->x3 = x;
bp->y3 = y;
_moving = false;
- return;
- }
- if (_posSet) {
+ Geom::Path::iterator it = _pathv.back().end();
+ if ( Geom::LineSegment const *last_line_segment = dynamic_cast<Geom::LineSegment const *>( &(*it) )) {
+ Geom::LineSegment new_seg( *last_line_segment );
+ new_seg.setFinal( Geom::Point(x,y) );
+ _pathv.back().replace(it, new_seg);
+ }
+ } else if (_posSet) {
/* start a new segment */
ensure_space(2);
NArtBpath *bp = _bpath + _end;
_end += 2;
_posSet = false;
_closed = false;
- return;
- }
-
- /* add line */
-
- g_return_if_fail(_end > 1);
- ensure_space(1);
- NArtBpath *bp = _bpath + _end;
- bp->code = NR_LINETO;
- bp->x3 = x;
- bp->y3 = y;
- bp++;
- bp->code = NR_END;
- _end++;
-}
-/// Unused
-void
-SPCurve::lineto_moving(gdouble x, gdouble y)
-{
- g_return_if_fail(this != NULL);
- g_return_if_fail(_hascpt);
-
- if (_moving) {
- /* change endpoint */
- g_return_if_fail(!_posSet);
- g_return_if_fail(_end > 1);
- NArtBpath *bp = _bpath + _end - 1;
- g_return_if_fail(bp->code == NR_LINETO);
- bp->x3 = x;
- bp->y3 = y;
+ _pathv.back().appendNew<Geom::LineSegment>( Geom::Point(x,y) );
return;
- }
+ } else {
+ /* add line */
- if (_posSet) {
- /* start a new segment */
- ensure_space(2);
+ g_return_if_fail(_end > 1);
+ ensure_space(1);
NArtBpath *bp = _bpath + _end;
- bp->code = NR_MOVETO_OPEN;
- bp->setC(3, _movePos);
- bp++;
bp->code = NR_LINETO;
bp->x3 = x;
bp->y3 = y;
bp++;
bp->code = NR_END;
- _end += 2;
- _posSet = false;
- _moving = true;
- _closed = false;
- return;
+ _end++;
+ _pathv.back().appendNew<Geom::LineSegment>( Geom::Point(x,y) );
}
- /* add line */
-
- g_return_if_fail(_end > 1);
- ensure_space(1);
- NArtBpath *bp = _bpath + _end;
- bp->code = NR_LINETO;
- bp->x3 = x;
- bp->y3 = y;
- bp++;
- bp->code = NR_END;
- _end++;
- _moving = true;
+ debug_check("SPCurve::lineto", this);
}
+/**
+ * Calls SPCurve::curveto() with coordinates of three points.
+ */
+void
+SPCurve::curveto(Geom::Point const &p0, Geom::Point const &p1, Geom::Point const &p2)
+{
+ using Geom::X;
+ using Geom::Y;
+ curveto( p0[X], p0[Y],
+ p1[X], p1[Y],
+ p2[X], p2[Y] );
+}
/**
* Calls SPCurve::curveto() with coordinates of three points.
*/
p1[X], p1[Y],
p2[X], p2[Y] );
}
-
/**
* Adds a bezier segment to the current subpath.
+ * 2GEOMified
*/
void
SPCurve::curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2)
@@ -542,28 +685,33 @@ SPCurve::curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdo
_end += 2;
_posSet = false;
_closed = false;
- return;
+ _pathv.back().appendNew<Geom::CubicBezier>( Geom::Point(x0,y0), Geom::Point(x1,y1), Geom::Point(x2,y2) );
+ } else {
+ /* add curve */
+
+ g_return_if_fail(_end > 1);
+ ensure_space(1);
+ NArtBpath *bp = _bpath + _end;
+ bp->code = NR_CURVETO;
+ bp->x1 = x0;
+ bp->y1 = y0;
+ bp->x2 = x1;
+ bp->y2 = y1;
+ bp->x3 = x2;
+ bp->y3 = y2;
+ bp++;
+ bp->code = NR_END;
+ _end++;
+ if (_pathv.empty()) g_message("leeg");
+ else _pathv.back().appendNew<Geom::CubicBezier>( Geom::Point(x0,y0), Geom::Point(x1,y1), Geom::Point(x2,y2) );
}
- /* add curve */
-
- g_return_if_fail(_end > 1);
- ensure_space(1);
- NArtBpath *bp = _bpath + _end;
- bp->code = NR_CURVETO;
- bp->x1 = x0;
- bp->y1 = y0;
- bp->x2 = x1;
- bp->y2 = y1;
- bp->x3 = x2;
- bp->y3 = y2;
- bp++;
- bp->code = NR_END;
- _end++;
+ debug_check("SPCurve::curveto", this);
}
/**
* Close current subpath by possibly adding a line between start and end.
+ * 2GEOMified
*/
void
SPCurve::closepath()
bs->code = NR_MOVETO;
}
+ // Inkscape always manually adds the closing line segment to SPCurve with a lineto.
+ // This lineto is removed in the writing function for NArtBpath,
+ // so when path is closed and the last segment is a lineto, the closing line segment must really be removed first!
+ // TODO: fix behavior in Inkscape!
+ if ( /*Geom::LineSegment const *line_segment = */ dynamic_cast<Geom::LineSegment const *>(&_pathv.back().back())) {
+ _pathv.back().erase_last();
+ }
+ _pathv.back().close(true);
_closed = true;
+ for (Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); it++) {
+ if ( ! it->closed() ) {
+ _closed = false;
+ break;
+ }
+ }
+
for (NArtBpath const *bp = _bpath; bp->code != NR_END; bp++) {
/** \todo
* effic: Maintain a count of NR_MOVETO_OPEN's (e.g. instead of
}
_hascpt = false;
+
+ debug_check("SPCurve::closepath", this);
}
/** Like SPCurve::closepath() but sets the end point of the current
bs->code = NR_MOVETO;
}
+ // Inkscape always manually adds the closing line segment to SPCurve with a lineto.
+ // This lineto is removed in the writing function for NArtBpath,
+ // so when path is closed and the last segment is a lineto, the closing line segment must really be removed first!
+ // TODO: fix behavior in Inkscape!
+ if ( /*Geom::LineSegment const *line_segment = */ dynamic_cast<Geom::LineSegment const *>(&_pathv.back().back())) {
+ _pathv.back().erase_last();
+ }
+ _pathv.back().close(true);
_closed = true;
+ for (Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); it++) {
+ if ( ! it->closed() ) {
+ _closed = false;
+ break;
+ }
+ }
+
for (NArtBpath const *bp = _bpath; bp->code != NR_END; bp++) {
/** \todo
* effic: Maintain a count of NR_MOVETO_OPEN's (e.g. instead of
_hascpt = false;
_moving = false;
+
+ debug_check("SPCurve::closepath_current", this);
}
/**
{
g_return_val_if_fail(this != NULL, TRUE);
+ bool empty = _pathv.empty(); /* || _pathv.front().empty(); */
+ debug_check("SPCurve::is_empty", (_bpath->code == NR_END) == empty );
+
return (_bpath->code == NR_END);
}
bool
SPCurve::is_closed() const
{
+ bool closed = true;
+ for (Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); it++) {
+ if ( ! it->closed() ) {
+ closed = false;
+ break;
+ }
+ }
+ debug_check("SPCurve::is_closed", (closed) == (_closed) );
+
return _closed;
}
/**
* Return last subpath or NULL.
*/
-NArtBpath *
+NArtBpath const *
SPCurve::last_bpath() const
{
g_return_val_if_fail(this != NULL, NULL);
/**
* Return first subpath or NULL.
*/
-NArtBpath *
+NArtBpath const *
SPCurve::first_bpath() const
{
g_return_val_if_fail(this != NULL, NULL);
}
/**
- * Return first point of first subpath or (0,0).
+ * Return first point of first subpath or (0,0). TODO: shouldn't this be (NR_HUGE, NR_HUGE) to be able to tell it apart from normal (0,0) ?
*/
NR::Point
SPCurve::first_point() const
{
- NArtBpath *const bpath = first_bpath();
+ NArtBpath const * bpath = first_bpath();
g_return_val_if_fail(bpath != NULL, NR::Point(0, 0));
+ if (is_empty())
+ return NR::Point(0, 0);
+
+ debug_check("SPCurve::first_point", bpath->c(3) == _pathv.front().initialPoint() );
+
return bpath->c(3);
+ // return from_2geom( _pathv.front().initialPoint() );
}
/**
bpath = _bpath + 1;
}
g_return_val_if_fail(bpath != NULL, NR::Point(0, 0));
+
+ debug_check("SPCurve::second_point", bpath->c(3) == _pathv.front()[0].finalPoint() );
+
return bpath->c(3);
}
NArtBpath *const bpath = _bpath + _end - 2;
g_return_val_if_fail(bpath != NULL, NR::Point(0, 0));
+
+ Geom::Point p(NR_HUGE, NR_HUGE);
+ Geom::Curve const& back = _pathv.back().back();
+ if (_pathv.back().closed()) {
+ p = back.finalPoint();
+ } else {
+ p = back.initialPoint();
+ }
+
+ debug_check("SPCurve::penultimate_point", bpath->c(3) == p );
return bpath->c(3);
}
/**
- * Return last point of last subpath or (0,0).
+ * Return last point of last subpath or (0,0). TODO: shouldn't this be (NR_HUGE, NR_HUGE) to be able to tell it apart from normal (0,0) ?
*/
NR::Point
SPCurve::last_point() const
{
- NArtBpath *const bpath = last_bpath();
+ NArtBpath const * bpath = last_bpath();
g_return_val_if_fail(bpath != NULL, NR::Point(0, 0));
+ if (is_empty())
+ return NR::Point(0, 0);
+
+ debug_check("SPCurve::last_point", bpath->c(3) == _pathv.back().finalPoint() );
return bpath->c(3);
+ // return from_2geom( _pathv.back().finalPoint() );
}
inline static bool
* Returns a *new* \a curve but drawn in the opposite direction.
* Should result in the same shape, but
* with all its markers drawn facing the other direction.
+ * Reverses the order of subpaths as well
+ * 2GEOMified
**/
SPCurve *
SPCurve::create_reverse() const
g_assert_not_reached();
}
}
+
+ new_curve->_pathv = Geom::reverse_paths_and_order(_pathv);
+
+ debug_check("SPCurve::create_reverse", new_curve);
}
/**
- * Append \a curve2 to \a curve.
+ * Append \a curve2 to \a this.
+ * If \a use_lineto is false, simply add all paths in \a curve2 to \a this;
+ * if \a use_lineto is true, combine \a this's last path and \a curve2's first path and add the rest of the paths in \a curve2 to \a this.
+ * 2GEOMified
*/
void
SPCurve::append(SPCurve const *curve2,
g_return_if_fail(this != NULL);
g_return_if_fail(curve2 != NULL);
+ if (curve2->is_empty())
+ return;
if (curve2->_end < 1)
return;
if (closed) {
closepath();
}
+
+ debug_check("SPCurve::append", this);
+
+ /* 2GEOM code when code above is removed:
+ if (use_lineto) {
+ Geom::PathVector::const_iterator it = curve2->_pathv.begin();
+ if ( ! _pathv.empty() ) {
+ Geom::Path & lastpath = _pathv.back();
+ lastpath.appendNew<Geom::LineSegment>( (*it).initialPoint() );
+ lastpath.append( (*it) );
+ } else {
+ _pathv.push_back( (*it) );
+ }
+
+ for (it++; it != curve2->_pathv.end(); it++) {
+ _pathv.push_back( (*it) );
+ }
+ } else {
+ for (Geom::PathVector::const_iterator it = curve2->_pathv.begin(); it != curve2->_pathv.end(); it++) {
+ _pathv.push_back( (*it) );
+ }
+ }
+ */
}
/**
return this;
}
- NArtBpath *be = last_bpath();
+ debug_check("SPCurve::append_continuous 11", this);
+
+ NArtBpath const *be = last_bpath();
if (be) {
NArtBpath const *bs = c1->first_bpath();
if ( bs
append(c1, TRUE);
}
+ debug_check("SPCurve::append_continuous", this);
+
return this;
}
/**
* Remove last segment of curve.
+ * (Only used once in /src/pen-context.cpp)
*/
void
SPCurve::backspace()
{
g_return_if_fail(this != NULL);
+ if ( is_empty() )
+ return;
+
if (_end > 0) {
_end -= 1;
if (_end > 0) {
}
_bpath[_end].code = NR_END;
}
+
+ if ( !_pathv.back().empty() ) {
+ _pathv.back().erase_last();
+ _pathv.back().close(false);
+ }
+
+ debug_check("SPCurve::backspace", this);
}
/* Private methods */
@@ -1089,6 +1356,9 @@ sp_curve_nonzero_distance_including_space(SPCurve const *const curve, double seg
}
}
+/**
+ *
+ */
void
SPCurve::stretch_endpoints(NR::Point const &new_p0, NR::Point const &new_p1)
{
/* Explicit set for better numerical properties. */
_bpath[nSegs].setC(3, new_p1);
delete [] seg2len;
+
+ Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _pathv.front().toPwSb();
+ Geom::Piecewise<Geom::SBasis> arclength = Geom::arcLengthSb(pwd2);
+ if ( arclength.lastValue() <= 0 ) {
+ g_error("SPCurve::stretch_endpoints - arclength <= 0");
+ throw;
+ }
+ arclength *= 1./arclength.lastValue();
+ Geom::Point const A( to_2geom(offset0) );
+ Geom::Point const B( to_2geom(offset1) );
+ Geom::Piecewise<Geom::SBasis> offsetx = (arclength*-1.+1)*A[0] + arclength*B[0];
+ Geom::Piecewise<Geom::SBasis> offsety = (arclength*-1.+1)*A[1] + arclength*B[1];
+ Geom::Piecewise<Geom::D2<Geom::SBasis> > offsetpath = Geom::sectionize( Geom::D2<Geom::Piecewise<Geom::SBasis> >(offsetx, offsety) );
+ pwd2 += offsetpath;
+ _pathv = Geom::path_from_piecewise( pwd2, 0.001 );
+
+ debug_check("SPCurve::stretch_endpoints", this);
}
+/**
+ * sets start of first path to new_p0, and end of first path to new_p1
+ * 2GEOMified
+ */
void
SPCurve::move_endpoints(NR::Point const &new_p0, NR::Point const &new_p1)
{
_bpath->setC(3, new_p0);
_bpath[nSegs].setC(3, new_p1);
+
+ _pathv.front().setInitial(to_2geom(new_p0));
+ _pathv.front().setFinal(to_2geom(new_p1));
+
+ debug_check("SPCurve::move_endpoints", this);
+}
+
+/**
+ * returns the number of nodes in a path, used for statusbar text when selecting an spcurve.
+ * 2GEOMified
+ */
+guint
+SPCurve::nodes_in_path() const
+{
+ gint r = _end;
+ gint i = _length - 1;
+ if (i > r) i = r; // sometimes after switching from node editor length is wrong, e.g. f6 - draw - f2 - tab - f1, this fixes it
+ for (; i >= 0; i --)
+ if (_bpath[i].code == NR_MOVETO)
+ r --;
+
+ guint nr = 0;
+ for(Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); ++it) {
+ nr += (*it).size();
+
+ nr++; // count last node (this works also for closed paths because although they don't have a 'last node', they do have an extra segment
+ }
+
+ debug_check("SPCurve::nodes_in_path", r == (gint)nr);
+
+ return r;
}
+/**
+ * Adds p to the last point (and last handle if present) of the last path
+ */
+void
+SPCurve::last_point_additive_move(Geom::Point const & p)
+{
+ if (is_empty()) {
+ return;
+ }
+ if (_end == 0) {
+ return;
+ }
+ NArtBpath * path = _bpath + _end - 1;
+
+ if (path->code == NR_CURVETO) {
+ path->x2 += p[Geom::X];
+ path->y2 += p[Geom::Y];
+ }
+ path->x3 += p[Geom::X];
+ path->y3 += p[Geom::Y];
+
+ _pathv.back().setFinal( _pathv.back().finalPoint() + p );
+
+ // Move handle as well when the last segment is a cubic bezier segment:
+ // TODO: what to do for quadratic beziers?
+ if ( Geom::CubicBezier const *lastcube = dynamic_cast<Geom::CubicBezier const *>(&_pathv.back().back()) ) {
+ Geom::CubicBezier newcube( *lastcube );
+ newcube.setPoint(2, newcube[2] + p);
+ _pathv.back().replace( --_pathv.back().end(), newcube );
+ }
+
+ debug_check("SPCurve::last_point_additive_move", this);
+}
/*
Local Variables:
diff --git a/src/display/curve.h b/src/display/curve.h
index 5cd8bb12cadd1b04ca241308b3d890340e049b07..4e94578ed975084cfead90f3a42082238efb5734 100644 (file)
--- a/src/display/curve.h
+++ b/src/display/curve.h
#include <glib/gtypes.h>
#include <glib/gslist.h>
+#include <2geom/forward.h>
+#include <2geom/point.h>
+
#include "libnr/nr-forward.h"
#include "libnr/nr-rect.h"
#define SP_CURVE_LENSTEP 32
-/// Wrapper around NArtBpath.
+struct SPObject;
+
+/// Wrapper around Geom::PathVector.
class SPCurve {
public:
/* Constructors */
SPCurve(guint length = SP_CURVE_LENSTEP);
+ SPCurve(Geom::PathVector const& pathv);
static SPCurve * new_from_bpath(NArtBpath *bpath);
static SPCurve * new_from_foreign_bpath(NArtBpath const *bpath);
static SPCurve * new_from_rect(NR::Maybe<NR::Rect> const &rect);
virtual ~SPCurve();
- void set_bpath(NArtBpath * new_bpath);
+ void set_pathv(Geom::PathVector const & new_pathv);
NArtBpath const * get_bpath() const;
+ Geom::PathVector const & get_pathvector() const;
- /// Index in bpath[] of NR_END element.
- guint _end;
-
- /// Allocated size (i.e., capacity) of bpath[] array. Not to be confused
- /// with the SP_CURVE_LENGTH macro, which returns the logical length of
- /// the path (i.e., index of NR_END).
- guint _length;
-
- /// Index in bpath[] of the start (i.e., moveto element) of the last
- /// subpath in this path.
- guint _substart;
-
- /// Previous moveto position.
- /// \note This is used for coalescing moveto's, whereas if we're to
- /// conform to the SVG spec then we mustn't coalesce movetos if we have
- /// midpoint markers. Ref:
- /// http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes
- /// (first subitem of the item about zero-length path segments)
- NR::Point _movePos;
-
- /// True iff current point is defined. Initially false for a new curve;
- /// becomes true after moveto; becomes false on closepath. Curveto,
- /// lineto etc. require hascpt; hascpt remains true after lineto/curveto.
- bool _hascpt : 1;
-
- /// True iff previous was moveto.
- bool _posSet : 1;
-
- /// True iff bpath end is moving.
- bool _moving : 1;
-
- /// True iff all subpaths are closed.
- bool _closed : 1;
+ guint get_length() const;
SPCurve * ref();
SPCurve * unref();
SPCurve * copy() const;
GSList * split() const;
+ void transform(Geom::Matrix const &m);
void transform(NR::Matrix const &);
void transform(NR::translate const &);
void stretch_endpoints(NR::Point const &, NR::Point const &);
void move_endpoints(NR::Point const &, NR::Point const &);
+ void last_point_additive_move(Geom::Point const & p);
void reset();
+ void moveto(Geom::Point const &p);
void moveto(NR::Point const &p);
void moveto(gdouble x, gdouble y);
+ void lineto(Geom::Point const &p);
void lineto(NR::Point const &p);
void lineto(gdouble x, gdouble y);
- void lineto_moving(gdouble x, gdouble y);
+ void curveto(Geom::Point const &p0, Geom::Point const &p1, Geom::Point const &p2);
void curveto(NR::Point const &p0, NR::Point const &p1, NR::Point const &p2);
void curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2);
void closepath();
bool is_empty() const;
bool is_closed() const;
- NArtBpath * last_bpath() const;
- NArtBpath * first_bpath() const;
+ NArtBpath const * last_bpath() const;
+ NArtBpath const * first_bpath() const;
NR::Point first_point() const;
NR::Point last_point() const;
NR::Point second_point() const;
NR::Point penultimate_point() const;
+ guint nodes_in_path() const;
void append(SPCurve const *curve2, bool use_lineto);
SPCurve * create_reverse() const;
gint _refcount;
NArtBpath *_bpath;
+ Geom::PathVector _pathv;
+
+ /// Index in bpath[] of NR_END element.
+ guint _end;
+
+ /// Allocated size (i.e., capacity) of bpath[] array. Not to be confused
+ /// with the SP_CURVE_LENGTH macro, which returns the logical length of
+ /// the path (i.e., index of NR_END).
+ guint _length;
+
+ /// Index in bpath[] of the start (i.e., moveto element) of the last
+ /// subpath in this path.
+ guint _substart;
+
+ /// Previous moveto position.
+ /// \note This is used for coalescing moveto's, whereas if we're to
+ /// conform to the SVG spec then we mustn't coalesce movetos if we have
+ /// midpoint markers. Ref:
+ /// http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes
+ /// (first subitem of the item about zero-length path segments)
+ NR::Point _movePos;
+
+ /// True iff current point is defined. Initially false for a new curve;
+ /// becomes true after moveto; becomes false on closepath. Curveto,
+ /// lineto etc. require hascpt; hascpt remains true after lineto/curveto.
+ bool _hascpt : 1;
+
+ /// True iff previous was moveto.
+ bool _posSet : 1;
+
+ /// True iff bpath end is moving.
+ bool _moving : 1;
+
+ /// True iff all subpaths are closed.
+ bool _closed : 1;
private:
// Don't implement these:
SPCurve(const SPCurve&);
SPCurve& operator=(const SPCurve&);
+//friends:
friend double sp_curve_distance_including_space(SPCurve const *const curve, double seg2len[]);
friend double sp_curve_nonzero_distance_including_space(SPCurve const *const curve, double seg2len[]);
template<class M> friend void tmpl_curve_transform(SPCurve *const curve, M const &m);
+ // this function is the only one who needs read access to _movePos and _posSet
+ friend void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value);
+
+ static void debug_check( char const * text, SPCurve const * curve);
+ static void debug_check( char const * text, bool a);
};
-#define SP_CURVE_LENGTH(c) (((SPCurve const *)(c))->_end)
-#define SP_CURVE_BPATH(c) ((c)->get_bpath())
-#define SP_CURVE_SEGMENT(c,i) ((c)->get_bpath() + (i))
+#define SP_CURVE_LENGTH(c) (((SPCurve const *)(c))->get_length())
+#define SP_CURVE_BPATH(c) (((SPCurve const *)(c))->get_bpath())
+#define SP_CURVE_SEGMENT(c,i) (((SPCurve const *)(c))->get_bpath() + (i))
#endif /* !SEEN_DISPLAY_CURVE_H */
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index 0ff7132e189d419b11abc94c154a3d2feb4d86bb..0cd0de2bb6715c16ae9298adfd575987ce1b220c 100644 (file)
nr_arena_shape_update_fill(NRArenaShape *shape, NRGC *gc, NRRectL *area, bool force_shape)
{
if ((shape->_fill.paint.type() != NRArenaShape::Paint::NONE || force_shape) &&
- ((shape->curve->_end > 2) || (SP_CURVE_BPATH(shape->curve)[1].code == NR_CURVETO)) ) {
+ ((shape->curve->get_length() > 2) || (SP_CURVE_BPATH(shape->curve)[1].code == NR_CURVETO)) ) {
if (TRUE || !shape->fill_shp) {
NR::Matrix cached_to_new = NR::identity();
int isometry = 0;
index 8670f61b29ac604cb47396de534f141825ec255a..02a195bb0cbfef4d1176a254c2ba558b6032c8c7 100644 (file)
}
void FilterComposite::set_arithmetic(double k1, double k2, double k3, double k4) {
- if (!isFinite(k1) || !isFinite(k2) || !isFinite(k3) || !isFinite(k4)) {
+ if (!IS_FINITE(k1) || !IS_FINITE(k2) || !IS_FINITE(k3) || !IS_FINITE(k4)) {
g_warning("Non-finite parameter for feComposite arithmetic operator");
return;
}
index 5ef43039475e1570cb7c745693270805e98d3d79..3113332476e40a62df6f523573d6e16a694ebaa0 100644 (file)
void FilterGaussian::set_deviation(double deviation)
{
- if(isFinite(deviation) && deviation >= 0) {
+ if(IS_FINITE(deviation) && deviation >= 0) {
_deviation_x = _deviation_y = deviation;
}
}
void FilterGaussian::set_deviation(double x, double y)
{
- if(isFinite(x) && x >= 0 && isFinite(y) && y >= 0) {
+ if(IS_FINITE(x) && x >= 0 && IS_FINITE(y) && y >= 0) {
_deviation_x = x;
_deviation_y = y;
}
diff --git a/src/draw-context.cpp b/src/draw-context.cpp
index 6e919d81d1a7f186aceca886dabd2c994b95b142..33c3898a735168100cbd9296580422efe038eda7 100644 (file)
--- a/src/draw-context.cpp
+++ b/src/draw-context.cpp
for (GSList *l = dc->white_curves; l != NULL; l = l->next) {
SPCurve *c;
c = (SPCurve*)l->data;
- g_return_if_fail( c->_end > 1 );
+ g_return_if_fail( c->get_length() > 1 );
if ( SP_CURVE_BPATH(c)->code == NR_MOVETO_OPEN ) {
- NArtBpath *s, *e;
+ NArtBpath const *s, *e;
SPDrawAnchor *a;
s = c->first_bpath();
e = c->last_bpath();
index 7f3c41c2ec94ebc0939b3a249d1ba2bdcb772ad2..c6140d17d08e30ce0ae78699df481b84b05b9788 100644 (file)
// so _gradually_ let go attraction to prevent jerks
target = (dc->hatch_spacing * speed + hatch_dist * (SPEED_NORMAL - speed))/SPEED_NORMAL;
}
- if (!isNaN(dot) && dot < -0.5) {// flip
+ if (!IS_NAN(dot) && dot < -0.5) {// flip
target = -target;
}
} else {
// Not drawing but spacing set: gray, center snapped, fixed radius
NR::Point c = (nearest + dc->hatch_spacing * hatch_unit_vector) * motion_to_curve.inverse();
- if (!isNaN(c[NR::X]) && !isNaN(c[NR::Y])) {
+ if (!IS_NAN(c[NR::X]) && !IS_NAN(c[NR::Y])) {
NR::Matrix const sm (NR::scale(dc->hatch_spacing, dc->hatch_spacing) * NR::translate(c));
sp_canvas_item_affine_absolute(dc->hatch_area, sm);
sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0x7f7f7fff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
item->updateRepr();
}
- abp = nr_artpath_affine(dc->accumulated->first_bpath(), sp_desktop_dt2root_affine(desktop));
+ abp = nr_artpath_affine(dc->accumulated->get_bpath(), sp_desktop_dt2root_affine(desktop));
str = sp_svg_write_path(abp);
g_assert( str != NULL );
g_free(abp);
dc->accumulated->reset(); /* Is this required ?? */
SPCurve *rev_cal2 = dc->cal2->create_reverse();
- g_assert(dc->cal1->_end > 1);
- g_assert(rev_cal2->_end > 1);
+ g_assert(dc->cal1->get_length() > 1);
+ g_assert(rev_cal2->get_length() > 1);
g_assert(SP_CURVE_SEGMENT(dc->cal1, 0)->code == NR_MOVETO_OPEN);
g_assert(SP_CURVE_SEGMENT(rev_cal2, 0)->code == NR_MOVETO_OPEN);
g_assert(SP_CURVE_SEGMENT(dc->cal1, 1)->code == NR_CURVETO);
g_assert(SP_CURVE_SEGMENT(rev_cal2, 1)->code == NR_CURVETO);
- g_assert(SP_CURVE_SEGMENT(dc->cal1, dc->cal1->_end-1)->code == NR_CURVETO);
- g_assert(SP_CURVE_SEGMENT(rev_cal2, rev_cal2->_end-1)->code == NR_CURVETO);
+ g_assert(SP_CURVE_SEGMENT(dc->cal1, dc->cal1->get_length()-1)->code == NR_CURVETO);
+ g_assert(SP_CURVE_SEGMENT(rev_cal2, rev_cal2->get_length()-1)->code == NR_CURVETO);
dc->accumulated->append(dc->cal1, FALSE);
- add_cap(dc->accumulated, SP_CURVE_SEGMENT(dc->cal1, dc->cal1->_end-1)->c(2), SP_CURVE_SEGMENT(dc->cal1, dc->cal1->_end-1)->c(3), SP_CURVE_SEGMENT(rev_cal2, 0)->c(3), SP_CURVE_SEGMENT(rev_cal2, 1)->c(1), dc->cap_rounding);
+ add_cap(dc->accumulated, SP_CURVE_SEGMENT(dc->cal1, dc->cal1->get_length()-1)->c(2), SP_CURVE_SEGMENT(dc->cal1, dc->cal1->get_length()-1)->c(3), SP_CURVE_SEGMENT(rev_cal2, 0)->c(3), SP_CURVE_SEGMENT(rev_cal2, 1)->c(1), dc->cap_rounding);
dc->accumulated->append(rev_cal2, TRUE);
- add_cap(dc->accumulated, SP_CURVE_SEGMENT(rev_cal2, rev_cal2->_end-1)->c(2), SP_CURVE_SEGMENT(rev_cal2, rev_cal2->_end-1)->c(3), SP_CURVE_SEGMENT(dc->cal1, 0)->c(3), SP_CURVE_SEGMENT(dc->cal1, 1)->c(1), dc->cap_rounding);
+ add_cap(dc->accumulated, SP_CURVE_SEGMENT(rev_cal2, rev_cal2->get_length()-1)->c(2), SP_CURVE_SEGMENT(rev_cal2, rev_cal2->get_length()-1)->c(3), SP_CURVE_SEGMENT(dc->cal1, 0)->c(3), SP_CURVE_SEGMENT(dc->cal1, 1)->c(1), dc->cap_rounding);
dc->accumulated->closepath();
#endif
/* Current calligraphic */
- if ( dc->cal1->_end == 0 || dc->cal2->_end == 0 ) {
+ if ( dc->cal1->get_length() == 0 || dc->cal2->get_length() == 0 ) {
/* dc->npoints > 0 */
/* g_print("calligraphics(1|2) reset\n"); */
dc->cal1->reset();
diff --git a/src/eraser-context.cpp b/src/eraser-context.cpp
index 88496b06554c157517467a9da66f607b869c206b..36cfb0d15a945406aa91f1195c9db9c50fd3f3cd 100644 (file)
--- a/src/eraser-context.cpp
+++ b/src/eraser-context.cpp
item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
item->updateRepr();
}
- abp = nr_artpath_affine(dc->accumulated->first_bpath(), sp_desktop_dt2root_affine(desktop));
+ abp = nr_artpath_affine(dc->accumulated->get_bpath(), sp_desktop_dt2root_affine(desktop));
str = sp_svg_write_path(abp);
g_assert( str != NULL );
g_free(abp);
dc->accumulated->reset(); /* Is this required ?? */
SPCurve *rev_cal2 = dc->cal2->create_reverse();
- g_assert(dc->cal1->_end > 1);
- g_assert(rev_cal2->_end > 1);
+ g_assert(dc->cal1->get_length() > 1);
+ g_assert(rev_cal2->get_length() > 1);
g_assert(SP_CURVE_SEGMENT(dc->cal1, 0)->code == NR_MOVETO_OPEN);
g_assert(SP_CURVE_SEGMENT(rev_cal2, 0)->code == NR_MOVETO_OPEN);
g_assert(SP_CURVE_SEGMENT(dc->cal1, 1)->code == NR_CURVETO);
g_assert(SP_CURVE_SEGMENT(rev_cal2, 1)->code == NR_CURVETO);
- g_assert(SP_CURVE_SEGMENT(dc->cal1, dc->cal1->_end-1)->code == NR_CURVETO);
- g_assert(SP_CURVE_SEGMENT(rev_cal2, rev_cal2->_end-1)->code == NR_CURVETO);
+ g_assert(SP_CURVE_SEGMENT(dc->cal1, dc->cal1->get_length()-1)->code == NR_CURVETO);
+ g_assert(SP_CURVE_SEGMENT(rev_cal2, rev_cal2->get_length()-1)->code == NR_CURVETO);
dc->accumulated->append(dc->cal1, FALSE);
- add_cap(dc->accumulated, SP_CURVE_SEGMENT(dc->cal1, dc->cal1->_end-1)->c(2), SP_CURVE_SEGMENT(dc->cal1, dc->cal1->_end-1)->c(3), SP_CURVE_SEGMENT(rev_cal2, 0)->c(3), SP_CURVE_SEGMENT(rev_cal2, 1)->c(1), dc->cap_rounding);
+ add_cap(dc->accumulated, SP_CURVE_SEGMENT(dc->cal1, dc->cal1->get_length()-1)->c(2), SP_CURVE_SEGMENT(dc->cal1, dc->cal1->get_length()-1)->c(3), SP_CURVE_SEGMENT(rev_cal2, 0)->c(3), SP_CURVE_SEGMENT(rev_cal2, 1)->c(1), dc->cap_rounding);
dc->accumulated->append(rev_cal2, TRUE);
- add_cap(dc->accumulated, SP_CURVE_SEGMENT(rev_cal2, rev_cal2->_end-1)->c(2), SP_CURVE_SEGMENT(rev_cal2, rev_cal2->_end-1)->c(3), SP_CURVE_SEGMENT(dc->cal1, 0)->c(3), SP_CURVE_SEGMENT(dc->cal1, 1)->c(1), dc->cap_rounding);
+ add_cap(dc->accumulated, SP_CURVE_SEGMENT(rev_cal2, rev_cal2->get_length()-1)->c(2), SP_CURVE_SEGMENT(rev_cal2, rev_cal2->get_length()-1)->c(3), SP_CURVE_SEGMENT(dc->cal1, 0)->c(3), SP_CURVE_SEGMENT(dc->cal1, 1)->c(1), dc->cap_rounding);
dc->accumulated->closepath();
#endif
/* Current eraser */
- if ( dc->cal1->_end == 0 || dc->cal2->_end == 0 ) {
+ if ( dc->cal1->get_length() == 0 || dc->cal2->get_length() == 0 ) {
/* dc->npoints > 0 */
/* g_print("erasers(1|2) reset\n"); */
dc->cal1->reset();
diff --git a/src/isnan.h b/src/isnan.h
index 608f9bb561fe3b1182c32cfccb7c34a432421327..57c221fce5381969ac86b5bf21dac7219dae0b68 100644 (file)
--- a/src/isnan.h
+++ b/src/isnan.h
*/
#if defined(__isnan)
-# define isNaN(_a) (__isnan(_a))
+# define IS_NAN(_a) (__isnan(_a))
#elif defined(__APPLE__) && __GNUC__ == 3
-# define isNaN(_a) (__isnan(_a)) /* MacOSX/Darwin definition < 10.4 */
+# define IS_NAN(_a) (__isnan(_a)) /* MacOSX/Darwin definition < 10.4 */
#elif defined(WIN32) || defined(_isnan)
-# define isNaN(_a) (_isnan(_a)) /* Win32 definition */
+# define IS_NAN(_a) (_isnan(_a)) /* Win32 definition */
#elif defined(isnan) || defined(__FreeBSD__) || defined(__osf__)
-# define isNaN(_a) (isnan(_a)) /* GNU definition */
+# define IS_NAN(_a) (isnan(_a)) /* GNU definition */
#elif defined (SOLARIS_2_8) && __GNUC__ == 3 && __GNUC_MINOR__ == 2
-# define isNaN(_a) (isnan(_a)) /* GNU definition */
+# define IS_NAN(_a) (isnan(_a)) /* GNU definition */
#else
-# define isNaN(_a) (std::isnan(_a))
+# define IS_NAN(_a) (std::isnan(_a))
#endif
/* If the above doesn't work, then try (a != a).
* Also, please report a bug as per http://www.inkscape.org/report_bugs.php,
#if defined(__isfinite)
-# define isFinite(_a) (__isfinite(_a))
+# define IS_FINITE(_a) (__isfinite(_a))
#elif defined(__APPLE__) && __GNUC__ == 3
-# define isFinite(_a) (__isfinite(_a)) /* MacOSX/Darwin definition < 10.4 */
+# define IS_FINITE(_a) (__isfinite(_a)) /* MacOSX/Darwin definition < 10.4 */
#elif defined(__sgi)
-# define isFinite(_a) (_isfinite(_a))
+# define IS_FINITE(_a) (_isfinite(_a))
#elif defined(isfinite)
-# define isFinite(_a) (isfinite(_a))
+# define IS_FINITE(_a) (isfinite(_a))
#elif defined(__osf__)
-# define isFinite(_a) (finite(_a) && !isNaN(_a))
+# define IS_FINITE(_a) (finite(_a) && !IS_NAN(_a))
#elif defined (SOLARIS_2_8) && __GNUC__ == 3 && __GNUC_MINOR__ == 2
#include <ieeefp.h>
-#define isFinite(_a) (finite(_a) && !isNaN(_a))
+#define IS_FINITE(_a) (finite(_a) && !IS_NAN(_a))
#else
-# define isFinite(_a) (std::isfinite(_a))
+# define IS_FINITE(_a) (std::isfinite(_a))
#endif
-/* If the above doesn't work, then try (finite(_a) && !isNaN(_a)) or (!isNaN((_a) - (_a))).
+/* If the above doesn't work, then try (finite(_a) && !IS_NAN(_a)) or (!IS_NAN((_a) - (_a))).
* Also, please report a bug as per http://www.inkscape.org/report_bugs.php,
* giving information about what platform and compiler version you're using.
*/
diff --git a/src/libcola/cola.cpp b/src/libcola/cola.cpp
index afad49eb2f59ba786375d60b5b386a4217e0e408..2119ea981d847de9aa758b1a972b2cd4b3e5b287 100644 (file)
--- a/src/libcola/cola.cpp
+++ b/src/libcola/cola.cpp
}
b[i] += degree * coords[i];
}
- assert(!isNaN(b[i]));
+ assert(!IS_NAN(b[i]));
}
if(constrainedLayout) {
setupDummyVars();
index 94844ca881c0bda3b8c95c308eb785234e0f2df2..237cb94af377fef8011cf04aeb126299dd945bb6 100644 (file)
solver = setupVPSC();
//cerr << "in gradient projection: n=" << n << endl;
for (i=0;i<n;i++) {
- assert(!isNaN(place[i]));
+ assert(!IS_NAN(place[i]));
assert(!isinf(place[i]));
vars[i]->desiredPosition=place[i];
}
// move to new unconstrained position
for (i=0; i<n; i++) {
place[i]-=alpha*g[i];
- assert(!isNaN(place[i]));
+ assert(!IS_NAN(place[i]));
assert(!isinf(place[i]));
vars[i]->desiredPosition=place[i];
}
index f5620c32bf94053a0878eec1ebdfba8ec97c818b..138812655077cf9dcd316e29f815f47f3a2ad9f5 100644 (file)
NR::Point const small_n3_4(-3.0 * small, 4.0 * small);
NR::Point const part_nan(3., nan);
- assert(isNaN(nan));
- assert(!isNaN(small));
+ assert(IS_NAN(nan));
+ assert(!IS_NAN(small));
UTEST_TEST("in_svg_plane") {
UTEST_ASSERT(in_svg_plane(p3n4));
index 6cd29bd6ab9431b73fa38534fa6aebd01e1fab76..ced9f978ca619f85804ad86753f797aee1220331 100644 (file)
small_n3_4( -3.0 * small, 4.0 * small ),
part_nan( 3., nan )
{
- setupValid &= isNaN(nan);
- setupValid &= !isNaN(small);
+ setupValid &= IS_NAN(nan);
+ setupValid &= !IS_NAN(small);
}
virtual ~InSvgPlaneTest() {}
index 89ac85b2b34832a1bdc25269d0e730595db868a9..e9dd9f5a625c93f01441cd1d04e6fc027328b568 100644 (file)
/** \file
* Contains functions to convert from NArtBpath to 2geom's Path
*
- * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Copyright (C) Johan Engelen 2007-2008 <j.b.c.engelen@utwente.nl>
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-
#include "libnr/n-art-bpath-2geom.h"
+
#include "svg/svg.h"
#include <glib.h>
#include <2geom/path.h>
#include <2geom/svg-path.h>
#include <2geom/svg-path-parser.h>
-#include <2geom/sbasis-to-bezier.h>
-
-//##########################################################
-
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <boost/format.hpp>
-
-static void curve_to_svgd(std::ostream & f, Geom::Curve const* c) {
- if(Geom::LineSegment const *line_segment = dynamic_cast<Geom::LineSegment const *>(c)) {
- f << boost::format("L %g,%g ") % (*line_segment)[1][0] % (*line_segment)[1][1];
- }
- else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const *>(c)) {
- f << boost::format("Q %g,%g %g,%g ") % (*quadratic_bezier)[1][0] % (*quadratic_bezier)[1][0]
- % (*quadratic_bezier)[2][0] % (*quadratic_bezier)[2][1];
- }
- else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const *>(c)) {
- f << boost::format("C %g,%g %g,%g %g,%g ")
- % (*cubic_bezier)[1][0] % (*cubic_bezier)[1][1]
- % (*cubic_bezier)[2][0] % (*cubic_bezier)[2][1]
- % (*cubic_bezier)[3][0] % (*cubic_bezier)[3][1];
- }
-// else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc *>(c)) {
-// //get at the innards and spit them out as svgd
-// }
- else {
- //this case handles sbasis as well as all other curve types
- Geom::Path sbasis_path = Geom::path_from_sbasis(c->toSBasis(), 0.1);
-
- //recurse to convert the new path resulting from the sbasis to svgd
- for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) {
- curve_to_svgd(f, &(*iter));
- }
- }
-}
-
-static void write_svgd(std::ostream & f, Geom::Path const &p) {
- if(f == NULL) {
- f << "ERRRRRRORRRRR";
- return;
- }
-
- f << boost::format("M %g,%g ") % p.initialPoint()[0] % p.initialPoint()[1];
-
- for(Geom::Path::const_iterator iter(p.begin()), end(p.end()); iter != end; ++iter) {
- curve_to_svgd(f, &(*iter));
- }
- if(p.closed())
- f << "Z ";
-}
-
-static void write_svgd(std::ostream & f, std::vector<Geom::Path> const &p) {
- std::vector<Geom::Path>::const_iterator it(p.begin());
- for(; it != p.end(); it++) {
- write_svgd(f, *it);
- }
-}
-
-std::vector<Geom::Path>
-SVGD_to_2GeomPath (char const *svgd)
-{
- std::vector<Geom::Path> pathv;
-
- try {
- pathv = Geom::parse_svg_path(svgd);
- }
- catch (std::runtime_error e) {
- g_warning("SVGPathParseError: %s", e.what());
- }
-
- return pathv;
-}
std::vector<Geom::Path>
g_warning("BPath_to_2GeomPath - empty path returned");
return pathv;
}
- pathv = SVGD_to_2GeomPath(svgpath);
+ pathv = sp_svg_read_pathv(svgpath);
g_free(svgpath);
return pathv;
}
-char *
-SVGD_from_2GeomPath(std::vector<Geom::Path> const & path)
-{
- std::ostringstream ss;
- write_svgd(ss, path);
- ss.flush();
- std::string str = ss.str();
- char * svgd = g_strdup(str.c_str());
- return svgd;
-}
-
NArtBpath *
BPath_from_2GeomPath(std::vector<Geom::Path> const & path)
{
- char * svgd = SVGD_from_2GeomPath(path);
+ char * svgd = sp_svg_write_path(path);
NArtBpath *bpath = sp_svg_read_path(svgd);
g_free(svgd);
return bpath;
index 21995656b88cf13b148661f8590b077f27586ef4..bf1592e2827a6fc63685bb93fa3cbfc00b9f9522 100644 (file)
#include <2geom/path.h>
#include <libnr/n-art-bpath.h>
-std::vector<Geom::Path> SVGD_to_2GeomPath (char const *svgd);
std::vector<Geom::Path> BPath_to_2GeomPath (NArtBpath const *bpath);
-char * SVGD_from_2GeomPath(std::vector<Geom::Path> const & path);
NArtBpath * BPath_from_2GeomPath (std::vector<Geom::Path> const & path);
index 7741e7782b8ff57aad00ec87bb891043c7cee912..5e60215696d921ec68bc6552199771f827dfd555 100644 (file)
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <2geom/matrix.h>
#include <libnr/nr-matrix.h>
-#include <2geom/d2.h>
#include <libnr/nr-rect.h>
+#include <libnr/nr-point.h>
+#include <2geom/matrix.h>
+#include <2geom/d2.h>
+#include <2geom/transforms.h>
+#include <2geom/point.h>
+
+inline Geom::Point to_2geom(NR::Point const & _pt) {
+ return Geom::Point(_pt[0], _pt[1]);
+}
+
+inline NR::Point from_2geom(Geom::Point const & _pt) {
+ return NR::Point(_pt[0], _pt[1]);
+}
inline Geom::Matrix to_2geom(NR::Matrix const & mat) {
Geom::Matrix mat2geom(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
return mat2geom;
}
+inline NR::Matrix from_2geom(Geom::Matrix const & mat) {
+ NR::Matrix mat2geom(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
+ return mat2geom;
+}
+
+inline Geom::Translate to_2geom(NR::translate const & mat) {
+ return Geom::Translate( mat.offset[0], mat.offset[1] );
+}
+
inline NR::Rect from_2geom(Geom::Rect const & rect2geom) {
NR::Rect rect(rect2geom.min(), rect2geom.max());
return rect;
index 11181436bd2d5106de47f5f5cb78a4f656f07914..00a704b596cfda1ac7cf5cf88fa29b4fc9cca061 100644 (file)
Point const part_nan(3., nan);
Point const inf_left(-inf, 5.0);
- assert(isNaN(nan));
- assert(!isNaN(small));
+ assert(IS_NAN(nan));
+ assert(!IS_NAN(small));
UTEST_TEST("L1") {
UTEST_ASSERT( NR::L1(p0) == 0.0 );
UTEST_ASSERT( NR::L1(small_left) == small );
UTEST_ASSERT( NR::L1(inf_left) == inf );
UTEST_ASSERT( NR::L1(small_n3_4) == 7.0 * small );
- UTEST_ASSERT(isNaN(NR::L1(part_nan)));
+ UTEST_ASSERT(IS_NAN(NR::L1(part_nan)));
}
UTEST_TEST("L2") {
UTEST_ASSERT( NR::L2(small_left) == small );
UTEST_ASSERT( NR::L2(inf_left) == inf );
UTEST_ASSERT( NR::L2(small_n3_4) == 5.0 * small );
- UTEST_ASSERT(isNaN(NR::L2(part_nan)));
+ UTEST_ASSERT(IS_NAN(NR::L2(part_nan)));
}
UTEST_TEST("LInfty") {
UTEST_ASSERT( NR::LInfty(small_left) == small );
UTEST_ASSERT( NR::LInfty(inf_left) == inf );
UTEST_ASSERT( NR::LInfty(small_n3_4) == 4.0 * small );
- UTEST_ASSERT(isNaN(NR::LInfty(part_nan)));
+ UTEST_ASSERT(IS_NAN(NR::LInfty(part_nan)));
}
UTEST_TEST("is_zero") {
index 509d9d2fab931d06eb4d37c00e02633b8e96e64d..a94ef1b7368d860d5f2c28cd3e315e961e9ee1e6 100644 (file)
part_nan( 3., nan ),
inf_left( -inf, 5.0 )
{
- TS_ASSERT( isNaN(nan) );
- TS_ASSERT( !isNaN(small) );
+ TS_ASSERT( IS_NAN(nan) );
+ TS_ASSERT( !IS_NAN(small) );
- setupValid &= isNaN(nan);
- setupValid &= !isNaN(small);
+ setupValid &= IS_NAN(nan);
+ setupValid &= !IS_NAN(small);
}
virtual ~NrPointFnsTest() {}
TS_ASSERT_EQUALS( NR::L1(small_left), small );
TS_ASSERT_EQUALS( NR::L1(inf_left), inf );
TS_ASSERT_EQUALS( NR::L1(small_n3_4), 7.0 * small );
- TS_ASSERT(isNaN(NR::L1(part_nan)));
+ TS_ASSERT(IS_NAN(NR::L1(part_nan)));
}
void testL2(void)
TS_ASSERT_EQUALS( NR::L2(small_left), small );
TS_ASSERT_EQUALS( NR::L2(inf_left), inf );
TS_ASSERT_EQUALS( NR::L2(small_n3_4), 5.0 * small );
- TS_ASSERT( isNaN(NR::L2(part_nan)) );
+ TS_ASSERT( IS_NAN(NR::L2(part_nan)) );
}
void testLInfty(void)
TS_ASSERT_EQUALS( NR::LInfty(small_left), small );
TS_ASSERT_EQUALS( NR::LInfty(inf_left), inf );
TS_ASSERT_EQUALS( NR::LInfty(small_n3_4), 4.0 * small );
- TS_ASSERT( isNaN(NR::LInfty(part_nan)) );
+ TS_ASSERT( IS_NAN(NR::LInfty(part_nan)) );
}
void testIsZero(void)
index a7b128bdbeaf597201dbcb7617984712600a8987..f73f71e3bb0388b912fcb8c4f8dce1b4fc87fb6e 100644 (file)
NR::Coord NR::LInfty(Point const &p) {
NR::Coord const a(fabs(p[0]));
NR::Coord const b(fabs(p[1]));
- return ( a < b || isNaN(b)
+ return ( a < b || IS_NAN(b)
? b
: a );
}
diff --git a/src/libnr/nr-types.cpp b/src/libnr/nr-types.cpp
index 98054a55177b32b0ebb9096fe27432c70b2ff445..a4e16d1278b636e7c5b641f48d596e0d49dd8d75 100644 (file)
--- a/src/libnr/nr-types.cpp
+++ b/src/libnr/nr-types.cpp
void NR::Point::normalize() {
double len = hypot(_pt[0], _pt[1]);
g_return_if_fail(len != 0);
- g_return_if_fail(!isNaN(len));
+ g_return_if_fail(!IS_NAN(len));
static double const inf = 1e400;
if(len != inf) {
*this /= len;
index 3574a2743b3ac1f39ee4698e8a7f9bae106f06d1..f3bc65eed858f5d7cdca322f8632277f72627808 100644 (file)
if (v->pos < u->pos) {
return false;
}
- if (isNaN(u->pos) != isNaN(v->pos)) {
- return isNaN(u->pos);
+ if (IS_NAN(u->pos) != IS_NAN(v->pos)) {
+ return IS_NAN(u->pos);
}
return u < v;
return 1;
} else if(ea->pos < eb->pos) {
return -1;
- } else if(isNaN(ea->pos) != isNaN(ea->pos)) {
+ } else if(IS_NAN(ea->pos) != IS_NAN(ea->pos)) {
/* See comment in CmpNodePos. */
- return ( isNaN(ea->pos)
+ return ( IS_NAN(ea->pos)
? -1
: 1 );
}
index 765d0a59bb2d21866dd48a27af8d63656d104b72..0749e4e93b250117d6dfe9c1ff757807408c7cb6 100644 (file)
void
Effect::doEffect (SPCurve * curve)
{
- NArtBpath *new_bpath = doEffect_nartbpath(curve->get_bpath());
+ NArtBpath const *bpath_in = curve->get_bpath();
- curve->set_bpath(new_bpath);
-}
+ std::vector<Geom::Path> result_pathv;
-NArtBpath *
-Effect::doEffect_nartbpath (NArtBpath const * path_in)
-{
try {
- std::vector<Geom::Path> orig_pathv = BPath_to_2GeomPath(path_in);
-
- std::vector<Geom::Path> result_pathv = doEffect_path(orig_pathv);
+ std::vector<Geom::Path> orig_pathv = BPath_to_2GeomPath(bpath_in);
- NArtBpath *new_bpath = BPath_from_2GeomPath(result_pathv);
-
- return new_bpath;
+ result_pathv = doEffect_path(orig_pathv);
}
catch (std::exception & e) {
g_warning("Exception during LPE %s execution. \n %s", getName().c_str(), e.what());
SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE,
_("An exception occurred during execution of the Path Effect.") );
-
- NArtBpath *path_out;
-
- unsigned ret = 0;
- while ( path_in[ret].code != NR_END ) {
- ++ret;
- }
- unsigned len = ++ret;
-
- path_out = g_new(NArtBpath, len);
- memcpy(path_out, path_in, len * sizeof(NArtBpath));
- return path_out;
}
+
+ curve->set_pathv(result_pathv);
}
std::vector<Geom::Path>
index c04f248e331a3716162a2859357e22001b75a032..a8cb525b8f500b915fa73f1d3ab05826bbac2d8f 100644 (file)
// the order in which they appear is the order in which they are
// called by this base class. (i.e. doEffect(SPCurve * curve) defaults to calling
// doEffect(std::vector<Geom::Path> )
- virtual NArtBpath *
- doEffect_nartbpath (NArtBpath const * path_in) __attribute__ ((deprecated));
virtual std::vector<Geom::Path>
doEffect_path (std::vector<Geom::Path> const & path_in);
virtual Geom::Piecewise<Geom::D2<Geom::SBasis> >
index 9cf9f2f26fe16311555bf41fa3ff815c7bb7fafb..814a381af6ede23ae2c1914369576d9786d7608b 100644 (file)
#include "sp-item.h"
#include "sp-path.h"
-#include "libnr/n-art-bpath-2geom.h"
+#include "svg/svg.h"
#include "xml/repr.h"
#include <2geom/path.h>
// calculate bounding box: (isn't there a simpler way?)
Piecewise<D2<SBasis> > pwd2;
- std::vector<Geom::Path> temppath = SVGD_to_2GeomPath( SP_OBJECT_REPR(item)->attribute("inkscape:original-d"));
+ std::vector<Geom::Path> temppath = sp_svg_read_pathv( SP_OBJECT_REPR(item)->attribute("inkscape:original-d"));
for (unsigned int i=0; i < temppath.size(); i++) {
pwd2.concat( temppath[i].toPwSb() );
}
index 521c2d7c96e7e4dcedd676c8bb33dda43044a774..a68888105c70314a3c15292d24de267c196afcd5 100644 (file)
// Choose to implement one of the doEffect functions. You can delete or comment out the others.
// virtual void doEffect (SPCurve * curve);
-// virtual NArtBpath * doEffect_nartbpath (NArtBpath * path_in);
virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & input_path);
// virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);
diff --git a/src/live_effects/lpe-test-doEffect-stack.cpp b/src/live_effects/lpe-test-doEffect-stack.cpp
index f3fb346fe1ebee095cb3099ccebea7d37b72be18..3b578b2c6c4096c8aca20f16e69cb9232929c087 100644 (file)
}
}
-NArtBpath *
-LPEdoEffectStackTest::doEffect_nartbpath (NArtBpath const * path_in)
-{
- if (step >= 2) {
- return Effect::doEffect_nartbpath(path_in);
- } else {
- // return here
- NArtBpath *path_out;
-
- unsigned ret = 0;
- while ( path_in[ret].code != NR_END ) {
- ++ret;
- }
- unsigned len = ++ret;
-
- path_out = g_new(NArtBpath, len);
- memcpy(path_out, path_in, len * sizeof(NArtBpath));
- return path_out;
- }
-}
-
std::vector<Geom::Path>
LPEdoEffectStackTest::doEffect_path (std::vector<Geom::Path> const & path_in)
{
- if (step >= 3) {
+ if (step >= 2) {
return Effect::doEffect_path(path_in);
} else {
// return here
diff --git a/src/live_effects/lpe-test-doEffect-stack.h b/src/live_effects/lpe-test-doEffect-stack.h
index cf2d480b1f7fa7c9f9f25a6ebff7ed792c2cc1a2..7c22a3b37cddcda79b8aabab9f61b762d6500cc4 100644 (file)
virtual ~LPEdoEffectStackTest();
virtual void doEffect (SPCurve * curve);
- virtual NArtBpath * doEffect_nartbpath (NArtBpath const * path_in);
virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in);
virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
index ee09221ed5668c28c07a1545f630eb200dcb9dd0..114dd726306165610eec3397a3334457998927a7 100644 (file)
// set the bend path to run horizontally in the middle of the bounding box of the original path
Piecewise<D2<SBasis> > pwd2;
- std::vector<Geom::Path> temppath = SVGD_to_2GeomPath( SP_OBJECT_REPR(item)->attribute("inkscape:original-d"));
+ std::vector<Geom::Path> temppath = sp_svg_read_pathv( SP_OBJECT_REPR(item)->attribute("inkscape:original-d"));
for (unsigned int i=0; i < temppath.size(); i++) {
pwd2.concat( temppath[i].toPwSb() );
}
index d3afec3af4ffd625c3ac42a03a05ae573de66a00..511ce46a23edfd8fa8f17764c9cc978973f10ea7 100644 (file)
*/
#include <glibmm/ustring.h>
-#include <2geom/point.h>
-#include <2geom/path.h>
+#include <2geom/forward.h>
struct SPDesktop;
struct SPItem;
index 376e61beefbe94b618e2b6779e89ee955c2ad970..759e9f788c148083a306a1d9c54939ef3b0a1c98 100644 (file)
} catch (Inkscape::BadURIException &e) {
g_warning("%s", e.what());
ref.detach();
- _pathvector = SVGD_to_2GeomPath(defvalue);
+ _pathvector = sp_svg_read_pathv(defvalue);
}
} else {
- _pathvector = SVGD_to_2GeomPath(strvalue);
+ _pathvector = sp_svg_read_pathv(strvalue);
}
signal_path_changed.emit();
if (href) {
return href;
} else {
- gchar * svgd = SVGD_from_2GeomPath( _pathvector );
+ gchar * svgd = sp_svg_write_path( _pathvector );
return svgd;
}
}
@@ -233,7 +233,7 @@ PathParam::param_set_and_write_new_value (Geom::Piecewise<Geom::D2<Geom::SBasis>
{
remove_link();
_pathvector = Geom::path_from_piecewise(newpath, LPE_CONVERSION_TOLERANCE);
- gchar * svgd = SVGD_from_2GeomPath( _pathvector );
+ gchar * svgd = sp_svg_write_path( _pathvector );
param_write_to_repr(svgd);
g_free(svgd);
// force value upon pwd2 and don't recalculate.
@@ -248,7 +248,7 @@ PathParam::param_set_and_write_new_value (std::vector<Geom::Path> const & newpat
_pathvector = newpath;
must_recalculate_pwd2 = true;
- gchar * svgd = SVGD_from_2GeomPath( _pathvector );
+ gchar * svgd = sp_svg_write_path( _pathvector );
param_write_to_repr(svgd);
g_free(svgd);
}
if (curve == NULL) {
// curve invalid, set default value
- _pathvector = SVGD_to_2GeomPath(defvalue);
+ _pathvector = sp_svg_read_pathv(defvalue);
} else {
_pathvector = BPath_to_2GeomPath(SP_CURVE_BPATH(curve));
curve->unref();
diff --git a/src/nodepath.cpp b/src/nodepath.cpp
index e827f9fb07dafa522d5c39433d58eefd700fa48c..249721cfaba134849578428dc4ef98e323d1b823 100644 (file)
--- a/src/nodepath.cpp
+++ b/src/nodepath.cpp
/* Creation from object */
-static NArtBpath *subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath *b, gchar const *t);
+static NArtBpath const * subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath const *b, gchar const *t);
static gchar *parse_nodetypes(gchar const *types, gint length);
/* Object updating */
if (curve == NULL)
return NULL;
- NArtBpath *bpath = curve->first_bpath();
- gint length = curve->_end;
+ NArtBpath const *bpath = curve->get_bpath();
+ gint length = curve->get_length();
if (length == 0) {
curve->unref();
return NULL; // prevent crash for one-node paths
gchar *typestr = parse_nodetypes(nodetypes, length);
// create the subpath(s) from the bpath
- NArtBpath *b = bpath;
+ NArtBpath const *b = bpath;
while (b->code != NR_END) {
b = subpath_from_bpath(np, b, typestr + (b - bpath));
}
* \param t The node type.
* \todo Fixme: t should be a proper type, rather than gchar
*/
-static NArtBpath *subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath *b, gchar const *t)
+static NArtBpath const * subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath const *b, gchar const *t)
{
NR::Point ppos, pos, npos;
diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp
index 996ae3fd5203afc8521730305ee0fb363620766f..05ea6c1300fb77dd97ae0e776db29b16de6d771b 100644 (file)
--- a/src/path-chemistry.cpp
+++ b/src/path-chemistry.cpp
// Prevent empty paths from being added to the document
// otherwise we end up with zomby markup in the SVG file
- if(curve->_end <= 0)
+ if(curve->get_length() <= 0)
{
curve->unref();
return NULL;
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index 8d7ac08192fc343a203bb947228379d5002394da..7dc489540bb4e60eec6e298e562e34c8cc71151f 100644 (file)
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
sp_canvas_item_hide (pc->cl1);
}
- NArtBpath *const bpath = pc->green_curve->last_bpath();
+ NArtBpath const * bpath = pc->green_curve->last_bpath();
if (bpath) {
if (bpath->code == NR_CURVETO && NR::Point(bpath->x2, bpath->y2) != pc->p[0]) {
SP_CTRL(pc->c0)->moveto(NR::Point(bpath->x2, bpath->y2));
return;
// green
- NArtBpath *const bpath = pc->green_curve->last_bpath();
+ NArtBpath const * bpath = pc->green_curve->last_bpath();
if (bpath) {
- if (bpath->code == NR_CURVETO) {
- bpath->x2 += x;
- bpath->y2 += y;
- }
- bpath->x3 += x;
- bpath->y3 += y;
+ pc->green_curve->last_point_additive_move( Geom::Point(x,y) );
} else {
// start anchor too
if (pc->green_anchor) {
return;
// red
- NArtBpath *const bpath = pc->green_curve->last_bpath();
+ NArtBpath const * bpath = pc->green_curve->last_bpath();
if (bpath && bpath->code == NR_CURVETO) {
pc->p[1] = pc->p[0] + (NR::Point(bpath->x3, bpath->y3) - NR::Point(bpath->x2, bpath->y2));
} else {
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index e25be12af91eb9fcf517918433bdf31693a7c212..e7a42ab7f2027d3aae65c624e46ce3632941f6ef 100644 (file)
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
if (write) {
Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape);
if ( shape->curve != NULL ) {
- NArtBpath *abp = shape->curve->first_bpath();
+ NArtBpath const *abp = shape->curve->get_bpath();
if (abp) {
gchar *str = sp_svg_write_path(abp);
repr->setAttribute("d", str);
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 20efd8fe72c76e4c370d84f51eb9e015b1ab8bdb..347f50491454b596e88d1077f4b6e86bb720621e 100644 (file)
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
Inkscape::XML::Node *repr = SP_OBJECT_REPR(subitem);
- NArtBpath *abp = c->first_bpath();
+ NArtBpath const *abp = c->first_bpath();
if (abp) {
gchar *str = sp_svg_write_path(abp);
repr->setAttribute("d", str);
diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp
index 3f52232cb52d78f1cca3c5aced43c7a5732ceb05..9851e146af4b119c9d1d1cc69479f5c29d76849c 100644 (file)
--- a/src/sp-namedview.cpp
+++ b/src/sp-namedview.cpp
}
// restore zoom and view
- if (nv->zoom != 0 && nv->zoom != HUGE_VAL && !isNaN(nv->zoom)
- && nv->cx != HUGE_VAL && !isNaN(nv->cx)
- && nv->cy != HUGE_VAL && !isNaN(nv->cy)) {
+ if (nv->zoom != 0 && nv->zoom != HUGE_VAL && !IS_NAN(nv->zoom)
+ && nv->cx != HUGE_VAL && !IS_NAN(nv->cx)
+ && nv->cy != HUGE_VAL && !IS_NAN(nv->cy)) {
desktop->zoom_absolute(nv->cx, nv->cy, nv->zoom);
} else if (sp_desktop_document(desktop)) { // document without saved zoom, zoom to its page
desktop->zoom_page();
diff --git a/src/sp-path.cpp b/src/sp-path.cpp
index 511e1efc5584ed6cb346592c744b88d4f6f49290..81d05ebef05a3b904c843ea0f690d43428417ac9 100644 (file)
--- a/src/sp-path.cpp
+++ b/src/sp-path.cpp
sp_nodes_in_path(SPPath *path)
{
SPCurve *curve = SP_SHAPE(path)->curve;
- if (!curve) return 0;
- gint r = curve->_end;
- gint i = curve->_length - 1;
- if (i > r) i = r; // sometimes after switching from node editor length is wrong, e.g. f6 - draw - f2 - tab - f1, this fixes it
- for (; i >= 0; i --)
- if (SP_CURVE_BPATH(curve)[i].code == NR_MOVETO)
- r --;
- return r;
+ if (!curve)
+ return 0;
+ return curve->nodes_in_path();
}
static gchar *
}
if ( shape->curve != NULL ) {
- NArtBpath *abp = shape->curve->first_bpath();
+ NArtBpath const * abp = shape->curve->get_bpath();
if (abp) {
gchar *str = sp_svg_write_path(abp);
repr->setAttribute("d", str);
SPPath *path = (SPPath *) object;
if ( path->original_curve != NULL ) {
- NArtBpath *abp = path->original_curve->first_bpath();
+ NArtBpath const * abp = path->original_curve->get_bpath();
if (abp) {
gchar *str = sp_svg_write_path(abp);
repr->setAttribute("inkscape:original-d", str);
// could also do SP_OBJECT(shape)->updateRepr(); but only the d attribute needs updating.
Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape);
if ( shape->curve != NULL ) {
- NArtBpath *abp = shape->curve->first_bpath();
+ NArtBpath const *abp = shape->curve->get_bpath();
if (abp) {
gchar *str = sp_svg_write_path(abp);
repr->setAttribute("d", str);
diff --git a/src/sp-polygon.cpp b/src/sp-polygon.cpp
index 6012e065d4a11c492c95b4f876c173c3d22820ad..d90f829b943e292c53a8c1ae636fc5ac73197bf6 100644 (file)
--- a/src/sp-polygon.cpp
+++ b/src/sp-polygon.cpp
static void sp_polygon_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
static Inkscape::XML::Node *sp_polygon_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
-static void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value);
static gchar *sp_polygon_description(SPItem *item);
@@ -128,7 +127,7 @@ static Inkscape::XML::Node *sp_polygon_write(SPObject *object, Inkscape::XML::No
}
/* We can safely write points here, because all subclasses require it too (Lauris) */
- NArtBpath *abp = shape->curve->first_bpath();
+ NArtBpath const * abp = shape->curve->get_bpath();
gchar *str = sp_svg_write_polygon(abp);
repr->setAttribute("points", str);
g_free(str);
}
-static void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value)
+void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value)
{
SPPolygon *polygon = SP_POLYGON(object);
diff --git a/src/sp-polygon.h b/src/sp-polygon.h
index 0da720fc2111bf43e1d83108e98463b652182ca8..3ea91be761cca57a7a7f7b18d43ee45e5597f968 100644 (file)
--- a/src/sp-polygon.h
+++ b/src/sp-polygon.h
GType sp_polygon_get_type (void);
+// made 'public' so that SPCurve can set it as friend:
+void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value);
+
#endif
diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp
index 991381bda87a3b6ae5a54ad72fdea7cb449ff426..99e4ed485940b0cca5bf586ca3f388e2efaf8d2c 100644 (file)
--- a/src/sp-shape.cpp
+++ b/src/sp-shape.cpp
sp_shape_marker_get_transform(SPShape const *shape, NArtBpath const *bp)
{
g_return_val_if_fail(( is_moveto(SP_CURVE_BPATH(shape->curve)[0].code)
- && ( 0 < shape->curve->_end )
- && ( SP_CURVE_BPATH(shape->curve)[shape->curve->_end].code == NR_END ) ),
+ && ( 0 < shape->curve->get_length() )
+ && ( SP_CURVE_BPATH(shape->curve)[shape->curve->get_length()].code == NR_END ) ),
NR::Matrix(NR::translate(bp->c(3))));
double const angle1 = incoming_tangent(bp);
double const angle2 = outgoing_tangent(bp);
diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp
index 60f2bbc92efc24708f006450d2318ef8ce6796f1..7351ff61fdd71950501e97855fe238a8965d7852 100644 (file)
--- a/src/sp-spiral.cpp
+++ b/src/sp-spiral.cpp
if (write) {
Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape);
if ( shape->curve != NULL ) {
- NArtBpath *abp = shape->curve->first_bpath();
+ NArtBpath const * abp = shape->curve->get_bpath();
if (abp) {
gchar *str = sp_svg_write_path(abp);
repr->setAttribute("d", str);
diff --git a/src/sp-star.cpp b/src/sp-star.cpp
index 4c5f9623b0f525e917c33375a0a146c076f30fd6..6543a98660040dea094e7a27d9bc5585b1c161a7 100644 (file)
--- a/src/sp-star.cpp
+++ b/src/sp-star.cpp
if (write) {
Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape);
if ( shape->curve != NULL ) {
- NArtBpath *abp = shape->curve->first_bpath();
+ NArtBpath const * abp = shape->curve->get_bpath();
if (abp) {
gchar *str = sp_svg_write_path(abp);
repr->setAttribute("d", str);
diff --git a/src/style.cpp b/src/style.cpp
index fd6b17892fe718c2767f048285c8510900020947..a67b86167221ecf6ef0e562a228906819e6dc103 100644 (file)
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -1672,7 +1672,7 @@ sp_style_merge_length_prop_from_dying_parent(LengthT &child, LengthT const &pare
* fixme: Have separate ex ratio parameter.
* Get x height from libnrtype or pango.
*/
- if (!isFinite(child.value)) {
+ if (!IS_FINITE(child.value)) {
child.value = child.computed;
child.unit = SP_CSS_UNIT_NONE;
}
diff --git a/src/svg/svg-path.cpp b/src/svg/svg-path.cpp
index bd0d4a4f5ff1dbb7c7af872f8ff6779a4ec20dba..d610b9212eb0a4baf1ed46b43bb5489614e3c241 100644 (file)
--- a/src/svg/svg-path.cpp
+++ b/src/svg/svg-path.cpp
#include "gnome-canvas-bpath-util.h"
#include "svg/path-string.h"
+#include <2geom/pathvector.h>
+#include <2geom/path.h>
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/svg-path.h>
+#include <2geom/svg-path-parser.h>
/* This module parses an SVG path element into an RsvgBpathDef.
return bpath;
}
+Geom::PathVector sp_svg_read_pathv(char const * str)
+{
+ std::vector<Geom::Path> pathv;
+
+ // TODO: enable this exception catching. don't catch now to better see when things go wrong
+// try {
+ pathv = Geom::parse_svg_path(str);
+// }
+// catch (std::runtime_error e) {
+// g_warning("SVGPathParseError: %s", e.what());
+// }
+
+ return pathv;
+}
+
gchar *sp_svg_write_path(NArtBpath const *bpath)
{
bool closed=false;
return g_strdup(str.c_str());
}
+static void sp_svg_write_curve(Inkscape::SVG::PathString & str, Geom::Curve const * c) {
+ if(Geom::LineSegment const *line_segment = dynamic_cast<Geom::LineSegment const *>(c)) {
+ str.lineTo( (*line_segment)[1][0], (*line_segment)[1][1] );
+ }
+ else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const *>(c)) {
+ str.quadTo( (*quadratic_bezier)[1][0], (*quadratic_bezier)[1][0],
+ (*quadratic_bezier)[2][0], (*quadratic_bezier)[2][1] );
+ }
+ else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const *>(c)) {
+ str.curveTo( (*cubic_bezier)[1][0], (*cubic_bezier)[1][1],
+ (*cubic_bezier)[2][0], (*cubic_bezier)[2][1],
+ (*cubic_bezier)[3][0], (*cubic_bezier)[3][1] );
+ }
+ else if(Geom::EllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::EllipticalArc const *>(c)) {
+ str.arcTo( svg_elliptical_arc->ray(0), svg_elliptical_arc->ray(1),
+ svg_elliptical_arc->rotation_angle(),
+ svg_elliptical_arc->large_arc_flag(), svg_elliptical_arc->sweep_flag(),
+ svg_elliptical_arc->finalPoint() );
+ } else {
+ //this case handles sbasis as well as all other curve types
+ Geom::Path sbasis_path = Geom::path_from_sbasis(c->toSBasis(), 0.1);
+
+ //recurse to convert the new path resulting from the sbasis to svgd
+ for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) {
+ sp_svg_write_curve(str, &(*iter));
+ }
+ }
+}
+
+gchar * sp_svg_write_path(Geom::PathVector const &p) {
+ Inkscape::SVG::PathString str;
+
+ for(Geom::PathVector::const_iterator pit = p.begin(); pit != p.end(); pit++) {
+ str.moveTo( pit->initialPoint()[0], pit->initialPoint()[1] );
+
+ for(Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); cit++) {
+ sp_svg_write_curve(str, &(*cit));
+ }
+
+ if (pit->closed()) {
+ str.closePath();
+ }
+ }
+
+ return g_strdup(str.c_str());
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/svg/svg.h b/src/svg/svg.h
index 4b2dea9940e975a3474f2cc4b6a32fcf5efff838..0e5b4d5d5ee57df4b0ee30dfdbe1f31933f665c9 100644 (file)
--- a/src/svg/svg.h
+++ b/src/svg/svg.h
#include "svg/svg-length.h"
#include "libnr/nr-forward.h"
+#include <2geom/forward.h>
/* Generic */
/* NB! As paths can be long, we use here dynamic string */
NArtBpath * sp_svg_read_path (const char * str);
-char * sp_svg_write_path (const NArtBpath * bpath);
-
+Geom::PathVector sp_svg_read_pathv (char const * str);
+gchar * sp_svg_write_path (const NArtBpath * bpath);
+gchar * sp_svg_write_path (Geom::PathVector const &p);
#endif
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index 2d38f5ccd227909ed44b289618749aa962f99972..227d57a964f240a2b141ce9e7dab20d4e4fbec70 100644 (file)
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
void ClipboardManagerImpl::copyPathParameter(Inkscape::LivePathEffect::PathParam *pp)
{
if ( pp == NULL ) return;
- gchar *svgd = SVGD_from_2GeomPath( pp->get_pathvector() );
+ gchar *svgd = sp_svg_write_path( pp->get_pathvector() );
if ( svgd == NULL || *svgd == '\0' ) return;
_discardInternalClipboard();