diff options
| author | jtx <javier.arraiza@marker.es> | 2013-02-19 16:48:44 +0000 |
|---|---|---|
| committer | jtx <javier.arraiza@marker.es> | 2013-02-19 16:48:44 +0000 |
| commit | e77f8af15850e964f5d69c84b0f45a66ae229d94 (patch) | |
| tree | 66eeb27d793d6874bc51e7e2601b1b41fa6aae81 /src | |
| parent | Fix cusp continuous? path close broken (diff) | |
| parent | Mayor refactor (diff) | |
| download | inkscape-e77f8af15850e964f5d69c84b0f45a66ae229d94.tar.gz inkscape-e77f8af15850e964f5d69c84b0f45a66ae229d94.zip | |
Refactor problem cusp nodes
(bzr r11950.3.2)
Diffstat (limited to 'src')
28 files changed, 309 insertions, 214 deletions
diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 5fd38a473..51a6dd89b 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -779,7 +779,7 @@ _wr.setUpdating (true); _rsu_ox->setProgrammatically = false; _rsu_oy->setProgrammatically = false; _rsu_sx->setProgrammatically = false; - _rsu_sx->setProgrammatically = false; + _rsu_sy->setProgrammatically = false; return table; } diff --git a/src/dom/io/bufferstream.cpp b/src/dom/io/bufferstream.cpp index 7baab4814..3389bd80e 100644 --- a/src/dom/io/bufferstream.cpp +++ b/src/dom/io/bufferstream.cpp @@ -146,7 +146,7 @@ void BufferOutputStream::flush() /** * Writes the specified byte to this output stream. */ -int BufferOutputStream::put(XMLCh ch) +int BufferOutputStream::put(gunichar ch) { if (closed) return -1; diff --git a/src/dom/io/bufferstream.h b/src/dom/io/bufferstream.h index 9a36b30e2..0ac06b362 100644 --- a/src/dom/io/bufferstream.h +++ b/src/dom/io/bufferstream.h @@ -102,7 +102,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); virtual std::vector<unsigned char> &getBuffer() { return buffer; } diff --git a/src/dom/io/domstream.cpp b/src/dom/io/domstream.cpp index de221f855..21d09662a 100644 --- a/src/dom/io/domstream.cpp +++ b/src/dom/io/domstream.cpp @@ -510,7 +510,7 @@ void BasicOutputStream::flush() /** * Writes the specified byte to this output stream. */ -int BasicOutputStream::put(XMLCh ch) +int BasicOutputStream::put(gunichar ch) { if (closed) return -1; @@ -886,7 +886,7 @@ void BasicWriter::flush() /** * Writes the specified byte to this output writer. */ -int BasicWriter::put(XMLCh ch) +int BasicWriter::put(gunichar ch) { if (destination && destination->put(ch)>=0) return 1; @@ -1079,7 +1079,7 @@ void OutputStreamWriter::flush() * Overloaded to redirect the output chars from the next Writer * in the chain to an OutputStream instead. */ -int OutputStreamWriter::put(XMLCh ch) +int OutputStreamWriter::put(gunichar ch) { //Do we need conversions here? int intCh = (int) ch; @@ -1133,11 +1133,10 @@ void StdWriter::flush() * Overloaded to redirect the output chars from the next Writer * in the chain to an OutputStream instead. */ -int StdWriter::put(XMLCh ch) +int StdWriter::put(gunichar ch) { //Do we need conversions here? - int intCh = (int) ch; - if (outputStream->put(intCh) < 0) + if (outputStream->put(ch) < 0) return -1; return 1; } diff --git a/src/dom/io/domstream.h b/src/dom/io/domstream.h index 1a93e73b2..925e52bfe 100644 --- a/src/dom/io/domstream.h +++ b/src/dom/io/domstream.h @@ -218,7 +218,7 @@ public: /** * Send one byte to the destination stream. */ - virtual int put(XMLCh ch) = 0; + virtual int put(gunichar ch) = 0; }; // class OutputStream @@ -241,7 +241,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); protected: @@ -267,7 +267,7 @@ public: void flush() { } - int put(XMLCh ch) + int put(gunichar ch) { putchar(ch); return 1; } }; @@ -492,7 +492,7 @@ public: virtual void flush() = 0; - virtual int put(XMLCh ch) = 0; + virtual int put(gunichar ch) = 0; /* Formatted output */ virtual Writer& printf(const DOMString &fmt, ...) = 0; @@ -542,7 +542,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); @@ -635,7 +635,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); private: @@ -663,7 +663,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); private: diff --git a/src/dom/io/stringstream.cpp b/src/dom/io/stringstream.cpp index c6e47045e..ca058a575 100644 --- a/src/dom/io/stringstream.cpp +++ b/src/dom/io/stringstream.cpp @@ -140,7 +140,7 @@ void StringOutputStream::flush() /** * Writes the specified byte to this output stream. */ -int StringOutputStream::put(XMLCh ch) +int StringOutputStream::put(gunichar ch) { buffer.push_back(ch); return 1; diff --git a/src/dom/io/stringstream.h b/src/dom/io/stringstream.h index f6ed89e65..9ba24fc26 100644 --- a/src/dom/io/stringstream.h +++ b/src/dom/io/stringstream.h @@ -100,7 +100,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); virtual DOMString &getString() { return buffer; } diff --git a/src/dom/io/uristream.cpp b/src/dom/io/uristream.cpp index 09b0ac361..68a14a166 100644 --- a/src/dom/io/uristream.cpp +++ b/src/dom/io/uristream.cpp @@ -372,7 +372,7 @@ void UriOutputStream::flush() throw(StreamException) /** * Writes the specified byte to this output stream. */ -int UriOutputStream::put(XMLCh ch) throw(StreamException) +int UriOutputStream::put(gunichar ch) throw(StreamException) { if (closed) return -1; @@ -440,10 +440,9 @@ void UriWriter::flush() throw(StreamException) /** * */ -int UriWriter::put(XMLCh ch) throw(StreamException) +int UriWriter::put(gunichar ch) throw(StreamException) { - int ich = (int)ch; - if (outputStream->put(ich) < 0) + if (outputStream->put(ch) < 0) return -1; return 1; } diff --git a/src/dom/io/uristream.h b/src/dom/io/uristream.h index 8d60468a5..2a659d030 100644 --- a/src/dom/io/uristream.h +++ b/src/dom/io/uristream.h @@ -143,7 +143,7 @@ public: virtual void flush() throw(StreamException); - virtual int put(XMLCh ch) throw(StreamException); + virtual int put(gunichar ch) throw(StreamException); private: @@ -181,7 +181,7 @@ public: virtual void flush() throw(StreamException); - virtual int put(XMLCh ch) throw(StreamException); + virtual int put(gunichar ch) throw(StreamException); private: diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index d3aeace55..4af778e04 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -956,7 +956,14 @@ int Script::execute (const std::list<std::string> &in_command, // assemble the rest of argv std::copy(in_params.begin(), in_params.end(), std::back_inserter(argv)); if (!filein.empty()) { - argv.push_back(filein); + if(Glib::path_is_absolute(filein)) + argv.push_back(filein); + else { + std::vector<std::string> buildargs; + buildargs.push_back(Glib::get_current_dir()); + buildargs.push_back(filein); + argv.push_back(Glib::build_filename(buildargs)); + } } int stdout_pipe, stderr_pipe; diff --git a/src/extension/system.cpp b/src/extension/system.cpp index 7fb6e1591..a9ca5c456 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -21,6 +21,7 @@ #endif #include <interface.h> +#include <unistd.h> #include "system.h" #include "preferences.h" @@ -68,34 +69,6 @@ static Extension *build_from_reprdoc(Inkscape::XML::Document *doc, Implementatio */ SPDocument *open(Extension *key, gchar const *filename) { - // Convert to absolute pathname to tolerate chdir(). - bool relpath = (filename[0] != '/'); -#ifdef WIN32 - relpath &= (filename[0] != '\\') && !(isalpha(filename[0]) && (filename[1] == ':')); -#endif - - // Do not consider an URI as a relative path. - if (relpath) { - gchar const * cp = filename; - - while (isalpha(*cp) || isdigit(*cp) || *cp == '+' || *cp == '-' || *cp == '.') - cp++; - - relpath = *cp != ':' || cp[1] != '/' || cp[2] != '/'; - } - - if (relpath) { - gchar * curdir = NULL; -#ifndef WIN32 - curdir = getcwd(NULL, 0); -#else - curdir = _getcwd(NULL, 0); -#endif - - filename = g_build_filename(curdir, filename, NULL); - free(curdir); - } - Input *imod = NULL; if (key == NULL) { @@ -137,9 +110,6 @@ SPDocument *open(Extension *key, gchar const *filename) } if (!imod->prefs(filename)) { - if (relpath){ - free((void *) filename); - } return NULL; } @@ -162,9 +132,6 @@ SPDocument *open(Extension *key, gchar const *filename) imod->set_gui(true); } - if (relpath){ - free((void *) filename); - } return doc; } diff --git a/src/io/base64stream.cpp b/src/io/base64stream.cpp index 667487c35..42a6ba1e4 100644 --- a/src/io/base64stream.cpp +++ b/src/io/base64stream.cpp @@ -290,7 +290,7 @@ void Base64OutputStream::putCh(int ch) /** * Writes the specified byte to this output stream. */ -void Base64OutputStream::put(int ch) +void Base64OutputStream::put(gunichar ch) { if (closed) { diff --git a/src/io/base64stream.h b/src/io/base64stream.h index 554a92fe2..836939130 100644 --- a/src/io/base64stream.h +++ b/src/io/base64stream.h @@ -88,7 +88,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual void put(gunichar ch); /** * Sets the maximum line length for base64 output. If diff --git a/src/io/gzipstream.cpp b/src/io/gzipstream.cpp index f9e30de91..071179b48 100644 --- a/src/io/gzipstream.cpp +++ b/src/io/gzipstream.cpp @@ -433,7 +433,7 @@ void GzipOutputStream::flush() /** * Writes the specified byte to this output stream. */ -void GzipOutputStream::put(int ch) +void GzipOutputStream::put(gunichar ch) { if (closed) { diff --git a/src/io/gzipstream.h b/src/io/gzipstream.h index 89c5f64f3..5af57b4c5 100644 --- a/src/io/gzipstream.h +++ b/src/io/gzipstream.h @@ -98,7 +98,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual void put(gunichar ch); private: diff --git a/src/io/inkscapestream.cpp b/src/io/inkscapestream.cpp index 65f24cf59..3270127d6 100644 --- a/src/io/inkscapestream.cpp +++ b/src/io/inkscapestream.cpp @@ -125,7 +125,7 @@ void BasicOutputStream::flush() /** * Writes the specified byte to this output stream. */ -void BasicOutputStream::put(int ch) +void BasicOutputStream::put(gunichar ch) { if (closed) return; @@ -775,9 +775,7 @@ void OutputStreamWriter::flush() */ void OutputStreamWriter::put(gunichar ch) { - //Do we need conversions here? - int intCh = (int) ch; - outputStream.put(intCh); + outputStream.put(ch); } //######################################################################### @@ -827,9 +825,7 @@ void StdWriter::flush() */ void StdWriter::put(gunichar ch) { - //Do we need conversions here? - int intCh = (int) ch; - outputStream->put(intCh); + outputStream->put(ch); } diff --git a/src/io/inkscapestream.h b/src/io/inkscapestream.h index 37c41552f..a9854ae6d 100644 --- a/src/io/inkscapestream.h +++ b/src/io/inkscapestream.h @@ -189,7 +189,7 @@ public: /** * Send one byte to the destination stream. */ - virtual void put(int ch) = 0; + virtual void put(gunichar ch) = 0; }; // class OutputStream @@ -212,7 +212,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual void put(gunichar ch); protected: @@ -238,7 +238,7 @@ public: void flush() { } - void put(int ch) + void put(gunichar ch) { putchar(ch); } }; diff --git a/src/io/stringstream.cpp b/src/io/stringstream.cpp index 44d11dd04..f204a99d5 100644 --- a/src/io/stringstream.cpp +++ b/src/io/stringstream.cpp @@ -112,10 +112,9 @@ void StringOutputStream::flush() /** * Writes the specified byte to this output stream. */ -void StringOutputStream::put(int ch) +void StringOutputStream::put(gunichar ch) { - gunichar uch = (gunichar)ch; - buffer.push_back(uch); + buffer.push_back(ch); } diff --git a/src/io/stringstream.h b/src/io/stringstream.h index 4a05d88a9..a78935599 100644 --- a/src/io/stringstream.h +++ b/src/io/stringstream.h @@ -67,7 +67,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual void put(gunichar ch); virtual Glib::ustring &getString() { return buffer; } diff --git a/src/io/uristream.cpp b/src/io/uristream.cpp index 19994bc82..8d7fd9b38 100644 --- a/src/io/uristream.cpp +++ b/src/io/uristream.cpp @@ -402,16 +402,14 @@ void UriOutputStream::flush() throw(StreamException) /** * Writes the specified byte to this output stream. */ -void UriOutputStream::put(int ch) throw(StreamException) +void UriOutputStream::put(gunichar ch) throw(StreamException) { if (closed) return; unsigned char uch; - gunichar gch; switch (scheme) { - case SCHEME_FILE: if (!outf) return; @@ -420,13 +418,11 @@ void UriOutputStream::put(int ch) throw(StreamException) Glib::ustring err = "ERROR writing to file "; throw StreamException(err); } - //fwrite(uch, 1, 1, outf); - break; + break; case SCHEME_DATA: - gch = (gunichar) ch; - data.push_back(gch); - break; + data.push_back(ch); + break; }//switch @@ -474,8 +470,7 @@ void UriWriter::flush() throw(StreamException) */ void UriWriter::put(gunichar ch) throw(StreamException) { - int ich = (int)ch; - outputStream->put(ich); + outputStream->put(ch); } diff --git a/src/io/uristream.h b/src/io/uristream.h index 16b1b0894..e519335e8 100644 --- a/src/io/uristream.h +++ b/src/io/uristream.h @@ -115,7 +115,7 @@ public: virtual void flush() throw(StreamException); - virtual void put(int ch) throw(StreamException); + virtual void put(gunichar ch) throw(StreamException); private: diff --git a/src/io/xsltstream.cpp b/src/io/xsltstream.cpp index 6b72627d3..1c260c0b3 100644 --- a/src/io/xsltstream.cpp +++ b/src/io/xsltstream.cpp @@ -230,10 +230,9 @@ void XsltOutputStream::flush() throw (StreamException) /** * Writes the specified byte to this output stream. */ -void XsltOutputStream::put(int ch) throw (StreamException) +void XsltOutputStream::put(gunichar ch) throw (StreamException) { - gunichar uch = (gunichar) ch; - outbuf.push_back(uch); + outbuf.push_back(ch); } diff --git a/src/io/xsltstream.h b/src/io/xsltstream.h index cfe9e5124..9b8e19215 100644 --- a/src/io/xsltstream.h +++ b/src/io/xsltstream.h @@ -120,7 +120,7 @@ public: virtual void flush() throw (StreamException); - virtual void put(int ch) throw (StreamException); + virtual void put(gunichar ch) throw (StreamException); private: diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 0ce18dcea..8147ae014 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -41,18 +41,15 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); //Sbasis - Geom::D2< Geom::SBasis > SBasisIn; - Geom::D2< Geom::SBasis > SBasisOut; - Geom::D2< Geom::SBasis > SBasisEnd; Geom::D2< Geom::SBasis > SBasisHelper; - //Curvas temporales - SPCurve *lineHelper = new SPCurve(); - SPCurve *curveHelper = new SPCurve(); - SPCurve *nCurve = new SPCurve(); //curves SPCurve * in = new SPCurve(); SPCurve * out = new SPCurve(); SPCurve * end = new SPCurve(); + //Curvas temporales + SPCurve *lineHelper = new SPCurve(); + SPCurve *curveHelper = new SPCurve(); + SPCurve *nCurve = new SPCurve(); //Puntos a usar. Ponemos todos los posibles para hacer más inteligible el código Geom::Point startNode(0,0); Geom::Point previousNode(0,0); @@ -80,6 +77,7 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve Geom::Path::const_iterator curve_end = path_it->end(); // end curve Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + //Creamos las lineas rectas que unen todos los puntos del trazado y donde se calcularán //los puntos clave para los manejadores. //Esto hace que la curva BSpline no pierda su condición aunque se trasladen @@ -91,19 +89,15 @@ LPEBSpline::doEffect(SPCurve * curve) //este no cambia. end->moveto(curve_end->initialPoint()); end->lineto(curve_end->finalPoint()); - //Si la curva está cerrada calculamos el punto donde //deveria estar el nodo BSpline de cierre/inicio de la curva //en posible caso de que se cierre con una linea recta creando un nodo BSPline - cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); - cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); cubicEnd = dynamic_cast<Geom::CubicBezier const*>(&*curve_end); - if (path_it->closed() && cubicEnd && (*cubicEnd)[3] != (*cubicEnd)[2]){ + cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); + if (path_it->closed() && cubicEnd && cubicIn) { //Calculamos el nodo de inicio BSpline - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); - lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment()))); - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubicEnd)[2],*end->first_segment()))); + lineHelper->moveto((*cubicIn)[1]); + lineHelper->lineto((*cubicEnd)[2]); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -111,57 +105,54 @@ LPEBSpline::doEffect(SPCurve * curve) //Definimos el punto de inicio original de la curva resultante node = startNode; }else{ + //Guardamos el principio de la curva startNode = in->first_segment()->initialPoint(); + //Definimos el punto de inicio original de la curva resultante node = startNode; } + //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { - SBasisIn = in->first_segment()->toSBasis(); - SBasisOut = out->first_segment()->toSBasis(); //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida + cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); if(cubicIn){ - pointAt0 = SBasisIn.valueAt(0); - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment())); - pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[2],*in->first_segment())); - pointAt3 = SBasisIn.valueAt(1); + pointAt0 = (*cubicIn)[0]; + pointAt1 = (*cubicIn)[1]; + pointAt2 = (*cubicIn)[2]; + pointAt3 = (*cubicIn)[3]; }else{ - pointAt0 = SBasisIn.valueAt(0); - pointAt1 = SBasisIn.valueAt(0); - pointAt2 = SBasisIn.valueAt(1); - pointAt3 = SBasisIn.valueAt(1); + pointAt0 = in->first_segment()->initialPoint(); + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + pointAt3 = in->first_segment()->finalPoint(); } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); + cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); if(cubicOut){ - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[2],*out->first_segment())); - nextPointAt3 = SBasisOut.valueAt(1); + nextPointAt1 = (*cubicOut)[1]; + nextPointAt2 = (*cubicOut)[2]; + nextPointAt3 = (*cubicOut)[3]; }else{ - nextPointAt1 = SBasisOut.valueAt(0); - nextPointAt2 = SBasisOut.valueAt(1); - nextPointAt3 = SBasisOut.valueAt(1); + nextPointAt1 = in->first_segment()->initialPoint(); + nextPointAt2 = in->first_segment()->finalPoint(); + nextPointAt3 = in->first_segment()->finalPoint(); } //La curva BSpline se forma calculando el centro del segmanto de unión //de el punto situado en las 2/3 partes de el segmento de entrada //con el punto situado en la posición 1/3 del segmento de salida //Estos dos puntos ademas estan posicionados en el lugas correspondiente de //los manejadores de la curva - if(nextPointAt1 != pointAt2){ - lineHelper->moveto(pointAt2); - lineHelper->lineto(nextPointAt1); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de principio de curva - previousNode = node; - //Y este hará de final de curva - node = SBasisHelper.valueAt(0.5); - }else{ - previousNode = node; - //Y este hará de final de curva - node = nextPointAt1; - } + lineHelper->moveto(pointAt2); + lineHelper->lineto(nextPointAt1); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de principio de curva + previousNode = node; + //Y este hará de final de curva + node = SBasisHelper.valueAt(0.5); curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal @@ -178,10 +169,7 @@ LPEBSpline::doEffect(SPCurve * curve) if(curve_it1 != curve_end){ out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); - cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); } - cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); - } //Aberiguamos la ultima parte de la curva correspondiente al último segmento curveHelper->moveto(node); diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 9577ecbf9..e393a706b 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1844,7 +1844,45 @@ static void bspline(SPPenContext *const pc, bool Shift) lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); previousCurve->backspace(); previousCurve->append_continuous(lastSeg, 0.0625); - pc->sa = previousCurve; + pc->sa->curve = previousCurve; + } + } + } + if(pc->anchor_statusbar && !pc->red_curve->is_empty()){ + // Step B - both start and end anchored to same curve + if ( pc->sa && pc->ea + && ( pc->sa->curve == pc->ea->curve ) + && ( ( pc->sa != pc->ea ) + || pc->sa->curve->is_closed() ) ) + { + SPCurve * same = pc->sa->curve->copy(); + if (pc->sa->start) { + same = same->create_reverse(); + } + cubic = dynamic_cast<Geom::CubicBezier const*>(&*same->last_segment()); + if(cubic){ + SPCurve *lastSeg = new SPCurve(); + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + same->backspace(); + same->append_continuous(lastSeg, 0.0625); + same = same->create_reverse(); + pc->sa->curve = same; + } + } + // Step A - test, whether we ended on green anchor + if ( pc->green_anchor && pc->green_anchor->active ) { + // We hit green anchor, closing Green-Blue-Red + SPCurve * green = pc->green_curve->copy()->create_reverse(); + cubic = dynamic_cast<Geom::CubicBezier const*>(&*green->last_segment()); + if(cubic){ + SPCurve *lastSeg = new SPCurve(); + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + green->backspace(); + green->append_continuous(lastSeg, 0.0625); + green = green->create_reverse(); + pc->green_curve = green; } } } @@ -1936,7 +1974,7 @@ static void bspline_build(SPPenContext *const pc) } } -static void bspline_doEffect(SPCurve * curve) +static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) { using Geom::X; using Geom::Y; @@ -1947,18 +1985,15 @@ static void bspline_doEffect(SPCurve * curve) Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); //Sbasis - Geom::D2< Geom::SBasis > SBasisIn; - Geom::D2< Geom::SBasis > SBasisOut; - Geom::D2< Geom::SBasis > SBasisEnd; Geom::D2< Geom::SBasis > SBasisHelper; - //Curvas temporales - SPCurve *lineHelper = new SPCurve(); - SPCurve *curveHelper = new SPCurve(); - SPCurve *nCurve = new SPCurve(); //curves SPCurve * in = new SPCurve(); SPCurve * out = new SPCurve(); SPCurve * end = new SPCurve(); + //Curvas temporales + SPCurve *lineHelper = new SPCurve(); + SPCurve *curveHelper = new SPCurve(); + SPCurve *nCurve = new SPCurve(); //Puntos a usar. Ponemos todos los posibles para hacer más inteligible el código Geom::Point startNode(0,0); Geom::Point previousNode(0,0); @@ -1986,6 +2021,7 @@ static void bspline_doEffect(SPCurve * curve) Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve Geom::Path::const_iterator curve_end = path_it->end(); // end curve Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + //Creamos las lineas rectas que unen todos los puntos del trazado y donde se calcularán //los puntos clave para los manejadores. //Esto hace que la curva BSpline no pierda su condición aunque se trasladen @@ -1997,19 +2033,15 @@ static void bspline_doEffect(SPCurve * curve) //este no cambia. end->moveto(curve_end->initialPoint()); end->lineto(curve_end->finalPoint()); - //Si la curva está cerrada calculamos el punto donde //deveria estar el nodo BSpline de cierre/inicio de la curva //en posible caso de que se cierre con una linea recta creando un nodo BSPline - cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); - cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); cubicEnd = dynamic_cast<Geom::CubicBezier const*>(&*curve_end); - if (path_it->closed()){ + cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); + if (path_it->closed() && cubicEnd && cubicIn) { //Calculamos el nodo de inicio BSpline - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); - lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment()))); - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubicEnd)[2],*end->first_segment()))); + lineHelper->moveto((*cubicIn)[1]); + lineHelper->lineto((*cubicEnd)[2]); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -2017,57 +2049,54 @@ static void bspline_doEffect(SPCurve * curve) //Definimos el punto de inicio original de la curva resultante node = startNode; }else{ + //Guardamos el principio de la curva startNode = in->first_segment()->initialPoint(); + //Definimos el punto de inicio original de la curva resultante node = startNode; } + //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { - SBasisIn = in->first_segment()->toSBasis(); - SBasisOut = out->first_segment()->toSBasis(); //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida + cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); if(cubicIn){ - pointAt0 = SBasisIn.valueAt(0); - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment())); - pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[2],*in->first_segment())); - pointAt3 = SBasisIn.valueAt(1); + pointAt0 = (*cubicIn)[0]; + pointAt1 = (*cubicIn)[1]; + pointAt2 = (*cubicIn)[2]; + pointAt3 = (*cubicIn)[3]; }else{ - pointAt0 = SBasisIn.valueAt(0); - pointAt1 = SBasisIn.valueAt(0); - pointAt2 = SBasisIn.valueAt(1); - pointAt3 = SBasisIn.valueAt(1); + pointAt0 = in->first_segment()->initialPoint(); + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + pointAt3 = in->first_segment()->finalPoint(); } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); + cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); if(cubicOut){ - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[2],*out->first_segment())); - nextPointAt3 = SBasisOut.valueAt(1); + nextPointAt1 = (*cubicOut)[1]; + nextPointAt2 = (*cubicOut)[2]; + nextPointAt3 = (*cubicOut)[3]; }else{ - nextPointAt1 = SBasisOut.valueAt(0); - nextPointAt2 = SBasisOut.valueAt(1); - nextPointAt3 = SBasisOut.valueAt(1); + nextPointAt1 = in->first_segment()->initialPoint(); + nextPointAt2 = in->first_segment()->finalPoint(); + nextPointAt3 = in->first_segment()->finalPoint(); } //La curva BSpline se forma calculando el centro del segmanto de unión //de el punto situado en las 2/3 partes de el segmento de entrada //con el punto situado en la posición 1/3 del segmento de salida //Estos dos puntos ademas estan posicionados en el lugas correspondiente de //los manejadores de la curva - if(nextPointAt1 != pointAt2){ - lineHelper->moveto(pointAt2); - lineHelper->lineto(nextPointAt1); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de principio de curva - previousNode = node; - //Y este hará de final de curva - node = SBasisHelper.valueAt(0.5); - }else{ - previousNode = node; - //Y este hará de final de curva - node = nextPointAt1; - } + lineHelper->moveto(pointAt2); + lineHelper->lineto(nextPointAt1); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de principio de curva + previousNode = node; + //Y este hará de final de curva + node = SBasisHelper.valueAt(0.5); curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal @@ -2084,10 +2113,7 @@ static void bspline_doEffect(SPCurve * curve) if(curve_it1 != curve_end){ out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); - cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2); } - cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1); - } //Aberiguamos la ultima parte de la curva correspondiente al último segmento curveHelper->moveto(node); @@ -2121,7 +2147,7 @@ static void bspline_doEffect(SPCurve * curve) //Todo: remove? //delete SBasisHelper; } - + //BSpline end static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point const p, bool statusbar, guint status) diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index dc6e0fbae..447133b7c 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -13,7 +13,6 @@ #include <glib/gi18n.h> #include <2geom/bezier-utils.h> #include <2geom/transforms.h> - #include "display/sp-ctrlline.h" #include "display/sp-canvas.h" #include "display/sp-canvas-util.h" @@ -136,6 +135,14 @@ void Handle::move(Geom::Point const &new_pos) Node *node_away = _parent->nodeAwayFrom(this); // node in the opposite direction Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; + //BSpline + bool isBSpline = false; + double pos = 0; + Handle *h = this; + if(_pm().isBSpline()){ + isBSpline = true; + //BSpline End + } if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. @@ -167,6 +174,16 @@ void Handle::move(Geom::Point const &new_pos) } } setPosition(new_pos); + //BSpline + if(isBSpline){ + setPosition(_pm().BSplineHandleReposition(h)); + pos = _pm().BSplineHandlePosition(h); + other->setPosition(_pm().BSplineHandleReposition(other,pos)); + if(pos == 0){ + _parent->setPosition(h->position()); + } + } + //BSpline End return; } @@ -196,8 +213,17 @@ void Handle::move(Geom::Point const &new_pos) break; default: break; } - setPosition(new_pos); + //BSpline + if(isBSpline){ + setPosition(_pm().BSplineHandleReposition(h)); + pos = _pm().BSplineHandlePosition(h); + other->setPosition(_pm().BSplineHandleReposition(other,pos)); + if(pos == 0){ + _parent->setPosition(h->position()); + } + } + //BSpline End } void Handle::setPosition(Geom::Point const &p) @@ -550,10 +576,26 @@ void Node::move(Geom::Point const &new_pos) // move handles when the node moves. Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); + //BSpline + double pos = 0; + if(_pm().isBSpline()){ + Node *n = this; + pos = _pm().BSplineHandlePosition(n->front()); + if(pos == 0) + pos = _pm().BSplineHandlePosition(n->back()); + } + //BSpline End setPosition(new_pos); _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); - + //BSpline + if(_pm().isBSpline()){ + Handle* front = &_front; + Handle* back = &_back; + _front.setPosition(_pm().BSplineHandleReposition(front,pos)); + _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + } + //BSpline End // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f1b2e12be..03e25dfa3 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1102,7 +1102,6 @@ void PathManipulator::_createControlPointsFromGeometry() Geom::Curve const &cseg = pit->back_closed(); bool fuse_ends = pit->closed() && Geom::are_near(cseg.initialPoint(), cseg.finalPoint()); - for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) { Geom::Point pos = cit->finalPoint(); Node *current_node; @@ -1169,6 +1168,56 @@ void PathManipulator::_createControlPointsFromGeometry() } } + +bool PathManipulator::isBSpline(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) { + PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path)); + lpe_bsp = dynamic_cast<LivePathEffect::LPEBSpline*>( effect_list.front()->lpeobject->get_lpe()); + }else{ + lpe_bsp = NULL; + } + if(lpe_bsp){ + return true; + } + return false; +} +double PathManipulator::BSplineHandlePosition(Handle *h){ + double pos = 0; + Node *n = h->parent(); + Geom::D2< Geom::SBasis > SBasisInsideNodes; + SPCurve *lineInsideNodes = new SPCurve(); + Node * nextNode = n->nodeToward(h); + if(nextNode){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); + } + return pos; +} + +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ + double pos = 0; + pos = this->BSplineHandlePosition(h); + return BSplineHandleReposition(h,pos); +} + +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ + Node *n = h->parent(); + Geom::D2< Geom::SBasis > SBasisInsideNodes; + SPCurve *lineInsideNodes = new SPCurve(); + Node * nextNode = n->nodeToward(h); + if(nextNode && pos != 0){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + }else{ + return n->position(); + } + return SBasisInsideNodes.valueAt(pos); +} + /** Construct the geometric representation of nodes and handles, update the outline * and display * \param alert_LPE if true, first the LPE is warned what the new path is going to be before updating it @@ -1183,15 +1232,55 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); + //BSpline + double pos = 0; + bool isBSpline = false; + if(this->isBSpline()) + isBSpline = true; + if(isBSpline){ + pos = BSplineHandlePosition(prev.ptr()->front()); + prev.ptr()->front()->setPosition(BSplineHandleReposition(prev.ptr()->front(),pos)); + if(pos == 0){ + prev.ptr()->setPosition(prev.ptr()->front()->position()); + } + } + //BSpline End builder.moveTo(prev->position()); - for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { + //BSpline + if (isBSpline) { + pos = BSplineHandlePosition(i.ptr()->front()); + if(pos == 0) + pos = BSplineHandlePosition(i.ptr()->back()); + i.ptr()->front()->setPosition(BSplineHandleReposition(i.ptr()->front(),pos)); + i.ptr()->back()->setPosition(BSplineHandleReposition(i.ptr()->back(),pos)); + if(pos == 0){ + i.ptr()->setPosition(i.ptr()->front()->position()); + } + } + + //BSpline End build_segment(builder, prev.ptr(), i.ptr()); prev = i; } if (subpath->closed()) { // Here we link the last and first node if the path is closed. // If the last segment is Bezier, we add it. + /* + //BSpline + if (isBSpline) { + pos = BSplineHandlePosition(prev.ptr()->front()); + if(pos == 0) + pos = BSplineHandlePosition(subpath->begin().ptr()->back()); + subpath->begin().ptr()->front()->setPosition(BSplineHandleReposition(subpath->begin().ptr()->front(),pos)); + prev.ptr()->back()->setPosition(BSplineHandleReposition(prev.ptr()->back(),pos)); + if(pos == 0){ + subpath->begin().ptr()->setPosition(subpath->begin().ptr()->front()->position()); + prev.ptr()->setPosition(prev.ptr()->back()->position()); + } + } + //BSpline End + /*/ if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { build_segment(builder, prev.ptr(), subpath->begin().ptr()); } @@ -1200,6 +1289,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } ++spi; } + builder.finish(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); _spcurve->set_pathvector(pathv); @@ -1261,24 +1351,6 @@ void PathManipulator::_updateOutline() } Geom::PathVector pv = _spcurve->get_pathvector(); pv *= (_edit_transform * _i2d_transform); - //BSpline - if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) { - PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path)); - LivePathEffect::LPEBSpline *lpe_bsp = dynamic_cast<LivePathEffect::LPEBSpline*>( effect_list.front()->lpeobject->get_lpe()); - if (lpe_bsp) { - Geom::PathVector pv2; - for (Geom::PathVector::iterator i = pv.begin(); i != pv.end(); ++i) { - Geom::Path &path = *i; - for (Geom::Path::const_iterator j = path.begin(); j != path.end_default(); ++j) { - Geom::Path pv2j(j->pointAt(0)); - pv2j.appendNew<Geom::LineSegment>(j->pointAt(1)); - pv2.push_back(pv2j); - } - } - pv = pv2; - } - } - //BSpline End // This SPCurve thing has to be killed with extreme prejudice SPCurve *_hc = new SPCurve(); if (_show_path_direction) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index a51b8c410..55958530d 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -104,6 +104,12 @@ private: typedef boost::shared_ptr<NodeList> SubpathPtr; void _createControlPointsFromGeometry(); + //BSpline + bool isBSpline(); + double BSplineHandlePosition(Handle *h); + Geom::Point BSplineHandleReposition(Handle *h); + Geom::Point BSplineHandleReposition(Handle *h,double pos); + //BSpline End void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); |
