diff options
Diffstat (limited to 'src/pen-context.cpp')
| -rw-r--r-- | src/pen-context.cpp | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 9577ecbf9..26eb77b06 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; @@ -1951,14 +1989,14 @@ static void bspline_doEffect(SPCurve * curve) 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); @@ -1972,9 +2010,7 @@ static void bspline_doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::CubicBezier const *cubicIn; - Geom::CubicBezier const *cubicOut; - Geom::CubicBezier const *cubicEnd; + Geom::BezierCurve const *bezier; //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el penúltimo for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { //Si está vacío... @@ -1986,6 +2022,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 +2034,18 @@ 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()){ + bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_end); + if (path_it->closed() && bezier && (*bezier)[2] != (*bezier)[3]) { //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()))); + bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it1); + lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment()))); + bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_end); + lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*bezier)[2],*end->first_segment()))); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -2017,9 +2053,12 @@ 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 ) { @@ -2027,10 +2066,11 @@ static void bspline_doEffect(SPCurve * curve) 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 - if(cubicIn){ + bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it1); + if(bezier){ 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())); + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment())); + pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*bezier)[2],*in->first_segment())); pointAt3 = SBasisIn.valueAt(1); }else{ pointAt0 = SBasisIn.valueAt(0); @@ -2040,9 +2080,10 @@ static void bspline_doEffect(SPCurve * curve) } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - if(cubicOut){ - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[2],*out->first_segment())); + bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it2); + if(bezier){ + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*bezier)[1],*out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*bezier)[2],*out->first_segment())); nextPointAt3 = SBasisOut.valueAt(1); }else{ nextPointAt1 = SBasisOut.valueAt(0); @@ -2084,10 +2125,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); |
