From afcec343e905389d2645115d60f14dfd45f5f2d0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Dec 2012 01:01:57 +0100 Subject: bzr history lost by a killed merge (bzr r11950.1.1) --- src/draw-context.cpp | 5 + src/live_effects/CMakeLists.txt | 2 + src/live_effects/Makefile_insert | 2 + src/live_effects/effect-enum.h | 3 + src/live_effects/effect.cpp | 13 +- src/pen-context.cpp | 988 +++++++++++++++++++++++++++++++++++++-- src/pen-context.h | 5 + src/widgets/pencil-toolbar.cpp | 9 +- 8 files changed, 989 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 5996d600b..21e2a6883 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -314,6 +314,11 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } + //BSpline + if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { + Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); + } + //BSPline End int shape = prefs->getInt(tool_name(dc) + "/shape", 0); bool shape_applied = false; diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index a5f50a69d..7aeb911b0 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -34,6 +34,7 @@ set(live_effects_SRC lpe-spiro.cpp lpe-tangent_to_curve.cpp lpe-test-doEffect-stack.cpp + lpe-bspline.cpp lpe-text_label.cpp lpe-vonkoch.cpp lpegroupbbox.cpp @@ -94,6 +95,7 @@ set(live_effects_SRC lpe-spiro.h lpe-tangent_to_curve.h lpe-test-doEffect-stack.h + lpe-bspline.h lpe-text_label.h lpe-vonkoch.h lpegroupbbox.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 9c3c171f2..248030e8c 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -38,6 +38,8 @@ ink_common_sources += \ live_effects/lpe-interpolate.h \ live_effects/lpe-test-doEffect-stack.cpp \ live_effects/lpe-test-doEffect-stack.h \ + live_effects/lpe-bspline.cpp \ + live_effects/lpe-bspline.h \ live_effects/lpe-lattice.cpp \ live_effects/lpe-lattice.h \ live_effects/lpe-envelope.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 43af33b53..cf97dd87f 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -45,6 +45,9 @@ enum EffectType { PATH_LENGTH, LINE_SEGMENT, DOEFFECTSTACK_TEST, + //BSpline + BSPLINE, + //BSpline End DYNASTROKE, RECURSIVE_SKELETON, EXTRUDE, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 3b57de25c..e9ec2076f 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -10,7 +10,7 @@ #include "live_effects/effect.h" #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif // include effects: @@ -22,6 +22,9 @@ #include "live_effects/lpe-rough-hatches.h" #include "live_effects/lpe-dynastroke.h" #include "live_effects/lpe-test-doEffect-stack.h" +//BSpline +#include "live_effects/lpe-bspline.h" +//BSpline End #include "live_effects/lpe-gears.h" #include "live_effects/lpe-curvestitch.h" #include "live_effects/lpe-circle_with_radius.h" @@ -123,6 +126,9 @@ const Util::EnumData LPETypeData[] = { /* 0.49 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, + //BSpline + {BSPLINE, N_("BSpline"), "bspline"}, + //BSpline End }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -231,6 +237,11 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case DOEFFECTSTACK_TEST: neweffect = static_cast ( new LPEdoEffectStackTest(lpeobj) ); break; + //BSpline + case BSPLINE: + neweffect = static_cast ( new LPEBSpline(lpeobj) ); + break; + //BSpline End case DYNASTROKE: neweffect = static_cast ( new LPEDynastroke(lpeobj) ); break; diff --git a/src/pen-context.cpp b/src/pen-context.cpp index cb20eb3eb..be25b6a7f 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -44,7 +44,26 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" +//BSpline +//Incluimos +#define INKSCAPE_LPE_SPIRO_C +#include "live_effects/lpe-spiro.h" +#include "display/curve.h" +#include +#include <2geom/pathvector.h> +#include <2geom/affine.h> +#include <2geom/bezier-curve.h> +#include <2geom/hvlinesegment.h> +#include "helper/geom-nodetype.h" +#include "helper/geom-curves.h" + +#include "live_effects/spiro.h" + +#define INKSCAPE_LPE_BSPLINE_C +#include "live_effects/lpe-bspline.h" + +//BSpline End using Inkscape::ControlManager; @@ -59,6 +78,34 @@ static gint sp_pen_context_root_handler(SPEventContext *ec, GdkEvent *event); static gint sp_pen_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); static void spdc_pen_set_initial_point(SPPenContext *pc, Geom::Point const p); + +//BSpline +//Added functions +//Sobrecarga la función "sp_pen_context_set_polyline_mode" +//Le da valor a la nueva propiedad "pc->spiro" que como se auto define indica si estamos en modo spiro +//En el futuro se la dará a "pc->bspline" +static void sp_pen_context_set_mode(SPPenContext *const pc, guint mode); +//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +static void spiro_color(SPPenContext *const pc); +//Combierte el el último nodo a CUSP +static void spiro_node_cusp (SPPenContext *const pc); +//Combierte el el último nodo a SYMM +static void spiro_node_symm (SPPenContext *const pc); +//preparates the curves for its trasformation into spiro curves. +static void spiro_build(SPPenContext *const pc, bool Shift); +//function spiro cloned from lpe-spiro.cpp +static void spiro_doEffect(SPCurve * curve); +//Combierte el el último nodo a CUSP +static void bspline_node_cusp (SPPenContext *const pc); +//Combierte el el último nodo a BSpline +static void bspline_node (SPPenContext *const pc); +//preparates the curves for its trasformation into bspline curves. +static void bspline_build(SPPenContext *const pc, bool Shift); +//function bspline cloned from lpe-bspline.cpp +static void bspline_doEffect(SPCurve * curve); +//BSpline end + + static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point const p, bool statusbar, guint status = 0); static void spdc_pen_set_ctrl(SPPenContext *pc, Geom::Point const p, guint state); static void spdc_pen_finish_segment(SPPenContext *pc, Geom::Point p, guint state); @@ -192,10 +239,21 @@ static void sp_pen_context_dispose(GObject *object) void sp_pen_context_set_polyline_mode(SPPenContext *const pc) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - pc->polylines_only = (mode == 2 || mode == 3); - pc->polylines_paraxial = (mode == 3); + pc->polylines_only = (mode == 3 || mode == 4); + pc->polylines_paraxial = (mode == 4); + //BSpline + //we call the function which defines the Spiro modes and the B-spline in the future + //todo: merge to one function only + sp_pen_context_set_mode(pc, mode); + //BSpline End } - +//BSpline +//Set the mode of draw now spiro, and later b-splines +void sp_pen_context_set_mode(SPPenContext *const pc, guint mode) { + pc->spiro = (mode == 1); + pc->bspline = (mode == 2); +} +//BSpline End /** * Callback to initialize SPPenContext object. */ @@ -414,11 +472,18 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const Geom::Point const event_w(bevent.x, bevent.y); Geom::Point event_dt(desktop->w2d(event_w)); SPEventContext *event_context = SP_EVENT_CONTEXT(pc); - + //Test whether we hit any anchor. + SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); + //BSpline + //with this we avoid creating a new point over the existing one + if((pc->spiro || pc->bspline) && (!anchor || pc->p[0] == pc->p[3]) && pc->p[0] == pc->desktop->w2d(event_w)){ + return FALSE; + } + //BSpline end gint ret = FALSE; if (bevent.button == 1 && !event_context->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) - && pc->expecting_clicks_for_LPE != 1) { + && (pc->expecting_clicks_for_LPE != 1)) { if (Inkscape::have_viable_layer(desktop, dc->_message_context) == false) { return TRUE; @@ -436,9 +501,6 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const pen_drag_origin_w = event_w; pen_within_tolerance = true; - // Test whether we hit any anchor. - SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); - switch (pc->mode) { case SP_PEN_CONTEXT_MODE_CLICK: // In click mode we add point on release @@ -460,7 +522,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const case SP_PEN_CONTEXT_STOP: // This is allowed, if we just canceled curve case SP_PEN_CONTEXT_POINT: - if (pc->npoints == 0) { + if (pc->npoints == 0 ) { Geom::Point p; if ((bevent.state & GDK_CONTROL_MASK) && (pc->polylines_only || pc->polylines_paraxial)) { @@ -533,6 +595,11 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const } pc->state = pc->polylines_only ? SP_PEN_CONTEXT_POINT : SP_PEN_CONTEXT_CONTROL; + //BSpline + //Esto evita arrastrar los manejadores ya que el punto se crea + //al soltar el botón del ratón. + if((pc->spiro || pc->bspline) && pc->state != SP_PEN_CONTEXT_CLOSE ) pc->state = SP_PEN_CONTEXT_POINT; + //BSpline End ret = TRUE; break; case SP_PEN_CONTEXT_CONTROL: @@ -594,14 +661,19 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons } Geom::Point const event_w(mevent.x, - mevent.y); + mevent.y); + //BSpline + //we take out the function the const "tolerance" because we need it later + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); + //"spiro_color" lo ejecutamos siempre sea o no spiro + spiro_color(pc); if (pen_within_tolerance) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); - if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance ) { + if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance && mevent.time != 0) { return FALSE; // Do not drag if we're within tolerance from origin. } } + //BSpline END // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the // motion notify coordinates as given (no snapping back to origin) @@ -612,7 +684,6 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons // Test, whether we hit any anchor SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); - switch (pc->mode) { case SP_PEN_CONTEXT_MODE_CLICK: switch (pc->state) { @@ -657,7 +728,11 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons } if (anchor && !pc->anchor_statusbar) { - pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path.")); + if(!pc->spiro && !pc->bspline){ + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path.")); + }else{ + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path. Shift to cusp node")); + } pc->anchor_statusbar = true; } else if (!anchor && pc->anchor_statusbar) { pc->_message_context->clear(); @@ -667,7 +742,11 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons ret = TRUE; } else { if (anchor && !pc->anchor_statusbar) { - pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point.")); + if(!pc->spiro && !pc->bspline){ + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point.")); + }else{ + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point. Shift to cusp node")); + } pc->anchor_statusbar = true; } else if (!anchor && pc->anchor_statusbar) { pc->_message_context->clear(); @@ -712,6 +791,42 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons default: break; } + //BSpline + if(pc->spiro){ + //Here we redraw the Spiro curve when the cursor is moved + //and the tolerance distance is exceeded. + //the tolerance value can be multiplied to improve the performance + //but it would lost fluency. + //If the cursor stops the curve is also redrawed. + if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + //and we redraw the spiro + if ((mevent.state & GDK_SHIFT_MASK)){ + spiro_build(pc,true); + }else{ + spiro_build(pc,false); + } + //we update the distance and the tolerance + pen_drag_origin_w = event_w; + } + } + if(pc->bspline){ + //Here we redraw the Bspline curve when the cursor is moved + //and the tolerance distance is exceeded. + //the tolerance value can be multiplied to improve the performance + //but it would lost fluency. + //If the cursor stops the curve is also redrawed. + if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + //and we redraw the spiro + if ((mevent.state & GDK_SHIFT_MASK)){ + bspline_build(pc,true); + }else{ + bspline_build(pc,false); + } + //we update the distance and the tolerance + pen_drag_origin_w = event_w; + } + } + //BSpline End return ret; } @@ -724,11 +839,11 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con // skip event processing if events are disabled return FALSE; } - + gint ret = FALSE; + SPEventContext *event_context = SP_EVENT_CONTEXT(pc); - if ( revent.button == 1 && !event_context->space_panning) { - + if ( revent.button == 1 && !event_context->space_panning ) { SPDrawContext *dc = SP_DRAW_CONTEXT (pc); Geom::Point const event_w(revent.x, @@ -738,7 +853,14 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); - + //BSpline + if(pc->spiro || pc->bspline){ + //Si intentamos crear un nodo en el mismo sitio que el origen, paramos. + if((!anchor || pc->p[0] == pc->p[3]) && pc->p[0] == p){ + return FALSE; + } + } + //BSpline End switch (pc->mode) { case SP_PEN_CONTEXT_MODE_CLICK: switch (pc->state) { @@ -774,6 +896,12 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con } spdc_pen_finish_segment(pc, p, revent.state); spdc_pen_finish(pc, TRUE); + //BSpline + //Ocultamos la guia del penultimo nodo al cerrar la curva + if(pc->spiro){ + sp_canvas_item_hide(pc->c1); + } + //BSpline End pc->state = SP_PEN_CONTEXT_POINT; ret = TRUE; break; @@ -803,6 +931,12 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con // finishing at some other anchor, finish curve but not close spdc_pen_finish(pc, FALSE); } + //BSpline + if(pc->spiro){ + //Ocultamos la guia del penultimo nodo al cerrar la curva + sp_canvas_item_hide(pc->c1); + } + //BSpline End break; case SP_PEN_CONTEXT_STOP: // This is allowed, if we just cancelled curve @@ -816,7 +950,6 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con default: break; } - if (pc->grab) { // Release grab now sp_canvas_item_ungrab(pc->grab, revent.time); @@ -827,6 +960,28 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con dc->green_closed = FALSE; } + //BSpline + if(pc->spiro){ + //Ejecutamos la función tipo de nodo segun tengamos la mayuscula presionada + if ((revent.state & GDK_SHIFT_MASK)){ + spiro_node_cusp(pc); + spiro_build(pc,true); + }else{ + spiro_node_symm(pc); + spiro_build(pc,false); + } + } + if(pc->bspline){ + //Ejecutamos la función tipo de nodo segun tengamos la mayuscula presionada + if ((revent.state & GDK_SHIFT_MASK)){ + bspline_node_cusp(pc); + bspline_build(pc, true); + }else{ + bspline_node(pc); + bspline_build(pc, false); + } + } + //BSpline End // TODO: can we be sure that the path was created correctly? // TODO: should we offer an option to collect the clicks in a list? @@ -846,7 +1001,6 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con // handled in spdc_check_for_and_apply_waiting_LPE() in draw-context.cpp } } - return ret; } @@ -874,13 +1028,10 @@ static void pen_redraw_all (SPPenContext *const pc) SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), pc->green_curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); - pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); } - if (pc->green_anchor) SP_CTRL(pc->green_anchor->ctrl)->moveto(pc->green_anchor->dp); - pc->red_curve->reset(); pc->red_curve->moveto(pc->p[0]); pc->red_curve->curveto(pc->p[1], pc->p[2], pc->p[3]); @@ -913,6 +1064,19 @@ static void pen_redraw_all (SPPenContext *const pc) sp_canvas_item_hide(pc->cl0); } } + //BSpline + //Simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. + //como es un redibujo simplemente no llamamos a la función global + //sino al final de esta + if(pc->spiro){ + //we redraw spiro + spiro_build(pc, true); + } + if(pc->bspline){ + //we redraw bspline + bspline_build(pc, false); + } + //BSpline End } static void pen_lastpoint_move (SPPenContext *const pc, gdouble x, gdouble y) @@ -943,8 +1107,11 @@ static void pen_lastpoint_move_screen (SPPenContext *const pc, gdouble x, gdoubl static void pen_lastpoint_tocurve (SPPenContext *const pc) { - if (pc->npoints != 5) + //BSpline + //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + if (pc->npoints != 5 && !pc->spiro && !pc->bspline) return; + //BSpline Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment() ); if ( cubic ) { @@ -953,16 +1120,86 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); } + //BSpline + //Para formar una curva necesitamos un nodo symm en el "lastpoint" + //de esta manera modificamos el final de la "curva_verde" para que sea symm con el pricipio de la "red_curve" + if(pc->spiro){ + Geom::Point A(0,0); + Geom::Point B(0,0); + Geom::Point C(0,0); + Geom::Point D(0,0); + SPCurve * previous = new SPCurve(); + //We obtain the last segment 4 points in the previous curve + if ( cubic ){ + A = (*cubic)[0]; + B = (*cubic)[1]; + C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); + D = (*cubic)[3]; + }else{ + A = pc->green_curve->last_segment()->initialPoint(); + B = pc->green_curve->last_segment()->initialPoint(); + C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); + D = pc->green_curve->last_segment()->finalPoint(); + } + previous->moveto(A); + previous->curveto(B, C, D); + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } + //Para formar una curva bspline necesitamos un nodo cusp en el "lastpoint" + //de esta manera modificamos el final de la "curva_verde" para que sea cusp con el pricipio de la "red_curve" + //Que se quedará recta + if(pc->bspline){ + Geom::Point A(0,0); + Geom::Point B(0,0); + SPCurve * previous = new SPCurve(); + //We obtain the last segment 2 points in the previous curve + A = pc->green_curve->last_segment()->initialPoint(); + B = pc->green_curve->last_segment()->finalPoint(); + previous->moveto(A); + previous->lineto(B); + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } + //Spiro Live pen_redraw_all(pc); } static void pen_lastpoint_toline (SPPenContext *const pc) { - if (pc->npoints != 5) + //BSpline + //Si no es bspline + if (pc->npoints != 5 && !pc->bspline) return; - + //BSpline End pc->p[1] = pc->p[0]; + //BSpline + //Para formar una recta necesitamos un nodo con manejador en el "lastpoint" + //de esta manera modificamos el final de la "curva_verde" para que tenga manejador + if(pc->bspline){ + Geom::Point A(0,0); + Geom::Point B(0,0); + Geom::Point C(0,0); + Geom::Point D(0,0); + SPCurve * previous = new SPCurve(); + //We obtain the last segment 4 points in the previous curve + A = pc->green_curve->last_segment()->initialPoint(); + B = pc->green_curve->last_segment()->initialPoint(); + C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); + D = pc->green_curve->last_segment()->finalPoint(); + previous->moveto(A); + previous->curveto(B, C, D); + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } + pen_redraw_all(pc); } @@ -1148,8 +1385,6 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) : pc->p[3] )); pc->npoints = 2; pc->green_curve->backspace(); - sp_canvas_item_hide(pc->c0); - sp_canvas_item_hide(pc->c1); sp_canvas_item_hide(pc->cl0); sp_canvas_item_hide(pc->cl1); pc->state = SP_PEN_CONTEXT_POINT; @@ -1168,6 +1403,7 @@ static void spdc_reset_colors(SPPenContext *pc) { // Red pc->red_curve->reset(); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); // Blue pc->blue_curve->reset(); @@ -1223,6 +1459,677 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G g_string_free(dist, FALSE); } + +//BSpline Set Functions +//Creates a new curve resetting the original +static SPCurve * reverse_then_reset(SPCurve *orig) +{ + SPCurve *ret = orig->create_reverse(); + orig->reset(); + return ret; +} + +//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +static void spiro_color(SPPenContext *const pc) +{ + bool remake_green_bpaths = false; + if(pc->spiro){ + //If the colour is not defined as trasparent, por example when changing + //from drawing to spiro mode or when selecting the pen tool + if(pc->green_color != 0x00ff000){ + //We change the green and red colours to transparent, so this lines are not necessary + //to the drawing with spiro + pc->red_color = 0xff00000; + pc->green_color = 0x00ff000; + remake_green_bpaths = true; + } + }else{ + //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent + if(pc->green_color != 0x00ff007f){ + //since we are not im spiro mode, we assign the original colours + //to the red and the green curve, removing their transparency + pc->red_color = 0xff00007f; + pc->green_color = 0x00ff007f; + remake_green_bpaths = true; + } + //we hide the spiro/bspline rests + if(!pc->bspline){ + sp_canvas_item_hide(pc->blue_bpath); + } + } + //We erase all the "green_bpaths" to recreate them after with the colour + //transparency recently modified + if (pc->green_bpaths && remake_green_bpaths) { + // remove old piecewise green canvasitems + while (pc->green_bpaths) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data)); + pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data); + } + // one canvas bpath for all of green_curve + SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), pc->green_curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); + } + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->red_bpath), pc->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); +} + +//Combierte el el último nodo a CUSP +static void spiro_node_cusp (SPPenContext *const pc) +{ + if(pc->green_curve->is_empty()) + return; + Geom::Point P0(0,0); + Geom::Point P1(0,0); + Geom::Point P2(0,0); + Geom::Point P3(0,0); + Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment()); + if(cubic){ + P0 = (*cubic)[0]; + P1 = (*cubic)[1]; + P2 = (*cubic)[3]; + P3 = (*cubic)[3]; + } + pc->p[0] + P3; + pc->p[1] = P3 - (1./3)*(Geom::Point)( P0 - P3 ); + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->curveto(P1,P2,P3); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = last; + }else{ + pc->green_curve->backspace(); + pc->green_curve->append_continuous(last, 0.0625); + } +} + +//Combierte el el último nodo a SYMM +//Solo se ejecuta al final de el evento release button +static void spiro_node_symm(SPPenContext *const pc) +{ + //Si empezamos sobre una curva ya existente + if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ + Geom::CubicBezier const * cubic; + if (pc->sa->start) { + cubic = dynamic_cast( pc->sa->curve->first_segment() ); + if ( cubic ) { + pc->p[1] = (pc->p[0]-(*cubic)[1]) + pc->p[0]; + } + }else{ + cubic = dynamic_cast( pc->sa->curve->last_segment() ); + if ( cubic ) { + pc->p[1] = (pc->p[0]-(*cubic)[2]) + pc->p[0]; + } + } + } + //Cuando cerramos el segmento + if (!pc->green_curve->is_empty()){ + Geom::Point P0(0,0); + Geom::Point P1(0,0); + Geom::Point P2(0,0); + Geom::Point P3(0,0); + Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment()); + if(cubic){ + P0 = (*cubic)[0]; + P1 = (*cubic)[1]; + P2 = (*cubic)[3] + (1./3)*((*cubic)[0] - (*cubic)[3]); + P3 = (*cubic)[3]; + }else{ + P0 = pc->green_curve->last_segment()->initialPoint(); + P1 = P0; + P3 = pc->green_curve->last_segment()->finalPoint(); + P2 = P3 + (1./3)*(P0 - P3); + } + pc->p[1] = pc->p[0] + (Geom::Point)( pc->p[0] - P2 ); + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->curveto(P1,P2,P3); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = last; + }else{ + pc->green_curve->backspace(); + pc->green_curve->append_continuous(last, 0.0625); + } + } + //por si cerramos la curva + if(pc->ea && !pc->ea->curve->is_empty()){ + Geom::CubicBezier const * cubic; + if(pc->ea->start){ + cubic = dynamic_cast( pc->ea->curve->first_segment()); + if(cubic){ + pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[1] ); + } + }else{ + cubic = dynamic_cast( pc->ea->curve->last_segment()); + if(cubic){ + pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[2] ); + } + } + } +} + +//preparates the curves for its trasformation into spiro curves. +//Parámetro opcional que indica si la curva se cierra en que modo lo hace Cusp o Symm +static void spiro_build(SPPenContext *const pc, bool Shift) +{ + //We create the base curve + SPCurve *curve = new SPCurve(); + //If we continuate the existing curve we add it at the start + if(pc->sa && !pc->sa->curve->is_empty()){ + curve = pc->sa->curve->copy(); + if (pc->sa->start) { + curve = curve->create_reverse(); + } + } + //We add also the green curve + if (!pc->green_curve->is_empty()) { + curve->append_continuous(pc->green_curve, 0.0625); + } + //and the red one + if (!pc->red_curve->is_empty()) { + //we add the curve to the modified values + if(!Shift){ + if(pc->ea && !pc->ea->curve->is_empty()){ + Geom::CubicBezier const * cubic; + if(pc->ea->start){ + cubic = dynamic_cast( pc->ea->curve->first_segment()); + if(cubic){ + pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[1] ); + } + }else{ + cubic = dynamic_cast( pc->ea->curve->last_segment()); + if(cubic){ + pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[2] ); + } + } + } else if(pc->green_anchor && pc->green_anchor->active){ + Geom::CubicBezier const * cubic; + cubic = dynamic_cast( pc->green_curve->first_segment()); + if(cubic){ + pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[1] ); + } + } + if(pc->p[2] != pc->p[3]){ + pc->red_curve->reset(); + pc->npoints = 5; + pc->red_curve->moveto(pc->p[0]); + pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); + } + }else{ + if((pc->ea && !pc->ea->curve->is_empty()) || (pc->green_anchor && pc->green_anchor->active)){ + pc->p[2] == pc->p[3]; + pc->red_curve->reset(); + pc->npoints = 5; + pc->red_curve->moveto(pc->p[0]); + pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); + } + } + curve->append_continuous(pc->red_curve, 0.0625); + } + if(!curve->is_empty()){ + //cerramos la curva si estan cerca los puntos finales de la curva spiro + if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ + curve->closepath_current(); + } + //TODO: CALL TO CLONED FUNCTION SPIRO::doEffect IN lpe-spiro.cpp + //For example + //using namespace Inkscape::LivePathEffect; + //LivePathEffectObject *lpeobj = static_cast (curve); + //Effect *spr = static_cast ( new LPESpiro(lpeobj) ); + //spr->doEffect(curve); + spiro_doEffect(curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->blue_bpath), pc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_item_show(pc->blue_bpath); + curve->unref(); + sp_canvas_item_show(pc->c1); + pc->blue_curve->reset(); + SP_CTRL(pc->c1)->moveto(pc->p[0]); + //We hide the holders that doesn't contribute anything + sp_canvas_item_hide(pc->cl1); + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->cl0); + }else{ + //if the curve is empty + sp_canvas_item_hide(pc->blue_bpath); + } +} +//Spiro function cloned from lpe-spiro.cpp +static void spiro_doEffect(SPCurve * curve) +{ + using Geom::X; + using Geom::Y; + + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); + guint len = curve->get_segment_count() + 2; + + curve->reset(); + Spiro::spiro_cp *path = g_new (Spiro::spiro_cp, len); + int ip = 0; + + for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { + if (path_it->empty()) + continue; + + // start of path + { + Geom::Point p = path_it->front().pointAt(0); + path[ip].x = p[X]; + path[ip].y = p[Y]; + path[ip].ty = '{' ; // for closed paths, this is overwritten + ip++; + } + + // midpoints + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + + Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + + while ( curve_it2 != curve_endit ) + { + /* This deals with the node between curve_it1 and curve_it2. + * Loop to end_default (so without last segment), loop ends when curve_it2 hits the end + * and then curve_it1 points to end or closing segment */ + Geom::Point p = curve_it1->finalPoint(); + path[ip].x = p[X]; + path[ip].y = p[Y]; + + // Determine type of spiro node this is, determined by the tangents (angles) of the curves + // TODO: see if this can be simplified by using /helpers/geom-nodetype.cpp:get_nodetype + bool this_is_line = is_straight_curve(*curve_it1); + bool next_is_line = is_straight_curve(*curve_it2); + + Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2); + + if ( nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM ) + { + if (this_is_line && !next_is_line) { + path[ip].ty = ']'; + } else if (next_is_line && !this_is_line) { + path[ip].ty = '['; + } else { + path[ip].ty = 'c'; + } + } else { + path[ip].ty = 'v'; + } + + ++curve_it1; + ++curve_it2; + ip++; + } + + // add last point to the spiropath + Geom::Point p = curve_it1->finalPoint(); + path[ip].x = p[X]; + path[ip].y = p[Y]; + if (path_it->closed()) { + // curve_it1 points to the (visually) closing segment. determine the match between first and this last segment (the closing node) + Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front()); + switch (nodetype) { + case Geom::NODE_NONE: // can't happen! but if it does, it means the path isn't closed :-) + path[ip].ty = '}'; + ip++; + break; + case Geom::NODE_CUSP: + path[0].ty = path[ip].ty = 'v'; + break; + case Geom::NODE_SMOOTH: + case Geom::NODE_SYMM: + path[0].ty = path[ip].ty = 'c'; + break; + } + } else { + // set type to path closer + path[ip].ty = '}'; + ip++; + } + + // run subpath through spiro + int sp_len = ip; + Spiro::spiro_run(path, sp_len, *curve); + ip = 0; + } + + g_free (path); +} + +//Combierte el el último nodo a CUSP +//Crea una curva en el punto final de la green_curve +static void bspline_node_cusp(SPPenContext *const pc) +{ + + if (!pc->green_curve->is_empty()){ + using Geom::X; + using Geom::Y; + Geom::Point P0(0,0); + Geom::Point P1(0,0); + Geom::Point P2(0,0); + Geom::Point P3(0,0); + P0 = pc->green_curve->last_segment()->initialPoint(); + P1 = P0; + P3 = pc->green_curve->last_segment()->finalPoint(); + P2 = P3 + (1./3)*(P0 - P3); + P2 = Geom::Point(P2[X]+1,P2[Y]+1); + pc->p[0] = P3; + pc->p[1] = P3; + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->curveto(P1, P2,P3); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = last; + }else{ + pc->green_curve->backspace(); + pc->green_curve->append_continuous(last, 0.0625); + } + } + if (pc->sa && !pc->sa->curve->is_empty() && pc->green_curve->get_segment_count() == 1){ + using Geom::X; + using Geom::Y; + if(pc->sa->start){ + pc->sa->curve = reverse_then_reset(pc->sa->curve); + } + Geom::Point P0(0,0); + Geom::Point P1(0,0); + Geom::Point P2(0,0); + Geom::Point P3(0,0); + P0 = pc->sa->curve->last_segment()->initialPoint(); + P1 = P0; + P3 = pc->sa->curve->last_segment()->finalPoint(); + P2 = P3 + (1./3)*(P0 - P3); + P2 = Geom::Point(P2[X]+1,P2[Y]+1); + pc->p[0] = P3; + pc->p[1] = P3; + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->curveto(P1,P2,P3); + if( pc->sa->curve->get_segment_count() == 1){ + pc->sa->curve = last; + }else{ + pc->sa->curve->backspace(); + pc->sa->curve->append_continuous(last, 0.0625); + } + } + //Lo ejacutamos para que se actualize tosa la curva por un fallo de redibujo + bspline_build(pc,true); +} + +//Combierte el el último nodo a SYMM +//crea lineas rectas +static void bspline_node(SPPenContext *const pc) +{ + + if (!pc->green_curve->is_empty()){ + Geom::Point P0(0,0); + Geom::Point P1(0,0); + P0 = pc->green_curve->last_segment()->initialPoint(); + P1 = pc->green_curve->last_segment()->finalPoint(); + pc->p[1] = P1; + pc->p[0] = P1; + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->lineto(P1); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = last; + }else{ + pc->green_curve->backspace(); + pc->green_curve->append_continuous(last, 0.0625); + } + } +} + +//preparates the curves for its trasformation into BSline curves. +static void bspline_build(SPPenContext *const pc, bool Shift) +{ + if (pc->green_curve->is_empty() && !pc->sa) + return; + //We create the base curve + SPCurve *curve = new SPCurve(); + //If we continuate the existing curve we add it at the start + if(pc->sa && !pc->sa->curve->is_empty()){ + curve = pc->sa->curve->copy(); + if (pc->sa->start) { + curve = curve->create_reverse(); + } + } + //We add also the green curve + if (!pc->green_curve->is_empty()) { + curve->append_continuous(pc->green_curve, 0.0625); + } + //and the red one + if (!pc->red_curve->is_empty()) { + //we add the curve to the modified values + if((pc->ea && !pc->ea->curve->is_empty()) || (pc->green_anchor && pc->green_anchor->active)){ + if(Shift){ + using Geom::X; + using Geom::Y; + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); + pc->red_curve->reset(); + pc->npoints = 5; + pc->red_curve->moveto(pc->p[0]); + pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); + }else{ + pc->red_curve->reset(); + pc->npoints = 2; + pc->red_curve->moveto(pc->p[0]); + pc->red_curve->lineto(pc->red_curve->first_segment()->finalPoint()); + } + } + curve->append_continuous(pc->red_curve, 0.0625); + } + if(curve->get_segment_count() > 1 ){ + //cerramos la curva si estan cerca los puntos finales de la curva spiro + if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ + curve->closepath_current(); + } + //TODO: CALL TO CLONED FUNCTION SPIRO::doEffect IN lpe-spiro.cpp + //For example + //using namespace Inkscape::LivePathEffect; + //LivePathEffectObject *lpeobj = static_cast (curve); + //Effect *spr = static_cast ( new LPEBspline(lpeobj) ); + //spr->doEffect(curve); + bspline_doEffect(curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->blue_bpath), pc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_item_show(pc->blue_bpath); + curve->unref(); + pc->blue_curve->reset(); + //We hide the holders that doesn't contribute anything + sp_canvas_item_hide(pc->c1); + sp_canvas_item_hide(pc->cl1); + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->cl0); + }else { + //if the curve is empty + sp_canvas_item_hide(pc->blue_bpath); + } +} + +static void bspline_doEffect(SPCurve * curve) +{ + using Geom::X; + using Geom::Y; + + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); + curve->reset(); + int ip = 0; + //Sbasis + Geom::D2< Geom::SBasis > curveIn; + Geom::D2< Geom::SBasis > curveOut; + Geom::D2< Geom::SBasis > rectCurve; + Geom::D2< Geom::SBasis > rectCurveExtra; + //Puntos a usar. Ponemos todos los posibles para hacer más inteligible el código + Geom::Point startAnchor(0,0); + Geom::Point previousAnchor(0,0); + Geom::Point anchor(0,0); + Geom::Point previousSBasis0(0,0); + Geom::Point previousSBasis1(0,0); + Geom::Point previousSBasis2(0,0); + //Geom::Point previousSBasis3(0,0); + Geom::Point SBasis0(0,0); + Geom::Point SBasis1(0,0); + Geom::Point SBasis2(0,0); + Geom::Point SBasis3(0,0); + //Geom::Point nextSBasis0(0,0); + Geom::Point nextSBasis1(0,0); + Geom::Point nextSBasis2(0,0); + Geom::Point nextSBasis3(0,0); + //Curvas temporales + SPCurve *BSplineRectTemp = new SPCurve(); + SPCurve *BSplineCurveTemp = new SPCurve(); + SPCurve *BSplinePreviousCurveTemp = new SPCurve(); + //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... + if (path_it->empty()) + continue; + //Declaramos las variables + //Itreador + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + Geom::Path::const_iterator curve_end = path_it->end(); // last curve + Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + //por defecto la linea es recta. + //Para formar las bsplines contamos que si el nodo es cusp -sin manejadores + //se calcula el nodo resultante como BSpline. Si por el contrario tiene un manejador + //en el últimp punto de la cuva (pc->p[2]) calculamos la curva resultante para que forme un nodo cusp + bool is_line = true; + bool previous_is_line = true; + if (path_it->closed()) { + SBasis2 = curve_it1->toSBasis().valueAt(0.3334); + nextSBasis1 = curve_end->toSBasis().valueAt(0.6664); + BSplineRectTemp->moveto(nextSBasis1); + BSplineRectTemp->lineto(SBasis2); + startAnchor = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.5); + anchor = startAnchor; + BSplineRectTemp->reset(); + } + while ( curve_it2 != curve_endit ) + { + //Calculamos los dos puntos para seleccional el punto central de la línea que los une + curveIn = curve_it1->toSBasis(); + curveOut = curve_it2->toSBasis(); + previousSBasis0 = SBasis0; + previousSBasis1 = SBasis1; + previousSBasis2 = SBasis2; + //previousSBasis3 = SBasis3; + SBasis0 = curveIn.valueAt(0); + SBasis1 = curveIn.valueAt(0.3334); + SBasis2 = curveIn.valueAt(0.6667); + SBasis3 = curveIn.valueAt(1); + //nextSBasis0 = curveOut.valueAt(0); + nextSBasis1 = curveOut.valueAt(0.3334); + nextSBasis2 = curveOut.valueAt(0.6667);; + nextSBasis3 = curveOut.valueAt(1); + //Se forma con la union de dos puntos, el primero está en la curva entrante + // y se conoce dividiendo por tres la curva y seleccionado el + //punto mas cercano de los dos al nodo de union con la curva saliente. + //El otro punto es el puntio más cercano al nodo de union + //de la curva saliente dividida por tres. + BSplineRectTemp->moveto(SBasis2); + BSplineRectTemp->lineto(nextSBasis1); + previousAnchor = anchor; + anchor = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.5); + BSplineRectTemp->reset(); + //Vemos si el nodo es curva + previous_is_line = is_line; + is_line = is_straight_curve(*curve_it1); + if(!is_line && curve->get_segment_count() > 1){ + //Si no es curva convertimos la curva resultante a un nodo cusp + //aberiguamos el punto en donde deveria estar de manera fija + //independientemente de el manejador y movemos + BSplineRectTemp->moveto(SBasis0); + BSplineRectTemp->lineto(SBasis3); + SBasis1 = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.3334); + SBasis2 = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.6667); + BSplineRectTemp->reset(); + BSplineRectTemp->moveto(SBasis1); + BSplineRectTemp->lineto(previousSBasis2); + previousAnchor = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.5); + anchor = SBasis3; + BSplineRectTemp->reset(); + //averiguamos el nuevo vinal de curva entrante recreando de nuevo + //una linea y seleccionando su centro como origen + if(previous_is_line){ + BSplineCurveTemp->moveto(previousAnchor); + BSplineCurveTemp->curveto(SBasis1, SBasis2, anchor); + }else{ + BSplineCurveTemp->moveto(SBasis0); + BSplineCurveTemp->lineto(anchor); + } + BSplineRectTemp->reset(); + + //Como el origen ha cambiado, seleccionamos el ultimo punto + //de la curva ya creada y lo movemos al nuevo origen/final + Geom::CubicBezier const * cubic = dynamic_cast( curve->last_segment()); + if(cubic){ + BSplinePreviousCurveTemp->moveto((*cubic)[0]); + if(previous_is_line){ + BSplinePreviousCurveTemp->curveto((*cubic)[1],(*cubic)[2],previousAnchor); + } else { + BSplinePreviousCurveTemp->curveto((*cubic)[1],(*cubic)[2],curve->last_segment()->finalPoint()); + } + }else{ + BSplinePreviousCurveTemp->moveto(curve->last_segment()->initialPoint()); + BSplinePreviousCurveTemp->lineto(curve->last_segment()->finalPoint()); + } + if( curve->get_segment_count() == 1){ + curve = BSplinePreviousCurveTemp; + }else{ + curve->backspace(); + curve->append_continuous(BSplinePreviousCurveTemp, 0.0625); + } + BSplinePreviousCurveTemp->reset(); + }else{ + //Creamos la curva correspondiente a la posición actual del + //Iterador, para anexarla a la curva de salida + //almacena la SPCurve de un solo segmento que se va añadir al resiultado final + //en la itineración + if (ip == 0 && !path_it->closed()){ + BSplineCurveTemp->moveto(SBasis0); + }else{ + //Empezamos la curva el el final de la anterior curva + BSplineCurveTemp->moveto(previousAnchor); + } + BSplineCurveTemp->curveto(SBasis1, SBasis2, anchor); + } + curve->append_continuous(BSplineCurveTemp, 0.0625); + BSplineCurveTemp->reset(); + ++curve_it1; + ++curve_it2; + ip++; + } + //terminamos el trazado + BSplineCurveTemp->moveto(anchor); + is_line = is_straight_curve(*curve_it1); + if (path_it->closed() && is_line) { + BSplineCurveTemp->curveto(nextSBasis1, nextSBasis2, startAnchor); + }else{ + BSplineCurveTemp->curveto(nextSBasis1, nextSBasis2, nextSBasis3); + } + curve->append_continuous(BSplineCurveTemp, 0.0625); + BSplineCurveTemp->reset(); + if (path_it->closed()) { + curve->closepath_current(); + } + } +} + +//BSpline end + static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point const p, bool statusbar, guint status) { g_assert( pc->npoints != 0 ); @@ -1249,7 +2156,9 @@ static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point co is_curve = false; } else { // one of the 'regular' modes - if (pc->p[1] != pc->p[0]) { + //SpiroLive + if (pc->p[1] != pc->p[0] || pc->spiro) { + //SpiroLive End pc->red_curve->curveto(pc->p[1], p, p); is_curve = true; } else { @@ -1257,13 +2166,18 @@ static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point co is_curve = false; } } - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); - if (statusbar) { gchar *message = is_curve ? _("Curve segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path" ): _("Line segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"); + //BSpline + if(pc->spiro || pc->bspline){ + message = is_curve ? + _("Curve segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path" ): + _("Line segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path"); + } + //BSpline End spdc_pen_set_angle_distance_status_message(pc, p, 0, message); } } @@ -1277,9 +2191,12 @@ static void spdc_pen_set_ctrl(SPPenContext *const pc, Geom::Point const p, guint pc->p[1] = p; sp_canvas_item_hide(pc->c0); sp_canvas_item_hide(pc->cl0); - SP_CTRL(pc->c1)->moveto(pc->p[1]); + if(pc->spiro){ + SP_CTRL(pc->c1)->moveto(pc->p[1]); + }else{ + SP_CTRL(pc->c1)->moveto(pc->p[1]); + } pc->cl1->setCoords(pc->p[0], pc->p[1]); - spdc_pen_set_angle_distance_status_message(pc, p, 0, _("Curve handle: angle %3.2f°, length %s; with Ctrl to snap angle")); } else if ( pc->npoints == 5 ) { pc->p[4] = p; @@ -1300,7 +2217,6 @@ static void spdc_pen_set_ctrl(SPPenContext *const pc, Geom::Point const p, guint pc->cl0 ->setCoords(pc->p[3], pc->p[2]); SP_CTRL(pc->c1)->moveto(pc->p[4]); pc->cl1->setCoords(pc->p[3], pc->p[4]); - gchar *message = is_symm ? _("Curve handle, symmetric: angle %3.2f°, length %s; with Ctrl to snap angle, with Shift to move this handle only") : _("Curve handle: angle %3.2f°, length %s; with Ctrl to snap angle, with Shift to move this handle only"); diff --git a/src/pen-context.h b/src/pen-context.h index a68b76ff5..4485539cd 100644 --- a/src/pen-context.h +++ b/src/pen-context.h @@ -43,6 +43,11 @@ struct SPPenContext : public SPDrawContext { bool polylines_only; bool polylines_paraxial; + //SpiroLive + //Propiedad que guarda si el modo Spiro está activo o no + bool spiro; + bool bspline; + //SpiroLIve End int num_clicks; unsigned int expecting_clicks_for_LPE; // if positive, finish the path after this many clicks diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index d0e71d2b0..7e28f7c8c 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -139,7 +139,14 @@ static void sp_add_freehand_mode_toggle(GtkActionGroup* mainActions, GObject* ho 1, _("Create Spiro path"), 2, INKSCAPE_ICON("path-mode-spiro"), -1 ); - + //BSpline + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("BSpline"), + 1, _("Create BSpline path"), + 2, INKSCAPE_ICON("path-mode-bspline"), + -1 ); + //BSpline if (!tool_is_pencil) { gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, -- cgit v1.2.3 From e6d37f6e87aad1a48740c7096408e2457d3527a1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 21 Dec 2012 09:33:52 +0100 Subject: not working (bzr r11950.1.3) --- src/pen-context.cpp | 844 +++++++++++++++++++++++-------------------------- src/pencil-context.cpp | 19 +- 2 files changed, 411 insertions(+), 452 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index be25b6a7f..6d35d0897 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -58,6 +58,11 @@ #include "helper/geom-nodetype.h" #include "helper/geom-curves.h" +// For handling un-continuous paths: +#include "message-stack.h" +#include "inkscape.h" +#include "desktop.h" + #include "live_effects/spiro.h" #define INKSCAPE_LPE_BSPLINE_C @@ -87,20 +92,16 @@ static void spdc_pen_set_initial_point(SPPenContext *pc, Geom::Point const p); static void sp_pen_context_set_mode(SPPenContext *const pc, guint mode); //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void spiro_color(SPPenContext *const pc); -//Combierte el el último nodo a CUSP -static void spiro_node_cusp (SPPenContext *const pc); -//Combierte el el último nodo a SYMM -static void spiro_node_symm (SPPenContext *const pc); -//preparates the curves for its trasformation into spiro curves. -static void spiro_build(SPPenContext *const pc, bool Shift); +//Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT +static void spiro_prepare(SPPenContext *const pc, bool Shift); +//Unimos todas las curvas en juego y llamamos a la función doEffect. +static void spiro_build(SPPenContext *const pc); //function spiro cloned from lpe-spiro.cpp static void spiro_doEffect(SPCurve * curve); -//Combierte el el último nodo a CUSP -static void bspline_node_cusp (SPPenContext *const pc); -//Combierte el el último nodo a BSpline -static void bspline_node (SPPenContext *const pc); -//preparates the curves for its trasformation into bspline curves. -static void bspline_build(SPPenContext *const pc, bool Shift); +//Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT +static void bspline_prepare(SPPenContext *const pc,bool Shift); +//Unimos todas las curvas en juego y llamamos a la función doEffect. +static void bspline_build(SPPenContext *const pc); //function bspline cloned from lpe-bspline.cpp static void bspline_doEffect(SPCurve * curve); //BSpline end @@ -476,7 +477,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); //BSpline //with this we avoid creating a new point over the existing one - if((pc->spiro || pc->bspline) && (!anchor || pc->p[0] == pc->p[3]) && pc->p[0] == pc->desktop->w2d(event_w)){ + if((pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ return FALSE; } //BSpline end @@ -669,7 +670,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons //"spiro_color" lo ejecutamos siempre sea o no spiro spiro_color(pc); if (pen_within_tolerance) { - if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance && mevent.time != 0) { + if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance) { return FALSE; // Do not drag if we're within tolerance from origin. } } @@ -766,8 +767,9 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons // snap the handle spdc_endpoint_snap_handle(pc, p, mevent.state); - - if (!pc->polylines_only) { + //BSpline + if (!pc->polylines_only && !pc->bspline && !pc->spiro) { + //BSpline End spdc_pen_set_ctrl(pc, p, mevent.state); } else { spdc_pen_set_ctrl(pc, pc->p[1], mevent.state); @@ -792,39 +794,14 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons break; } //BSpline - if(pc->spiro){ - //Here we redraw the Spiro curve when the cursor is moved - //and the tolerance distance is exceeded. - //the tolerance value can be multiplied to improve the performance - //but it would lost fluency. - //If the cursor stops the curve is also redrawed. - if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { - //and we redraw the spiro - if ((mevent.state & GDK_SHIFT_MASK)){ - spiro_build(pc,true); - }else{ - spiro_build(pc,false); - } - //we update the distance and the tolerance - pen_drag_origin_w = event_w; + if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + if(pc->spiro){ + spiro_prepare(pc,(mevent.state & GDK_SHIFT_MASK)); } - } - if(pc->bspline){ - //Here we redraw the Bspline curve when the cursor is moved - //and the tolerance distance is exceeded. - //the tolerance value can be multiplied to improve the performance - //but it would lost fluency. - //If the cursor stops the curve is also redrawed. - if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { - //and we redraw the spiro - if ((mevent.state & GDK_SHIFT_MASK)){ - bspline_build(pc,true); - }else{ - bspline_build(pc,false); - } - //we update the distance and the tolerance - pen_drag_origin_w = event_w; + if(pc->bspline){ + bspline_prepare(pc,(mevent.state & GDK_SHIFT_MASK)); } + pen_drag_origin_w = event_w; } //BSpline End return ret; @@ -841,7 +818,6 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con } gint ret = FALSE; - SPEventContext *event_context = SP_EVENT_CONTEXT(pc); if ( revent.button == 1 && !event_context->space_panning ) { SPDrawContext *dc = SP_DRAW_CONTEXT (pc); @@ -856,7 +832,7 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con //BSpline if(pc->spiro || pc->bspline){ //Si intentamos crear un nodo en el mismo sitio que el origen, paramos. - if((!anchor || pc->p[0] == pc->p[3]) && pc->p[0] == p){ + if(pc->npoints > 0 && pc->p[0] == pc->p[3]){ return FALSE; } } @@ -879,6 +855,14 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con p = anchor->dp; } } + //BSpline + if(pc->spiro){ + spiro_prepare(pc,(revent.state & GDK_SHIFT_MASK)); + } + if(pc->bspline){ + bspline_prepare(pc,(revent.state & GDK_SHIFT_MASK)); + } + //BSpline End pc->state = SP_PEN_CONTEXT_CONTROL; ret = TRUE; break; @@ -895,13 +879,13 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con spdc_endpoint_snap(pc, p, revent.state); } spdc_pen_finish_segment(pc, p, revent.state); - spdc_pen_finish(pc, TRUE); //BSpline //Ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } //BSpline End + spdc_pen_finish(pc, TRUE); pc->state = SP_PEN_CONTEXT_POINT; ret = TRUE; break; @@ -924,6 +908,12 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con case SP_PEN_CONTEXT_CLOSE: spdc_endpoint_snap(pc, p, revent.state); spdc_pen_finish_segment(pc, p, revent.state); + //BSpline + //Ocultamos la guia del penultimo nodo al cerrar la curva + if(pc->spiro){ + sp_canvas_item_hide(pc->c1); + } + //BSpline End if (pc->green_closed) { // finishing at the start anchor, close curve spdc_pen_finish(pc, TRUE); @@ -931,12 +921,6 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con // finishing at some other anchor, finish curve but not close spdc_pen_finish(pc, FALSE); } - //BSpline - if(pc->spiro){ - //Ocultamos la guia del penultimo nodo al cerrar la curva - sp_canvas_item_hide(pc->c1); - } - //BSpline End break; case SP_PEN_CONTEXT_STOP: // This is allowed, if we just cancelled curve @@ -960,28 +944,6 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con dc->green_closed = FALSE; } - //BSpline - if(pc->spiro){ - //Ejecutamos la función tipo de nodo segun tengamos la mayuscula presionada - if ((revent.state & GDK_SHIFT_MASK)){ - spiro_node_cusp(pc); - spiro_build(pc,true); - }else{ - spiro_node_symm(pc); - spiro_build(pc,false); - } - } - if(pc->bspline){ - //Ejecutamos la función tipo de nodo segun tengamos la mayuscula presionada - if ((revent.state & GDK_SHIFT_MASK)){ - bspline_node_cusp(pc); - bspline_build(pc, true); - }else{ - bspline_node(pc); - bspline_build(pc, false); - } - } - //BSpline End // TODO: can we be sure that the path was created correctly? // TODO: should we offer an option to collect the clicks in a list? @@ -1070,11 +1032,11 @@ static void pen_redraw_all (SPPenContext *const pc) //sino al final de esta if(pc->spiro){ //we redraw spiro - spiro_build(pc, true); + spiro_build(pc); } if(pc->bspline){ //we redraw bspline - bspline_build(pc, false); + bspline_build(pc); } //BSpline End } @@ -1160,10 +1122,15 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) B = pc->green_curve->last_segment()->finalPoint(); previous->moveto(A); previous->lineto(B); - //we eliminate the last segment - pc->green_curve->backspace(); - //and we add it again with the recreation - pc->green_curve->append_continuous(previous, 0.0625); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = previous; + }else{ + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } + } //Spiro Live pen_redraw_all(pc); @@ -1181,7 +1148,7 @@ static void pen_lastpoint_toline (SPPenContext *const pc) //BSpline //Para formar una recta necesitamos un nodo con manejador en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que tenga manejador - if(pc->bspline){ + if(pc->bspline && !pc->green_curve->is_empty()){ Geom::Point A(0,0); Geom::Point B(0,0); Geom::Point C(0,0); @@ -1190,14 +1157,19 @@ static void pen_lastpoint_toline (SPPenContext *const pc) //We obtain the last segment 4 points in the previous curve A = pc->green_curve->last_segment()->initialPoint(); B = pc->green_curve->last_segment()->initialPoint(); - C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); + C = pc->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(pc->green_curve->last_segment()->initialPoint() - pc->green_curve->last_segment()->finalPoint()); D = pc->green_curve->last_segment()->finalPoint(); previous->moveto(A); previous->curveto(B, C, D); - //we eliminate the last segment - pc->green_curve->backspace(); - //and we add it again with the recreation - pc->green_curve->append_continuous(previous, 0.0625); + + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = previous; + }else{ + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } } pen_redraw_all(pc); @@ -1514,103 +1486,114 @@ static void spiro_color(SPPenContext *const pc) sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->red_bpath), pc->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); } -//Combierte el el último nodo a CUSP -static void spiro_node_cusp (SPPenContext *const pc) -{ - if(pc->green_curve->is_empty()) - return; - Geom::Point P0(0,0); - Geom::Point P1(0,0); - Geom::Point P2(0,0); - Geom::Point P3(0,0); - Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment()); - if(cubic){ - P0 = (*cubic)[0]; - P1 = (*cubic)[1]; - P2 = (*cubic)[3]; - P3 = (*cubic)[3]; - } - pc->p[0] + P3; - pc->p[1] = P3 - (1./3)*(Geom::Point)( P0 - P3 ); - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->curveto(P1,P2,P3); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = last; - }else{ - pc->green_curve->backspace(); - pc->green_curve->append_continuous(last, 0.0625); - } -} -//Combierte el el último nodo a SYMM -//Solo se ejecuta al final de el evento release button -static void spiro_node_symm(SPPenContext *const pc) +//Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT +static void spiro_prepare(SPPenContext *const pc, bool Shift) { - //Si empezamos sobre una curva ya existente - if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ - Geom::CubicBezier const * cubic; - if (pc->sa->start) { - cubic = dynamic_cast( pc->sa->curve->first_segment() ); - if ( cubic ) { - pc->p[1] = (pc->p[0]-(*cubic)[1]) + pc->p[0]; + if(Shift){ + //Creamos un nodo CUSP + pc->npoints = 5; + pc->p[2] = pc->p[3]; + //Si empezamos sobre otra curva en modo cusp la alteramos para que no tenga manejador final + //recreando la curva e igualando el punto del manejador al punto fiinal de la curva + if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && !pc->ea && pc->green_curve->is_empty()){ + bool reverse = false; + Geom::CubicBezier const * cubic; + if(pc->sa->start){ + reverse = true; + pc->sa->curve = reverse_then_reset(pc->sa->curve); } - }else{ - cubic = dynamic_cast( pc->sa->curve->last_segment() ); - if ( cubic ) { - pc->p[1] = (pc->p[0]-(*cubic)[2]) + pc->p[0]; + Geom::Point P0(0,0); + Geom::Point P1(0,0); + Geom::Point P2(0,0); + Geom::Point P3(0,0); + Geom::Point P4(0,0); + cubic = dynamic_cast( pc->sa->curve->last_segment()); + if(cubic){ + P0 = pc->sa->curve->last_segment()->initialPoint(); + P1 = (*cubic)[1]; + P3 = pc->sa->curve->last_segment()->finalPoint(); + P2 = P3; + }else{ + P0 = pc->sa->curve->last_segment()->initialPoint(); + P1 = P0; + P3 = pc->sa->curve->last_segment()->finalPoint(); + P2 = P3; + } + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->curveto(P1,P2,P3); + if( pc->sa->curve->get_segment_count() == 1){ + pc->sa->curve = last; + }else{ + pc->sa->curve->backspace(); + pc->sa->curve->append_continuous(last, 0.0625); + } + if(reverse){ + pc->sa->curve = reverse_then_reset(pc->sa->curve); } + delete last; } - } - //Cuando cerramos el segmento - if (!pc->green_curve->is_empty()){ - Geom::Point P0(0,0); - Geom::Point P1(0,0); - Geom::Point P2(0,0); - Geom::Point P3(0,0); - Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment()); - if(cubic){ - P0 = (*cubic)[0]; - P1 = (*cubic)[1]; - P2 = (*cubic)[3] + (1./3)*((*cubic)[0] - (*cubic)[3]); - P3 = (*cubic)[3]; - }else{ - P0 = pc->green_curve->last_segment()->initialPoint(); - P1 = P0; - P3 = pc->green_curve->last_segment()->finalPoint(); - P2 = P3 + (1./3)*(P0 - P3); + + }else{ + //Symm nodo + using Geom::X; + using Geom::Y; + Geom::CubicBezier const * cubic; + + //Damos valores a los puntos de la curva roja para que generen un nodo SYMM + if(!pc->red_curve->is_empty()){ + pc->npoints = 5; + //Les damos valor + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[4] = pc->p[3] + (Geom::Point)( pc->p[3] - pc->p[2] ); + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); } - pc->p[1] = pc->p[0] + (Geom::Point)( pc->p[0] - P2 ); - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->curveto(P1,P2,P3); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = last; - }else{ - pc->green_curve->backspace(); - pc->green_curve->append_continuous(last, 0.0625); + //Continuamos la curva en modo SPIRO + if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && !pc->ea && pc->green_curve->is_empty()){ + cubic = dynamic_cast( pc->sa->curve->last_segment()); + if (pc->sa->start) { + cubic = dynamic_cast( pc->sa->curve->create_reverse()->last_segment() ); + } + if(cubic){ + pc->p[1] = (pc->p[0] - (*cubic)[2]) + pc->p[0]; + } } - } - //por si cerramos la curva - if(pc->ea && !pc->ea->curve->is_empty()){ - Geom::CubicBezier const * cubic; - if(pc->ea->start){ - cubic = dynamic_cast( pc->ea->curve->first_segment()); + //Nos aseguramos que el primer nodo sea SYMM con el ultimo segmento de la curva verde + if(!pc->green_curve->is_empty()){ + cubic = dynamic_cast( pc->green_curve->last_segment()); + if(cubic && (*cubic)[2] != (*cubic)[3]){ + pc->p[1] = (pc->p[0] - (*cubic)[2]) + pc->p[0]; + } + } + + //Si cerramos sobre otra curva ponemos simetrico a esta el manejador del punto de cierre + if(pc->ea && !pc->ea->curve->is_empty()){ + cubic = dynamic_cast( pc->ea->curve->last_segment() ); + if (pc->ea->start) { + cubic = dynamic_cast( pc->ea->curve->create_reverse()->last_segment() ); + } if(cubic){ - pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[1] ); + pc->p[2] = (pc->p[3]-(*cubic)[2]) + pc->p[3]; } - }else{ - cubic = dynamic_cast( pc->ea->curve->last_segment()); + } + //Lo mismpo pero cerrando sobre la curva inicial + if(pc->green_anchor && pc->green_anchor->active){ + cubic = dynamic_cast( pc->green_curve->first_segment() ); if(cubic){ - pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[2] ); + pc->p[2] = (pc->p[3]-(*cubic)[1]) + pc->p[3]; } } + } + spiro_build(pc); } -//preparates the curves for its trasformation into spiro curves. -//Parámetro opcional que indica si la curva se cierra en que modo lo hace Cusp o Symm -static void spiro_build(SPPenContext *const pc, bool Shift) + +//Unimos todas las curvas en juego y llamamos a la función doEffect. +static void spiro_build(SPPenContext *const pc) { //We create the base curve SPCurve *curve = new SPCurve(); @@ -1622,49 +1605,23 @@ static void spiro_build(SPPenContext *const pc, bool Shift) } } //We add also the green curve - if (!pc->green_curve->is_empty()) { + if (!pc->green_curve->is_empty()) curve->append_continuous(pc->green_curve, 0.0625); - } + //and the red one - if (!pc->red_curve->is_empty()) { - //we add the curve to the modified values - if(!Shift){ - if(pc->ea && !pc->ea->curve->is_empty()){ - Geom::CubicBezier const * cubic; - if(pc->ea->start){ - cubic = dynamic_cast( pc->ea->curve->first_segment()); - if(cubic){ - pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[1] ); - } - }else{ - cubic = dynamic_cast( pc->ea->curve->last_segment()); - if(cubic){ - pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[2] ); - } - } - } else if(pc->green_anchor && pc->green_anchor->active){ - Geom::CubicBezier const * cubic; - cubic = dynamic_cast( pc->green_curve->first_segment()); - if(cubic){ - pc->p[2] = pc->p[3] + (Geom::Point)( pc->p[3] - (*cubic)[1] ); - } - } - if(pc->p[2] != pc->p[3]){ - pc->red_curve->reset(); - pc->npoints = 5; - pc->red_curve->moveto(pc->p[0]); - pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); - } + if (!pc->red_curve->is_empty()){ + pc->red_curve->reset(); + pc->red_curve->moveto(pc->p[0]); + pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); + curve->append_continuous(pc->red_curve, 0.0625); + } + + if(!pc->sa && pc->ea && !pc->ea->curve->is_empty()){ + if (pc->ea->start) { + curve->append_continuous(pc->ea->curve, 0.0625); }else{ - if((pc->ea && !pc->ea->curve->is_empty()) || (pc->green_anchor && pc->green_anchor->active)){ - pc->p[2] == pc->p[3]; - pc->red_curve->reset(); - pc->npoints = 5; - pc->red_curve->moveto(pc->p[0]); - pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); - } + curve->append_continuous(pc->ea->curve->create_reverse(), 0.0625); } - curve->append_continuous(pc->red_curve, 0.0625); } if(!curve->is_empty()){ //cerramos la curva si estan cerca los puntos finales de la curva spiro @@ -1675,7 +1632,7 @@ static void spiro_build(SPPenContext *const pc, bool Shift) //For example //using namespace Inkscape::LivePathEffect; //LivePathEffectObject *lpeobj = static_cast (curve); - //Effect *spr = static_cast ( new LPESpiro(lpeobj) ); + //Effect *spr = static_cast ( new LPEspiro(lpeobj) ); //spr->doEffect(curve); spiro_doEffect(curve); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve); @@ -1805,95 +1762,70 @@ static void spiro_doEffect(SPCurve * curve) g_free (path); } -//Combierte el el último nodo a CUSP -//Crea una curva en el punto final de la green_curve -static void bspline_node_cusp(SPPenContext *const pc) +//Unimos todas las curvas en juego y llamamos a la función doEffect. +static void bspline_prepare(SPPenContext *const pc, bool Shift) { - - if (!pc->green_curve->is_empty()){ - using Geom::X; - using Geom::Y; - Geom::Point P0(0,0); - Geom::Point P1(0,0); - Geom::Point P2(0,0); - Geom::Point P3(0,0); - P0 = pc->green_curve->last_segment()->initialPoint(); - P1 = P0; - P3 = pc->green_curve->last_segment()->finalPoint(); - P2 = P3 + (1./3)*(P0 - P3); - P2 = Geom::Point(P2[X]+1,P2[Y]+1); - pc->p[0] = P3; - pc->p[1] = P3; - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->curveto(P1, P2,P3); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = last; - }else{ - pc->green_curve->backspace(); - pc->green_curve->append_continuous(last, 0.0625); + if(!Shift){ + //Modo Bspline formado por nodos CUSP + if (pc->npoints == 5){ + pc->npoints = 2; + pc->p[1]= pc->p[3]; } - } - if (pc->sa && !pc->sa->curve->is_empty() && pc->green_curve->get_segment_count() == 1){ + }else{ + //NODO CUSP formado por nodo SMOOTH + //solo mobemos el manejador del nodo final de cada segmento + //Es suficiente para mostrar el nodo como CUSP using Geom::X; using Geom::Y; - if(pc->sa->start){ - pc->sa->curve = reverse_then_reset(pc->sa->curve); + bool reverse = false; + //Usamos 5 puntos + if(pc->npoints == 2){ + pc->npoints = 5; } - Geom::Point P0(0,0); - Geom::Point P1(0,0); - Geom::Point P2(0,0); - Geom::Point P3(0,0); - P0 = pc->sa->curve->last_segment()->initialPoint(); - P1 = P0; - P3 = pc->sa->curve->last_segment()->finalPoint(); - P2 = P3 + (1./3)*(P0 - P3); - P2 = Geom::Point(P2[X]+1,P2[Y]+1); - pc->p[0] = P3; - pc->p[1] = P3; - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->curveto(P1,P2,P3); - if( pc->sa->curve->get_segment_count() == 1){ - pc->sa->curve = last; - }else{ - pc->sa->curve->backspace(); - pc->sa->curve->append_continuous(last, 0.0625); + pc->p[1] = pc->p[0]; + //Les damos valor + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[4] = pc->p[3]; + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + + //Si empezamos sobre otra curva hay que modificarla para que tenga manejador en el último nodo + if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && !pc->ea && pc->green_curve->is_empty()){ + if(pc->sa->start){ + reverse = true; + pc->sa->curve = reverse_then_reset(pc->sa->curve); + } + Geom::Point P0(0,0); + Geom::Point P1(0,0); + Geom::Point P2(0,0); + Geom::Point P3(0,0); + Geom::Point P4(0,0); + P0 = pc->sa->curve->last_segment()->initialPoint(); + P1 = P0; + P3 = pc->sa->curve->last_segment()->finalPoint(); + P2 = P3 + (1./3)*(P0 - P3); + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->curveto(P1,P2,P3); + if( pc->sa->curve->get_segment_count() == 1){ + pc->sa->curve = last; + }else{ + pc->sa->curve->backspace(); + pc->sa->curve->append_continuous(last, 0.0625); + } + if(reverse){ + pc->sa->curve = reverse_then_reset(pc->sa->curve); + } + delete last; } } - //Lo ejacutamos para que se actualize tosa la curva por un fallo de redibujo - bspline_build(pc,true); +bspline_build(pc); } -//Combierte el el último nodo a SYMM -//crea lineas rectas -static void bspline_node(SPPenContext *const pc) -{ - if (!pc->green_curve->is_empty()){ - Geom::Point P0(0,0); - Geom::Point P1(0,0); - P0 = pc->green_curve->last_segment()->initialPoint(); - P1 = pc->green_curve->last_segment()->finalPoint(); - pc->p[1] = P1; - pc->p[0] = P1; - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->lineto(P1); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = last; - }else{ - pc->green_curve->backspace(); - pc->green_curve->append_continuous(last, 0.0625); - } - } -} //preparates the curves for its trasformation into BSline curves. -static void bspline_build(SPPenContext *const pc, bool Shift) +static void bspline_build(SPPenContext *const pc) { - if (pc->green_curve->is_empty() && !pc->sa) - return; //We create the base curve SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start @@ -1904,31 +1836,28 @@ static void bspline_build(SPPenContext *const pc, bool Shift) } } //We add also the green curve - if (!pc->green_curve->is_empty()) { + if (!pc->green_curve->is_empty()) curve->append_continuous(pc->green_curve, 0.0625); - } + //and the red one - if (!pc->red_curve->is_empty()) { - //we add the curve to the modified values - if((pc->ea && !pc->ea->curve->is_empty()) || (pc->green_anchor && pc->green_anchor->active)){ - if(Shift){ - using Geom::X; - using Geom::Y; - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); - pc->red_curve->reset(); - pc->npoints = 5; - pc->red_curve->moveto(pc->p[0]); - pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); - }else{ - pc->red_curve->reset(); - pc->npoints = 2; - pc->red_curve->moveto(pc->p[0]); - pc->red_curve->lineto(pc->red_curve->first_segment()->finalPoint()); - } + if (!pc->red_curve->is_empty()){ + pc->red_curve->reset(); + pc->red_curve->moveto(pc->p[0]); + if(pc->npoints == 2){ + pc->red_curve->lineto(pc->p[1]); + }else{ + pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); } curve->append_continuous(pc->red_curve, 0.0625); } + + if(!pc->sa && pc->ea && !pc->ea->curve->is_empty()){ + if (pc->ea->start) { + curve->append_continuous(pc->ea->curve, 0.0625); + }else{ + curve->append_continuous(pc->ea->curve->create_reverse(), 0.0625); + } + } if(curve->get_segment_count() > 1 ){ //cerramos la curva si estan cerca los puntos finales de la curva spiro if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ @@ -1938,7 +1867,7 @@ static void bspline_build(SPPenContext *const pc, bool Shift) //For example //using namespace Inkscape::LivePathEffect; //LivePathEffectObject *lpeobj = static_cast (curve); - //Effect *spr = static_cast ( new LPEBspline(lpeobj) ); + //Effect *spr = static_cast ( new LPEbspline_prepare(lpeobj) ); //spr->doEffect(curve); bspline_doEffect(curve); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve); @@ -1951,7 +1880,7 @@ static void bspline_build(SPPenContext *const pc, bool Shift) sp_canvas_item_hide(pc->cl1); sp_canvas_item_hide(pc->c0); sp_canvas_item_hide(pc->cl0); - }else { + }else{ //if the curve is empty sp_canvas_item_hide(pc->blue_bpath); } @@ -1965,167 +1894,174 @@ static void bspline_doEffect(SPCurve * curve) // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); - int ip = 0; //Sbasis - Geom::D2< Geom::SBasis > curveIn; - Geom::D2< Geom::SBasis > curveOut; - Geom::D2< Geom::SBasis > rectCurve; - Geom::D2< Geom::SBasis > rectCurveExtra; - //Puntos a usar. Ponemos todos los posibles para hacer más inteligible el código - Geom::Point startAnchor(0,0); - Geom::Point previousAnchor(0,0); - Geom::Point anchor(0,0); - Geom::Point previousSBasis0(0,0); - Geom::Point previousSBasis1(0,0); - Geom::Point previousSBasis2(0,0); - //Geom::Point previousSBasis3(0,0); - Geom::Point SBasis0(0,0); - Geom::Point SBasis1(0,0); - Geom::Point SBasis2(0,0); - Geom::Point SBasis3(0,0); - //Geom::Point nextSBasis0(0,0); - Geom::Point nextSBasis1(0,0); - Geom::Point nextSBasis2(0,0); - Geom::Point nextSBasis3(0,0); + Geom::D2< Geom::SBasis > SBasisIn; + Geom::D2< Geom::SBasis > SBasisOut; + Geom::D2< Geom::SBasis > SBasisEnd; + Geom::D2< Geom::SBasis > SBasisHelper; + //curves + SPCurve * in = new SPCurve(); + SPCurve * out = new SPCurve(); + SPCurve * end = new SPCurve(); //Curvas temporales - SPCurve *BSplineRectTemp = new SPCurve(); - SPCurve *BSplineCurveTemp = new SPCurve(); - SPCurve *BSplinePreviousCurveTemp = new SPCurve(); + 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); + Geom::Point node(0,0); + Geom::Point previousPointAt0(0,0); + Geom::Point previousPointAt1(0,0); + Geom::Point previousPointAt2(0,0); + //Geom::Point previousPointAt3(0,0); + Geom::Point pointAt0(0,0); + Geom::Point pointAt1(0,0); + Geom::Point pointAt2(0,0); + Geom::Point pointAt3(0,0); + //Geom::Point nextPointAt0(0,0); + Geom::Point nextPointAt1(0,0); + Geom::Point nextPointAt2(0,0); + Geom::Point nextPointAt3(0,0); + //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... if (path_it->empty()) continue; - //Declaramos las variables - //Itreador + //Itreadores Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_end = path_it->end(); // last 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 - //por defecto la linea es recta. - //Para formar las bsplines contamos que si el nodo es cusp -sin manejadores - //se calcula el nodo resultante como BSpline. Si por el contrario tiene un manejador - //en el últimp punto de la cuva (pc->p[2]) calculamos la curva resultante para que forme un nodo cusp - bool is_line = true; - bool previous_is_line = true; - if (path_it->closed()) { - SBasis2 = curve_it1->toSBasis().valueAt(0.3334); - nextSBasis1 = curve_end->toSBasis().valueAt(0.6664); - BSplineRectTemp->moveto(nextSBasis1); - BSplineRectTemp->lineto(SBasis2); - startAnchor = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.5); - anchor = startAnchor; - BSplineRectTemp->reset(); + //Las lineas rectas forman nodos BSpline + //Las curvas forman nodos CUSP + bool isBSpline = true; + //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 + //dichos manejadores + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + //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 + if (path_it->closed() && is_straight_curve(*curve_end)) { + //Calculamos el nodo de inicio BSpline + SBasisIn = in->first_segment()->toSBasis(); + SBasisEnd = end->first_segment()->toSBasis(); + lineHelper->moveto(SBasisIn.valueAt(0.3334)); + lineHelper->lineto(SBasisEnd.valueAt(0.6664)); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //Guardamos el principio de la curva + startNode = SBasisHelper.valueAt(0.5); + //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 ) { - //Calculamos los dos puntos para seleccional el punto central de la línea que los une - curveIn = curve_it1->toSBasis(); - curveOut = curve_it2->toSBasis(); - previousSBasis0 = SBasis0; - previousSBasis1 = SBasis1; - previousSBasis2 = SBasis2; - //previousSBasis3 = SBasis3; - SBasis0 = curveIn.valueAt(0); - SBasis1 = curveIn.valueAt(0.3334); - SBasis2 = curveIn.valueAt(0.6667); - SBasis3 = curveIn.valueAt(1); - //nextSBasis0 = curveOut.valueAt(0); - nextSBasis1 = curveOut.valueAt(0.3334); - nextSBasis2 = curveOut.valueAt(0.6667);; - nextSBasis3 = curveOut.valueAt(1); - //Se forma con la union de dos puntos, el primero está en la curva entrante - // y se conoce dividiendo por tres la curva y seleccionado el - //punto mas cercano de los dos al nodo de union con la curva saliente. - //El otro punto es el puntio más cercano al nodo de union - //de la curva saliente dividida por tres. - BSplineRectTemp->moveto(SBasis2); - BSplineRectTemp->lineto(nextSBasis1); - previousAnchor = anchor; - anchor = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.5); - BSplineRectTemp->reset(); - //Vemos si el nodo es curva - previous_is_line = is_line; - is_line = is_straight_curve(*curve_it1); - if(!is_line && curve->get_segment_count() > 1){ - //Si no es curva convertimos la curva resultante a un nodo cusp - //aberiguamos el punto en donde deveria estar de manera fija - //independientemente de el manejador y movemos - BSplineRectTemp->moveto(SBasis0); - BSplineRectTemp->lineto(SBasis3); - SBasis1 = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.3334); - SBasis2 = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.6667); - BSplineRectTemp->reset(); - BSplineRectTemp->moveto(SBasis1); - BSplineRectTemp->lineto(previousSBasis2); - previousAnchor = BSplineRectTemp->first_segment()->toSBasis().valueAt(0.5); - anchor = SBasis3; - BSplineRectTemp->reset(); - //averiguamos el nuevo vinal de curva entrante recreando de nuevo - //una linea y seleccionando su centro como origen - if(previous_is_line){ - BSplineCurveTemp->moveto(previousAnchor); - BSplineCurveTemp->curveto(SBasis1, SBasis2, anchor); - }else{ - BSplineCurveTemp->moveto(SBasis0); - BSplineCurveTemp->lineto(anchor); - } - BSplineRectTemp->reset(); - - //Como el origen ha cambiado, seleccionamos el ultimo punto - //de la curva ya creada y lo movemos al nuevo origen/final - Geom::CubicBezier const * cubic = dynamic_cast( curve->last_segment()); - if(cubic){ - BSplinePreviousCurveTemp->moveto((*cubic)[0]); - if(previous_is_line){ - BSplinePreviousCurveTemp->curveto((*cubic)[1],(*cubic)[2],previousAnchor); - } else { - BSplinePreviousCurveTemp->curveto((*cubic)[1],(*cubic)[2],curve->last_segment()->finalPoint()); - } - }else{ - BSplinePreviousCurveTemp->moveto(curve->last_segment()->initialPoint()); - BSplinePreviousCurveTemp->lineto(curve->last_segment()->finalPoint()); - } - if( curve->get_segment_count() == 1){ - curve = BSplinePreviousCurveTemp; - }else{ - curve->backspace(); - curve->append_continuous(BSplinePreviousCurveTemp, 0.0625); - } - BSplinePreviousCurveTemp->reset(); - }else{ - //Creamos la curva correspondiente a la posición actual del - //Iterador, para anexarla a la curva de salida - //almacena la SPCurve de un solo segmento que se va añadir al resiultado final - //en la itineración - if (ip == 0 && !path_it->closed()){ - BSplineCurveTemp->moveto(SBasis0); - }else{ - //Empezamos la curva el el final de la anterior curva - BSplineCurveTemp->moveto(previousAnchor); - } - BSplineCurveTemp->curveto(SBasis1, SBasis2, anchor); + //Damos valor a el objeto SBasis para el path de entrada y el de salida + SBasisIn = in->first_segment()->toSBasis(); + SBasisOut = out->first_segment()->toSBasis(); + //Damos valor a los puntos calculados en el anterior paso del bucle + previousPointAt0 = pointAt0; + previousPointAt1 = pointAt1; + previousPointAt2 = pointAt2; + //previousPointAt3 = pointAt3; + //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida + pointAt0 = SBasisIn.valueAt(0); + pointAt1 = SBasisIn.valueAt(0.3334); + pointAt2 = SBasisIn.valueAt(0.6667); + pointAt3 = SBasisIn.valueAt(1); + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + nextPointAt1 = SBasisOut.valueAt(0.3334); + nextPointAt2 = SBasisOut.valueAt(0.6667);; + nextPointAt3 = SBasisOut.valueAt(1); + //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 + 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); + //Vemos si el nodo es BSpline o CUSP + //Averiguamos si el path de entrada es recto o tiene manejadores + isBSpline = is_straight_curve(*curve_it1); + //Si no es recto, tenemos que generar la curva con nodo final CUSP + if(!isBSpline ){ + //Definimos como nodo el final del segmento de entrada + node = pointAt3; } - curve->append_continuous(BSplineCurveTemp, 0.0625); - BSplineCurveTemp->reset(); + curveHelper->moveto(previousNode); + curveHelper->curveto(pointAt1, pointAt2, node); + //añadimos la curva generada a la curva pricipal + nCurve->append_continuous(curveHelper, 0.0625); + curveHelper->reset(); + //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; - ip++; + in->reset(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + out->reset(); + if(curve_it1 != curve_end){ + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + } } - //terminamos el trazado - BSplineCurveTemp->moveto(anchor); - is_line = is_straight_curve(*curve_it1); - if (path_it->closed() && is_line) { - BSplineCurveTemp->curveto(nextSBasis1, nextSBasis2, startAnchor); + //Aberiguamos la ultima parte de la curva correspondiente al último segmento + curveHelper->moveto(node); + //Si está cerrada la curva, la cerramos sobre el valor guardado previamente + //Si no finalizamos en el punto final + if (path_it->closed()) { + curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); }else{ - BSplineCurveTemp->curveto(nextSBasis1, nextSBasis2, nextSBasis3); + curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); } - curve->append_continuous(BSplineCurveTemp, 0.0625); - BSplineCurveTemp->reset(); + //añadimos este último segmento + nCurve->append_continuous(curveHelper, 0.0625); + //y cerramos la curva if (path_it->closed()) { - curve->closepath_current(); + nCurve->closepath_current(); } - } + curve->append(nCurve,false); + nCurve->reset(); + //Limpiamos + in->reset(); + out->reset(); + end->reset(); + lineHelper->reset(); + curveHelper->reset(); + } + delete in; + delete out; + delete end; + delete lineHelper; + delete curveHelper; + //Todo: remove? + //delete SBasisIn; + //delete SBasisOut; + //delete SBasisEnd; + //delete SBasisHelper; } //BSpline end @@ -2235,6 +2171,14 @@ static void spdc_pen_finish_segment(SPPenContext *const pc, Geom::Point const p, ++pc->num_clicks; if (!pc->red_curve->is_empty()) { + //BSpline + if(pc->spiro){ + spiro_prepare(pc, (state & GDK_SHIFT_MASK)); + } + if(pc->bspline){ + bspline_prepare(pc, (state & GDK_SHIFT_MASK)); + } + //BSpline End pc->green_curve->append_continuous(pc->red_curve, 0.0625); SPCurve *curve = pc->red_curve->copy(); /// \todo fixme: diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index 19a040b24..32248d9b6 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -780,7 +780,14 @@ interpolate(SPPencilContext *pc) /* Fit and draw and reset state */ pc->green_curve->moveto(b[0]); for (int c = 0; c < n_segs; c++) { - pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); + //BSpline + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); + if(mode == 2){ + pc->green_curve->lineto(b[4*c+3]); + }else{ + pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); + } } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve); @@ -920,7 +927,15 @@ fit_and_split(SPPencilContext *pc) /* Fit and draw and reset state */ pc->red_curve->reset(); pc->red_curve->moveto(b[0]); - pc->red_curve->curveto(b[1], b[2], b[3]); + //BSpline + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); + if(mode == 2){ + pc->red_curve->lineto(b[3]); + }else{ + pc->red_curve->curveto(b[1], b[2], b[3]); + } + //BSpline End sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); pc->red_curve_is_valid = true; } else { -- cgit v1.2.3 From d395af6ee332142c63355d008d49b1f4b3487dfe Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 24 Dec 2012 08:05:24 +0100 Subject: Going to merge (bzr r11950.1.5) --- src/live_effects/lpe-bspline.cpp | 226 ++++++++++++++++++++++++++ src/live_effects/lpe-bspline.h | 35 ++++ src/pen-context.cpp | 342 +++++++++++++++++++++------------------ 3 files changed, 444 insertions(+), 159 deletions(-) create mode 100644 src/live_effects/lpe-bspline.cpp create mode 100644 src/live_effects/lpe-bspline.h (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp new file mode 100644 index 000000000..e125cc4e0 --- /dev/null +++ b/src/live_effects/lpe-bspline.cpp @@ -0,0 +1,226 @@ +#define INKSCAPE_LPE_BSPLINE_C + +/* + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-bspline.h" + +#include "display/curve.h" +#include +#include <2geom/pathvector.h> +#include <2geom/affine.h> +#include <2geom/bezier-curve.h> +#include "helper/geom-curves.h" + +// For handling un-continuous paths: +#include "message-stack.h" +#include "inkscape.h" +#include "desktop.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : + Effect(lpeobject) +{ +} + +LPEBSpline::~LPEBSpline() +{ +} +//Crea una nueva curva reseteando la original +SPCurve * +LPEBSpline::reverse_then_reset(SPCurve * orig){ + SPCurve *ret = orig->create_reverse(); + orig->reset(); + return ret; +} + +void +LPEBSpline::doEffect(SPCurve * curve) +{ + using Geom::X; + using Geom::Y; + + // Make copy of old path as it is changed during processing + 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; + //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); + Geom::Point node(0,0); + //Geom::Point previousPointAt3(0,0); + Geom::Point pointAt0(0,0); + Geom::Point pointAt1(0,0); + Geom::Point pointAt2(0,0); + Geom::Point pointAt3(0,0); + //Geom::Point nextPointAt0(0,0); + Geom::Point nextPointAt1(0,0); + Geom::Point nextPointAt2(0,0); + Geom::Point nextPointAt3(0,0); + + //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... + if (path_it->empty()) + continue; + //Itreadores + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming 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 + //Las lineas rectas forman nodos BSpline + //Las curvas forman nodos CUSP + bool isBSpline = true; + //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 + //dichos manejadores + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + //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 + if (path_it->closed() && is_straight_curve(*curve_end)) { + //Calculamos el nodo de inicio BSpline + SBasisIn = in->first_segment()->toSBasis(); + SBasisEnd = end->first_segment()->toSBasis(); + lineHelper->moveto(SBasisIn.valueAt(0.3334)); + lineHelper->lineto(SBasisEnd.valueAt(0.6664)); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //Guardamos el principio de la curva + startNode = SBasisHelper.valueAt(0.5); + //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 ) + { + //Damos valor a el objeto SBasis para el path de entrada y el de salida + 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 + pointAt0 = SBasisIn.valueAt(0); + pointAt1 = SBasisIn.valueAt(0.3334); + pointAt2 = SBasisIn.valueAt(0.6667); + pointAt3 = SBasisIn.valueAt(1); + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + nextPointAt1 = SBasisOut.valueAt(0.3334); + nextPointAt2 = SBasisOut.valueAt(0.6667);; + nextPointAt3 = SBasisOut.valueAt(1); + //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 + 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); + //Vemos si el nodo es BSpline o CUSP + //Averiguamos si el path de entrada es recto o tiene manejadores + isBSpline = is_straight_curve(*curve_it1); + //Si no es recto, tenemos que generar la curva con nodo final CUSP + if(!isBSpline ){ + //Definimos como nodo el final del segmento de entrada + node = pointAt3; + } + curveHelper->moveto(previousNode); + curveHelper->curveto(pointAt1, pointAt2, node); + //añadimos la curva generada a la curva pricipal + nCurve->append_continuous(curveHelper, 0.0625); + curveHelper->reset(); + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + in->reset(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + out->reset(); + if(curve_it1 != curve_end){ + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + } + } + //Aberiguamos la ultima parte de la curva correspondiente al último segmento + curveHelper->moveto(node); + //Si está cerrada la curva, la cerramos sobre el valor guardado previamente + //Si no finalizamos en el punto final + if (path_it->closed()) { + curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); + }else{ + curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + } + //añadimos este último segmento + nCurve->append_continuous(curveHelper, 0.0625); + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); + } + curve->append(nCurve,false); + nCurve->reset(); + //Limpiamos + in->reset(); + out->reset(); + end->reset(); + lineHelper->reset(); + curveHelper->reset(); + } + delete in; + delete out; + delete end; + delete lineHelper; + delete curveHelper; + //Todo: remove? + //delete SBasisIn; + //delete SBasisOut; + //delete SBasisEnd; + //delete SBasisHelper; +} + + + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h new file mode 100644 index 000000000..23ac495df --- /dev/null +++ b/src/live_effects/lpe-bspline.h @@ -0,0 +1,35 @@ +#ifndef INKSCAPE_LPE_BSPLINE_H +#define INKSCAPE_LPE_BSPLINE_H + +/* + * Inkscape::LPEBSpline + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" + + +namespace Inkscape { +namespace LivePathEffect { + +class LPEBSpline : public Effect { +public: + LPEBSpline(LivePathEffectObject *lpeobject); + virtual ~LPEBSpline(); + + virtual LPEPathFlashType pathFlashType() { return SUPPRESS_FLASH; } + + virtual SPCurve *reverse_then_reset(SPCurve * orig); + + virtual void doEffect(SPCurve * curve); + +private: + LPEBSpline(const LPEBSpline&); + LPEBSpline& operator=(const LPEBSpline&); +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape + +#endif diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 6d35d0897..20c95c13f 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -83,23 +83,29 @@ static gint sp_pen_context_root_handler(SPEventContext *ec, GdkEvent *event); static gint sp_pen_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); static void spdc_pen_set_initial_point(SPPenContext *pc, Geom::Point const p); +/* + *BSpline + *Added functions +*/ -//BSpline -//Added functions -//Sobrecarga la función "sp_pen_context_set_polyline_mode" -//Le da valor a la nueva propiedad "pc->spiro" que como se auto define indica si estamos en modo spiro -//En el futuro se la dará a "pc->bspline" +/* + *Sobrecarga la función "sp_pen_context_set_polyline_mode" + *Le da valor a la nueva propiedad "pc->spiro" que como se auto define indica si estamos en modo spiro + *En el futuro se la dará a "pc->bspline" +*/ static void sp_pen_context_set_mode(SPPenContext *const pc, guint mode); //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void spiro_color(SPPenContext *const pc); +//Guarda el valor si se ha pulsado la tecla SHIFT al continuar una curva +static bool saShift = false; //Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT -static void spiro_prepare(SPPenContext *const pc, bool Shift); +static void spiro(SPPenContext *const pc, bool Shift); //Unimos todas las curvas en juego y llamamos a la función doEffect. static void spiro_build(SPPenContext *const pc); //function spiro cloned from lpe-spiro.cpp static void spiro_doEffect(SPCurve * curve); //Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT -static void bspline_prepare(SPPenContext *const pc,bool Shift); +static void bspline(SPPenContext *const pc,bool Shift); //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline_build(SPPenContext *const pc); //function bspline cloned from lpe-bspline.cpp @@ -248,13 +254,17 @@ void sp_pen_context_set_polyline_mode(SPPenContext *const pc) { sp_pen_context_set_mode(pc, mode); //BSpline End } + //BSpline -//Set the mode of draw now spiro, and later b-splines +/* +*.Set the mode of draw now spiro, and later b-splines +*/ void sp_pen_context_set_mode(SPPenContext *const pc, guint mode) { pc->spiro = (mode == 1); pc->bspline = (mode == 2); } //BSpline End + /** * Callback to initialize SPPenContext object. */ @@ -637,7 +647,6 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const if (pc->expecting_clicks_for_LPE > 0) { --pc->expecting_clicks_for_LPE; } - return ret; } @@ -768,7 +777,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons // snap the handle spdc_endpoint_snap_handle(pc, p, mevent.state); //BSpline - if (!pc->polylines_only && !pc->bspline && !pc->spiro) { + if (!pc->polylines_only && !pc->spiro && !pc->bspline) { //BSpline End spdc_pen_set_ctrl(pc, p, mevent.state); } else { @@ -796,10 +805,10 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons //BSpline if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { if(pc->spiro){ - spiro_prepare(pc,(mevent.state & GDK_SHIFT_MASK)); + spiro(pc,(mevent.state & GDK_SHIFT_MASK)); } if(pc->bspline){ - bspline_prepare(pc,(mevent.state & GDK_SHIFT_MASK)); + bspline(pc,(mevent.state & GDK_SHIFT_MASK)); } pen_drag_origin_w = event_w; } @@ -857,10 +866,10 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con } //BSpline if(pc->spiro){ - spiro_prepare(pc,(revent.state & GDK_SHIFT_MASK)); + spiro(pc,(revent.state & GDK_SHIFT_MASK)); } if(pc->bspline){ - bspline_prepare(pc,(revent.state & GDK_SHIFT_MASK)); + bspline(pc,(revent.state & GDK_SHIFT_MASK)); } //BSpline End pc->state = SP_PEN_CONTEXT_CONTROL; @@ -1000,7 +1009,9 @@ static void pen_redraw_all (SPPenContext *const pc) sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); // handles - if (pc->p[0] != pc->p[1]) { + //BSpline + if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { + //BSpline End SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); sp_canvas_item_show(pc->c1); @@ -1013,9 +1024,11 @@ static void pen_redraw_all (SPPenContext *const pc) Geom::Curve const * last_seg = pc->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); + //BSpline if ( cubic && - (*cubic)[2] != pc->p[0] ) + (*cubic)[2] != pc->p[0]&& !pc->spiro && !pc->bspline ) { + //BSpline End Geom::Point p2 = (*cubic)[2]; SP_CTRL(pc->c0)->moveto(p2); pc->cl0->setCoords(p2, pc->p[0]); @@ -1074,15 +1087,16 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) if (pc->npoints != 5 && !pc->spiro && !pc->bspline) return; //BSpline - - Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment() ); - if ( cubic ) { - pc->p[1] = pc->p[0] + (Geom::Point)( (*cubic)[3] - (*cubic)[2] ); - } else { - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + Geom::CubicBezier const * cubic; + if(!pc->bspline){ + cubic = dynamic_cast( pc->green_curve->last_segment() ); + if ( cubic ) { + pc->p[1] = pc->p[0] + (Geom::Point)( (*cubic)[3] - (*cubic)[2] ); + } else { + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + } } - //BSpline //Para formar una curva necesitamos un nodo symm en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que sea symm con el pricipio de la "red_curve" if(pc->spiro){ @@ -1091,6 +1105,8 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) Geom::Point C(0,0); Geom::Point D(0,0); SPCurve * previous = new SPCurve(); + using Geom::X; + using Geom::Y; //We obtain the last segment 4 points in the previous curve if ( cubic ){ A = (*cubic)[0]; @@ -1103,12 +1119,17 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); D = pc->green_curve->last_segment()->finalPoint(); } + C = Geom::Point(C[X]+1,C[Y]+1); previous->moveto(A); previous->curveto(B, C, D); - //we eliminate the last segment - pc->green_curve->backspace(); - //and we add it again with the recreation - pc->green_curve->append_continuous(previous, 0.0625); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = previous; + }else{ + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } } //Para formar una curva bspline necesitamos un nodo cusp en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que sea cusp con el pricipio de la "red_curve" @@ -1142,9 +1163,39 @@ static void pen_lastpoint_toline (SPPenContext *const pc) //Si no es bspline if (pc->npoints != 5 && !pc->bspline) return; - //BSpline End - pc->p[1] = pc->p[0]; - + if(!pc->bspline) + pc->p[1] = pc->p[0]; + if(pc->spiro){ + Geom::Point A(0,0); + Geom::Point B(0,0); + Geom::Point C(0,0); + Geom::Point D(0,0); + SPCurve * previous = new SPCurve(); + Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment() ); + if ( cubic ) { + A = pc->green_curve->last_segment()->initialPoint(); + B = (*cubic)[1]; + C = pc->green_curve->last_segment()->finalPoint(); + D = C; + pc->p[1] = pc->p[0] + (Geom::Point)( (*cubic)[3] - (*cubic)[2] ); + } else { + //We obtain the last segment 4 points in the previous curve + A = pc->green_curve->last_segment()->initialPoint(); + B = A; + C = pc->green_curve->last_segment()->finalPoint(); + D = C; + } + previous->moveto(A); + previous->curveto(B, C, D); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = previous; + }else{ + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } + } //BSpline //Para formar una recta necesitamos un nodo con manejador en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que tenga manejador @@ -1153,15 +1204,17 @@ static void pen_lastpoint_toline (SPPenContext *const pc) Geom::Point B(0,0); Geom::Point C(0,0); Geom::Point D(0,0); + using Geom::X; + using Geom::Y; SPCurve * previous = new SPCurve(); //We obtain the last segment 4 points in the previous curve A = pc->green_curve->last_segment()->initialPoint(); B = pc->green_curve->last_segment()->initialPoint(); C = pc->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(pc->green_curve->last_segment()->initialPoint() - pc->green_curve->last_segment()->finalPoint()); + C = Geom::Point(C[X]+1,C[Y]+1); D = pc->green_curve->last_segment()->finalPoint(); previous->moveto(A); previous->curveto(B, C, D); - if( pc->green_curve->get_segment_count() == 1){ pc->green_curve = previous; }else{ @@ -1332,6 +1385,12 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) } } else { // Reset red curve + //BSpline + if ((pc->spiro || pc->bspline) && pc->green_curve->get_segment_count()==1) { + pen_cancel (pc); + ret = TRUE; + } + //BSpline End pc->red_curve->reset(); // Destroy topmost green bpath if (pc->green_bpaths) { @@ -1362,6 +1421,15 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) pc->state = SP_PEN_CONTEXT_POINT; spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; + //BSpline + if(pc->spiro || pc->bspline){ + SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), pc->green_curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); + pen_redraw_all(pc); + } + //BSpline End ret = TRUE; } break; @@ -1488,71 +1556,40 @@ static void spiro_color(SPPenContext *const pc) //Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT -static void spiro_prepare(SPPenContext *const pc, bool Shift) +static void spiro(SPPenContext *const pc, bool Shift) { if(Shift){ - //Creamos un nodo CUSP - pc->npoints = 5; - pc->p[2] = pc->p[3]; - //Si empezamos sobre otra curva en modo cusp la alteramos para que no tenga manejador final - //recreando la curva e igualando el punto del manejador al punto fiinal de la curva - if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && !pc->ea && pc->green_curve->is_empty()){ - bool reverse = false; - Geom::CubicBezier const * cubic; - if(pc->sa->start){ - reverse = true; - pc->sa->curve = reverse_then_reset(pc->sa->curve); - } - Geom::Point P0(0,0); - Geom::Point P1(0,0); - Geom::Point P2(0,0); - Geom::Point P3(0,0); - Geom::Point P4(0,0); - cubic = dynamic_cast( pc->sa->curve->last_segment()); - if(cubic){ - P0 = pc->sa->curve->last_segment()->initialPoint(); - P1 = (*cubic)[1]; - P3 = pc->sa->curve->last_segment()->finalPoint(); - P2 = P3; - }else{ - P0 = pc->sa->curve->last_segment()->initialPoint(); - P1 = P0; - P3 = pc->sa->curve->last_segment()->finalPoint(); - P2 = P3; - } - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->curveto(P1,P2,P3); - if( pc->sa->curve->get_segment_count() == 1){ - pc->sa->curve = last; - }else{ - pc->sa->curve->backspace(); - pc->sa->curve->append_continuous(last, 0.0625); - } - if(reverse){ - pc->sa->curve = reverse_then_reset(pc->sa->curve); - } - delete last; + if(!pc->red_curve->is_empty()){ + //Creamos un nodo CUSP + pc->npoints = 5; + pc->p[2] = pc->p[3]; + } + //Continuamos la curva en modo CUSP + //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM + if(pc->anchor_statusbar){ + saShift = true; } - }else{ //Symm nodo using Geom::X; using Geom::Y; Geom::CubicBezier const * cubic; - //Damos valores a los puntos de la curva roja para que generen un nodo SYMM if(!pc->red_curve->is_empty()){ + //Damos valores a los puntos de la curva roja para que generen un nodo SYMM pc->npoints = 5; //Les damos valor - pc->p[0] = pc->red_curve->first_segment()->initialPoint(); - pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[4] = pc->p[3] + (Geom::Point)( pc->p[3] - pc->p[2] ); pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); + pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); + pc->p[4] = pc->p[3] + (Geom::Point)( pc->p[3] - pc->p[2] ); } + //Continuamos la curva en modo SPIRO - if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && !pc->ea && pc->green_curve->is_empty()){ + if( saShift == false && pc->sa && !pc->sa->curve->is_empty() && !pc->ea && pc->green_curve->is_empty()){ cubic = dynamic_cast( pc->sa->curve->last_segment()); if (pc->sa->start) { cubic = dynamic_cast( pc->sa->curve->create_reverse()->last_segment() ); @@ -1561,32 +1598,34 @@ static void spiro_prepare(SPPenContext *const pc, bool Shift) pc->p[1] = (pc->p[0] - (*cubic)[2]) + pc->p[0]; } } + //Nos aseguramos que el primer nodo sea SYMM con el ultimo segmento de la curva verde if(!pc->green_curve->is_empty()){ cubic = dynamic_cast( pc->green_curve->last_segment()); if(cubic && (*cubic)[2] != (*cubic)[3]){ pc->p[1] = (pc->p[0] - (*cubic)[2]) + pc->p[0]; } + //Damos valor original a la variable por si se necesita de nuevo + saShift = false; } //Si cerramos sobre otra curva ponemos simetrico a esta el manejador del punto de cierre - if(pc->ea && !pc->ea->curve->is_empty()){ - cubic = dynamic_cast( pc->ea->curve->last_segment() ); - if (pc->ea->start) { - cubic = dynamic_cast( pc->ea->curve->create_reverse()->last_segment() ); + if(pc->anchor_statusbar && pc->sa && !Geom::are_near(pc->sa->dp, pc->red_curve->first_segment()->finalPoint())){ + cubic = dynamic_cast( pc->sa->curve->last_segment() ); + if (!pc->sa->start) { + cubic = dynamic_cast( pc->sa->curve->create_reverse()->last_segment() ); } if(cubic){ pc->p[2] = (pc->p[3]-(*cubic)[2]) + pc->p[3]; } } //Lo mismpo pero cerrando sobre la curva inicial - if(pc->green_anchor && pc->green_anchor->active){ + if(pc->anchor_statusbar && pc->green_anchor && pc->green_anchor->active){ cubic = dynamic_cast( pc->green_curve->first_segment() ); if(cubic){ pc->p[2] = (pc->p[3]-(*cubic)[1]) + pc->p[3]; } } - } spiro_build(pc); } @@ -1613,16 +1652,10 @@ static void spiro_build(SPPenContext *const pc) pc->red_curve->reset(); pc->red_curve->moveto(pc->p[0]); pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); curve->append_continuous(pc->red_curve, 0.0625); } - if(!pc->sa && pc->ea && !pc->ea->curve->is_empty()){ - if (pc->ea->start) { - curve->append_continuous(pc->ea->curve, 0.0625); - }else{ - curve->append_continuous(pc->ea->curve->create_reverse(), 0.0625); - } - } if(!curve->is_empty()){ //cerramos la curva si estan cerca los puntos finales de la curva spiro if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ @@ -1763,62 +1796,69 @@ static void spiro_doEffect(SPCurve * curve) } //Unimos todas las curvas en juego y llamamos a la función doEffect. -static void bspline_prepare(SPPenContext *const pc, bool Shift) +static void bspline(SPPenContext *const pc, bool Shift) { if(!Shift){ //Modo Bspline formado por nodos CUSP - if (pc->npoints == 5){ + if (pc->npoints == 5 || !pc->red_curve->is_empty()){ pc->npoints = 2; pc->p[1]= pc->p[3]; } }else{ - //NODO CUSP formado por nodo SMOOTH - //solo mobemos el manejador del nodo final de cada segmento - //Es suficiente para mostrar el nodo como CUSP using Geom::X; using Geom::Y; - bool reverse = false; - //Usamos 5 puntos - if(pc->npoints == 2){ + +/* +.* //TODO: No puedo conseguir que el siguoenmte codigo funcione +.* //Este trata de convertir el nodo de inicio de continuación de curva BSpline a CUSP +.* //modifiacandpo el segmento al que se trata de anexar la curva +.* //de manera que le obligue a tener manejador final +.* +.* if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()){ +.* bool reverse = false; +.* if(pc->sa->start){ +.* pc->sa->curve = reverse_then_reset(pc->sa->curve); +.* reverse = true; +.* } +.* Geom::Point P0(0,0); +.* Geom::Point P1(0,0); +.* Geom::Point P2(0,0); +.* Geom::Point P3(0,0); +.* Geom::Point P4(0,0); +.* P0 = pc->sa->curve->last_segment()->initialPoint(); +.* P1 = P0; +.* P3 = pc->sa->curve->last_segment()->finalPoint(); +.* P2 = P3 + (1./3)*(P0 - P3); +.* P2 = Geom::Point(P2[X]+1,P2[Y]+1); +.* SPCurve * last = new SPCurve(); +.* last->moveto(P0); +.* last->curveto(P1,P2,P3); +.* if( pc->sa->curve->get_segment_count() == 1){ +.* pc->sa->curve = last; +.* }else{ +.* pc->sa->curve->backspace(); +.* pc->sa->curve->append_continuous(last, 0.0625); +.* if(reverse) +.* pc->sa->curve = reverse_then_reset(pc->sa->curve); +.* } +.* delete last; +.* } +*/ + //NODO CUSP formado por nodo SMOOTH + //solo mobemos el manejador del nodo final de cada segmento + //Es suficiente para mostrar el nodo como CUSP + //Usamos 5 puntos + if(!pc->red_curve->is_empty()){ pc->npoints = 5; - } - pc->p[1] = pc->p[0]; - //Les damos valor - pc->p[3] = pc->red_curve->first_segment()->finalPoint(); - pc->p[4] = pc->p[3]; - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - - //Si empezamos sobre otra curva hay que modificarla para que tenga manejador en el último nodo - if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && !pc->ea && pc->green_curve->is_empty()){ - if(pc->sa->start){ - reverse = true; - pc->sa->curve = reverse_then_reset(pc->sa->curve); - } - Geom::Point P0(0,0); - Geom::Point P1(0,0); - Geom::Point P2(0,0); - Geom::Point P3(0,0); - Geom::Point P4(0,0); - P0 = pc->sa->curve->last_segment()->initialPoint(); - P1 = P0; - P3 = pc->sa->curve->last_segment()->finalPoint(); - P2 = P3 + (1./3)*(P0 - P3); - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->curveto(P1,P2,P3); - if( pc->sa->curve->get_segment_count() == 1){ - pc->sa->curve = last; - }else{ - pc->sa->curve->backspace(); - pc->sa->curve->append_continuous(last, 0.0625); - } - if(reverse){ - pc->sa->curve = reverse_then_reset(pc->sa->curve); - } - delete last; + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[1] = pc->p[0]; + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[4] = pc->p[3]; + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); } } -bspline_build(pc); + bspline_build(pc); } @@ -1848,16 +1888,10 @@ static void bspline_build(SPPenContext *const pc) }else{ pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); } + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); curve->append_continuous(pc->red_curve, 0.0625); } - if(!pc->sa && pc->ea && !pc->ea->curve->is_empty()){ - if (pc->ea->start) { - curve->append_continuous(pc->ea->curve, 0.0625); - }else{ - curve->append_continuous(pc->ea->curve->create_reverse(), 0.0625); - } - } if(curve->get_segment_count() > 1 ){ //cerramos la curva si estan cerca los puntos finales de la curva spiro if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ @@ -1867,7 +1901,7 @@ static void bspline_build(SPPenContext *const pc) //For example //using namespace Inkscape::LivePathEffect; //LivePathEffectObject *lpeobj = static_cast (curve); - //Effect *spr = static_cast ( new LPEbspline_prepare(lpeobj) ); + //Effect *spr = static_cast ( new LPEbspline(lpeobj) ); //spr->doEffect(curve); bspline_doEffect(curve); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve); @@ -1911,9 +1945,6 @@ static void bspline_doEffect(SPCurve * curve) Geom::Point startNode(0,0); Geom::Point previousNode(0,0); Geom::Point node(0,0); - Geom::Point previousPointAt0(0,0); - Geom::Point previousPointAt1(0,0); - Geom::Point previousPointAt2(0,0); //Geom::Point previousPointAt3(0,0); Geom::Point pointAt0(0,0); Geom::Point pointAt1(0,0); @@ -1975,10 +2006,6 @@ static void bspline_doEffect(SPCurve * curve) //Damos valor a el objeto SBasis para el path de entrada y el de salida SBasisIn = in->first_segment()->toSBasis(); SBasisOut = out->first_segment()->toSBasis(); - //Damos valor a los puntos calculados en el anterior paso del bucle - previousPointAt0 = pointAt0; - previousPointAt1 = pointAt1; - previousPointAt2 = pointAt2; //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida pointAt0 = SBasisIn.valueAt(0); @@ -2127,11 +2154,7 @@ static void spdc_pen_set_ctrl(SPPenContext *const pc, Geom::Point const p, guint pc->p[1] = p; sp_canvas_item_hide(pc->c0); sp_canvas_item_hide(pc->cl0); - if(pc->spiro){ - SP_CTRL(pc->c1)->moveto(pc->p[1]); - }else{ - SP_CTRL(pc->c1)->moveto(pc->p[1]); - } + SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); spdc_pen_set_angle_distance_status_message(pc, p, 0, _("Curve handle: angle %3.2f°, length %s; with Ctrl to snap angle")); } else if ( pc->npoints == 5 ) { @@ -2173,10 +2196,10 @@ static void spdc_pen_finish_segment(SPPenContext *const pc, Geom::Point const p, if (!pc->red_curve->is_empty()) { //BSpline if(pc->spiro){ - spiro_prepare(pc, (state & GDK_SHIFT_MASK)); + spiro(pc, (state & GDK_SHIFT_MASK)); } if(pc->bspline){ - bspline_prepare(pc, (state & GDK_SHIFT_MASK)); + bspline(pc, (state & GDK_SHIFT_MASK)); } //BSpline End pc->green_curve->append_continuous(pc->red_curve, 0.0625); @@ -2328,3 +2351,4 @@ void pen_set_to_nearest_horiz_vert(const SPPenContext *const pc, Geom::Point &pt End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + -- cgit v1.2.3 From 69282d367f74bd425ae11cab845208250d38ca24 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 24 Dec 2012 12:42:35 +0100 Subject: Fix shortcut Spiro to curve (bzr r11950.1.8) --- src/pen-context.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 20c95c13f..f6d07facc 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1088,14 +1088,6 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) return; //BSpline Geom::CubicBezier const * cubic; - if(!pc->bspline){ - cubic = dynamic_cast( pc->green_curve->last_segment() ); - if ( cubic ) { - pc->p[1] = pc->p[0] + (Geom::Point)( (*cubic)[3] - (*cubic)[2] ); - } else { - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); - } - } //Para formar una curva necesitamos un nodo symm en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que sea symm con el pricipio de la "red_curve" @@ -1105,8 +1097,7 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) Geom::Point C(0,0); Geom::Point D(0,0); SPCurve * previous = new SPCurve(); - using Geom::X; - using Geom::Y; + cubic = dynamic_cast( pc->green_curve->last_segment() ); //We obtain the last segment 4 points in the previous curve if ( cubic ){ A = (*cubic)[0]; @@ -1119,7 +1110,6 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); D = pc->green_curve->last_segment()->finalPoint(); } - C = Geom::Point(C[X]+1,C[Y]+1); previous->moveto(A); previous->curveto(B, C, D); if( pc->green_curve->get_segment_count() == 1){ @@ -1131,6 +1121,16 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } + + if(!pc->bspline){ + cubic = dynamic_cast( pc->green_curve->last_segment() ); + if ( cubic ) { + pc->p[1] = pc->p[0] + (Geom::Point)( pc->p[0] - (*cubic)[2] ); + } else { + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + } + } + //Para formar una curva bspline necesitamos un nodo cusp en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que sea cusp con el pricipio de la "red_curve" //Que se quedará recta -- cgit v1.2.3 From eac303cf672b1c09a0378ca8b34aafcfdf4ee08d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 4 Jan 2013 22:30:00 +0100 Subject: Fixing StartAnchor problems in bspline (bzr r11950.1.10) --- src/live_effects/lpe-bspline.cpp | 19 ++++-- src/pen-context.cpp | 128 ++++++++++++++++++++++----------------- 2 files changed, 87 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index e125cc4e0..24e7a5027 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -13,6 +13,7 @@ #include <2geom/bezier-curve.h> #include "helper/geom-curves.h" + // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -72,6 +73,8 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); + Geom::CubicBezier const * cubic; + Geom::PathVector newpathv; //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) { @@ -79,6 +82,7 @@ LPEBSpline::doEffect(SPCurve * curve) if (path_it->empty()) continue; //Itreadores + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve Geom::Path::const_iterator curve_end = path_it->end(); // end curve @@ -100,7 +104,12 @@ LPEBSpline::doEffect(SPCurve * curve) //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 - if (path_it->closed() && is_straight_curve(*curve_end)) { + + cubic = dynamic_cast(&*curve_endit); + if((*cubic)[2] == (*cubic)[3]) + isBSpline = false; + if (path_it->closed() && !isBSpline) { + isBSpline = true; //Calculamos el nodo de inicio BSpline SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); @@ -149,9 +158,11 @@ LPEBSpline::doEffect(SPCurve * curve) //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); //Vemos si el nodo es BSpline o CUSP - //Averiguamos si el path de entrada es recto o tiene manejadores - isBSpline = is_straight_curve(*curve_it1); - //Si no es recto, tenemos que generar la curva con nodo final CUSP + //Averiguamos si el punto de union tiene manejadores + cubic = dynamic_cast(&*curve_it1); + if((*cubic)[2] == (*cubic)[3]) + isBSpline = true; + //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP if(!isBSpline ){ //Definimos como nodo el final del segmento de entrada node = pointAt3; diff --git a/src/pen-context.cpp b/src/pen-context.cpp index f6d07facc..ea14a5183 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -58,6 +58,7 @@ #include "helper/geom-nodetype.h" #include "helper/geom-curves.h" + // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -1501,14 +1502,6 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G //BSpline Set Functions -//Creates a new curve resetting the original -static SPCurve * reverse_then_reset(SPCurve *orig) -{ - SPCurve *ret = orig->create_reverse(); - orig->reset(); - return ret; -} - //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void spiro_color(SPPenContext *const pc) { @@ -1794,6 +1787,14 @@ static void spiro_doEffect(SPCurve * curve) g_free (path); } +//BSpline Set Functions +//Creates a new curve resetting the original +static SPCurve * reverse_then_reset(SPCurve *orig) +{ + SPCurve *ret = orig->create_reverse(); + orig->reset(); + return ret; +} //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline(SPPenContext *const pc, bool Shift) @@ -1801,61 +1802,62 @@ static void bspline(SPPenContext *const pc, bool Shift) if(!Shift){ //Modo Bspline formado por nodos CUSP if (pc->npoints == 5 || !pc->red_curve->is_empty()){ - pc->npoints = 2; - pc->p[1]= pc->p[3]; + pc->npoints = 5; + pc->p[2]= pc->p[3]; } }else{ using Geom::X; using Geom::Y; + Geom::CubicBezier const * cubic; + if(pc->green_curve->is_empty() && pc->red_curve->is_empty() && pc->sa && !pc->ea && !pc->sa->curve->is_empty()){ + bool reverse = false; + if (pc->sa->start) { + reverse = true; + pc->sa->curve = reverse_then_reset(pc->sa->curve); + } + Geom::Point P0(0,0); + Geom::Point P1(0,0); + Geom::Point P2(0,0); + Geom::Point P3(0,0); + Geom::Point P4(0,0); + P0 = pc->sa->curve->last_segment()->initialPoint(); + P1 = P0; + cubic = dynamic_cast( pc->sa->curve->last_segment() ); + if(cubic) + P1 = (*cubic)[2]; + P3 = pc->sa->curve->last_segment()->finalPoint(); + P2 = P3 + (1./3)*(P0 - P3); + P2 = Geom::Point(P2[X]+1,P2[Y]+1); + SPCurve * last = new SPCurve(); + last->moveto(P0); + last->curveto(P1,P2,P3); + if( pc->sa->curve->get_segment_count() == 1){ + pc->sa->curve = last; + }else{ + pc->sa->curve->backspace(); + pc->sa->curve->append_continuous(last, 0.0625); + } + if(reverse) + pc->sa->curve = reverse_then_reset(pc->sa->curve); + last->reset(); + last->unref(); + } -/* -.* //TODO: No puedo conseguir que el siguoenmte codigo funcione -.* //Este trata de convertir el nodo de inicio de continuación de curva BSpline a CUSP -.* //modifiacandpo el segmento al que se trata de anexar la curva -.* //de manera que le obligue a tener manejador final -.* -.* if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()){ -.* bool reverse = false; -.* if(pc->sa->start){ -.* pc->sa->curve = reverse_then_reset(pc->sa->curve); -.* reverse = true; -.* } -.* Geom::Point P0(0,0); -.* Geom::Point P1(0,0); -.* Geom::Point P2(0,0); -.* Geom::Point P3(0,0); -.* Geom::Point P4(0,0); -.* P0 = pc->sa->curve->last_segment()->initialPoint(); -.* P1 = P0; -.* P3 = pc->sa->curve->last_segment()->finalPoint(); -.* P2 = P3 + (1./3)*(P0 - P3); -.* P2 = Geom::Point(P2[X]+1,P2[Y]+1); -.* SPCurve * last = new SPCurve(); -.* last->moveto(P0); -.* last->curveto(P1,P2,P3); -.* if( pc->sa->curve->get_segment_count() == 1){ -.* pc->sa->curve = last; -.* }else{ -.* pc->sa->curve->backspace(); -.* pc->sa->curve->append_continuous(last, 0.0625); -.* if(reverse) -.* pc->sa->curve = reverse_then_reset(pc->sa->curve); -.* } -.* delete last; -.* } -*/ - //NODO CUSP formado por nodo SMOOTH - //solo mobemos el manejador del nodo final de cada segmento - //Es suficiente para mostrar el nodo como CUSP - //Usamos 5 puntos + //NODO CUSP formado por nodo SMOOTH + //solo mobemos el manejador del nodo final de cada segmento + //Es suficiente para mostrar el nodo como CUSP + //Usamos 5 puntos if(!pc->red_curve->is_empty()){ pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[1] = pc->p[0]; + cubic = dynamic_cast( pc->red_curve->first_segment() ); + if(cubic) + pc->p[1] = (*cubic)[1]; pc->p[3] = pc->red_curve->first_segment()->finalPoint(); - pc->p[4] = pc->p[3]; - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); + pc->p[4] = pc->p[3] + (1./3)*(pc->p[3] - pc->p[0]); } } bspline_build(pc); @@ -1954,6 +1956,8 @@ static void bspline_doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); + Geom::CubicBezier const * cubic; + Geom::PathVector newpathv; //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) { @@ -1961,6 +1965,7 @@ static void bspline_doEffect(SPCurve * curve) if (path_it->empty()) continue; //Itreadores + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve Geom::Path::const_iterator curve_end = path_it->end(); // end curve @@ -1982,7 +1987,12 @@ static void bspline_doEffect(SPCurve * curve) //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 - if (path_it->closed() && is_straight_curve(*curve_end)) { + + cubic = dynamic_cast(&*curve_endit); + if((*cubic)[2] == (*cubic)[3]) + isBSpline = false; + if (path_it->closed() && !isBSpline) { + isBSpline = true; //Calculamos el nodo de inicio BSpline SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); @@ -2031,9 +2041,11 @@ static void bspline_doEffect(SPCurve * curve) //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); //Vemos si el nodo es BSpline o CUSP - //Averiguamos si el path de entrada es recto o tiene manejadores - isBSpline = is_straight_curve(*curve_it1); - //Si no es recto, tenemos que generar la curva con nodo final CUSP + //Averiguamos si el punto de union tiene manejadores + cubic = dynamic_cast(&*curve_it1); + if((*cubic)[2] == (*cubic)[3]) + isBSpline = true; + //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP if(!isBSpline ){ //Definimos como nodo el final del segmento de entrada node = pointAt3; @@ -2225,7 +2237,11 @@ static void spdc_pen_finish(SPPenContext *const pc, gboolean const closed) // don't let the path be finished before we have collected the required number of mouse clicks return; } + //BSpline + if(pc->bspline && pc->green_curve->get_segment_count() < 2 && !pc->sa ) + return; + //BSpline End pc->num_clicks = 0; pen_disable_events(pc); -- cgit v1.2.3 From 32866e3ed73a2a8c41520e2538687b5701a2d347 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Jan 2013 11:53:55 +0100 Subject: fix continue (bzr r11950.1.11) --- src/live_effects/lpe-bspline.cpp | 21 +++---- src/pen-context.cpp | 127 +++++++++++++++++++-------------------- 2 files changed, 71 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 24e7a5027..c8263282e 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -1,5 +1,5 @@ +#define INKSCAPE_HELPER_GEOM_CURVES_H #define INKSCAPE_LPE_BSPLINE_C - /* * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -73,9 +73,6 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::CubicBezier const * cubic; - Geom::PathVector newpathv; - //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... @@ -104,10 +101,10 @@ LPEBSpline::doEffect(SPCurve * curve) //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 - - cubic = dynamic_cast(&*curve_endit); - if((*cubic)[2] == (*cubic)[3]) - isBSpline = false; + if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_end)){ + if((*cubic)[2] == (*cubic)[3]) + isBSpline = false; + } if (path_it->closed() && !isBSpline) { isBSpline = true; //Calculamos el nodo de inicio BSpline @@ -159,9 +156,10 @@ LPEBSpline::doEffect(SPCurve * curve) node = SBasisHelper.valueAt(0.5); //Vemos si el nodo es BSpline o CUSP //Averiguamos si el punto de union tiene manejadores - cubic = dynamic_cast(&*curve_it1); - if((*cubic)[2] == (*cubic)[3]) - isBSpline = true; + if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_it1)){ + if((*cubic)[2] == (*cubic)[3]) + isBSpline = true; + } //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP if(!isBSpline ){ //Definimos como nodo el final del segmento de entrada @@ -221,7 +219,6 @@ LPEBSpline::doEffect(SPCurve * curve) } - }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/pen-context.cpp b/src/pen-context.cpp index ea14a5183..92481ec68 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -58,7 +58,6 @@ #include "helper/geom-nodetype.h" #include "helper/geom-curves.h" - // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -1502,6 +1501,14 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G //BSpline Set Functions +//Creates a new curve resetting the original +static SPCurve * reverse_then_reset(SPCurve *orig) +{ + SPCurve *ret = orig->create_reverse(); + orig->reset(); + return ret; +} + //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void spiro_color(SPPenContext *const pc) { @@ -1787,14 +1794,6 @@ static void spiro_doEffect(SPCurve * curve) g_free (path); } -//BSpline Set Functions -//Creates a new curve resetting the original -static SPCurve * reverse_then_reset(SPCurve *orig) -{ - SPCurve *ret = orig->create_reverse(); - orig->reset(); - return ret; -} //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline(SPPenContext *const pc, bool Shift) @@ -1802,62 +1801,61 @@ static void bspline(SPPenContext *const pc, bool Shift) if(!Shift){ //Modo Bspline formado por nodos CUSP if (pc->npoints == 5 || !pc->red_curve->is_empty()){ - pc->npoints = 5; - pc->p[2]= pc->p[3]; + pc->npoints = 2; + pc->p[1]= pc->p[3]; } }else{ using Geom::X; using Geom::Y; - Geom::CubicBezier const * cubic; - if(pc->green_curve->is_empty() && pc->red_curve->is_empty() && pc->sa && !pc->ea && !pc->sa->curve->is_empty()){ - bool reverse = false; - if (pc->sa->start) { - reverse = true; - pc->sa->curve = reverse_then_reset(pc->sa->curve); - } - Geom::Point P0(0,0); - Geom::Point P1(0,0); - Geom::Point P2(0,0); - Geom::Point P3(0,0); - Geom::Point P4(0,0); - P0 = pc->sa->curve->last_segment()->initialPoint(); - P1 = P0; - cubic = dynamic_cast( pc->sa->curve->last_segment() ); - if(cubic) - P1 = (*cubic)[2]; - P3 = pc->sa->curve->last_segment()->finalPoint(); - P2 = P3 + (1./3)*(P0 - P3); - P2 = Geom::Point(P2[X]+1,P2[Y]+1); - SPCurve * last = new SPCurve(); - last->moveto(P0); - last->curveto(P1,P2,P3); - if( pc->sa->curve->get_segment_count() == 1){ - pc->sa->curve = last; - }else{ - pc->sa->curve->backspace(); - pc->sa->curve->append_continuous(last, 0.0625); - } - if(reverse) - pc->sa->curve = reverse_then_reset(pc->sa->curve); - last->reset(); - last->unref(); - } - //NODO CUSP formado por nodo SMOOTH - //solo mobemos el manejador del nodo final de cada segmento - //Es suficiente para mostrar el nodo como CUSP - //Usamos 5 puntos +/* +.* //TODO: No puedo conseguir que el siguoenmte codigo funcione +.* //Este trata de convertir el nodo de inicio de continuación de curva BSpline a CUSP +.* //modifiacandpo el segmento al que se trata de anexar la curva +.* //de manera que le obligue a tener manejador final +.* +.* if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()){ +.* bool reverse = false; +.* if(pc->sa->start){ +.* pc->sa->curve = reverse_then_reset(pc->sa->curve); +.* reverse = true; +.* } +.* Geom::Point P0(0,0); +.* Geom::Point P1(0,0); +.* Geom::Point P2(0,0); +.* Geom::Point P3(0,0); +.* Geom::Point P4(0,0); +.* P0 = pc->sa->curve->last_segment()->initialPoint(); +.* P1 = P0; +.* P3 = pc->sa->curve->last_segment()->finalPoint(); +.* P2 = P3 + (1./3)*(P0 - P3); +.* P2 = Geom::Point(P2[X]+1,P2[Y]+1); +.* SPCurve * last = new SPCurve(); +.* last->moveto(P0); +.* last->curveto(P1,P2,P3); +.* if( pc->sa->curve->get_segment_count() == 1){ +.* pc->sa->curve = last; +.* }else{ +.* pc->sa->curve->backspace(); +.* pc->sa->curve->append_continuous(last, 0.0625); +.* if(reverse) +.* pc->sa->curve = reverse_then_reset(pc->sa->curve); +.* } +.* delete last; +.* } +*/ + //NODO CUSP formado por nodo SMOOTH + //solo mobemos el manejador del nodo final de cada segmento + //Es suficiente para mostrar el nodo como CUSP + //Usamos 5 puntos if(!pc->red_curve->is_empty()){ pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[1] = pc->p[0]; - cubic = dynamic_cast( pc->red_curve->first_segment() ); - if(cubic) - pc->p[1] = (*cubic)[1]; pc->p[3] = pc->red_curve->first_segment()->finalPoint(); - pc->p[2] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[4] = pc->p[3]; + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); - pc->p[4] = pc->p[3] + (1./3)*(pc->p[3] - pc->p[0]); } } bspline_build(pc); @@ -1956,9 +1954,6 @@ static void bspline_doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::CubicBezier const * cubic; - Geom::PathVector newpathv; - //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... @@ -1987,10 +1982,10 @@ static void bspline_doEffect(SPCurve * curve) //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 - - cubic = dynamic_cast(&*curve_endit); - if((*cubic)[2] == (*cubic)[3]) - isBSpline = false; + if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_end)){ + if((*cubic)[2] == (*cubic)[3]) + isBSpline = false; + } if (path_it->closed() && !isBSpline) { isBSpline = true; //Calculamos el nodo de inicio BSpline @@ -2042,9 +2037,10 @@ static void bspline_doEffect(SPCurve * curve) node = SBasisHelper.valueAt(0.5); //Vemos si el nodo es BSpline o CUSP //Averiguamos si el punto de union tiene manejadores - cubic = dynamic_cast(&*curve_it1); - if((*cubic)[2] == (*cubic)[3]) - isBSpline = true; + if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_it1)){ + if((*cubic)[2] == (*cubic)[3]) + isBSpline = true; + } //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP if(!isBSpline ){ //Definimos como nodo el final del segmento de entrada @@ -2237,11 +2233,12 @@ static void spdc_pen_finish(SPPenContext *const pc, gboolean const closed) // don't let the path be finished before we have collected the required number of mouse clicks return; } + //BSpline if(pc->bspline && pc->green_curve->get_segment_count() < 2 && !pc->sa ) return; - //BSpline End + pc->num_clicks = 0; pen_disable_events(pc); -- cgit v1.2.3 From 74b658f45b5044ab5903ccc255c1ae0f8a750fce Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Jan 2013 19:20:10 +0100 Subject: fix continue (bzr r11950.1.12) --- src/live_effects/lpe-bspline.cpp | 27 +++++----- src/pen-context.cpp | 111 +++++++++++++++++---------------------- 2 files changed, 64 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index c8263282e..a57cc9a88 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -1,4 +1,3 @@ -#define INKSCAPE_HELPER_GEOM_CURVES_H #define INKSCAPE_LPE_BSPLINE_C /* * Released under GNU GPL, read the file 'COPYING' for more information @@ -73,6 +72,7 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); + Geom::CubicBezier const *cubic; //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... @@ -101,17 +101,15 @@ LPEBSpline::doEffect(SPCurve * curve) //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 - if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_end)){ - if((*cubic)[2] == (*cubic)[3]) - isBSpline = false; - } - if (path_it->closed() && !isBSpline) { - isBSpline = true; + cubic = dynamic_cast(&*curve_end); + if(cubic && (*cubic)[2] != (*cubic)[3]) + isBSpline = false; + if (path_it->closed() && isBSpline) { //Calculamos el nodo de inicio BSpline SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); lineHelper->moveto(SBasisIn.valueAt(0.3334)); - lineHelper->lineto(SBasisEnd.valueAt(0.6664)); + lineHelper->lineto(SBasisEnd.valueAt(0.6667)); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -119,6 +117,7 @@ LPEBSpline::doEffect(SPCurve * curve) //Definimos el punto de inicio original de la curva resultante node = startNode; }else{ + isBSpline = true; //Guardamos el principio de la curva startNode = in->first_segment()->initialPoint(); //Definimos el punto de inicio original de la curva resultante @@ -156,13 +155,16 @@ LPEBSpline::doEffect(SPCurve * curve) node = SBasisHelper.valueAt(0.5); //Vemos si el nodo es BSpline o CUSP //Averiguamos si el punto de union tiene manejadores - if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_it1)){ - if((*cubic)[2] == (*cubic)[3]) - isBSpline = true; - } + cubic = dynamic_cast(&*curve_it1); + if(cubic && (*cubic)[2] != (*cubic)[3]) + isBSpline = false; + cubic = dynamic_cast(&*curve_it2); + if(cubic && (*cubic)[0] != (*cubic)[1]) + isBSpline = false; //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP if(!isBSpline ){ //Definimos como nodo el final del segmento de entrada + isBSpline = true; node = pointAt3; } curveHelper->moveto(previousNode); @@ -190,6 +192,7 @@ LPEBSpline::doEffect(SPCurve * curve) curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); }else{ curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + isBSpline = true; } //añadimos este último segmento nCurve->append_continuous(curveHelper, 0.0625); diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 92481ec68..eef82e379 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1566,7 +1566,7 @@ static void spiro(SPPenContext *const pc, bool Shift) } //Continuamos la curva en modo CUSP //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM - if(pc->anchor_statusbar){ + if(pc->anchor_statusbar && pc->red_curve->is_empty()){ saShift = true; } }else{ @@ -1574,7 +1574,9 @@ static void spiro(SPPenContext *const pc, bool Shift) using Geom::X; using Geom::Y; Geom::CubicBezier const * cubic; - + if(pc->anchor_statusbar && pc->red_curve->is_empty()){ + saShift = false; + } if(!pc->red_curve->is_empty()){ //Damos valores a los puntos de la curva roja para que generen un nodo SYMM pc->npoints = 5; @@ -1798,65 +1800,44 @@ static void spiro_doEffect(SPCurve * curve) //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline(SPPenContext *const pc, bool Shift) { - if(!Shift){ - //Modo Bspline formado por nodos CUSP - if (pc->npoints == 5 || !pc->red_curve->is_empty()){ - pc->npoints = 2; - pc->p[1]= pc->p[3]; + if(Shift){ + //Continuamos la curva en modo CUSP + //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM + if(pc->anchor_statusbar && pc->red_curve->is_empty()){ + saShift = true; } - }else{ using Geom::X; using Geom::Y; -/* -.* //TODO: No puedo conseguir que el siguoenmte codigo funcione -.* //Este trata de convertir el nodo de inicio de continuación de curva BSpline a CUSP -.* //modifiacandpo el segmento al que se trata de anexar la curva -.* //de manera que le obligue a tener manejador final -.* -.* if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()){ -.* bool reverse = false; -.* if(pc->sa->start){ -.* pc->sa->curve = reverse_then_reset(pc->sa->curve); -.* reverse = true; -.* } -.* Geom::Point P0(0,0); -.* Geom::Point P1(0,0); -.* Geom::Point P2(0,0); -.* Geom::Point P3(0,0); -.* Geom::Point P4(0,0); -.* P0 = pc->sa->curve->last_segment()->initialPoint(); -.* P1 = P0; -.* P3 = pc->sa->curve->last_segment()->finalPoint(); -.* P2 = P3 + (1./3)*(P0 - P3); -.* P2 = Geom::Point(P2[X]+1,P2[Y]+1); -.* SPCurve * last = new SPCurve(); -.* last->moveto(P0); -.* last->curveto(P1,P2,P3); -.* if( pc->sa->curve->get_segment_count() == 1){ -.* pc->sa->curve = last; -.* }else{ -.* pc->sa->curve->backspace(); -.* pc->sa->curve->append_continuous(last, 0.0625); -.* if(reverse) -.* pc->sa->curve = reverse_then_reset(pc->sa->curve); -.* } -.* delete last; -.* } -*/ - //NODO CUSP formado por nodo SMOOTH - //solo mobemos el manejador del nodo final de cada segmento - //Es suficiente para mostrar el nodo como CUSP - //Usamos 5 puntos + //NODO CUSP formado por nodo SMOOTH + //solo mobemos el manejador del nodo final de cada segmento + //Es suficiente para mostrar el nodo como CUSP + //Usamos 5 puntos + //Continuamos la curva en modo CUSP + //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM + if(!pc->red_curve->is_empty()){ pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); - pc->p[1] = pc->p[0]; pc->p[3] = pc->red_curve->first_segment()->finalPoint(); pc->p[4] = pc->p[3]; pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); } + }else{ + if(pc->anchor_statusbar && pc->red_curve->is_empty()){ + saShift = false; + } + if(!pc->green_curve->is_empty()){ + //Damos valor original a la variable por si se necesita de nuevo + saShift = false; + } + //Modo Bspline formado por nodos CUSP + if (pc->npoints == 5 || !pc->red_curve->is_empty()){ + pc->p[2]= pc->p[3]; + if(pc->green_curve->is_empty() && saShift) + pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); + } } bspline_build(pc); } @@ -1866,6 +1847,7 @@ static void bspline(SPPenContext *const pc, bool Shift) //preparates the curves for its trasformation into BSline curves. static void bspline_build(SPPenContext *const pc) { + //We create the base curve SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start @@ -1897,7 +1879,8 @@ static void bspline_build(SPPenContext *const pc) if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } - //TODO: CALL TO CLONED FUNCTION SPIRO::doEffect IN lpe-spiro.cpp + + //TODO: CALL TO CLONED FUNCTION BSPLINE::doEffect IN lpe-bspline.cpp //For example //using namespace Inkscape::LivePathEffect; //LivePathEffectObject *lpeobj = static_cast (curve); @@ -1954,6 +1937,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 *cubic; //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... @@ -1982,17 +1966,15 @@ static void bspline_doEffect(SPCurve * curve) //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 - if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_end)){ - if((*cubic)[2] == (*cubic)[3]) - isBSpline = false; - } - if (path_it->closed() && !isBSpline) { - isBSpline = true; + cubic = dynamic_cast(&*curve_end); + if(cubic && (*cubic)[2] != (*cubic)[3]) + isBSpline = false; + if (path_it->closed() && isBSpline) { //Calculamos el nodo de inicio BSpline SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); lineHelper->moveto(SBasisIn.valueAt(0.3334)); - lineHelper->lineto(SBasisEnd.valueAt(0.6664)); + lineHelper->lineto(SBasisEnd.valueAt(0.6667)); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -2000,6 +1982,7 @@ static void bspline_doEffect(SPCurve * curve) //Definimos el punto de inicio original de la curva resultante node = startNode; }else{ + isBSpline = true; //Guardamos el principio de la curva startNode = in->first_segment()->initialPoint(); //Definimos el punto de inicio original de la curva resultante @@ -2037,13 +2020,16 @@ static void bspline_doEffect(SPCurve * curve) node = SBasisHelper.valueAt(0.5); //Vemos si el nodo es BSpline o CUSP //Averiguamos si el punto de union tiene manejadores - if (Geom::CubicBezier const *cubic = dynamic_cast(&*curve_it1)){ - if((*cubic)[2] == (*cubic)[3]) - isBSpline = true; - } + cubic = dynamic_cast(&*curve_it1); + if(cubic && (*cubic)[2] != (*cubic)[3]) + isBSpline = false; + cubic = dynamic_cast(&*curve_it2); + if(cubic && (*cubic)[0] != (*cubic)[1]) + isBSpline = false; //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP if(!isBSpline ){ //Definimos como nodo el final del segmento de entrada + isBSpline = true; node = pointAt3; } curveHelper->moveto(previousNode); @@ -2071,6 +2057,7 @@ static void bspline_doEffect(SPCurve * curve) curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); }else{ curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + isBSpline = true; } //añadimos este último segmento nCurve->append_continuous(curveHelper, 0.0625); @@ -2128,7 +2115,7 @@ static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point co } else { // one of the 'regular' modes //SpiroLive - if (pc->p[1] != pc->p[0] || pc->spiro) { + if (pc->p[1] != pc->p[0] || pc->spiro ) { //SpiroLive End pc->red_curve->curveto(pc->p[1], p, p); is_curve = true; -- cgit v1.2.3 From 1a2b144ddb576654cf6672db8528901db92f0e20 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Jan 2013 20:52:24 +0100 Subject: Fixed StartAnchor continue errors with bspline (bzr r11950.1.13) --- src/pen-context.cpp | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index eef82e379..936000c9c 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1801,24 +1801,22 @@ static void spiro_doEffect(SPCurve * curve) static void bspline(SPPenContext *const pc, bool Shift) { if(Shift){ + + using Geom::X; + using Geom::Y; //Continuamos la curva en modo CUSP //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM if(pc->anchor_statusbar && pc->red_curve->is_empty()){ saShift = true; } - using Geom::X; - using Geom::Y; - - //NODO CUSP formado por nodo SMOOTH - //solo mobemos el manejador del nodo final de cada segmento - //Es suficiente para mostrar el nodo como CUSP - //Usamos 5 puntos - //Continuamos la curva en modo CUSP - //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM - + //NODO CUSP formado por nodo SMOOTH + //solo mobemos el manejador del nodo final de cada segmento + //Es suficiente para mostrar el nodo como CUSP + //Usamos 5 puntos if(!pc->red_curve->is_empty()){ pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[1] = pc->p[0]; pc->p[3] = pc->red_curve->first_segment()->finalPoint(); pc->p[4] = pc->p[3]; pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); @@ -1832,11 +1830,17 @@ static void bspline(SPPenContext *const pc, bool Shift) //Damos valor original a la variable por si se necesita de nuevo saShift = false; } - //Modo Bspline formado por nodos CUSP + + //Modo Bspline formado por nodos CUSP if (pc->npoints == 5 || !pc->red_curve->is_empty()){ - pc->p[2]= pc->p[3]; - if(pc->green_curve->is_empty() && saShift) - pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); + pc->npoints = 2; + pc->p[1]= pc->p[3]; + } + if(pc->green_curve->is_empty() && saShift){ + pc->npoints = 5; + pc->p[3] = pc->p[1]; + pc->p[2] = pc->p[3]; + pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); } } bspline_build(pc); @@ -1847,7 +1851,6 @@ static void bspline(SPPenContext *const pc, bool Shift) //preparates the curves for its trasformation into BSline curves. static void bspline_build(SPPenContext *const pc) { - //We create the base curve SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start @@ -1879,8 +1882,7 @@ static void bspline_build(SPPenContext *const pc) if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } - - //TODO: CALL TO CLONED FUNCTION BSPLINE::doEffect IN lpe-bspline.cpp + //TODO: CALL TO CLONED FUNCTION SPIRO::doEffect IN lpe-spiro.cpp //For example //using namespace Inkscape::LivePathEffect; //LivePathEffectObject *lpeobj = static_cast (curve); @@ -2115,7 +2117,7 @@ static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point co } else { // one of the 'regular' modes //SpiroLive - if (pc->p[1] != pc->p[0] || pc->spiro ) { + if (pc->p[1] != pc->p[0] || pc->spiro) { //SpiroLive End pc->red_curve->curveto(pc->p[1], p, p); is_curve = true; @@ -2225,7 +2227,7 @@ static void spdc_pen_finish(SPPenContext *const pc, gboolean const closed) if(pc->bspline && pc->green_curve->get_segment_count() < 2 && !pc->sa ) return; //BSpline End - + pc->num_clicks = 0; pen_disable_events(pc); -- cgit v1.2.3 From 209a1bb14d539824b0c45f5354b471e5596fcf70 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 7 Jan 2013 02:10:39 +0100 Subject: Update name (bzr r11950.1.15) --- src/pencil-context.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index 32248d9b6..4ddeb6a4f 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -788,6 +788,7 @@ interpolate(SPPencilContext *pc) }else{ pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); } + //BSpline } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve); -- cgit v1.2.3 From eeb9410c8748a03536119dd01615cda3ca215cb1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 8 Jan 2013 01:57:47 +0100 Subject: Fix BSplines whit 1 segment (bzr r11950.1.16) --- src/live_effects/lpe-bspline.cpp | 2 ++ src/pen-context.cpp | 8 ++------ src/pencil-context.cpp | 9 ++++++--- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index a57cc9a88..a1f51de0b 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -43,6 +43,8 @@ LPEBSpline::doEffect(SPCurve * curve) using Geom::X; using Geom::Y; + if(curve->get_segment_count() < 2) + return; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 936000c9c..bc57fc603 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1909,7 +1909,8 @@ static void bspline_doEffect(SPCurve * curve) { using Geom::X; using Geom::Y; - + if(curve->get_segment_count() < 2) + return; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); @@ -2223,11 +2224,6 @@ static void spdc_pen_finish(SPPenContext *const pc, gboolean const closed) return; } - //BSpline - if(pc->bspline && pc->green_curve->get_segment_count() < 2 && !pc->sa ) - return; - //BSpline End - pc->num_clicks = 0; pen_disable_events(pc); diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index 4ddeb6a4f..cce04abb7 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -779,10 +779,12 @@ interpolate(SPPencilContext *pc) { /* Fit and draw and reset state */ pc->green_curve->moveto(b[0]); + //BSpline + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); + //BSpline End for (int c = 0; c < n_segs; c++) { - //BSpline - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); + //BSpline if(mode == 2){ pc->green_curve->lineto(b[4*c+3]); }else{ @@ -790,6 +792,7 @@ interpolate(SPPencilContext *pc) } //BSpline } + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve); /* Fit and draw and copy last point */ -- cgit v1.2.3 From 45c35505428e178b32c8f32f85058e4d894bd62d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 18 Jan 2013 23:32:27 +0100 Subject: Delete bspline node whith node tool and fix 1 segment continue shift error (bzr r11950.1.17) --- src/pen-context.cpp | 4 +++- src/ui/tool/multi-path-manipulator.cpp | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index bc57fc603..a5b79cf82 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -2225,7 +2225,9 @@ static void spdc_pen_finish(SPPenContext *const pc, gboolean const closed) } pc->num_clicks = 0; - + if(pc->spiro || pc->bspline){ + saShift = false; + } pen_disable_events(pc); SPDesktop *const desktop = pc->desktop; diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 1f074c8da..c9e35e5b2 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,7 +671,16 @@ bool MultiPathManipulator::event(SPEventContext *event_context, GdkEvent *event) // a) del preserves shape, and control is not pressed // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor - deleteNodes(del_preserves_shape ^ held_control(event->key)); + guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); + if(mode==2){ + if(del_preserves_shape ^ held_control(event->key)) + deleteNodes(false); + else + deleteNodes(true); + } + else + //BSpline end + deleteNodes(del_preserves_shape ^ held_control(event->key)); // Delete any selected gradient nodes as well event_context->deleteSelectedDrag(held_control(event->key)); -- cgit v1.2.3 From e7f30f2084fa4b7169f36012afe7230ac61d2628 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 10 Feb 2013 02:53:57 +0100 Subject: Fix a obsolete dep on src CMake List (bzr r11950.1.23) --- src/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cc3df1bc..a8925e24f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -188,7 +188,6 @@ set(inkscape_SRC composite-undo-stack-observer.cpp conditions.cpp conn-avoid-ref.cpp - connection-points.cpp connector-context.cpp console-output-undo-observer.cpp context-fns.cpp @@ -332,7 +331,6 @@ set(inkscape_SRC composite-undo-stack-observer.h conditions.h conn-avoid-ref.h - connection-points.h connection-pool.h connector-context.h console-output-undo-observer.h -- cgit v1.2.3 From 91942b752107bb44bbc64af31d5912a8b04c815a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 13 Feb 2013 00:07:12 +0100 Subject: First attempt for Adjustable Wheight (bzr r11950.1.28) --- src/live_effects/lpe-bspline.cpp | 82 +++++++++++--------------------- src/live_effects/lpe-bspline.h | 2 - src/pen-context.cpp | 100 ++++++++++++++++----------------------- 3 files changed, 69 insertions(+), 115 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index a1f51de0b..8a01beabd 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -53,14 +53,14 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::D2< Geom::SBasis > SBasisOut; Geom::D2< Geom::SBasis > SBasisEnd; Geom::D2< Geom::SBasis > SBasisHelper; - //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(); + //curves + SPCurve * in = new SPCurve(); + SPCurve * out = new SPCurve(); + SPCurve * end = 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); @@ -74,7 +74,9 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::CubicBezier const *cubic; + Geom::CubicBezier const *cubicIn; + Geom::CubicBezier const *cubicOut; + Geom::CubicBezier const *cubicEnd; //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... @@ -86,9 +88,6 @@ 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 - //Las lineas rectas forman nodos BSpline - //Las curvas forman nodos CUSP - bool isBSpline = true; //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 @@ -100,31 +99,22 @@ 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 - cubic = dynamic_cast(&*curve_end); - if(cubic && (*cubic)[2] != (*cubic)[3]) - isBSpline = false; - if (path_it->closed() && isBSpline) { - //Calculamos el nodo de inicio BSpline - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); - lineHelper->moveto(SBasisIn.valueAt(0.3334)); - lineHelper->lineto(SBasisEnd.valueAt(0.6667)); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - //Guardamos el principio de la curva - startNode = SBasisHelper.valueAt(0.5); - //Definimos el punto de inicio original de la curva resultante - node = startNode; - }else{ - isBSpline = true; - //Guardamos el principio de la curva - startNode = in->first_segment()->initialPoint(); - //Definimos el punto de inicio original de la curva resultante - node = startNode; - } + cubicIn = dynamic_cast(&*curve_it1); + cubicOut = dynamic_cast(&*curve_it2); + cubicEnd = dynamic_cast(&*curve_end); + //Calculamos el nodo de inicio BSpline + lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment()))); + lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubicEnd)[2],*end->first_segment()))); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //Guardamos el principio de la curva + startNode = SBasisHelper.valueAt(0.5); + //Definimos el punto de inicio original de la curva resultante + node = startNode; //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { @@ -134,14 +124,15 @@ LPEBSpline::doEffect(SPCurve * curve) //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida pointAt0 = SBasisIn.valueAt(0); - pointAt1 = SBasisIn.valueAt(0.3334); - pointAt2 = SBasisIn.valueAt(0.6667); + 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); //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - nextPointAt1 = SBasisOut.valueAt(0.3334); - nextPointAt2 = SBasisOut.valueAt(0.6667);; + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*in->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment())); nextPointAt3 = SBasisOut.valueAt(1); + //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 @@ -155,20 +146,6 @@ LPEBSpline::doEffect(SPCurve * curve) previousNode = node; //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); - //Vemos si el nodo es BSpline o CUSP - //Averiguamos si el punto de union tiene manejadores - cubic = dynamic_cast(&*curve_it1); - if(cubic && (*cubic)[2] != (*cubic)[3]) - isBSpline = false; - cubic = dynamic_cast(&*curve_it2); - if(cubic && (*cubic)[0] != (*cubic)[1]) - isBSpline = false; - //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP - if(!isBSpline ){ - //Definimos como nodo el final del segmento de entrada - isBSpline = true; - node = pointAt3; - } curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal @@ -177,6 +154,7 @@ LPEBSpline::doEffect(SPCurve * curve) //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; + //Damos valor a el objeto para el path de entrada y el de salida in->reset(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); @@ -185,6 +163,8 @@ LPEBSpline::doEffect(SPCurve * curve) out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); } + cubicIn = dynamic_cast(&*curve_it1); + cubicOut = dynamic_cast(&*curve_it2); } //Aberiguamos la ultima parte de la curva correspondiente al último segmento curveHelper->moveto(node); @@ -194,7 +174,6 @@ LPEBSpline::doEffect(SPCurve * curve) curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); }else{ curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - isBSpline = true; } //añadimos este último segmento nCurve->append_continuous(curveHelper, 0.0625); @@ -217,13 +196,8 @@ LPEBSpline::doEffect(SPCurve * curve) delete lineHelper; delete curveHelper; //Todo: remove? - //delete SBasisIn; - //delete SBasisOut; - //delete SBasisEnd; //delete SBasisHelper; } - - }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 23ac495df..898f638ed 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -18,8 +18,6 @@ public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); - virtual LPEPathFlashType pathFlashType() { return SUPPRESS_FLASH; } - virtual SPCurve *reverse_then_reset(SPCurve * orig); virtual void doEffect(SPCurve * curve); diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 3055f8504..9e5bb836f 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1772,10 +1772,11 @@ static void spiro_doEffect(SPCurve * curve) //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline(SPPenContext *const pc, bool Shift) { - if(Shift){ + if(!Shift){ using Geom::X; using Geom::Y; + Geom::CubicBezier const *cubic; //Continuamos la curva en modo CUSP //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM if(pc->anchor_statusbar && pc->red_curve->is_empty()){ @@ -1788,11 +1789,16 @@ static void bspline(SPPenContext *const pc, bool Shift) if(!pc->red_curve->is_empty()){ pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); - pc->p[1] = pc->p[0]; + if(pc->green_curve->is_empty()) + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[1]); + else + cubic = dynamic_cast(&*pc->green_curve->last_segment() + if(cubic && (*cubic)[2] == (*cubicIn)[3]) + pc->p[1] = pc->p[0]; + else + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[1]); pc->p[3] = pc->red_curve->first_segment()->finalPoint(); - pc->p[4] = pc->p[3]; pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); } }else{ if(pc->anchor_statusbar && pc->red_curve->is_empty()){ @@ -1803,7 +1809,6 @@ static void bspline(SPPenContext *const pc, bool Shift) saShift = false; } - //Modo Bspline formado por nodos CUSP if (pc->npoints == 5 || !pc->red_curve->is_empty()){ pc->npoints = 2; pc->p[1]= pc->p[3]; @@ -1881,8 +1886,9 @@ static void bspline_doEffect(SPCurve * curve) { using Geom::X; using Geom::Y; + if(curve->get_segment_count() < 2) - return; + return; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); @@ -1891,14 +1897,14 @@ static void bspline_doEffect(SPCurve * curve) Geom::D2< Geom::SBasis > SBasisOut; Geom::D2< Geom::SBasis > SBasisEnd; Geom::D2< Geom::SBasis > SBasisHelper; - //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(); + //curves + SPCurve * in = new SPCurve(); + SPCurve * out = new SPCurve(); + SPCurve * end = 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); @@ -1912,7 +1918,9 @@ static void bspline_doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::CubicBezier const *cubic; + Geom::CubicBezier const *cubicIn; + Geom::CubicBezier const *cubicOut; + Geom::CubicBezier const *cubicEnd; //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... @@ -1924,9 +1932,6 @@ 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 - //Las lineas rectas forman nodos BSpline - //Las curvas forman nodos CUSP - bool isBSpline = true; //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 @@ -1938,31 +1943,22 @@ 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 - cubic = dynamic_cast(&*curve_end); - if(cubic && (*cubic)[2] != (*cubic)[3]) - isBSpline = false; - if (path_it->closed() && isBSpline) { - //Calculamos el nodo de inicio BSpline - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); - lineHelper->moveto(SBasisIn.valueAt(0.3334)); - lineHelper->lineto(SBasisEnd.valueAt(0.6667)); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - //Guardamos el principio de la curva - startNode = SBasisHelper.valueAt(0.5); - //Definimos el punto de inicio original de la curva resultante - node = startNode; - }else{ - isBSpline = true; - //Guardamos el principio de la curva - startNode = in->first_segment()->initialPoint(); - //Definimos el punto de inicio original de la curva resultante - node = startNode; - } + cubicIn = dynamic_cast(&*curve_it1); + cubicOut = dynamic_cast(&*curve_it2); + cubicEnd = dynamic_cast(&*curve_end); + //Calculamos el nodo de inicio BSpline + lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment()))); + lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubicEnd)[2],*end->first_segment()))); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //Guardamos el principio de la curva + startNode = SBasisHelper.valueAt(0.5); + //Definimos el punto de inicio original de la curva resultante + node = startNode; //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { @@ -1972,14 +1968,15 @@ static void bspline_doEffect(SPCurve * curve) //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida pointAt0 = SBasisIn.valueAt(0); - pointAt1 = SBasisIn.valueAt(0.3334); - pointAt2 = SBasisIn.valueAt(0.6667); + 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); //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - nextPointAt1 = SBasisOut.valueAt(0.3334); - nextPointAt2 = SBasisOut.valueAt(0.6667);; + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*in->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment())); nextPointAt3 = SBasisOut.valueAt(1); + //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 @@ -1993,20 +1990,6 @@ static void bspline_doEffect(SPCurve * curve) previousNode = node; //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); - //Vemos si el nodo es BSpline o CUSP - //Averiguamos si el punto de union tiene manejadores - cubic = dynamic_cast(&*curve_it1); - if(cubic && (*cubic)[2] != (*cubic)[3]) - isBSpline = false; - cubic = dynamic_cast(&*curve_it2); - if(cubic && (*cubic)[0] != (*cubic)[1]) - isBSpline = false; - //Si no tiene manejador, tenemos que generar la curva con nodo final CUSP - if(!isBSpline ){ - //Definimos como nodo el final del segmento de entrada - isBSpline = true; - node = pointAt3; - } curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal @@ -2015,6 +1998,7 @@ static void bspline_doEffect(SPCurve * curve) //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; + //Damos valor a el objeto para el path de entrada y el de salida in->reset(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); @@ -2023,6 +2007,8 @@ static void bspline_doEffect(SPCurve * curve) out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); } + cubicIn = dynamic_cast(&*curve_it1); + cubicOut = dynamic_cast(&*curve_it2); } //Aberiguamos la ultima parte de la curva correspondiente al último segmento curveHelper->moveto(node); @@ -2032,7 +2018,6 @@ static void bspline_doEffect(SPCurve * curve) curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); }else{ curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - isBSpline = true; } //añadimos este último segmento nCurve->append_continuous(curveHelper, 0.0625); @@ -2055,12 +2040,9 @@ static void bspline_doEffect(SPCurve * curve) delete lineHelper; delete curveHelper; //Todo: remove? - //delete SBasisIn; - //delete SBasisOut; - //delete SBasisEnd; //delete SBasisHelper; } - + //BSpline end static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point const p, bool statusbar, guint status) -- cgit v1.2.3 From 8988dd2782f290d9b2e88290ce07384839560027 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 13 Feb 2013 01:00:39 +0100 Subject: Removed unused function (bzr r11950.2.2) --- src/live_effects/lpe-bspline.cpp | 8 +------- src/live_effects/lpe-bspline.h | 2 -- src/pen-context.cpp | 9 --------- 3 files changed, 1 insertion(+), 18 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index a1f51de0b..b8e6094f6 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -29,13 +29,7 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : LPEBSpline::~LPEBSpline() { } -//Crea una nueva curva reseteando la original -SPCurve * -LPEBSpline::reverse_then_reset(SPCurve * orig){ - SPCurve *ret = orig->create_reverse(); - orig->reset(); - return ret; -} + void LPEBSpline::doEffect(SPCurve * curve) diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 23ac495df..bb826eee8 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -20,8 +20,6 @@ public: virtual LPEPathFlashType pathFlashType() { return SUPPRESS_FLASH; } - virtual SPCurve *reverse_then_reset(SPCurve * orig); - virtual void doEffect(SPCurve * curve); private: diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 3055f8504..9056003e0 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1472,15 +1472,6 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G } -//BSpline Set Functions -//Creates a new curve resetting the original -static SPCurve * reverse_then_reset(SPCurve *orig) -{ - SPCurve *ret = orig->create_reverse(); - orig->reset(); - return ret; -} - //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void spiro_color(SPPenContext *const pc) { -- cgit v1.2.3 From 23e56d5e362d55bb22edaf1070cbac0b604aee36 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 13 Feb 2013 03:55:29 +0100 Subject: First Steps, BSpline Live Path Ok, working Pen Context (bzr r11950.1.29) --- src/live_effects/lpe-bspline.cpp | 88 ++++++++++++-------- src/live_effects/lpe-bspline.h | 2 +- src/pen-context.cpp | 169 ++++++++++++++++++++++----------------- 3 files changed, 148 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 8a01beabd..408f0f8a6 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -12,7 +12,6 @@ #include <2geom/bezier-curve.h> #include "helper/geom-curves.h" - // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -29,13 +28,6 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : LPEBSpline::~LPEBSpline() { } -//Crea una nueva curva reseteando la original -SPCurve * -LPEBSpline::reverse_then_reset(SPCurve * orig){ - SPCurve *ret = orig->create_reverse(); - orig->reset(); - return ret; -} void LPEBSpline::doEffect(SPCurve * curve) @@ -106,46 +98,70 @@ LPEBSpline::doEffect(SPCurve * curve) cubicIn = dynamic_cast(&*curve_it1); cubicOut = dynamic_cast(&*curve_it2); cubicEnd = dynamic_cast(&*curve_end); - //Calculamos el nodo de inicio BSpline - lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment()))); - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubicEnd)[2],*end->first_segment()))); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - //Guardamos el principio de la curva - startNode = SBasisHelper.valueAt(0.5); - //Definimos el punto de inicio original de la curva resultante - node = startNode; + if (path_it->closed() && cubicIn && cubicEnd && (*cubicIn)[1] != (*cubicEnd)[2]){ + //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()))); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //Guardamos el principio de la curva + startNode = SBasisHelper.valueAt(0.5); + //Definimos el punto de inicio original de la curva resultante + node = startNode; + }else{ + startNode = in->first_segment()->initialPoint(); + node = startNode; + } //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { - //Damos valor a el objeto SBasis para el path de entrada y el de salida 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 - 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); + 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); + }else{ + pointAt0 = SBasisIn.valueAt(0); + pointAt1 = SBasisIn.valueAt(0); + pointAt2 = SBasisIn.valueAt(1); + pointAt3 = SBasisIn.valueAt(1); + } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*in->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment())); - nextPointAt3 = SBasisOut.valueAt(1); - + 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); + }else{ + nextPointAt1 = SBasisOut.valueAt(0); + nextPointAt2 = SBasisOut.valueAt(1); + nextPointAt3 = SBasisOut.valueAt(1); + } //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 - 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); + 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; + } curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal @@ -162,9 +178,10 @@ LPEBSpline::doEffect(SPCurve * curve) if(curve_it1 != curve_end){ out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); + cubicOut = dynamic_cast(&*curve_it2); } cubicIn = dynamic_cast(&*curve_it1); - cubicOut = dynamic_cast(&*curve_it2); + } //Aberiguamos la ultima parte de la curva correspondiente al último segmento curveHelper->moveto(node); @@ -198,6 +215,7 @@ LPEBSpline::doEffect(SPCurve * curve) //Todo: remove? //delete SBasisHelper; } + }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 898f638ed..d983a7654 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -18,7 +18,7 @@ public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); - virtual SPCurve *reverse_then_reset(SPCurve * orig); + virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } virtual void doEffect(SPCurve * curve); diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 9e5bb836f..3c8e46a54 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -65,8 +65,10 @@ #include "live_effects/spiro.h" + #define INKSCAPE_LPE_BSPLINE_C #include "live_effects/lpe-bspline.h" +#include <2geom/nearest-point.h> //BSpline End using Inkscape::ControlManager; @@ -1060,7 +1062,8 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) return; //BSpline Geom::CubicBezier const * cubic; - + if(!pc->bspline) + pc->p[1] = pc->p[0]; //Para formar una curva necesitamos un nodo symm en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que sea symm con el pricipio de la "red_curve" if(pc->spiro){ @@ -1094,27 +1097,25 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) } } - if(!pc->bspline){ - cubic = dynamic_cast( pc->green_curve->last_segment() ); - if ( cubic ) { - pc->p[1] = pc->p[0] + (Geom::Point)( pc->p[0] - (*cubic)[2] ); - } else { - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); - } - } - - //Para formar una curva bspline necesitamos un nodo cusp en el "lastpoint" - //de esta manera modificamos el final de la "curva_verde" para que sea cusp con el pricipio de la "red_curve" - //Que se quedará recta - if(pc->bspline){ +//BSpline + //Para formar una recta necesitamos un nodo con manejador en el "lastpoint" + //de esta manera modificamos el final de la "curva_verde" para que tenga manejador + if(pc->bspline && !pc->green_curve->is_empty()){ Geom::Point A(0,0); Geom::Point B(0,0); + Geom::Point C(0,0); + Geom::Point D(0,0); + using Geom::X; + using Geom::Y; SPCurve * previous = new SPCurve(); - //We obtain the last segment 2 points in the previous curve + //We obtain the last segment 4 points in the previous curve A = pc->green_curve->last_segment()->initialPoint(); - B = pc->green_curve->last_segment()->finalPoint(); + B = pc->green_curve->last_segment()->initialPoint(); + C = pc->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(pc->green_curve->last_segment()->initialPoint() - pc->green_curve->last_segment()->finalPoint()); + pc->p[1] = pc->p[0] + (1./3)*(C - pc->p[0]); + D = pc->green_curve->last_segment()->finalPoint(); previous->moveto(A); - previous->lineto(B); + previous->curveto(B, C, D); if( pc->green_curve->get_segment_count() == 1){ pc->green_curve = previous; }else{ @@ -1123,7 +1124,6 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) //and we add it again with the recreation pc->green_curve->append_continuous(previous, 0.0625); } - } //Spiro Live pen_redraw_all(pc); @@ -1135,8 +1135,7 @@ static void pen_lastpoint_toline (SPPenContext *const pc) //Si no es bspline if (pc->npoints != 5 && !pc->bspline) return; - if(!pc->bspline) - pc->p[1] = pc->p[0]; + Geom::CubicBezier const * cubic; if(pc->spiro){ Geom::Point A(0,0); Geom::Point B(0,0); @@ -1168,25 +1167,28 @@ static void pen_lastpoint_toline (SPPenContext *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } - //BSpline - //Para formar una recta necesitamos un nodo con manejador en el "lastpoint" - //de esta manera modificamos el final de la "curva_verde" para que tenga manejador - if(pc->bspline && !pc->green_curve->is_empty()){ + + if(!pc->bspline){ + cubic = dynamic_cast( pc->green_curve->last_segment() ); + if ( cubic ) { + pc->p[1] = pc->p[0] + (Geom::Point)( pc->p[0] - (*cubic)[2] ); + } else { + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + } + } + + //Para formar una curva bspline necesitamos un nodo cusp en el "lastpoint" + //de esta manera modificamos el final de la "curva_verde" para que sea cusp con el pricipio de la "red_curve" + //Que se quedará recta + if(pc->bspline){ Geom::Point A(0,0); Geom::Point B(0,0); - Geom::Point C(0,0); - Geom::Point D(0,0); - using Geom::X; - using Geom::Y; SPCurve * previous = new SPCurve(); - //We obtain the last segment 4 points in the previous curve + //We obtain the last segment 2 points in the previous curve A = pc->green_curve->last_segment()->initialPoint(); - B = pc->green_curve->last_segment()->initialPoint(); - C = pc->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(pc->green_curve->last_segment()->initialPoint() - pc->green_curve->last_segment()->finalPoint()); - C = Geom::Point(C[X]+1,C[Y]+1); - D = pc->green_curve->last_segment()->finalPoint(); + B = pc->green_curve->last_segment()->finalPoint(); previous->moveto(A); - previous->curveto(B, C, D); + previous->lineto(B); if( pc->green_curve->get_segment_count() == 1){ pc->green_curve = previous; }else{ @@ -1195,8 +1197,8 @@ static void pen_lastpoint_toline (SPPenContext *const pc) //and we add it again with the recreation pc->green_curve->append_continuous(previous, 0.0625); } + } - pen_redraw_all(pc); } @@ -1472,14 +1474,6 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G } -//BSpline Set Functions -//Creates a new curve resetting the original -static SPCurve * reverse_then_reset(SPCurve *orig) -{ - SPCurve *ret = orig->create_reverse(); - orig->reset(); - return ret; -} //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void spiro_color(SPPenContext *const pc) @@ -1789,15 +1783,15 @@ static void bspline(SPPenContext *const pc, bool Shift) if(!pc->red_curve->is_empty()){ pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); if(pc->green_curve->is_empty()) - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[1]); + pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); else - cubic = dynamic_cast(&*pc->green_curve->last_segment() - if(cubic && (*cubic)[2] == (*cubicIn)[3]) + cubic = dynamic_cast(&*pc->green_curve->last_segment()); + if(cubic && ((*cubic)[2] == (*cubic)[3])) pc->p[1] = pc->p[0]; else - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[1]); - pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); } }else{ @@ -1950,46 +1944,70 @@ static void bspline_doEffect(SPCurve * curve) cubicIn = dynamic_cast(&*curve_it1); cubicOut = dynamic_cast(&*curve_it2); cubicEnd = dynamic_cast(&*curve_end); - //Calculamos el nodo de inicio BSpline - lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment()))); - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubicEnd)[2],*end->first_segment()))); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - //Guardamos el principio de la curva - startNode = SBasisHelper.valueAt(0.5); - //Definimos el punto de inicio original de la curva resultante - node = startNode; + if (path_it->closed() && cubicIn && cubicEnd && (*cubicIn)[1] != (*cubicEnd)[2]){ + //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()))); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //Guardamos el principio de la curva + startNode = SBasisHelper.valueAt(0.5); + //Definimos el punto de inicio original de la curva resultante + node = startNode; + }else{ + startNode = in->first_segment()->initialPoint(); + node = startNode; + } //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { - //Damos valor a el objeto SBasis para el path de entrada y el de salida 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 - 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); + 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); + }else{ + pointAt0 = SBasisIn.valueAt(0); + pointAt1 = SBasisIn.valueAt(0); + pointAt2 = SBasisIn.valueAt(1); + pointAt3 = SBasisIn.valueAt(1); + } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*in->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment())); - nextPointAt3 = SBasisOut.valueAt(1); - + 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); + }else{ + nextPointAt1 = SBasisOut.valueAt(0); + nextPointAt2 = SBasisOut.valueAt(1); + nextPointAt3 = SBasisOut.valueAt(1); + } //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 - 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); + 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; + } curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal @@ -2006,9 +2024,10 @@ static void bspline_doEffect(SPCurve * curve) if(curve_it1 != curve_end){ out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); + cubicOut = dynamic_cast(&*curve_it2); } cubicIn = dynamic_cast(&*curve_it1); - cubicOut = dynamic_cast(&*curve_it2); + } //Aberiguamos la ultima parte de la curva correspondiente al último segmento curveHelper->moveto(node); -- cgit v1.2.3 From 0905e866b43bc83405adc3b03a8db47956779c19 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 14 Feb 2013 03:18:29 +0100 Subject: Pen Context working in mode BSpline,Cusp mode to fix (bzr r11950.1.30) --- src/pen-context.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 3c8e46a54..8d5887223 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -583,7 +583,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const //BSpline //Esto evita arrastrar los manejadores ya que el punto se crea //al soltar el botón del ratón. - if((pc->spiro || pc->bspline) && pc->state != SP_PEN_CONTEXT_CLOSE ) pc->state = SP_PEN_CONTEXT_POINT; + if(((pc->spiro || pc->bspline) && pc->state != SP_PEN_CONTEXT_CLOSE)&&!(pc->bspline && bevent.state & GDK_SHIFT_MASK) ) pc->state = SP_PEN_CONTEXT_POINT; //BSpline End ret = TRUE; break; @@ -984,8 +984,20 @@ static void pen_redraw_all (SPPenContext *const pc) // handles //BSpline - if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { + SPCurve * WPower = new SPCurve(); + Geom::D2< Geom::SBasis > SBasisWPower; + float WP = 0; + if (pc->p[0] != pc->p[1] && !pc->spiro /*&& !pc->bspline*/) { //BSpline End + if(pc->bspline){ + WPower->moveto(pc->red_curve->first_segment()->initialPoint()); + WPower->lineto(pc->red_curve->first_segment()->finalPoint()); + SBasisWPower = WPower->first_segment()->toSBasis(); + + WPower->reset(); + pc->p[1] = SBasisWPower.valueAt(WP); + } + SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); sp_canvas_item_show(pc->c1); @@ -994,16 +1006,23 @@ static void pen_redraw_all (SPPenContext *const pc) sp_canvas_item_hide(pc->c1); sp_canvas_item_hide(pc->cl1); } - + Geom::Point p2; Geom::Curve const * last_seg = pc->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); //BSpline if ( cubic && - (*cubic)[2] != pc->p[0]&& !pc->spiro && !pc->bspline ) + (*cubic)[2] != pc->p[0]&& !pc->spiro /*&& !pc->bspline*/ ) { //BSpline End - Geom::Point p2 = (*cubic)[2]; + if(pc->bspline){ + WPower->moveto(last_seg->finalPoint()); + WPower->lineto(last_seg->initialPoint()); + SBasisWPower = WPower->first_segment()->toSBasis(); + p2 = SBasisWPower.valueAt(WP); + }else{ + p2 = (*cubic)[2]; + } SP_CTRL(pc->c0)->moveto(p2); pc->cl0->setCoords(p2, pc->p[0]); sp_canvas_item_show(pc->c0); @@ -1784,15 +1803,35 @@ static void bspline(SPPenContext *const pc, bool Shift) pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[3] = pc->red_curve->first_segment()->finalPoint(); - if(pc->green_curve->is_empty()) + if(pc->green_curve->is_empty()){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); - else + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); + }else{ cubic = dynamic_cast(&*pc->green_curve->last_segment()); - if(cubic && ((*cubic)[2] == (*cubic)[3])) + if(!cubic || ((*cubic)[2] == (*cubic)[3])) pc->p[1] = pc->p[0]; - else - pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); + else{ + if(cubic){ + SPCurve * WPower = new SPCurve(); + Geom::D2< Geom::SBasis > SBasisWPower; + WPower->moveto(pc->green_curve->last_segment()->finalPoint()); + WPower->lineto(pc->green_curve->last_segment()->initialPoint()); + float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); + WPower->reset(); + WPower->moveto(pc->red_curve->last_segment()->initialPoint()); + WPower->lineto(pc->red_curve->last_segment()->finalPoint()); + SBasisWPower = WPower->first_segment()->toSBasis(); + WPower->reset(); + pc->p[1] = SBasisWPower.valueAt(WP); + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); + }else{ + pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); + } + } + } pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); } }else{ if(pc->anchor_statusbar && pc->red_curve->is_empty()){ @@ -1803,9 +1842,11 @@ static void bspline(SPPenContext *const pc, bool Shift) saShift = false; } - if (pc->npoints == 5 || !pc->red_curve->is_empty()){ - pc->npoints = 2; - pc->p[1]= pc->p[3]; + if (!pc->red_curve->is_empty()){ + pc->npoints = 5; + pc->p[0] = pc->red_curve->first_segment()->finalPoint(); + pc->p[3] = pc->red_curve->first_segment()->initialPoint(); + pc->p[2] = pc->p[3]; } if(pc->green_curve->is_empty() && saShift){ pc->npoints = 5; -- cgit v1.2.3 From 28b44133e0d9df8054e17ed9724ea645220e1530 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 14 Feb 2013 06:01:26 +0100 Subject: All done except cusp continuous and close bspline (bzr r11950.1.32) --- src/live_effects/lpe-bspline.cpp | 2 +- src/pen-context.cpp | 78 +++++++++++++++++++++------------------- src/ui/tool/path-manipulator.cpp | 23 ++++++++++-- 3 files changed, 63 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 408f0f8a6..0ce18dcea 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -98,7 +98,7 @@ LPEBSpline::doEffect(SPCurve * curve) cubicIn = dynamic_cast(&*curve_it1); cubicOut = dynamic_cast(&*curve_it2); cubicEnd = dynamic_cast(&*curve_end); - if (path_it->closed() && cubicIn && cubicEnd && (*cubicIn)[1] != (*cubicEnd)[2]){ + if (path_it->closed() && cubicEnd && (*cubicEnd)[3] != (*cubicEnd)[2]){ //Calculamos el nodo de inicio BSpline SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 8d5887223..5c3c49250 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -583,7 +583,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const //BSpline //Esto evita arrastrar los manejadores ya que el punto se crea //al soltar el botón del ratón. - if(((pc->spiro || pc->bspline) && pc->state != SP_PEN_CONTEXT_CLOSE)&&!(pc->bspline && bevent.state & GDK_SHIFT_MASK) ) pc->state = SP_PEN_CONTEXT_POINT; + if((pc->spiro || pc->bspline) && pc->state != SP_PEN_CONTEXT_CLOSE) pc->state = SP_PEN_CONTEXT_POINT; //BSpline End ret = TRUE; break; @@ -1785,15 +1785,12 @@ static void spiro_doEffect(SPCurve * curve) //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline(SPPenContext *const pc, bool Shift) { + using Geom::X; + using Geom::Y; + Geom::CubicBezier const *cubic; if(!Shift){ - - using Geom::X; - using Geom::Y; - Geom::CubicBezier const *cubic; - //Continuamos la curva en modo CUSP - //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM if(pc->anchor_statusbar && pc->red_curve->is_empty()){ - saShift = true; + saShift = false; } //NODO CUSP formado por nodo SMOOTH //solo mobemos el manejador del nodo final de cada segmento @@ -1804,39 +1801,39 @@ static void bspline(SPPenContext *const pc, bool Shift) pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[3] = pc->red_curve->first_segment()->finalPoint(); if(pc->green_curve->is_empty()){ - pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); }else{ cubic = dynamic_cast(&*pc->green_curve->last_segment()); if(!cubic || ((*cubic)[2] == (*cubic)[3])) pc->p[1] = pc->p[0]; else{ - if(cubic){ - SPCurve * WPower = new SPCurve(); - Geom::D2< Geom::SBasis > SBasisWPower; - WPower->moveto(pc->green_curve->last_segment()->finalPoint()); - WPower->lineto(pc->green_curve->last_segment()->initialPoint()); - float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); - WPower->reset(); - WPower->moveto(pc->red_curve->last_segment()->initialPoint()); - WPower->lineto(pc->red_curve->last_segment()->finalPoint()); - SBasisWPower = WPower->first_segment()->toSBasis(); - WPower->reset(); - pc->p[1] = SBasisWPower.valueAt(WP); - pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); - }else{ - pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); - } + SPCurve * WPower = new SPCurve(); + Geom::D2< Geom::SBasis > SBasisWPower; + WPower->moveto(pc->green_curve->last_segment()->finalPoint()); + WPower->lineto(pc->green_curve->last_segment()->initialPoint()); + float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); + WPower->reset(); + WPower->moveto(pc->red_curve->last_segment()->initialPoint()); + WPower->lineto(pc->red_curve->last_segment()->finalPoint()); + SBasisWPower = WPower->first_segment()->toSBasis(); + WPower->reset(); + pc->p[1] = SBasisWPower.valueAt(WP); + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); } } pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); } + if(pc->green_curve->is_empty() && saShift) + pc->p[1] = pc->p[0]; }else{ + //Continuamos la curva en modo CUSP + //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM if(pc->anchor_statusbar && pc->red_curve->is_empty()){ - saShift = false; + saShift = true; } + if(!pc->green_curve->is_empty()){ //Damos valor original a la variable por si se necesita de nuevo saShift = false; @@ -1844,15 +1841,22 @@ static void bspline(SPPenContext *const pc, bool Shift) if (!pc->red_curve->is_empty()){ pc->npoints = 5; - pc->p[0] = pc->red_curve->first_segment()->finalPoint(); - pc->p[3] = pc->red_curve->first_segment()->initialPoint(); - pc->p[2] = pc->p[3]; - } - if(pc->green_curve->is_empty() && saShift){ - pc->npoints = 5; - pc->p[3] = pc->p[1]; - pc->p[2] = pc->p[3]; - pc->p[1] = pc->p[0] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + if(pc->green_curve->is_empty()){ + pc->p[1] = pc->p[0]; + }else{ + cubic = dynamic_cast(&*pc->green_curve->last_segment()); + if(!cubic || ((*cubic)[2] == (*cubic)[3])){ + pc->p[1] = pc->p[0]; + pc->p[2] = pc->p[3]; + }else{ + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); + pc->p[2] = pc->p[3]; + } + + } } } bspline_build(pc); @@ -1985,7 +1989,7 @@ static void bspline_doEffect(SPCurve * curve) cubicIn = dynamic_cast(&*curve_it1); cubicOut = dynamic_cast(&*curve_it2); cubicEnd = dynamic_cast(&*curve_end); - if (path_it->closed() && cubicIn && cubicEnd && (*cubicIn)[1] != (*cubicEnd)[2]){ + if (path_it->closed() && cubicEnd && (*cubicEnd)[3] != (*cubicEnd)[2]){ //Calculamos el nodo de inicio BSpline SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 35eb23f42..f1b2e12be 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -9,7 +9,9 @@ * Copyright (C) 2009 Authors * Released under GNU GPL, read the file 'COPYING' for more information */ - +//BSpline +#include "live_effects/lpe-bspline.h" +//BSpline end #include "live_effects/lpe-powerstroke.h" #include #include @@ -1257,9 +1259,26 @@ void PathManipulator::_updateOutline() sp_canvas_item_hide(_outline); return; } - 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( 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(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) { -- cgit v1.2.3 From 4a0858ff965d54fc08f721fbbc2503f9ab3d9d3c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 18 Feb 2013 11:23:51 +0100 Subject: refactor (bzr r11950.1.35) --- src/live_effects/lpe-bspline.cpp | 46 +++++++++--------- src/pen-context.cpp | 88 +++++++++++++++++++++++---------- src/ui/tool/node.cpp | 26 ++++++++-- src/ui/tool/path-manipulator.cpp | 102 +++++++++++++++++++++++++++++++-------- src/ui/tool/path-manipulator.h | 6 +++ 5 files changed, 196 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 0ce18dcea..858a09159 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -45,14 +45,14 @@ LPEBSpline::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); @@ -66,9 +66,7 @@ LPEBSpline::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... @@ -80,6 +78,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 +90,18 @@ 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(&*curve_it1); - cubicOut = dynamic_cast(&*curve_it2); - cubicEnd = dynamic_cast(&*curve_end); - if (path_it->closed() && cubicEnd && (*cubicEnd)[3] != (*cubicEnd)[2]){ + bezier = dynamic_cast(&*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(&*curve_it1); + lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment()))); + bezier = dynamic_cast(&*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 @@ -111,9 +109,12 @@ 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 ) { @@ -121,10 +122,11 @@ LPEBSpline::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(&*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); @@ -134,9 +136,10 @@ LPEBSpline::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(&*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); @@ -178,10 +181,7 @@ LPEBSpline::doEffect(SPCurve * curve) if(curve_it1 != curve_end){ out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); - cubicOut = dynamic_cast(&*curve_it2); } - cubicIn = dynamic_cast(&*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..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(&*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(&*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(&*curve_it1); - cubicOut = dynamic_cast(&*curve_it2); - cubicEnd = dynamic_cast(&*curve_end); - if (path_it->closed()){ + bezier = dynamic_cast(&*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(&*curve_it1); + lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment()))); + bezier = dynamic_cast(&*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(&*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(&*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(&*curve_it2); } - cubicIn = dynamic_cast(&*curve_it1); - } //Aberiguamos la ultima parte de la curva correspondiente al último segmento curveHelper->moveto(node); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index dc6e0fbae..dff8d3dd9 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -13,7 +13,6 @@ #include #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" @@ -196,8 +195,13 @@ void Handle::move(Geom::Point const &new_pos) break; default: break; } - - setPosition(new_pos); + //BSpline + if(_pm().isBSpline()){ + Handle *h = this; + setPosition(_pm().BSplineHandleReposition(h)); + }else + setPosition(new_pos); + //BSpline End } void Handle::setPosition(Geom::Point const &p) @@ -550,10 +554,24 @@ 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 + float pos = 0; + if(_pm().isBSpline()){ + Node *n = this; + pos = _pm().BSplineMaxPosition(n); + } + //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().BSplineHandleRepositionFixed(front,pos)); + _back.setPosition(_pm().BSplineHandleRepositionFixed(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..b650987bc 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,75 @@ 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( effect_list.front()->lpeobject->get_lpe()); + }else{ + lpe_bsp = NULL; + } + if(lpe_bsp){ + return true; + } + return false; +} +double PathManipulator::BSplineMaxPosition(Node *n){ + double nearestPointAt = 0; + Geom::D2< Geom::SBasis > SBasisInsideNodes; + SPCurve *lineInsideNodes = new SPCurve(); + Node * frontNode = n->nodeToward(n->front()); + if(frontNode){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(frontNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); + } + Node * backNode = n->nodeToward(n->back()); + if(backNode){ + lineInsideNodes->reset(); + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(backNode->position()); + SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + using std::max; + nearestPointAt = max(nearestPointAt,1-Geom::nearest_point(n->back()->position(),*lineInsideNodes->first_segment())); + } + return nearestPointAt; +} + +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ + double nearestPointAt = 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(); + nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); + } + return SBasisInsideNodes.valueAt(nearestPointAt); +} + +Geom::Point PathManipulator::BSplineHandleRepositionFixed(Handle *h,double pos){ + Node *n = h->parent(); + if(n->back()->position() == h->position()) + pos = 1-pos; + 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(); + }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 @@ -1184,14 +1252,25 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } NodeList::iterator prev = subpath->begin(); builder.moveTo(prev->position()); - for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { + if (this->isBSpline()) { + float pos = BSplineMaxPosition(i.ptr()); + i.ptr()->front()->setPosition(BSplineHandleRepositionFixed(i.ptr()->front(),pos)); + i.ptr()->back()->setPosition(BSplineHandleRepositionFixed(i.ptr()->back(),pos)); + } + //BSplie 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. + if (this->isBSpline()) { + float pos = BSplineMaxPosition(prev.ptr()); + subpath->begin().ptr()->front()->setPosition(BSplineHandleRepositionFixed(subpath->begin().ptr()->front(),pos)); + prev.ptr()->back()->setPosition(BSplineHandleRepositionFixed(prev.ptr()->back(),pos)); + + } if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { build_segment(builder, prev.ptr(), subpath->begin().ptr()); } @@ -1200,6 +1279,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 +1341,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( 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(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..72d84a241 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -104,6 +104,12 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); + //BSpline + bool isBSpline(); + double BSplineMaxPosition(Node *n); + Geom::Point BSplineHandleReposition(Handle *h); + Geom::Point BSplineHandleRepositionFixed(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(); -- cgit v1.2.3 From dfe131791aef37e26fd0358c32222dacf813864c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 19 Feb 2013 12:08:14 +0100 Subject: Mayor refactor (bzr r11950.1.36) --- src/live_effects/lpe-bspline.cpp | 80 +++++++++++++++-------------------- src/pen-context.cpp | 82 ++++++++++++++++-------------------- src/ui/tool/node.cpp | 39 +++++++++++++---- src/ui/tool/path-manipulator.cpp | 90 ++++++++++++++++++++++------------------ src/ui/tool/path-manipulator.h | 4 +- 5 files changed, 151 insertions(+), 144 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 858a09159..8147ae014 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -41,9 +41,6 @@ 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; //curves SPCurve * in = new SPCurve(); @@ -66,7 +63,9 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::BezierCurve const *bezier; + Geom::CubicBezier const *cubicIn; + Geom::CubicBezier const *cubicOut; + Geom::CubicBezier const *cubicEnd; //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... @@ -93,15 +92,12 @@ LPEBSpline::doEffect(SPCurve * curve) //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 - bezier = dynamic_cast(&*curve_end); - if (path_it->closed() && bezier && (*bezier)[2] != (*bezier)[3]) { + cubicEnd = dynamic_cast(&*curve_end); + cubicIn = dynamic_cast(&*curve_it1); + if (path_it->closed() && cubicEnd && cubicIn) { //Calculamos el nodo de inicio BSpline - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); - bezier = dynamic_cast(&*curve_it1); - lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment()))); - bezier = dynamic_cast(&*curve_end); - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*bezier)[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 @@ -118,53 +114,45 @@ LPEBSpline::doEffect(SPCurve * curve) //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 - bezier = dynamic_cast(&*curve_it1); - if(bezier){ - pointAt0 = SBasisIn.valueAt(0); - 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); + cubicIn = dynamic_cast(&*curve_it1); + if(cubicIn){ + 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); - bezier = dynamic_cast(&*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); + cubicOut = dynamic_cast(&*curve_it2); + if(cubicOut){ + 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 diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 26eb77b06..e393a706b 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1985,9 +1985,6 @@ static void __attribute__((optimize(0))) 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; //curves SPCurve * in = new SPCurve(); @@ -2010,7 +2007,9 @@ static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); - Geom::BezierCurve const *bezier; + Geom::CubicBezier const *cubicIn; + Geom::CubicBezier const *cubicOut; + Geom::CubicBezier const *cubicEnd; //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... @@ -2037,15 +2036,12 @@ static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) //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 - bezier = dynamic_cast(&*curve_end); - if (path_it->closed() && bezier && (*bezier)[2] != (*bezier)[3]) { + cubicEnd = dynamic_cast(&*curve_end); + cubicIn = dynamic_cast(&*curve_it1); + if (path_it->closed() && cubicEnd && cubicIn) { //Calculamos el nodo de inicio BSpline - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); - bezier = dynamic_cast(&*curve_it1); - lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment()))); - bezier = dynamic_cast(&*curve_end); - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*bezier)[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 @@ -2062,53 +2058,45 @@ static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) //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 - bezier = dynamic_cast(&*curve_it1); - if(bezier){ - pointAt0 = SBasisIn.valueAt(0); - 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); + cubicIn = dynamic_cast(&*curve_it1); + if(cubicIn){ + 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); - bezier = dynamic_cast(&*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); + cubicOut = dynamic_cast(&*curve_it2); + if(cubicOut){ + 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 @@ -2159,7 +2147,7 @@ static void __attribute__((optimize(0))) 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 dff8d3dd9..1a196c857 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -135,6 +135,15 @@ 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 = NULL; + Handle *h2 = NULL; + if(_pm().isBSpline()){ + isBSpline = true; + //BSpline End + } if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. @@ -165,6 +174,15 @@ void Handle::move(Geom::Point const &new_pos) other->setDirection(*node_towards, *_parent); } } + //BSpline + if(isBSpline){ + h = this; + setPosition(_pm().BSplineHandleReposition(h)); + pos = _pm().BSplineHandlePosition(h); + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + } + //BSpline End setPosition(new_pos); return; } @@ -195,12 +213,15 @@ void Handle::move(Geom::Point const &new_pos) break; default: break; } + setPosition(new_pos); //BSpline - if(_pm().isBSpline()){ - Handle *h = this; + if(isBSpline){ + h = this; setPosition(_pm().BSplineHandleReposition(h)); - }else - setPosition(new_pos); + pos = _pm().BSplineHandlePosition(h); + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + } //BSpline End } @@ -555,10 +576,12 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); //BSpline - float pos = 0; + double pos = 0; if(_pm().isBSpline()){ Node *n = this; - pos = _pm().BSplineMaxPosition(n); + pos = _pm().BSplineHandlePosition(n->front()); + if(pos == 0) + pos = _pm().BSplineHandlePosition(n->back()); } //BSpline End setPosition(new_pos); @@ -568,8 +591,8 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline()){ Handle* front = &_front; Handle* back = &_back; - _front.setPosition(_pm().BSplineHandleRepositionFixed(front,pos)); - _back.setPosition(_pm().BSplineHandleRepositionFixed(back,pos)); + _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 diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index b650987bc..c4158931a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1182,31 +1182,8 @@ bool PathManipulator::isBSpline(){ } return false; } -double PathManipulator::BSplineMaxPosition(Node *n){ - double nearestPointAt = 0; - Geom::D2< Geom::SBasis > SBasisInsideNodes; - SPCurve *lineInsideNodes = new SPCurve(); - Node * frontNode = n->nodeToward(n->front()); - if(frontNode){ - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(frontNode->position()); - SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); - } - Node * backNode = n->nodeToward(n->back()); - if(backNode){ - lineInsideNodes->reset(); - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(backNode->position()); - SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - using std::max; - nearestPointAt = max(nearestPointAt,1-Geom::nearest_point(n->back()->position(),*lineInsideNodes->first_segment())); - } - return nearestPointAt; -} - -Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ - double nearestPointAt = 0; +double PathManipulator::BSplineHandlePosition(Handle *h){ + double pos = 0; Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); @@ -1215,19 +1192,23 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } - return SBasisInsideNodes.valueAt(nearestPointAt); + return pos; } -Geom::Point PathManipulator::BSplineHandleRepositionFixed(Handle *h,double 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(); - if(n->back()->position() == h->position()) - pos = 1-pos; Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode){ + if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); @@ -1251,26 +1232,53 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); + //BSpline + float pos = NULL; + 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(BSplineHandleReposition(i.ptr()->front(),pos)); + } + } + //BSpline End builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - if (this->isBSpline()) { - float pos = BSplineMaxPosition(i.ptr()); - i.ptr()->front()->setPosition(BSplineHandleRepositionFixed(i.ptr()->front(),pos)); - i.ptr()->back()->setPosition(BSplineHandleRepositionFixed(i.ptr()->back(),pos)); + //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(BSplineHandleReposition(i.ptr()->front(),pos)); + } } - //BSplie End + + //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. - if (this->isBSpline()) { - float pos = BSplineMaxPosition(prev.ptr()); - subpath->begin().ptr()->front()->setPosition(BSplineHandleRepositionFixed(subpath->begin().ptr()->front(),pos)); - prev.ptr()->back()->setPosition(BSplineHandleRepositionFixed(prev.ptr()->back(),pos)); - + //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(BSplineHandleReposition(subpath->begin().ptr()->front(),pos)); + prev.ptr()->setPosition(BSplineHandleReposition(prev.ptr()->back(),pos)); + } } + //BSpline End if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { build_segment(builder, prev.ptr(), subpath->begin().ptr()); } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 72d84a241..55958530d 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,9 +106,9 @@ private: void _createControlPointsFromGeometry(); //BSpline bool isBSpline(); - double BSplineMaxPosition(Node *n); + double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); - Geom::Point BSplineHandleRepositionFixed(Handle *h,double pos); + 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); -- cgit v1.2.3 From 9af17a6572db964acebd2b7eeea29c8b722c8221 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 23 Feb 2013 23:34:58 +0100 Subject: Saved for next refactor (bzr r11950.1.37) --- src/live_effects/lpe-bspline.cpp | 77 +++++++++++------- src/pen-context.cpp | 171 ++++++++++++++++++++++----------------- src/ui/tool/curve-drag-point.cpp | 20 +++-- src/ui/tool/node.cpp | 5 +- src/ui/tool/path-manipulator.cpp | 38 +++------ 5 files changed, 170 insertions(+), 141 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 8147ae014..8dc840556 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -32,15 +32,15 @@ LPEBSpline::~LPEBSpline() void LPEBSpline::doEffect(SPCurve * curve) { - using Geom::X; - using Geom::Y; - if(curve->get_segment_count() < 2) return; // Make copy of old path as it is changed during processing 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; //curves SPCurve * in = new SPCurve(); @@ -63,9 +63,9 @@ LPEBSpline::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::Point endPointAt2(0,0); + Geom::CubicBezier const *cubic; //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... @@ -75,7 +75,7 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming 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_end = path_it->end_open(); // 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 @@ -92,12 +92,31 @@ LPEBSpline::doEffect(SPCurve * curve) //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 - cubicEnd = dynamic_cast(&*curve_end); - cubicIn = dynamic_cast(&*curve_it1); - if (path_it->closed() && cubicEnd && cubicIn) { - //Calculamos el nodo de inicio BSpline - lineHelper->moveto((*cubicIn)[1]); - lineHelper->lineto((*cubicEnd)[2]); + + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + SBasisIn = in->first_segment()->toSBasis(); + SBasisEnd = end->first_segment()->toSBasis(); + cubic = dynamic_cast(&*curve_it1); + if(cubic){ + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + } + cubic = dynamic_cast(&*curve_end); + if(cubic){ + endPointAt2 = SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())); + }else{ + endPointAt2 = end->first_segment()->finalPoint(); + } + lineHelper->moveto(pointAt1); + lineHelper->lineto(endPointAt2); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -110,18 +129,18 @@ LPEBSpline::doEffect(SPCurve * curve) //Definimos el punto de inicio original de la curva resultante node = startNode; } - //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - cubicIn = dynamic_cast(&*curve_it1); - if(cubicIn){ - pointAt0 = (*cubicIn)[0]; - pointAt1 = (*cubicIn)[1]; - pointAt2 = (*cubicIn)[2]; - pointAt3 = (*cubicIn)[3]; + cubic = dynamic_cast(&*curve_it1); + if(cubic){ + SBasisIn = in->first_segment()->toSBasis(); + pointAt0 = (*cubic)[0]; + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); + pointAt3 = (*cubic)[3]; }else{ pointAt0 = in->first_segment()->initialPoint(); pointAt1 = in->first_segment()->initialPoint(); @@ -130,15 +149,16 @@ LPEBSpline::doEffect(SPCurve * curve) } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - cubicOut = dynamic_cast(&*curve_it2); - if(cubicOut){ - nextPointAt1 = (*cubicOut)[1]; - nextPointAt2 = (*cubicOut)[2]; - nextPointAt3 = (*cubicOut)[3]; + cubic = dynamic_cast(&*curve_it2); + if(cubic){ + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; + nextPointAt3 = (*cubic)[3]; }else{ - nextPointAt1 = in->first_segment()->initialPoint(); - nextPointAt2 = in->first_segment()->finalPoint(); - nextPointAt3 = in->first_segment()->finalPoint(); + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->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 @@ -203,7 +223,6 @@ LPEBSpline::doEffect(SPCurve * curve) //Todo: remove? //delete SBasisHelper; } - }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/pen-context.cpp b/src/pen-context.cpp index e393a706b..350924adb 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1788,49 +1788,10 @@ static void bspline(SPPenContext *const pc, bool Shift) using Geom::X; using Geom::Y; Geom::CubicBezier const *cubic; - if(!Shift){ - //NODO CUSP formado por nodo SMOOTH - //solo mobemos el manejador del nodo final de cada segmento - //Es suficiente para mostrar el nodo como CUSP - //Usamos 5 puntos - if(!pc->red_curve->is_empty()){ - pc->npoints = 5; - pc->p[0] = pc->red_curve->first_segment()->initialPoint(); - pc->p[3] = pc->red_curve->first_segment()->finalPoint(); - if(pc->green_curve->is_empty()){ - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); - pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); - }else{ - cubic = dynamic_cast(&*pc->green_curve->last_segment()); - if(!cubic || ((*cubic)[2] == (*cubic)[3])) - pc->p[1] = pc->p[0]; - else{ - SPCurve * WPower = new SPCurve(); - Geom::D2< Geom::SBasis > SBasisWPower; - WPower->moveto(pc->green_curve->last_segment()->finalPoint()); - WPower->lineto(pc->green_curve->last_segment()->initialPoint()); - float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); - WPower->reset(); - WPower->moveto(pc->red_curve->last_segment()->initialPoint()); - WPower->lineto(pc->red_curve->last_segment()->finalPoint()); - SBasisWPower = WPower->first_segment()->toSBasis(); - WPower->reset(); - pc->p[1] = SBasisWPower.valueAt(WP); - pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); - } - } - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); - } - if(pc->green_curve->is_empty() && saShift) - pc->p[1] = pc->p[0]; - if(pc->anchor_statusbar && pc->red_curve->is_empty()) - saShift = false; - }else{ + if(Shift){ //Continuamos la curva en modo CUSP //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM if(pc->anchor_statusbar && pc->red_curve->is_empty()){ - saShift = true; SPCurve *previousCurve = new SPCurve(); if(pc->sa && !pc->sa->curve->is_empty()){ previousCurve = pc->sa->curve->copy(); @@ -1844,10 +1805,15 @@ static void bspline(SPPenContext *const pc, bool Shift) lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); previousCurve->backspace(); previousCurve->append_continuous(lastSeg, 0.0625); + if (pc->sa->start) { + previousCurve = previousCurve->create_reverse(); + } + pc->sa->curve->reset(); 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 @@ -1866,7 +1832,10 @@ static void bspline(SPPenContext *const pc, bool Shift) lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); same->backspace(); same->append_continuous(lastSeg, 0.0625); - same = same->create_reverse(); + if (pc->sa->start) { + same = same->create_reverse(); + } + pc->sa->curve->reset(); pc->sa->curve = same; } } @@ -1882,16 +1851,12 @@ static void bspline(SPPenContext *const pc, bool Shift) green->backspace(); green->append_continuous(lastSeg, 0.0625); green = green->create_reverse(); + pc->green_curve->reset(); pc->green_curve = green; } } } - if(!pc->green_curve->is_empty()){ - //Damos valor original a la variable por si se necesita de nuevo - saShift = false; - } - if (!pc->red_curve->is_empty()){ pc->npoints = 5; pc->p[0] = pc->red_curve->first_segment()->initialPoint(); @@ -1911,6 +1876,42 @@ static void bspline(SPPenContext *const pc, bool Shift) } } + }else{ + //NODO CUSP formado por nodo SMOOTH + //solo mobemos el manejador del nodo final de cada segmento + //Es suficiente para mostrar el nodo como CUSP + //Usamos 5 puntos + if(!pc->red_curve->is_empty()){ + pc->npoints = 5; + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + if(pc->green_curve->is_empty()){ + if(!pc->sa || (pc->sa && pc->p[0] != pc->p[1])){ + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); + } + }else{ + cubic = dynamic_cast(&*pc->green_curve->last_segment()); + if(!cubic || ((*cubic)[2] == (*cubic)[3])) + pc->p[1] = pc->p[0]; + else{ + SPCurve * WPower = new SPCurve(); + Geom::D2< Geom::SBasis > SBasisWPower; + WPower->moveto(pc->green_curve->last_segment()->finalPoint()); + WPower->lineto(pc->green_curve->last_segment()->initialPoint()); + float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); + WPower->reset(); + WPower->moveto(pc->red_curve->last_segment()->initialPoint()); + WPower->lineto(pc->red_curve->last_segment()->finalPoint()); + SBasisWPower = WPower->first_segment()->toSBasis(); + WPower->reset(); + pc->p[1] = SBasisWPower.valueAt(WP); + pc->p[1] = Geom::Point(pc->p[1][X]+1,pc->p[1][Y]+1); + } + } + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X]+1,pc->p[2][Y]+1); + } } bspline_build(pc); } @@ -1974,17 +1975,17 @@ static void bspline_build(SPPenContext *const pc) } } -static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) +static void bspline_doEffect(SPCurve * curve) { - using Geom::X; - using Geom::Y; - if(curve->get_segment_count() < 2) return; // Make copy of old path as it is changed during processing 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; //curves SPCurve * in = new SPCurve(); @@ -2007,9 +2008,9 @@ static void __attribute__((optimize(0))) 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::Point endPointAt2(0,0); + Geom::CubicBezier const *cubic; //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... @@ -2019,7 +2020,7 @@ static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming 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_end = path_it->end_open(); // 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 @@ -2036,12 +2037,31 @@ static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) //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 - cubicEnd = dynamic_cast(&*curve_end); - cubicIn = dynamic_cast(&*curve_it1); - if (path_it->closed() && cubicEnd && cubicIn) { - //Calculamos el nodo de inicio BSpline - lineHelper->moveto((*cubicIn)[1]); - lineHelper->lineto((*cubicEnd)[2]); + + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + SBasisIn = in->first_segment()->toSBasis(); + SBasisEnd = end->first_segment()->toSBasis(); + cubic = dynamic_cast(&*curve_it1); + if(cubic){ + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + } + cubic = dynamic_cast(&*curve_end); + if(cubic){ + endPointAt2 = SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())); + }else{ + endPointAt2 = end->first_segment()->finalPoint(); + } + lineHelper->moveto(pointAt1); + lineHelper->lineto(endPointAt2); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -2054,18 +2074,18 @@ static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) //Definimos el punto de inicio original de la curva resultante node = startNode; } - //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - cubicIn = dynamic_cast(&*curve_it1); - if(cubicIn){ - pointAt0 = (*cubicIn)[0]; - pointAt1 = (*cubicIn)[1]; - pointAt2 = (*cubicIn)[2]; - pointAt3 = (*cubicIn)[3]; + cubic = dynamic_cast(&*curve_it1); + if(cubic){ + SBasisIn = in->first_segment()->toSBasis(); + pointAt0 = (*cubic)[0]; + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); + pointAt3 = (*cubic)[3]; }else{ pointAt0 = in->first_segment()->initialPoint(); pointAt1 = in->first_segment()->initialPoint(); @@ -2074,15 +2094,16 @@ static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve) } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - cubicOut = dynamic_cast(&*curve_it2); - if(cubicOut){ - nextPointAt1 = (*cubicOut)[1]; - nextPointAt2 = (*cubicOut)[2]; - nextPointAt3 = (*cubicOut)[3]; + cubic = dynamic_cast(&*curve_it2); + if(cubic){ + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; + nextPointAt3 = (*cubic)[3]; }else{ - nextPointAt1 = in->first_segment()->initialPoint(); - nextPointAt2 = in->first_segment()->finalPoint(); - nextPointAt3 = in->first_segment()->finalPoint(); + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->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 diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index b83ce1b3c..40dcb5058 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,9 +53,12 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - first->front()->move(first->front()->position() + delta); - second->back()->move(second->back()->position() - delta); - + //BSpline + if(!_pm.isBSpline()){ + first->front()->move(first->front()->position() + delta); + second->back()->move(second->back()->position() - delta); + } + //BSpline End _pm.update(); } else { _segment_was_degenerate = false; @@ -87,10 +90,13 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - - first->front()->move(first->front()->position() + offset0); - second->back()->move(second->back()->position() + offset1); - + //BSpline + if(!_pm.isBSpline()){ + first->front()->move(first->front()->position() + offset0); + second->back()->move(second->back()->position() + offset1); + }else if(weight>=0.8)second->back()->move(new_pos); + else if(weight<=0.2)first->front()->move(new_pos); + //BSpline End _pm.update(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1a196c857..c6a2df749 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -142,6 +142,7 @@ void Handle::move(Geom::Point const &new_pos) Handle *h2 = NULL; if(_pm().isBSpline()){ isBSpline = true; + _parent->_selection.insert(_parent); //BSpline End } @@ -174,6 +175,7 @@ void Handle::move(Geom::Point const &new_pos) other->setDirection(*node_towards, *_parent); } } + setPosition(new_pos); //BSpline if(isBSpline){ h = this; @@ -183,7 +185,6 @@ void Handle::move(Geom::Point const &new_pos) this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); } //BSpline End - setPosition(new_pos); return; } @@ -580,8 +581,6 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline()){ Node *n = this; pos = _pm().BSplineHandlePosition(n->front()); - if(pos == 0) - pos = _pm().BSplineHandlePosition(n->back()); } //BSpline End setPosition(new_pos); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index c4158931a..ecb8abcf4 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1185,21 +1185,18 @@ bool PathManipulator::isBSpline(){ 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); + double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } @@ -1208,7 +1205,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode && pos != 0){ + if(nextNode){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); @@ -1233,50 +1230,37 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } NodeList::iterator prev = subpath->begin(); //BSpline - float pos = NULL; + 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(BSplineHandleReposition(i.ptr()->front(),pos)); - } + prev->front()->setPosition(BSplineHandleReposition(prev->front(),pos)); } //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(BSplineHandleReposition(i.ptr()->front(),pos)); - } + pos = BSplineHandlePosition(i->back()); + i->front()->setPosition(BSplineHandleReposition(i->front(),pos)); + i->back()->setPosition(BSplineHandleReposition(i->back(),pos)); } //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(BSplineHandleReposition(subpath->begin().ptr()->front(),pos)); - prev.ptr()->setPosition(BSplineHandleReposition(prev.ptr()->back(),pos)); - } + pos = BSplineHandlePosition(prev.next()->back()); + subpath->begin()->front()->setPosition(BSplineHandleReposition(subpath->begin()->front(),pos)); + prev.next()->back()->setPosition(BSplineHandleReposition(prev.next()->back(),pos)); } //BSpline End if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { -- cgit v1.2.3 From ca40dfd444c2543a6debc0786fa8679a108b1056 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 25 Feb 2013 10:59:10 +0100 Subject: BSpline refactor (bzr r11950.1.38) --- src/pen-context.cpp | 311 ++++++++++++++++++++++++++++++++++++++++----------- src/ui/tool/node.cpp | 18 ++- 2 files changed, 264 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 350924adb..4270aecea 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -97,6 +97,7 @@ static void sp_pen_context_set_mode(SPPenContext *const pc, guint mode); static void spiro_color(SPPenContext *const pc); //Guarda el valor si se ha pulsado la tecla SHIFT al continuar una curva static bool saShift = false; + //Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT static void spiro(SPPenContext *const pc, bool Shift); //Unimos todas las curvas en juego y llamamos a la función doEffect. @@ -104,7 +105,14 @@ static void spiro_build(SPPenContext *const pc); //function spiro cloned from lpe-spiro.cpp static void spiro_doEffect(SPCurve * curve); //Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT -static void bspline(SPPenContext *const pc,bool Shift); +static void bspline(SPPenContext *const pc,bool shift); +static void bsplineInMotion(SPPenContext *const pc,bool shift); +static void bsplineOn(SPPenContext *const pc); +static void bsplineStartAnchorOn(SPPenContext *const pc); +static void bsplineEndAnchorOn(SPPenContext *const pc); +static void bsplineOff(SPPenContext *const pc); +static void bsplineStartAnchorOff(SPPenContext *const pc); +static void bsplineEndAnchorOff(SPPenContext *const pc); //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline_build(SPPenContext *const pc); //function bspline cloned from lpe-bspline.cpp @@ -528,6 +536,16 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const // Set start anchor pc->sa = anchor; + //BSpline + if(anchor){ + if(pc->spiro){ + spiro(pc,(bevent.state & GDK_SHIFT_MASK)); + } + if(pc->bspline){ + bspline(pc,(bevent.state & GDK_SHIFT_MASK)); + } + } + //BSpline End if (anchor && !sp_pen_context_has_waiting_LPE(pc)) { // Adjust point to anchor if needed; if we have a waiting LPE, we need // a fresh path to be created so don't continue an existing one @@ -578,12 +596,8 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const spdc_pen_set_subsequent_point(pc, p, true); } } - - pc->state = pc->polylines_only ? SP_PEN_CONTEXT_POINT : SP_PEN_CONTEXT_CONTROL; - //BSpline - //Esto evita arrastrar los manejadores ya que el punto se crea - //al soltar el botón del ratón. - if((pc->spiro || pc->bspline) && pc->state != SP_PEN_CONTEXT_CLOSE) pc->state = SP_PEN_CONTEXT_POINT; + //BSpline; + pc->state = (pc->polylines_only || pc->spiro || pc->bspline )? SP_PEN_CONTEXT_POINT : SP_PEN_CONTEXT_CONTROL; //BSpline End ret = TRUE; break; @@ -665,7 +679,6 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons // Find desktop coordinates Geom::Point p = dt->w2d(event_w); - // Test, whether we hit any anchor SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); switch (pc->mode) { @@ -750,9 +763,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons // snap the handle spdc_endpoint_snap_handle(pc, p, mevent.state); - //BSpline - if (!pc->polylines_only && !pc->spiro && !pc->bspline) { - //BSpline End + if (!pc->polylines_only) { spdc_pen_set_ctrl(pc, p, mevent.state); } else { spdc_pen_set_ctrl(pc, pc->p[1], mevent.state); @@ -782,7 +793,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons spiro(pc,(mevent.state & GDK_SHIFT_MASK)); } if(pc->bspline){ - bspline(pc,(mevent.state & GDK_SHIFT_MASK)); + bsplineInMotion(pc,(mevent.state & GDK_SHIFT_MASK)); } pen_drag_origin_w = event_w; } @@ -830,6 +841,14 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con p = anchor->dp; } pc->sa = anchor; + //BSpline + if(pc->spiro){ + spiro(pc,(revent.state & GDK_SHIFT_MASK)); + } + if(pc->bspline){ + bspline(pc,(revent.state & GDK_SHIFT_MASK)); + } + //BSpline End spdc_pen_set_initial_point(pc, p); } else { // Set end anchor here @@ -838,14 +857,6 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con p = anchor->dp; } } - //BSpline - if(pc->spiro){ - spiro(pc,(revent.state & GDK_SHIFT_MASK)); - } - if(pc->bspline){ - bspline(pc,(revent.state & GDK_SHIFT_MASK)); - } - //BSpline End pc->state = SP_PEN_CONTEXT_CONTROL; ret = TRUE; break; @@ -984,20 +995,8 @@ static void pen_redraw_all (SPPenContext *const pc) // handles //BSpline - SPCurve * WPower = new SPCurve(); - Geom::D2< Geom::SBasis > SBasisWPower; - float WP = 0; - if (pc->p[0] != pc->p[1] && !pc->spiro /*&& !pc->bspline*/) { + if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { //BSpline End - if(pc->bspline){ - WPower->moveto(pc->red_curve->first_segment()->initialPoint()); - WPower->lineto(pc->red_curve->first_segment()->finalPoint()); - SBasisWPower = WPower->first_segment()->toSBasis(); - - WPower->reset(); - pc->p[1] = SBasisWPower.valueAt(WP); - } - SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); sp_canvas_item_show(pc->c1); @@ -1006,23 +1005,16 @@ static void pen_redraw_all (SPPenContext *const pc) sp_canvas_item_hide(pc->c1); sp_canvas_item_hide(pc->cl1); } - Geom::Point p2; + Geom::Curve const * last_seg = pc->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); //BSpline if ( cubic && - (*cubic)[2] != pc->p[0]&& !pc->spiro /*&& !pc->bspline*/ ) + (*cubic)[2] != pc->p[0]&& !pc->spiro && !pc->bspline ) { //BSpline End - if(pc->bspline){ - WPower->moveto(last_seg->finalPoint()); - WPower->lineto(last_seg->initialPoint()); - SBasisWPower = WPower->first_segment()->toSBasis(); - p2 = SBasisWPower.valueAt(WP); - }else{ - p2 = (*cubic)[2]; - } + Geom::Point p2 = (*cubic)[2]; SP_CTRL(pc->c0)->moveto(p2); pc->cl0->setCoords(p2, pc->p[0]); sp_canvas_item_show(pc->c0); @@ -1378,12 +1370,6 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) } } else { // Reset red curve - //BSpline - if ((pc->spiro || pc->bspline) && pc->green_curve->get_segment_count()==1) { - pen_cancel (pc); - ret = TRUE; - } - //BSpline End pc->red_curve->reset(); // Destroy topmost green bpath if (pc->green_bpaths) { @@ -1415,13 +1401,11 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; //BSpline - if(pc->spiro || pc->bspline){ - SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), pc->green_curve); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); - pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); - pen_redraw_all(pc); - } + if((pc->spiro || pc->bspline) && ( pc->green_curve->is_empty() || pc->green_curve->last_segment() == NULL )){ + pen_cancel (pc); + ret = TRUE; + } pc->blue_curve->reset(); + if(pc->spiro || pc->bspline) bspline_build(pc); //BSpline End ret = TRUE; } @@ -1782,6 +1766,209 @@ static void spiro_doEffect(SPCurve * curve) g_free (path); } +//Unimos todas las curvas en juego y llamamos a la función doEffect. + +static void bspline(SPPenContext *const pc, bool shift) +{ + shift?bsplineOff(pc):bsplineOn(pc); + bspline_build(pc); +} + +static void bsplineInMotion(SPPenContext *const pc, bool shift){ + SPCurve *tmpCurve = new SPCurve(); + if(pc->green_curve->is_empty() && !pc->sa){ + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + }else if(!pc->green_curve->is_empty()){ + tmpCurve = pc->green_curve->copy(); + }else{ + tmpCurve = pc->sa->curve->copy(); + if(pc->sa->start) + tmpCurve = tmpCurve->create_reverse(); + } + if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){ + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + SPCurve * WPower = new SPCurve(); + Geom::D2< Geom::SBasis > SBasisWPower; + WPower->moveto(tmpCurve->last_segment()->finalPoint()); + WPower->lineto(tmpCurve->last_segment()->initialPoint()); + float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); + WPower->reset(); + WPower->moveto(pc->red_curve->last_segment()->initialPoint()); + WPower->lineto(pc->red_curve->last_segment()->finalPoint()); + SBasisWPower = WPower->first_segment()->toSBasis(); + WPower->reset(); + pc->p[1] = SBasisWPower.valueAt(WP); + }else{ + pc->p[1] = pc->p[0]; + } + } + + if(pc->anchor_statusbar && !pc->red_curve->is_empty()){ + if(shift) + bsplineEndAnchorOff(pc); + else + bsplineEndAnchorOn(pc); + } + + bspline_build(pc); +} + +static void bsplineOff(SPPenContext *const pc) +{ + if(!pc->red_curve->is_empty()){ + pc->npoints = 5; + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[2] = pc->p[3]; + pc->p[4] = pc->p[3]; + } + if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()) + bsplineStartAnchorOff(pc); +} + +static void bsplineStartAnchorOff(SPPenContext *const pc) +{ + SPCurve *tmpCurve = new SPCurve(); + tmpCurve = pc->sa->curve->copy(); + if(pc->sa->start) + tmpCurve = tmpCurve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + SPCurve *lastSeg = new SPCurve(); + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + tmpCurve->backspace(); + tmpCurve->append_continuous(lastSeg, 0.0625); + if (pc->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + pc->sa->curve->reset(); + pc->sa->curve = tmpCurve; + } + +} + +static void bsplineEndAnchorOff(SPPenContext *const pc) +{ + pc->p[2] = pc->p[3]; + SPCurve *tmpCurve = new SPCurve(); + SPCurve *lastSeg = new SPCurve(); + if(!pc->sa || pc->sa->curve->is_empty()){ + tmpCurve = pc->green_curve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + tmpCurve->backspace(); + tmpCurve->append_continuous(lastSeg, 0.0625); + tmpCurve = tmpCurve->create_reverse(); + pc->green_curve->reset(); + pc->green_curve = tmpCurve; + } + }else{ + tmpCurve = pc->sa->curve->copy(); + if(!pc->sa->start) + tmpCurve = tmpCurve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + tmpCurve->backspace(); + tmpCurve->append_continuous(lastSeg, 0.0625); + if (!pc->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + pc->sa->curve->reset(); + pc->sa->curve = tmpCurve; + } + } +} + +static void bsplineOn(SPPenContext *const pc){ + if(!pc->red_curve->is_empty()){ + pc->npoints = 5; + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + } + if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()) + bsplineStartAnchorOn(pc); +} + +static void bsplineStartAnchorOn(SPPenContext *const pc) +{ + SPCurve *tmpCurve = new SPCurve(); + tmpCurve = pc->sa->curve->copy(); + if(pc->sa->start) + tmpCurve = tmpCurve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + SPCurve *lastSeg = new SPCurve(); + Geom::Point A = tmpCurve->last_segment()->initialPoint(); + Geom::Point D = tmpCurve->last_segment()->finalPoint(); + Geom::Point C(0,0); + if(cubic){ + C = D + (1./3)*(A - D); + lastSeg->moveto(A); + lastSeg->curveto((*cubic)[1],C,D); + }else{ + lastSeg->moveto(A); + lastSeg->curveto(A,C,D); + } + tmpCurve->backspace(); + tmpCurve->append_continuous(lastSeg, 0.0625); + if (pc->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + pc->sa->curve->reset(); + pc->sa->curve = tmpCurve; +} + +static void bsplineEndAnchorOn(SPPenContext *const pc) +{ + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + SPCurve *tmpCurve = new SPCurve(); + SPCurve *lastSeg = new SPCurve(); + Geom::Point C(0,0); + if(!pc->sa || pc->sa->curve->is_empty()){ + tmpCurve = pc->green_curve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); + }else{ + lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); + lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + } + tmpCurve->backspace(); + tmpCurve->append_continuous(lastSeg, 0.0625); + tmpCurve = tmpCurve->create_reverse(); + pc->green_curve->reset(); + pc->green_curve = tmpCurve; + }else{ + tmpCurve = pc->sa->curve->copy(); + if(!pc->sa->start) + tmpCurve = tmpCurve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); + }else{ + lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); + lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + } + tmpCurve->backspace(); + tmpCurve->append_continuous(lastSeg, 0.0625); + if (!pc->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + pc->sa->curve->reset(); + pc->sa->curve = tmpCurve; + } +} +/* //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline(SPPenContext *const pc, bool Shift) { @@ -1789,6 +1976,7 @@ static void bspline(SPPenContext *const pc, bool Shift) using Geom::Y; Geom::CubicBezier const *cubic; if(Shift){ + //Continuamos la curva en modo CUSP //Guardamos el valor de inicio en cusp para que no se redibuje como SYMM if(pc->anchor_statusbar && pc->red_curve->is_empty()){ @@ -1916,7 +2104,7 @@ static void bspline(SPPenContext *const pc, bool Shift) bspline_build(pc); } - +/*/ //preparates the curves for its trasformation into BSline curves. static void bspline_build(SPPenContext *const pc) @@ -2272,14 +2460,12 @@ static void spdc_pen_finish_segment(SPPenContext *const pc, Geom::Point const p, ++pc->num_clicks; if (!pc->red_curve->is_empty()) { - //BSpline if(pc->spiro){ - spiro(pc, (state & GDK_SHIFT_MASK)); + spiro(pc,(state & GDK_SHIFT_MASK)); } if(pc->bspline){ - bspline(pc, (state & GDK_SHIFT_MASK)); + bspline(pc,(state & GDK_SHIFT_MASK)); } - //BSpline End pc->green_curve->append_continuous(pc->red_curve, 0.0625); SPCurve *curve = pc->red_curve->copy(); /// \todo fixme: @@ -2305,9 +2491,6 @@ static void spdc_pen_finish(SPPenContext *const pc, gboolean const closed) } pc->num_clicks = 0; - if(pc->spiro || pc->bspline){ - saShift = false; - } pen_disable_events(pc); SPDesktop *const desktop = pc->desktop; diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index c6a2df749..6dc6c7528 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -577,13 +577,29 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); //BSpline + double prevPos = 0; double pos = 0; + double nextPos = 0; + Node *n = this; + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); if(_pm().isBSpline()){ - Node *n = this; + if(prevNode) + prevPos = _pm().BSplineHandlePosition(prevNode->front()); pos = _pm().BSplineHandlePosition(n->front()); + if(nextNode) + nextPos = _pm().BSplineHandlePosition(nextNode->back()); } //BSpline End setPosition(new_pos); + //BSpline + if(prevNode){ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); + } + if(nextNode){ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); + } + //BSpline End _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); //BSpline -- cgit v1.2.3 From ecc57932f1e7d157950ada2901f6ea6f3acc8aad Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 28 Feb 2013 04:43:21 +0100 Subject: Fixed closed pc->ea (bzr r11950.1.40) --- src/draw-context.cpp | 22 +- src/live_effects/lpe-bspline.cpp | 10 +- src/pen-context.cpp | 420 ++++++++++++++++++++++----------------- src/ui/tool/node.cpp | 38 ++-- src/ui/tool/path-manipulator.cpp | 45 ++--- 5 files changed, 293 insertions(+), 242 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 8da39b027..dcd0fc7ec 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -561,7 +561,15 @@ void spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - spdc_flush_white(dc, NULL); + //BSpline + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); + spdc_flush_white(dc, dc->sa->curve); + }else + //BSpline End + spdc_flush_white(dc, NULL); return; } @@ -687,6 +695,18 @@ SPDrawAnchor *spdc_test_inside(SPDrawContext *dc, Geom::Point p) } } + //BSpline + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && + dc->sa && !dc->red_curve->is_empty() && !dc->green_anchor){ + if(active){ + active->curve = dc->sa->curve; + active->curve->ref(); + } + } + //BSpline End + return active; } diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 8dc840556..36caf73c5 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -34,6 +34,8 @@ LPEBSpline::doEffect(SPCurve * curve) { if(curve->get_segment_count() < 2) return; + using Geom::X; + using Geom::Y; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); @@ -94,13 +96,6 @@ LPEBSpline::doEffect(SPCurve * curve) //en posible caso de que se cierre con una linea recta creando un nodo BSPline if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); cubic = dynamic_cast(&*curve_it1); @@ -223,6 +218,7 @@ LPEBSpline::doEffect(SPCurve * curve) //Todo: remove? //delete SBasisHelper; } + }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 4270aecea..6910e903b 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -106,12 +106,13 @@ static void spiro_build(SPPenContext *const pc); static void spiro_doEffect(SPCurve * curve); //Preparamos la curva roja para que se muestre según esté pulsada la tecla SHIFT static void bspline(SPPenContext *const pc,bool shift); -static void bsplineInMotion(SPPenContext *const pc,bool shift); static void bsplineOn(SPPenContext *const pc); -static void bsplineStartAnchorOn(SPPenContext *const pc); -static void bsplineEndAnchorOn(SPPenContext *const pc); static void bsplineOff(SPPenContext *const pc); +static void bsplineStartAnchor(SPPenContext *const pc,bool shift); +static void bsplineStartAnchorOn(SPPenContext *const pc); static void bsplineStartAnchorOff(SPPenContext *const pc); +static void bsplineMotion(SPPenContext *const pc,bool shift); +static void bsplineEndAnchorOn(SPPenContext *const pc); static void bsplineEndAnchorOff(SPPenContext *const pc); //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline_build(SPPenContext *const pc); @@ -466,7 +467,8 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const Geom::Point event_dt(desktop->w2d(event_w)); SPEventContext *event_context = SP_EVENT_CONTEXT(pc); //Test whether we hit any anchor. - SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); + //Anchor changed from Const because need to update pc->ea for BSpline. + SPDrawAnchor * anchor = spdc_test_inside(pc, event_w); //BSpline //with this we avoid creating a new point over the existing one if((pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ @@ -542,7 +544,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const spiro(pc,(bevent.state & GDK_SHIFT_MASK)); } if(pc->bspline){ - bspline(pc,(bevent.state & GDK_SHIFT_MASK)); + bsplineStartAnchor(pc,(bevent.state & GDK_SHIFT_MASK)); } } //BSpline End @@ -596,8 +598,10 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const spdc_pen_set_subsequent_point(pc, p, true); } } - //BSpline; - pc->state = (pc->polylines_only || pc->spiro || pc->bspline )? SP_PEN_CONTEXT_POINT : SP_PEN_CONTEXT_CONTROL; + //BSpline + //Esto evita arrastrar los manejadores ya que el punto se crea + //al soltar el botón del ratón. + pc->state = (pc->spiro || pc->bspline || pc->polylines_only) ? SP_PEN_CONTEXT_POINT : SP_PEN_CONTEXT_CONTROL; //BSpline End ret = TRUE; break; @@ -760,7 +764,6 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons case SP_PEN_CONTEXT_CONTROL: case SP_PEN_CONTEXT_CLOSE: // Placing controls is last operation in CLOSE state - // snap the handle spdc_endpoint_snap_handle(pc, p, mevent.state); if (!pc->polylines_only) { @@ -768,6 +771,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons } else { spdc_pen_set_ctrl(pc, pc->p[1], mevent.state); } + gobble_motion_events(GDK_BUTTON1_MASK); ret = TRUE; break; @@ -793,7 +797,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons spiro(pc,(mevent.state & GDK_SHIFT_MASK)); } if(pc->bspline){ - bsplineInMotion(pc,(mevent.state & GDK_SHIFT_MASK)); + bsplineMotion(pc,(mevent.state & GDK_SHIFT_MASK)); } pen_drag_origin_w = event_w; } @@ -842,11 +846,13 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con } pc->sa = anchor; //BSpline - if(pc->spiro){ - spiro(pc,(revent.state & GDK_SHIFT_MASK)); - } - if(pc->bspline){ - bspline(pc,(revent.state & GDK_SHIFT_MASK)); + if (anchor) { + if(pc->spiro){ + spiro(pc,(revent.state & GDK_SHIFT_MASK)); + } + if(pc->bspline){ + bsplineStartAnchor(pc,(revent.state & GDK_SHIFT_MASK)); + } } //BSpline End spdc_pen_set_initial_point(pc, p); @@ -900,7 +906,10 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con spdc_pen_finish_segment(pc, p, revent.state); break; case SP_PEN_CONTEXT_CLOSE: - spdc_endpoint_snap(pc, p, revent.state); + // End current segment + if (!anchor) { // Snap node only if not hitting anchor + spdc_endpoint_snap(pc, p, revent.state); + } spdc_pen_finish_segment(pc, p, revent.state); //BSpline //Ocultamos la guia del penultimo nodo al cerrar la curva @@ -919,7 +928,7 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con case SP_PEN_CONTEXT_STOP: // This is allowed, if we just cancelled curve break; - default: + default: break; } pc->state = SP_PEN_CONTEXT_POINT; @@ -1011,7 +1020,7 @@ static void pen_redraw_all (SPPenContext *const pc) Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); //BSpline if ( cubic && - (*cubic)[2] != pc->p[0]&& !pc->spiro && !pc->bspline ) + (*cubic)[2] != pc->p[0] && !pc->spiro && !pc->bspline ) { //BSpline End Geom::Point p2 = (*cubic)[2]; @@ -1387,24 +1396,37 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) pc->p[0] = crv->initialPoint(); if ( Geom::CubicBezier const * cubic = dynamic_cast(crv)) { pc->p[1] = (*cubic)[1]; + //BSpline + if(pc->spiro || pc->bspline)pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + //BSpline End } else { pc->p[1] = pc->p[0]; } - Geom::Point const pt(( pc->npoints < 4 + + Geom::Point const pt((pc->npoints < 4 ? (Geom::Point)(crv->finalPoint()) - : pc->p[3] )); + : pc->p[3])); + pc->npoints = 2; - pc->green_curve->backspace(); + //BSpline + if( pc->green_curve->get_segment_count() == 1){ + pc->npoints = 5; + if (pc->green_bpaths) { + if (pc->green_bpaths->data) + sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data)); + pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data); + } + pc->green_curve->reset(); + }else{ + pc->green_curve->backspace(); + } + //BSpline End sp_canvas_item_hide(pc->cl0); sp_canvas_item_hide(pc->cl1); pc->state = SP_PEN_CONTEXT_POINT; spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; //BSpline - if((pc->spiro || pc->bspline) && ( pc->green_curve->is_empty() || pc->green_curve->last_segment() == NULL )){ - pen_cancel (pc); - ret = TRUE; - } pc->blue_curve->reset(); if(pc->spiro || pc->bspline) bspline_build(pc); //BSpline End ret = TRUE; @@ -1770,48 +1792,22 @@ static void spiro_doEffect(SPCurve * curve) static void bspline(SPPenContext *const pc, bool shift) { - shift?bsplineOff(pc):bsplineOn(pc); + if(!pc->anchor_statusbar) + shift?bsplineOff(pc):bsplineOn(pc); + bspline_build(pc); } -static void bsplineInMotion(SPPenContext *const pc, bool shift){ - SPCurve *tmpCurve = new SPCurve(); - if(pc->green_curve->is_empty() && !pc->sa){ - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); - }else if(!pc->green_curve->is_empty()){ - tmpCurve = pc->green_curve->copy(); - }else{ - tmpCurve = pc->sa->curve->copy(); - if(pc->sa->start) - tmpCurve = tmpCurve->create_reverse(); - } - if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){ - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(cubic){ - SPCurve * WPower = new SPCurve(); - Geom::D2< Geom::SBasis > SBasisWPower; - WPower->moveto(tmpCurve->last_segment()->finalPoint()); - WPower->lineto(tmpCurve->last_segment()->initialPoint()); - float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); - WPower->reset(); - WPower->moveto(pc->red_curve->last_segment()->initialPoint()); - WPower->lineto(pc->red_curve->last_segment()->finalPoint()); - SBasisWPower = WPower->first_segment()->toSBasis(); - WPower->reset(); - pc->p[1] = SBasisWPower.valueAt(WP); - }else{ - pc->p[1] = pc->p[0]; - } - } - - if(pc->anchor_statusbar && !pc->red_curve->is_empty()){ - if(shift) - bsplineEndAnchorOff(pc); - else - bsplineEndAnchorOn(pc); +static void bsplineOn(SPPenContext *const pc){ + if(!pc->red_curve->is_empty()){ + using Geom::X; + using Geom::Y; + pc->npoints = 5; + pc->p[0] = pc->red_curve->first_segment()->initialPoint(); + pc->p[3] = pc->red_curve->first_segment()->finalPoint(); + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625); } - - bspline_build(pc); } static void bsplineOff(SPPenContext *const pc) @@ -1821,10 +1817,54 @@ static void bsplineOff(SPPenContext *const pc) pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[3] = pc->red_curve->first_segment()->finalPoint(); pc->p[2] = pc->p[3]; - pc->p[4] = pc->p[3]; } - if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()) +} + +static void bsplineStartAnchor(SPPenContext *const pc, bool shift) +{ + if(pc->sa->curve->is_empty()) + return; + + if(shift) bsplineStartAnchorOff(pc); + else + bsplineStartAnchorOn(pc); +} + +static void bsplineStartAnchorOn(SPPenContext *const pc) +{ + using Geom::X; + using Geom::Y; + SPCurve *tmpCurve = new SPCurve(); + tmpCurve = pc->sa->curve->copy(); + if(pc->sa->start) + tmpCurve = tmpCurve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + SPCurve *lastSeg = new SPCurve(); + Geom::Point A = tmpCurve->last_segment()->initialPoint(); + Geom::Point D = tmpCurve->last_segment()->finalPoint(); + Geom::Point C = D + (1./3)*(A - D); + C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625); + if(cubic){ + lastSeg->moveto(A); + lastSeg->curveto((*cubic)[1],C,D); + }else{ + lastSeg->moveto(A); + lastSeg->curveto(A,C,D); + } + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (pc->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + pc->sa->curve->reset(); + pc->sa->curve = tmpCurve; } static void bsplineStartAnchorOff(SPPenContext *const pc) @@ -1838,8 +1878,14 @@ static void bsplineStartAnchorOff(SPPenContext *const pc) SPCurve *lastSeg = new SPCurve(); lastSeg->moveto((*cubic)[0]); lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - tmpCurve->backspace(); - tmpCurve->append_continuous(lastSeg, 0.0625); + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } if (pc->sa->start) { tmpCurve = tmpCurve->create_reverse(); } @@ -1849,84 +1895,61 @@ static void bsplineStartAnchorOff(SPPenContext *const pc) } -static void bsplineEndAnchorOff(SPPenContext *const pc) -{ - pc->p[2] = pc->p[3]; +static void bsplineMotion(SPPenContext *const pc, bool shift){ + using Geom::X; + using Geom::Y; SPCurve *tmpCurve = new SPCurve(); - SPCurve *lastSeg = new SPCurve(); - if(!pc->sa || pc->sa->curve->is_empty()){ - tmpCurve = pc->green_curve->create_reverse(); - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - tmpCurve->backspace(); - tmpCurve->append_continuous(lastSeg, 0.0625); - tmpCurve = tmpCurve->create_reverse(); - pc->green_curve->reset(); - pc->green_curve = tmpCurve; - } + if(shift) + pc->p[2] = pc->p[3]; + else + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625); + + if(pc->green_curve->is_empty() && !pc->sa){ + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + }else if(!pc->green_curve->is_empty()){ + tmpCurve = pc->green_curve->copy(); }else{ tmpCurve = pc->sa->curve->copy(); - if(!pc->sa->start) + if(pc->sa->start) tmpCurve = tmpCurve->create_reverse(); + } + if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){ Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - tmpCurve->backspace(); - tmpCurve->append_continuous(lastSeg, 0.0625); - if (!pc->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } - pc->sa->curve->reset(); - pc->sa->curve = tmpCurve; + SPCurve * WPower = new SPCurve(); + Geom::D2< Geom::SBasis > SBasisWPower; + WPower->moveto(tmpCurve->last_segment()->finalPoint()); + WPower->lineto(tmpCurve->last_segment()->initialPoint()); + float WP = Geom::nearest_point((*cubic)[2],*WPower->first_segment()); + WPower->reset(); + WPower->moveto(pc->red_curve->last_segment()->initialPoint()); + WPower->lineto(pc->red_curve->last_segment()->finalPoint()); + SBasisWPower = WPower->first_segment()->toSBasis(); + WPower->reset(); + pc->p[1] = SBasisWPower.valueAt(WP); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.0625,pc->p[1][Y] + 0.0625); + }else{ + pc->p[1] = pc->p[0]; } } -} -static void bsplineOn(SPPenContext *const pc){ - if(!pc->red_curve->is_empty()){ - pc->npoints = 5; - pc->p[0] = pc->red_curve->first_segment()->initialPoint(); - pc->p[3] = pc->red_curve->first_segment()->finalPoint(); - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + if(pc->anchor_statusbar && !pc->red_curve->is_empty()){ + if(shift) + bsplineEndAnchorOff(pc); + else + bsplineEndAnchorOn(pc); } - if(pc->anchor_statusbar && pc->sa && !pc->sa->curve->is_empty() && pc->red_curve->is_empty()) - bsplineStartAnchorOn(pc); -} -static void bsplineStartAnchorOn(SPPenContext *const pc) -{ - SPCurve *tmpCurve = new SPCurve(); - tmpCurve = pc->sa->curve->copy(); - if(pc->sa->start) - tmpCurve = tmpCurve->create_reverse(); - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - SPCurve *lastSeg = new SPCurve(); - Geom::Point A = tmpCurve->last_segment()->initialPoint(); - Geom::Point D = tmpCurve->last_segment()->finalPoint(); - Geom::Point C(0,0); - if(cubic){ - C = D + (1./3)*(A - D); - lastSeg->moveto(A); - lastSeg->curveto((*cubic)[1],C,D); - }else{ - lastSeg->moveto(A); - lastSeg->curveto(A,C,D); - } - tmpCurve->backspace(); - tmpCurve->append_continuous(lastSeg, 0.0625); - if (pc->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } - pc->sa->curve->reset(); - pc->sa->curve = tmpCurve; + bspline_build(pc); } static void bsplineEndAnchorOn(SPPenContext *const pc) { + using Geom::X; + using Geom::Y; pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625); SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); @@ -1934,6 +1957,7 @@ static void bsplineEndAnchorOn(SPPenContext *const pc) tmpCurve = pc->green_curve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); + C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625); if(cubic){ lastSeg->moveto((*cubic)[0]); lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); @@ -1941,8 +1965,14 @@ static void bsplineEndAnchorOn(SPPenContext *const pc) lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); } - tmpCurve->backspace(); - tmpCurve->append_continuous(lastSeg, 0.0625); + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } tmpCurve = tmpCurve->create_reverse(); pc->green_curve->reset(); pc->green_curve = tmpCurve; @@ -1952,6 +1982,7 @@ static void bsplineEndAnchorOn(SPPenContext *const pc) tmpCurve = tmpCurve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); + C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625); if(cubic){ lastSeg->moveto((*cubic)[0]); lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); @@ -1959,8 +1990,14 @@ static void bsplineEndAnchorOn(SPPenContext *const pc) lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); } - tmpCurve->backspace(); - tmpCurve->append_continuous(lastSeg, 0.0625); + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } if (!pc->sa->start) { tmpCurve = tmpCurve->create_reverse(); } @@ -1968,6 +2005,55 @@ static void bsplineEndAnchorOn(SPPenContext *const pc) pc->sa->curve = tmpCurve; } } + +static void bsplineEndAnchorOff(SPPenContext *const pc) +{ + pc->p[2] = pc->p[3]; + SPCurve *tmpCurve = new SPCurve(); + SPCurve *lastSeg = new SPCurve(); + if(!pc->sa || pc->sa->curve->is_empty()){ + tmpCurve = pc->green_curve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + tmpCurve = tmpCurve->create_reverse(); + pc->green_curve->reset(); + pc->green_curve = tmpCurve; + } + }else{ + tmpCurve = pc->sa->curve->copy(); + if(!pc->sa->start) + tmpCurve = tmpCurve->create_reverse(); + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (!pc->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + pc->sa->curve->reset(); + pc->sa->curve = tmpCurve; + } + } +} + /* //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline(SPPenContext *const pc, bool Shift) @@ -2118,7 +2204,7 @@ static void bspline_build(SPPenContext *const pc) curve = curve->create_reverse(); } } - //We add also the green curve + if (!pc->green_curve->is_empty()) curve->append_continuous(pc->green_curve, 0.0625); @@ -2126,16 +2212,12 @@ static void bspline_build(SPPenContext *const pc) if (!pc->red_curve->is_empty()){ pc->red_curve->reset(); pc->red_curve->moveto(pc->p[0]); - if(pc->npoints == 2){ - pc->red_curve->lineto(pc->p[1]); - }else{ - pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); - } + pc->red_curve->curveto(pc->p[1],pc->p[2],pc->p[3]); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); curve->append_continuous(pc->red_curve, 0.0625); } - if(curve->get_segment_count() > 1 ){ + if(!curve->is_empty()){ //cerramos la curva si estan cerca los puntos finales de la curva spiro if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); @@ -2167,6 +2249,8 @@ static void bspline_doEffect(SPCurve * curve) { if(curve->get_segment_count() < 2) return; + using Geom::X; + using Geom::Y; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); @@ -2227,29 +2311,11 @@ static void bspline_doEffect(SPCurve * curve) //en posible caso de que se cierre con una linea recta creando un nodo BSPline if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } + //Calculamos el nodo de inicio BSpline SBasisIn = in->first_segment()->toSBasis(); SBasisEnd = end->first_segment()->toSBasis(); - cubic = dynamic_cast(&*curve_it1); - if(cubic){ - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); - }else{ - pointAt1 = in->first_segment()->initialPoint(); - } - cubic = dynamic_cast(&*curve_end); - if(cubic){ - endPointAt2 = SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())); - }else{ - endPointAt2 = end->first_segment()->finalPoint(); - } - lineHelper->moveto(pointAt1); - lineHelper->lineto(endPointAt2); + lineHelper->moveto(SBasisIn.valueAt(0.3334)); + lineHelper->lineto(SBasisEnd.valueAt(0.6667)); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); //Guardamos el principio de la curva @@ -2267,32 +2333,17 @@ static void bspline_doEffect(SPCurve * curve) { //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - cubic = dynamic_cast(&*curve_it1); - if(cubic){ - SBasisIn = in->first_segment()->toSBasis(); - pointAt0 = (*cubic)[0]; - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); - pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); - pointAt3 = (*cubic)[3]; - }else{ - pointAt0 = in->first_segment()->initialPoint(); - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - pointAt3 = in->first_segment()->finalPoint(); - } + SBasisIn = in->first_segment()->toSBasis(); + SBasisOut = out->first_segment()->toSBasis(); + pointAt0 = SBasisIn.valueAt(0); + pointAt1 = SBasisIn.valueAt(0.3334); + pointAt2 = SBasisIn.valueAt(0.6667); + pointAt3 = SBasisIn.valueAt(1); //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - cubic = dynamic_cast(&*curve_it2); - if(cubic){ - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; - nextPointAt3 = (*cubic)[3]; - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - } + nextPointAt1 = SBasisOut.valueAt(0.3334); + nextPointAt2 = SBasisOut.valueAt(0.6667);; + nextPointAt3 = SBasisOut.valueAt(1); //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 @@ -2356,7 +2407,6 @@ 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 fef904006..4cac0e543 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -138,12 +138,14 @@ void Handle::move(Geom::Point const &new_pos) //BSpline bool isBSpline = false; double pos = 0; - Handle *h = this; + Handle *h = NULL; + Handle *h2 = NULL; if(_pm().isBSpline()){ isBSpline = true; - _parent->_selection.insert(_parent); - //BSpline End + if(!_parent->selected()) + _parent->_selection.insert(_parent); } + //BSpline End if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. @@ -177,12 +179,11 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //BSpline if(isBSpline){ + h = this; setPosition(_pm().BSplineHandleReposition(h)); pos = _pm().BSplineHandlePosition(h); - other->setPosition(_pm().BSplineHandleReposition(other,pos)); - if(pos == 0){ - _parent->setPosition(h->position()); - } + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); } //BSpline End return; @@ -217,12 +218,11 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //BSpline if(isBSpline){ + h = this; setPosition(_pm().BSplineHandleReposition(h)); pos = _pm().BSplineHandlePosition(h); - other->setPosition(_pm().BSplineHandleReposition(other,pos)); - if(pos == 0){ - _parent->setPosition(h->position()); - } + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); } //BSpline End } @@ -588,21 +588,25 @@ void Node::move(Geom::Point const &new_pos) if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); pos = _pm().BSplineHandlePosition(n->front()); + if(pos == 0) + pos = _pm().BSplineHandlePosition(n->back()); if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); } //BSpline End setPosition(new_pos); //BSpline - if(prevNode){ + if(prevNode) prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); - } - if(nextNode){ + if(nextNode) nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); - } //BSpline End _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); + //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); //BSpline if(_pm().isBSpline()){ Handle* front = &_front; @@ -610,10 +614,6 @@ void Node::move(Geom::Point const &new_pos) _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); } void Node::transform(Geom::Affine const &m) diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index ecb8abcf4..7c23ee153 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1182,15 +1182,20 @@ bool PathManipulator::isBSpline(){ } return false; } + double PathManipulator::BSplineHandlePosition(Handle *h){ + using Geom::X; + using Geom::Y; double pos = 0; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode){ + Geom::Point positionH = h->position(); + positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + if(nextNode && n->position() != h->position()){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); } return pos; } @@ -1201,18 +1206,23 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ } Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ + using Geom::X; + using Geom::Y; + Geom::Point ret(0,0); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = n->nodeToward(h); - if(nextNode){ + if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + ret = SBasisInsideNodes.valueAt(pos); + ret = Geom::Point(ret[X] + 0.0625,ret[Y] + 0.0625); }else{ - return n->position(); + ret = n->position(); } - return SBasisInsideNodes.valueAt(pos); + return ret; } /** Construct the geometric representation of nodes and handles, update the outline @@ -1229,26 +1239,8 @@ 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->front()->setPosition(BSplineHandleReposition(prev->front(),pos)); - } - //BSpline End builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - //BSpline - if (isBSpline) { - pos = BSplineHandlePosition(i->back()); - i->front()->setPosition(BSplineHandleReposition(i->front(),pos)); - i->back()->setPosition(BSplineHandleReposition(i->back(),pos)); - } - - //BSpline End build_segment(builder, prev.ptr(), i.ptr()); prev = i; } @@ -1256,13 +1248,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) 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.next()->back()); - subpath->begin()->front()->setPosition(BSplineHandleReposition(subpath->begin()->front(),pos)); - prev.next()->back()->setPosition(BSplineHandleReposition(prev.next()->back(),pos)); - } - //BSpline End if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) { build_segment(builder, prev.ptr(), subpath->begin().ptr()); } -- cgit v1.2.3 From 9c35b88816e60d7fe413a76b48d1764e45157612 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 1 Mar 2013 02:36:23 +0100 Subject: BSpline refactor (bzr r11950.1.41) --- src/live_effects/lpe-bspline.cpp | 118 +++++++++++++++------------------ src/pen-context.cpp | 140 +++++++++++++++++++++------------------ 2 files changed, 128 insertions(+), 130 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 36caf73c5..d046ad683 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -33,41 +33,11 @@ void LPEBSpline::doEffect(SPCurve * curve) { if(curve->get_segment_count() < 2) - return; - using Geom::X; - using Geom::Y; + return; // Make copy of old path as it is changed during processing 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; - //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); - Geom::Point node(0,0); - //Geom::Point previousPointAt3(0,0); - Geom::Point pointAt0(0,0); - Geom::Point pointAt1(0,0); - Geom::Point pointAt2(0,0); - Geom::Point pointAt3(0,0); - //Geom::Point nextPointAt0(0,0); - Geom::Point nextPointAt1(0,0); - Geom::Point nextPointAt2(0,0); - Geom::Point nextPointAt3(0,0); - - Geom::Point endPointAt2(0,0); - Geom::CubicBezier const *cubic; + //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... @@ -77,43 +47,60 @@ LPEBSpline::doEffect(SPCurve * curve) Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_end = path_it->end_open(); // 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 //dichos manejadores + SPCurve * in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); + SPCurve * out = new SPCurve(); out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); - //este no cambia. - end->moveto(curve_end->initialPoint()); - end->lineto(curve_end->finalPoint()); + SPCurve *nCurve = new SPCurve(); + Geom::Point startNode(0,0); + Geom::Point previousNode(0,0); + Geom::Point node(0,0); + Geom::Point pointAt1(0,0); + Geom::Point pointAt2(0,0); + Geom::Point nextPointAt1(0,0); + Geom::Point nextPointAt2(0,0); + Geom::Point nextPointAt3(0,0); + Geom::CubicBezier const *cubic = NULL; //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 if (path_it->closed()) { - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); + //Calculamos el nodo de inicio BSpline + const Geom::Curve &closingline = path_it->back_closed(); + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + curve_endit = path_it->end_open(); + } + SPCurve * end = new SPCurve(); + end->moveto(curve_endit->initialPoint()); + end->lineto(curve_endit->finalPoint()); + Geom::D2< Geom::SBasis > SBasisIn = in->first_segment()->toSBasis(); + Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis(); + end->reset(); + delete end; + SPCurve *lineHelper = new SPCurve(); cubic = dynamic_cast(&*curve_it1); if(cubic){ - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment()))); }else{ - pointAt1 = in->first_segment()->initialPoint(); + lineHelper->moveto(in->first_segment()->initialPoint()); } - cubic = dynamic_cast(&*curve_end); + cubic = dynamic_cast(&*curve_endit); if(cubic){ - endPointAt2 = SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())); + lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment()))); }else{ - endPointAt2 = end->first_segment()->finalPoint(); + lineHelper->lineto(end->first_segment()->finalPoint()); } - lineHelper->moveto(pointAt1); - lineHelper->lineto(endPointAt2); - SBasisHelper = lineHelper->first_segment()->toSBasis(); + Geom::D2< Geom::SBasis > SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); + delete lineHelper; //Guardamos el principio de la curva startNode = SBasisHelper.valueAt(0.5); //Definimos el punto de inicio original de la curva resultante @@ -131,22 +118,18 @@ LPEBSpline::doEffect(SPCurve * curve) //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida cubic = dynamic_cast(&*curve_it1); if(cubic){ - SBasisIn = in->first_segment()->toSBasis(); - pointAt0 = (*cubic)[0]; + Geom::D2< Geom::SBasis > SBasisIn = in->first_segment()->toSBasis(); pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); - pointAt3 = (*cubic)[3]; }else{ - 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); cubic = dynamic_cast(&*curve_it2); if(cubic){ - SBasisOut = out->first_segment()->toSBasis(); + Geom::D2< Geom::SBasis > SBasisOut = out->first_segment()->toSBasis(); nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; nextPointAt3 = (*cubic)[3]; @@ -160,33 +143,41 @@ LPEBSpline::doEffect(SPCurve * curve) //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 + SPCurve *lineHelper = new SPCurve(); lineHelper->moveto(pointAt2); lineHelper->lineto(nextPointAt1); - SBasisHelper = lineHelper->first_segment()->toSBasis(); + Geom::D2< Geom::SBasis > SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); + delete lineHelper; //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); + SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal nCurve->append_continuous(curveHelper, 0.0625); curveHelper->reset(); + delete curveHelper; //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; - //Damos valor a el objeto para el path de entrada y el de salida in->reset(); + delete in; + SPCurve * in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); out->reset(); - if(curve_it1 != curve_end){ + delete out; + if(curve_it1 != curve_endit){ + SPCurve * out = new SPCurve(); out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); } } //Aberiguamos la ultima parte de la curva correspondiente al último segmento + SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(node); //Si está cerrada la curva, la cerramos sobre el valor guardado previamente //Si no finalizamos en el punto final @@ -197,26 +188,21 @@ LPEBSpline::doEffect(SPCurve * curve) } //añadimos este último segmento nCurve->append_continuous(curveHelper, 0.0625); + curveHelper->reset(); + delete curveHelper; //y cerramos la curva if (path_it->closed()) { nCurve->closepath_current(); } curve->append(nCurve,false); nCurve->reset(); + delete nCurve; //Limpiamos in->reset(); out->reset(); - end->reset(); - lineHelper->reset(); - curveHelper->reset(); + delete in; + delete out; } - delete in; - delete out; - delete end; - delete lineHelper; - delete curveHelper; - //Todo: remove? - //delete SBasisHelper; } }; //namespace LivePathEffect diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 6910e903b..a505f8de7 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -2248,41 +2248,11 @@ static void bspline_build(SPPenContext *const pc) static void bspline_doEffect(SPCurve * curve) { if(curve->get_segment_count() < 2) - return; - using Geom::X; - using Geom::Y; + return; // Make copy of old path as it is changed during processing 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; - //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); - Geom::Point node(0,0); - //Geom::Point previousPointAt3(0,0); - Geom::Point pointAt0(0,0); - Geom::Point pointAt1(0,0); - Geom::Point pointAt2(0,0); - Geom::Point pointAt3(0,0); - //Geom::Point nextPointAt0(0,0); - Geom::Point nextPointAt1(0,0); - Geom::Point nextPointAt2(0,0); - Geom::Point nextPointAt3(0,0); - - Geom::Point endPointAt2(0,0); - Geom::CubicBezier const *cubic; + //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... @@ -2292,32 +2262,60 @@ static void bspline_doEffect(SPCurve * curve) Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve - Geom::Path::const_iterator curve_end = path_it->end_open(); // 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 //dichos manejadores + SPCurve * in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); + SPCurve * out = new SPCurve(); out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); - //este no cambia. - end->moveto(curve_end->initialPoint()); - end->lineto(curve_end->finalPoint()); + SPCurve *nCurve = new SPCurve(); + Geom::Point startNode(0,0); + Geom::Point previousNode(0,0); + Geom::Point node(0,0); + Geom::Point pointAt1(0,0); + Geom::Point pointAt2(0,0); + Geom::Point nextPointAt1(0,0); + Geom::Point nextPointAt2(0,0); + Geom::Point nextPointAt3(0,0); + Geom::CubicBezier const *cubic = NULL; //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 if (path_it->closed()) { //Calculamos el nodo de inicio BSpline - SBasisIn = in->first_segment()->toSBasis(); - SBasisEnd = end->first_segment()->toSBasis(); - lineHelper->moveto(SBasisIn.valueAt(0.3334)); - lineHelper->lineto(SBasisEnd.valueAt(0.6667)); - SBasisHelper = lineHelper->first_segment()->toSBasis(); + const Geom::Curve &closingline = path_it->back_closed(); + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + curve_endit = path_it->end_open(); + } + SPCurve * end = new SPCurve(); + end->moveto(curve_endit->initialPoint()); + end->lineto(curve_endit->finalPoint()); + Geom::D2< Geom::SBasis > SBasisIn = in->first_segment()->toSBasis(); + Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis(); + end->reset(); + delete end; + SPCurve *lineHelper = new SPCurve(); + cubic = dynamic_cast(&*curve_it1); + if(cubic){ + lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment()))); + }else{ + lineHelper->moveto(in->first_segment()->initialPoint()); + } + cubic = dynamic_cast(&*curve_endit); + if(cubic){ + lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment()))); + }else{ + lineHelper->lineto(end->first_segment()->finalPoint()); + } + Geom::D2< Geom::SBasis > SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); + delete lineHelper; //Guardamos el principio de la curva startNode = SBasisHelper.valueAt(0.5); //Definimos el punto de inicio original de la curva resultante @@ -2333,49 +2331,68 @@ static void bspline_doEffect(SPCurve * curve) { //previousPointAt3 = pointAt3; //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - SBasisIn = in->first_segment()->toSBasis(); - SBasisOut = out->first_segment()->toSBasis(); - pointAt0 = SBasisIn.valueAt(0); - pointAt1 = SBasisIn.valueAt(0.3334); - pointAt2 = SBasisIn.valueAt(0.6667); - pointAt3 = SBasisIn.valueAt(1); + cubic = dynamic_cast(&*curve_it1); + if(cubic){ + Geom::D2< Geom::SBasis > SBasisIn = in->first_segment()->toSBasis(); + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } //Y hacemos lo propio con el path de salida //nextPointAt0 = curveOut.valueAt(0); - nextPointAt1 = SBasisOut.valueAt(0.3334); - nextPointAt2 = SBasisOut.valueAt(0.6667);; - nextPointAt3 = SBasisOut.valueAt(1); + cubic = dynamic_cast(&*curve_it2); + if(cubic){ + Geom::D2< Geom::SBasis > SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; + nextPointAt3 = (*cubic)[3]; + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->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 + SPCurve *lineHelper = new SPCurve(); lineHelper->moveto(pointAt2); lineHelper->lineto(nextPointAt1); - SBasisHelper = lineHelper->first_segment()->toSBasis(); + Geom::D2< Geom::SBasis > SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); + delete lineHelper; //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); + SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); //añadimos la curva generada a la curva pricipal nCurve->append_continuous(curveHelper, 0.0625); curveHelper->reset(); + delete curveHelper; //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; - //Damos valor a el objeto para el path de entrada y el de salida in->reset(); + delete in; + SPCurve * in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); out->reset(); - if(curve_it1 != curve_end){ + delete out; + if(curve_it1 != curve_endit){ + SPCurve * out = new SPCurve(); out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); } } //Aberiguamos la ultima parte de la curva correspondiente al último segmento + SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(node); //Si está cerrada la curva, la cerramos sobre el valor guardado previamente //Si no finalizamos en el punto final @@ -2386,26 +2403,21 @@ static void bspline_doEffect(SPCurve * curve) } //añadimos este último segmento nCurve->append_continuous(curveHelper, 0.0625); + curveHelper->reset(); + delete curveHelper; //y cerramos la curva if (path_it->closed()) { nCurve->closepath_current(); } curve->append(nCurve,false); nCurve->reset(); + delete nCurve; //Limpiamos in->reset(); out->reset(); - end->reset(); - lineHelper->reset(); - curveHelper->reset(); + delete in; + delete out; } - delete in; - delete out; - delete end; - delete lineHelper; - delete curveHelper; - //Todo: remove? - //delete SBasisHelper; } //BSpline end -- cgit v1.2.3 From 558d770276900cf82341f00970609c0663237130 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 3 Mar 2013 23:19:39 +0100 Subject: Fix sintax (bzr r11950.1.43) --- src/pen-context.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 0af9570c1..e781a048f 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1708,7 +1708,7 @@ static void spiroEndAnchorOn(SPPenContext *const pc) if(!pc->sa || pc->sa->curve->is_empty()){ tmpCurve = pc->green_curve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - C = tmpCurve->last_segment()->finalPoint() + + (Geom::Point)(tmpCurve->last_segment()->finalPoint() - pc->p[2]); + C = tmpCurve->last_segment()->finalPoint() + (Geom::Point)(tmpCurve->last_segment()->finalPoint() - pc->p[2]); if(cubic){ lastSeg->moveto((*cubic)[0]); lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); @@ -1732,7 +1732,7 @@ static void spiroEndAnchorOn(SPPenContext *const pc) if(!pc->sa->start) tmpCurve = tmpCurve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - C = tmpCurve->last_segment()->finalPoint() + + (Geom::Point)(tmpCurve->last_segment()->finalPoint() - pc->p[2]); + C = tmpCurve->last_segment()->finalPoint() + (Geom::Point)(tmpCurve->last_segment()->finalPoint() - pc->p[2]); if(cubic){ lastSeg->moveto((*cubic)[0]); lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); -- cgit v1.2.3 From 93394bdda7e0c876eafe9847a01c6d91e0dc0f7a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 5 Mar 2013 22:51:31 +0100 Subject: BPower for testing. (bzr r11950.1.45) --- src/pen-context.cpp | 216 ++++++++++++++++++++++----------------------------- src/ui/tool/node.cpp | 20 +++-- 2 files changed, 107 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 26f800328..6232c5e59 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1055,69 +1055,51 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) return; //BSpline Geom::CubicBezier const * cubic; - if(!pc->bspline) - pc->p[1] = pc->p[0]; + pc->p[1] = pc->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(pc->red_curve->last_segment()->finalPoint() - pc->red_curve->last_segment()->initialPoint()); //Para formar una curva necesitamos un nodo symm en el "lastpoint" //de esta manera modificamos el final de la "curva_verde" para que sea symm con el pricipio de la "red_curve" - if(pc->spiro){ - Geom::Point A(0,0); - Geom::Point B(0,0); - Geom::Point C(0,0); - Geom::Point D(0,0); - SPCurve * previous = new SPCurve(); - cubic = dynamic_cast( pc->green_curve->last_segment() ); - //We obtain the last segment 4 points in the previous curve - if ( cubic ){ - A = (*cubic)[0]; - B = (*cubic)[1]; - C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); - D = (*cubic)[3]; - }else{ - A = pc->green_curve->last_segment()->initialPoint(); - B = pc->green_curve->last_segment()->initialPoint(); - C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); - D = pc->green_curve->last_segment()->finalPoint(); + if(pc->spiro||pc->bspline){ + if(!pc->green_curve->is_empty()){ + Geom::Point A(0,0); + Geom::Point B(0,0); + Geom::Point C(0,0); + Geom::Point D(0,0); + SPCurve * previous = new SPCurve(); + cubic = dynamic_cast( pc->green_curve->last_segment() ); + //We obtain the last segment 4 points in the previous curve + if ( cubic ){ + A = (*cubic)[0]; + B = (*cubic)[1]; + if(pc->spiro){ + C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); + }else + C = pc->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(pc->green_curve->last_segment()->initialPoint() - pc->green_curve->last_segment()->finalPoint()); + D = (*cubic)[3]; + }else{ + A = pc->green_curve->last_segment()->initialPoint(); + B = pc->green_curve->last_segment()->initialPoint(); + if(pc->spiro) + C = pc->p[0] + (Geom::Point)(pc->p[0] - pc->p[1]); + else + C = pc->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(pc->green_curve->last_segment()->initialPoint() - pc->green_curve->last_segment()->finalPoint()); + D = pc->green_curve->last_segment()->finalPoint(); + } + previous->moveto(A); + previous->curveto(B, C, D); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = previous; + }else{ + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } } - previous->moveto(A); - previous->curveto(B, C, D); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = previous; - }else{ - //we eliminate the last segment - pc->green_curve->backspace(); - //and we add it again with the recreation - pc->green_curve->append_continuous(previous, 0.0625); + if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ + bspline_spiro_start_anchor(pc, false); } } -//BSpline - //Para formar una recta necesitamos un nodo con manejador en el "lastpoint" - //de esta manera modificamos el final de la "curva_verde" para que tenga manejador - if(pc->bspline && !pc->green_curve->is_empty()){ - Geom::Point A(0,0); - Geom::Point B(0,0); - Geom::Point C(0,0); - Geom::Point D(0,0); - using Geom::X; - using Geom::Y; - SPCurve * previous = new SPCurve(); - //We obtain the last segment 4 points in the previous curve - A = pc->green_curve->last_segment()->initialPoint(); - B = pc->green_curve->last_segment()->initialPoint(); - C = pc->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(pc->green_curve->last_segment()->initialPoint() - pc->green_curve->last_segment()->finalPoint()); - pc->p[1] = pc->p[0] + (1./3)*(C - pc->p[0]); - D = pc->green_curve->last_segment()->finalPoint(); - previous->moveto(A); - previous->curveto(B, C, D); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = previous; - }else{ - //we eliminate the last segment - pc->green_curve->backspace(); - //and we add it again with the recreation - pc->green_curve->append_continuous(previous, 0.0625); - } - } //Spiro Live pen_redraw_all(pc); } @@ -1128,70 +1110,43 @@ static void pen_lastpoint_toline (SPPenContext *const pc) //Si no es bspline if (pc->npoints != 5 && !pc->bspline) return; - Geom::CubicBezier const * cubic; - if(pc->spiro){ - Geom::Point A(0,0); - Geom::Point B(0,0); - Geom::Point C(0,0); - Geom::Point D(0,0); - SPCurve * previous = new SPCurve(); - Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment() ); - if ( cubic ) { - A = pc->green_curve->last_segment()->initialPoint(); - B = (*cubic)[1]; - C = pc->green_curve->last_segment()->finalPoint(); - D = C; - pc->p[1] = pc->p[0] + (Geom::Point)( (*cubic)[3] - (*cubic)[2] ); - } else { - //We obtain the last segment 4 points in the previous curve - A = pc->green_curve->last_segment()->initialPoint(); - B = A; - C = pc->green_curve->last_segment()->finalPoint(); - D = C; - } - previous->moveto(A); - previous->curveto(B, C, D); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = previous; - }else{ - //we eliminate the last segment - pc->green_curve->backspace(); - //and we add it again with the recreation - pc->green_curve->append_continuous(previous, 0.0625); + if(pc->spiro || pc->bspline){ + if(!pc->green_curve->is_empty()){ + Geom::Point A(0,0); + Geom::Point B(0,0); + Geom::Point C(0,0); + Geom::Point D(0,0); + SPCurve * previous = new SPCurve(); + Geom::CubicBezier const * cubic = dynamic_cast( pc->green_curve->last_segment() ); + if ( cubic ) { + A = pc->green_curve->last_segment()->initialPoint(); + B = (*cubic)[1]; + C = pc->green_curve->last_segment()->finalPoint(); + D = C; + } else { + //We obtain the last segment 4 points in the previous curve + A = pc->green_curve->last_segment()->initialPoint(); + B = A; + C = pc->green_curve->last_segment()->finalPoint(); + D = C; + } + previous->moveto(A); + previous->curveto(B, C, D); + if( pc->green_curve->get_segment_count() == 1){ + pc->green_curve = previous; + }else{ + //we eliminate the last segment + pc->green_curve->backspace(); + //and we add it again with the recreation + pc->green_curve->append_continuous(previous, 0.0625); + } } - } - - if(!pc->bspline){ - cubic = dynamic_cast( pc->green_curve->last_segment() ); - if ( cubic ) { - pc->p[1] = pc->p[0] + (Geom::Point)( pc->p[0] - (*cubic)[2] ); - } else { - pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ + bspline_spiro_start_anchor(pc, true); } } - - //Para formar una curva bspline necesitamos un nodo cusp en el "lastpoint" - //de esta manera modificamos el final de la "curva_verde" para que sea cusp con el pricipio de la "red_curve" - //Que se quedará recta - if(pc->bspline){ - Geom::Point A(0,0); - Geom::Point B(0,0); - SPCurve * previous = new SPCurve(); - //We obtain the last segment 2 points in the previous curve - A = pc->green_curve->last_segment()->initialPoint(); - B = pc->green_curve->last_segment()->finalPoint(); - previous->moveto(A); - previous->lineto(B); - if( pc->green_curve->get_segment_count() == 1){ - pc->green_curve = previous; - }else{ - //we eliminate the last segment - pc->green_curve->backspace(); - //and we add it again with the recreation - pc->green_curve->append_continuous(previous, 0.0625); - } - - } + + pc->p[1] = pc->p[0]; pen_redraw_all(pc); } @@ -1352,6 +1307,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) } } else { // Reset red curve + Geom::CubicBezier const * cubic = NULL; pc->red_curve->reset(); // Destroy topmost green bpath if (pc->green_bpaths) { @@ -1367,14 +1323,15 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) // The code below assumes that pc->green_curve has only ONE path ! Geom::Curve const * crv = pc->green_curve->last_segment(); pc->p[0] = crv->initialPoint(); - if ( Geom::CubicBezier const * cubic = dynamic_cast(crv)) { + cubic = dynamic_cast(crv); + if ( cubic ) { pc->p[1] = (*cubic)[1]; - //BSpline - if(pc->spiro || pc->bspline)pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); - //BSpline End } else { pc->p[1] = pc->p[0]; } + if(pc->bspline){ + pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + } Geom::Point const pt((pc->npoints < 4 ? (Geom::Point)(crv->finalPoint()) @@ -1393,6 +1350,15 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) }else{ pc->green_curve->backspace(); } + if(pc->spiro){ + cubic = dynamic_cast(pc->green_curve->last_segment()); + if ( cubic ) { + pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2]); + SP_CTRL(pc->c1)->moveto(pc->p[0]); + } else { + pc->p[1] = pc->p[0]; + } + } //BSpline End sp_canvas_item_hide(pc->cl0); sp_canvas_item_hide(pc->cl1); @@ -1856,7 +1822,11 @@ static void bspline_spiro_build(SPPenContext *const pc) curve->unref(); pc->blue_curve->reset(); //We hide the holders that doesn't contribute anything - sp_canvas_item_hide(pc->c1); + if(pc->spiro){ + sp_canvas_item_show(pc->c1); + SP_CTRL(pc->c1)->moveto(pc->p[0]); + }else + sp_canvas_item_hide(pc->c1); sp_canvas_item_hide(pc->cl1); sp_canvas_item_hide(pc->c0); sp_canvas_item_hide(pc->cl0); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 4cac0e543..e7d62d619 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -142,8 +142,14 @@ void Handle::move(Geom::Point const &new_pos) Handle *h2 = NULL; if(_pm().isBSpline()){ isBSpline = true; - if(!_parent->selected()) - _parent->_selection.insert(_parent); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + _parent->_selection.erase(n); + } + //if(!_parent->selected()) + _parent->_selection.insert(_parent); } //BSpline End @@ -596,10 +602,12 @@ void Node::move(Geom::Point const &new_pos) //BSpline End setPosition(new_pos); //BSpline - if(prevNode) - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); - if(nextNode) - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); + if(_pm().isBSpline()){ + if(prevNode) + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); + if(nextNode) + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); + } //BSpline End _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); -- cgit v1.2.3 From caaed5a4603d40a0043bdcb564e213ea9e7d0021 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 6 Mar 2013 04:01:15 +0100 Subject: Permanent show outline in BSpline mode (bzr r11950.1.47) --- src/ui/tool/path-manipulator.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7c23ee153..0a100ecfb 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -895,6 +895,9 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { + //BSpline + if(isBSpline()) show = true; + //BSpline if (show == _show_outline) return; _show_outline = show; _updateOutline(); -- cgit v1.2.3 From 8e034f847b5d49b1ed1aaa0a005da626fdc213da Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 10 Mar 2013 21:34:14 +0100 Subject: Add pencil BSpline mode (bzr r11950.1.49) --- src/pencil-context.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index 5c5780fbb..1ece4528a 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -759,7 +759,9 @@ interpolate(SPPencilContext *pc) for (int c = 0; c < n_segs; c++) { //BSpline if(mode == 2){ - pc->green_curve->lineto(b[4*c+3]); + Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); + Geom::Point CP = b[4*c+3] + (1./3)*(b[4*c+0] - b[4*c+3]); + pc->green_curve->curveto(BP,CP,b[4*c+3]); }else{ pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); } @@ -908,7 +910,9 @@ fit_and_split(SPPencilContext *pc) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ - pc->red_curve->lineto(b[3]); + Geom::Point B = b[0] + (1./3)*(b[3] - b[0]); + Geom::Point C = b[3] + (1./3)*(b[0] - b[3]); + pc->red_curve->curveto(B,C,b[3]); }else{ pc->red_curve->curveto(b[1], b[2], b[3]); } -- cgit v1.2.3 From b2981a3b8f54bccfa45c76f57b38c9c93808d2fc Mon Sep 17 00:00:00 2001 From: root Date: Tue, 12 Mar 2013 00:48:05 +0100 Subject: ~sub fix, double click to reset default handles and control to 10% step (bzr r11950.1.51) --- src/draw-context.cpp | 6 ++ src/live_effects/lpe-bspline.cpp | 135 ++++++++++++++++++++++++++++++++- src/live_effects/lpe-bspline.h | 5 +- src/pen-context.cpp | 50 +++++++----- src/pencil-context.cpp | 4 +- src/ui/tool/multi-path-manipulator.cpp | 4 +- src/ui/tool/node.cpp | 68 +++++++++++++++-- src/ui/tool/node.h | 3 + 8 files changed, 248 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/draw-context.cpp b/src/draw-context.cpp index dcd0fc7ec..356853e09 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -291,6 +291,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } //BSpline + //Añadimos el modo BSpline a los efectos en espera if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -562,6 +563,8 @@ void spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) c->unref(); dc->sa->curve->closepath_current(); //BSpline + //Si la curva tiene un LPE del tipo BSpline ejecutamos spdc_flush_white + //pasándole la curva de inicio necesaria Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ @@ -696,6 +699,9 @@ SPDrawAnchor *spdc_test_inside(SPDrawContext *dc, Geom::Point p) } //BSpline + //Modificamos la curva del "anchor" final para que sea igual que la curva de inicio. + //Esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en + //la que cerramos el trazado. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index d91f7297e..fcca38e4c 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -11,7 +11,7 @@ #include <2geom/affine.h> #include <2geom/bezier-curve.h> #include "helper/geom-curves.h" - +#include // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -21,8 +21,11 @@ namespace Inkscape { namespace LivePathEffect { LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : - Effect(lpeobject) + Effect(lpeobject),unify_weights(_("Unify weights:"), + _("Percent of the with for all poinrs"), "unify_weights", &wr, this, 33.) { + registerParameter( dynamic_cast(&unify_weights) ); + unify_weights.param_set_range(0, 100.); } LPEBSpline::~LPEBSpline() @@ -205,6 +208,134 @@ LPEBSpline::doEffect(SPCurve * curve) } } +std::vector +LPEBSpline::doEffect_path (std::vector const &path_in) +{ + Geom::PathVector const original_pathv = path_in; + SPCurve *curve = new SPCurve(); + //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... + if (path_it->empty()) + continue; + //Itreadores + + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing 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 + //dichos manejadores + SPCurve *nCurve = new SPCurve(); + Geom::Point previousNode(0,0); + Geom::Point node(0,0); + Geom::Point pointAt0(0,0); + Geom::Point pointAt1(0,0); + Geom::Point pointAt2(0,0); + Geom::Point pointAt3(0,0); + double pos1 = 0; + double pos2 = 0; + Geom::Point nextPointAt1(0,0); + Geom::Point nextPointAt2(0,0); + Geom::Point nextPointAt3(0,0); + Geom::D2< Geom::SBasis > SBasisIn; + Geom::D2< Geom::SBasis > SBasisOut; + Geom::D2< Geom::SBasis > SBasisHelper; + Geom::CubicBezier const *cubic = NULL; + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + //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 + + //Recorremos todos los segmentos menos el último + while ( curve_it2 != curve_endit ) + { + //previousPointAt3 = pointAt3; + //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida + SPCurve * in = new SPCurve(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + if(cubic){ + SBasisIn = in->first_segment()->toSBasis(); + pointAt0 = in->first_segment()->initialPoint(); + pos1 = unify_weights/100; + pos2 = 1-unify_weights/100; + pointAt1 = SBasisIn.valueAt(pos1); + pointAt2 = SBasisIn.valueAt(pos2); + pointAt3 = in->first_segment()->finalPoint(); + }else{ + pointAt0 = in->first_segment()->initialPoint(); + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + pointAt3 = in->first_segment()->finalPoint(); + } + in->reset(); + delete in; + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + SPCurve * out = new SPCurve(); + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + cubic = dynamic_cast(&*curve_it2); + if(cubic){ + SBasisOut = out->first_segment()->toSBasis(); + pos1 = unify_weights/100; + pos2 = 1-unify_weights/100; + nextPointAt1 = SBasisOut.valueAt(pos1); + nextPointAt2 = SBasisOut.valueAt(pos2); + nextPointAt3 = (*cubic)[3]; + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + } + out->reset(); + delete out; + //Y este hará de final de curva + SPCurve *curveHelper = new SPCurve(); + curveHelper->moveto(pointAt0); + curveHelper->curveto(pointAt1, pointAt2, pointAt3); + //añadimos la curva generada a la curva pricipal + nCurve->append_continuous(curveHelper, 0.0625); + curveHelper->reset(); + delete curveHelper; + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + } + //Aberiguamos la ultima parte de la curva correspondiente al último segmento + SPCurve *curveHelper = new SPCurve(); + curveHelper->moveto(node); + //Si está cerrada la curva, la cerramos sobre el valor guardado previamente + //Si no finalizamos en el punto final + Geom::Point startNode(0,0); + startNode = path_it->begin()->initialPoint(); + curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + nCurve->append_continuous(curveHelper, 0.0625); + nCurve->move_endpoints(startNode,nextPointAt3); + curveHelper->reset(); + delete curveHelper; + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); + } + curve->append(nCurve,false); + nCurve->reset(); + delete nCurve; + } + return curve->get_pathvector(); +} + }; //namespace LivePathEffect }; /* namespace Inkscape */ diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index d983a7654..27c79f040 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -8,7 +8,7 @@ */ #include "live_effects/effect.h" - +#include "live_effects/parameter/parameter.h" namespace Inkscape { namespace LivePathEffect { @@ -18,11 +18,14 @@ public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); + virtual std::vector doEffect_path (std::vector const & input_path); + virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } virtual void doEffect(SPCurve * curve); private: + ScalarParam unify_weights; LPEBSpline(const LPEBSpline&); LPEBSpline& operator=(const LPEBSpline&); }; diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 6232c5e59..79e4cbabf 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -45,7 +45,7 @@ #include "tools-switch.h" #include "ui/control-manager.h" //BSpline -//Incluimos +//Incluimos los archivos necesarios para las BSpline y Spiro #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" @@ -86,23 +86,27 @@ static void spdc_pen_set_initial_point(SPPenContext *pc, Geom::Point const p); *BSpline *Added functions */ - -/* - *Sobrecarga la función "sp_pen_context_set_polyline_mode" - *Le da valor a la nueva propiedad "pc->spiro" que como se auto define indica si estamos en modo spiro - *En el futuro se la dará a "pc->bspline" -*/ +//Añade los modos spiro y bspline static void sp_pen_context_set_mode(SPPenContext *const pc, guint mode); //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void bspline_spiro_color(SPPenContext *const pc); +//Crea un nodo en modo bspline o spiro static void bspline_spiro(SPPenContext *const pc,bool shift); +//Crea un nodo de modo spiro o bspline static void bspline_spiro_on(SPPenContext *const pc); +//Crea un nodo de tipo CUSP static void bspline_spiro_off(SPPenContext *const pc); +//Continua una curva existente en modo bspline o spiro static void bspline_spiro_start_anchor(SPPenContext *const pc,bool shift); +//Continua una curva exsitente con el nodo de union en modo bspline o spiro static void bspline_spiro_start_anchor_on(SPPenContext *const pc); +//Continua una curva existente con el nodo de union en modo CUSP static void bspline_spiro_start_anchor_off(SPPenContext *const pc); +//Modifica la "red_curve" cuando se detecta movimiento static void bspline_spiro_motion(SPPenContext *const pc,bool shift); +//Cierra la curva con el último nodo en modo bspline o spiro static void bspline_spiro_end_anchor_on(SPPenContext *const pc); +//Cierra la curva con el último nodo en modo CUSP static void bspline_spiro_end_anchor_off(SPPenContext *const pc); //Unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline_spiro_build(SPPenContext *const pc); @@ -224,7 +228,7 @@ void sp_pen_context_set_polyline_mode(SPPenContext *const pc) { pc->polylines_only = (mode == 3 || mode == 4); pc->polylines_paraxial = (mode == 4); //BSpline - //we call the function which defines the Spiro modes and the B-spline in the future + //we call the function which defines the Spiro modes and the BSpline //todo: merge to one function only sp_pen_context_set_mode(pc, mode); //BSpline End @@ -232,7 +236,7 @@ void sp_pen_context_set_polyline_mode(SPPenContext *const pc) { //BSpline /* -*.Set the mode of draw now spiro, and later b-splines +*.Set the mode of draw spiro, and bsplines */ void sp_pen_context_set_mode(SPPenContext *const pc, guint mode) { pc->spiro = (mode == 1); @@ -461,7 +465,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const //Test whether we hit any anchor. SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); //with this we avoid creating a new point over the existing one - if((pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ + if(!bevent.button == 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ return FALSE; } //BSpline end @@ -529,9 +533,9 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const // Set start anchor pc->sa = anchor; //BSpline + //Continuamos una curva existente if(anchor){ - if(pc->bspline || pc->spiro) - bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); + bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); } //BSpline End if (anchor && !sp_pen_context_has_waiting_LPE(pc)) { @@ -585,8 +589,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const } } //BSpline - //Esto evita arrastrar los manejadores ya que el punto se crea - //al soltar el botón del ratón. + //Evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar pc->state = (pc->spiro || pc->bspline || pc->polylines_only) ? SP_PEN_CONTEXT_POINT : SP_PEN_CONTEXT_CONTROL; //BSpline End ret = TRUE; @@ -778,6 +781,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons break; } //BSpline + //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); pen_drag_origin_w = event_w; @@ -809,6 +813,7 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); //BSpline + //with this we avoid creating a new point over the existing one if(pc->spiro || pc->bspline){ //Si intentamos crear un nodo en el mismo sitio que el origen, paramos. if(pc->npoints > 0 && pc->p[0] == pc->p[3]){ @@ -827,6 +832,7 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con } pc->sa = anchor; //BSpline + //continuamos una curva existente if (anchor) { if(pc->bspline || pc->spiro){ bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK)); @@ -982,6 +988,7 @@ static void pen_redraw_all (SPPenContext *const pc) // handles //BSpline + //Ocultamos los tiradores en modo BSpline y spiro if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { //BSpline End SP_CTRL(pc->c1)->moveto(pc->p[1]); @@ -997,6 +1004,7 @@ static void pen_redraw_all (SPPenContext *const pc) if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); //BSpline + //Ocultamos los tiradores en modo BSpline y spiro if ( cubic && (*cubic)[2] != pc->p[0] && !pc->spiro && !pc->bspline ) { @@ -1017,6 +1025,7 @@ static void pen_redraw_all (SPPenContext *const pc) //sino al final de esta //BSpline + //Lanzamos solamente el redibujado bspline_spiro_build(pc); //BSpline End } @@ -1056,8 +1065,7 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) //BSpline Geom::CubicBezier const * cubic; pc->p[1] = pc->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(pc->red_curve->last_segment()->finalPoint() - pc->red_curve->last_segment()->initialPoint()); - //Para formar una curva necesitamos un nodo symm en el "lastpoint" - //de esta manera modificamos el final de la "curva_verde" para que sea symm con el pricipio de la "red_curve" + //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(pc->spiro||pc->bspline){ if(!pc->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1095,6 +1103,7 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } + //Si el último nodo es una union con otra curva if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ bspline_spiro_start_anchor(pc, false); } @@ -1107,9 +1116,11 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc) static void pen_lastpoint_toline (SPPenContext *const pc) { //BSpline - //Si no es bspline + //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->bspline) return; + + //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(pc->spiro || pc->bspline){ if(!pc->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1141,6 +1152,7 @@ static void pen_lastpoint_toline (SPPenContext *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } + //Si el último nodo es una union con otra curva if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ bspline_spiro_start_anchor(pc, true); } @@ -1329,6 +1341,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) } else { pc->p[1] = pc->p[0]; } + //Asignamos el valor a un tercio de distancia del último segmento. if(pc->bspline){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); } @@ -1339,6 +1352,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) pc->npoints = 2; //BSpline + //Eliminamos el último segmento de la curva verde if( pc->green_curve->get_segment_count() == 1){ pc->npoints = 5; if (pc->green_bpaths) { @@ -1350,6 +1364,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) }else{ pc->green_curve->backspace(); } + //Asignamos el valor de pc->p[1] a el opuesto de el ultimo segmento de la línea verde if(pc->spiro){ cubic = dynamic_cast(pc->green_curve->last_segment()); if ( cubic ) { @@ -1366,6 +1381,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; //BSpline + //Redibujamos bspline_spiro_build(pc); //BSpline End ret = TRUE; diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index 1ece4528a..37df2588a 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -757,7 +757,8 @@ interpolate(SPPencilContext *pc) guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); //BSpline End for (int c = 0; c < n_segs; c++) { - //BSpline + //BSpline + //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); Geom::Point CP = b[4*c+3] + (1./3)*(b[4*c+0] - b[4*c+3]); @@ -907,6 +908,7 @@ fit_and_split(SPPencilContext *pc) pc->red_curve->reset(); pc->red_curve->moveto(b[0]); //BSpline + //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index c9e35e5b2..2ef8c1766 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -296,6 +296,7 @@ void MultiPathManipulator::invertSelectionInSubpaths() invokeForAll(&PathManipulator::invertSelectionInSubpaths); } + void MultiPathManipulator::setNodeType(NodeType type) { if (_selection.empty()) return; @@ -307,7 +308,7 @@ void MultiPathManipulator::setNodeType(NodeType type) Node *node = dynamic_cast(*i); if (node) { retract_handles &= (node->type() == NODE_CUSP); - node->setType(type); + node->setType(type,true); } } @@ -324,6 +325,7 @@ void MultiPathManipulator::setNodeType(NodeType type) _done(retract_handles ? _("Retract handles") : _("Change node type")); } + void MultiPathManipulator::setSegmentType(SegmentType type) { if (_selection.empty()) return; diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index e7d62d619..bee2cc477 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -29,6 +29,9 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include +//BSpline +#include +//BSpline End; namespace { @@ -146,10 +149,11 @@ void Handle::move(Geom::Point const &new_pos) Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - //if(!_parent->selected()) - _parent->_selection.insert(_parent); + if(n != _parent) + _parent->_selection.erase(n); + } + if(!_parent->selected()) + _parent->_selection.insert(_parent); } //BSpline End @@ -307,12 +311,33 @@ bool Handle::_eventHandler(SPEventContext *event_context, GdkEvent *event) break; default: break; } + //BSpline + case GDK_2BUTTON_PRESS: + handle_2button_press(); + break; + //BSpline End default: break; } return ControlPoint::_eventHandler(event_context, event); } +//BSpline +void Handle::handle_2button_press(){ + if(_pm().isBSpline()){ + Handle *h = NULL; + Handle *h2 = NULL; + double pos = 0; + h = this; + setPosition(_pm().BSplineHandleReposition(h,0.3334)); + pos = _pm().BSplineHandlePosition(h); + h2 = this->other(); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + _pm().update(); + } +} +//BSpline End + bool Handle::grabbed(GdkEventMotion *) { _saved_other_pos = other()->position(); @@ -360,6 +385,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; + //BSpline + if(_pm().isBSpline()){ + Handle *h = NULL; + double pos = 0; + h = this; + setPosition(new_pos); + pos = ceilf(_pm().BSplineHandlePosition(h)*10)/10; + new_pos=_pm().BSplineHandleReposition(h,pos); + } + //BSpline End } std::vector unselected; @@ -728,7 +763,7 @@ void Node::updateHandles() _front._handleControlStyling(); _back._handleControlStyling(); } - + void Node::setType(NodeType type, bool update_handles) { @@ -738,6 +773,27 @@ void Node::setType(NodeType type, bool update_handles) return; } + //BSpline + if(_pm().isBSpline()){ + if (isEndNode()) return; + Handle* front = &_front; + Handle* back = &_back; + double pos = 0.3334; + switch (type) { + case NODE_CUSP: + if(update_handles) + pos = 0; + else + pos = _pm().BSplineHandlePosition(front);; + break; + default: break; + } + type = NODE_CUSP; + _front.setPosition(_pm().BSplineHandleReposition(front,pos)); + _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + } + //BSpline End + // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -821,7 +877,9 @@ void Node::setType(NodeType type, bool update_handles) default: break; } } + _type = type; + _setControlType(nodeTypeToCtrlType(_type)); updateState(); } diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 591dd8532..e74698b1a 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -107,6 +107,9 @@ protected: Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); + //Bspline + virtual void handle_2button_press(); + //BSpline End virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); virtual void ungrabbed(GdkEventButton *event); -- cgit v1.2.3 From d0bebd018087b363bfde91bce46744dfd004549c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 14 Mar 2013 22:28:34 +0100 Subject: Updating original path (bzr r11950.1.53) --- src/live_effects/lpe-bspline.cpp | 208 +++++++++++-------------------- src/live_effects/lpe-bspline.h | 6 + src/live_effects/parameter/parameter.cpp | 7 +- 3 files changed, 85 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index fcca38e4c..f5dff3abe 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -34,6 +34,11 @@ LPEBSpline::~LPEBSpline() void LPEBSpline::doEffect(SPCurve * curve) +{ +LPEBSpline::doEffect(curve,NULL) +} +void +LPEBSpline::doEffect(SPCurve * curve,int value) { if(curve->get_segment_count() < 2) return; @@ -91,11 +96,21 @@ LPEBSpline::doEffect(SPCurve * curve) cubic = dynamic_cast(&*curve_it1); if(cubic){ SBasisIn = in->first_segment()->toSBasis(); - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); - pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); + if(value){ + pointAt1 = SBasisIn.valueAt(value); + pointAt2 = SBasisIn.valueAt(1-value); + }else{ + pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); + pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); + } }else{ - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); + if(value){ + pointAt1 = SBasisIn.valueAt(value); + pointAt2 = SBasisIn.valueAt(1-value); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } } in->reset(); delete in; @@ -107,12 +122,22 @@ LPEBSpline::doEffect(SPCurve * curve) cubic = dynamic_cast(&*curve_it2); if(cubic){ SBasisOut = out->first_segment()->toSBasis(); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; + if(value){ + nextPointAt1 = SBasisIn.valueAt(value); + nextPointAt2 = SBasisIn.valueAt(1-value); + }else{ + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; + ] nextPointAt3 = (*cubic)[3]; }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); + if(value){ + nextPointAt1 = SBasisIn.valueAt(value); + nextPointAt2 = SBasisIn.valueAt(1-value); + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + } nextPointAt3 = out->first_segment()->finalPoint(); } out->reset(); @@ -133,8 +158,13 @@ LPEBSpline::doEffect(SPCurve * curve) //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(previousNode); - curveHelper->curveto(pointAt1, pointAt2, node); + if(value){ + curveHelper->moveto(*in->first_segment()->initialPoint()); + curveHelper->curveto(pointAt1, pointAt2, *in->first_segment()->finalPoint()); + }else{ + curveHelper->moveto(previousNode); + curveHelper->curveto(pointAt1, pointAt2, node); + } //añadimos la curva generada a la curva pricipal nCurve->append_continuous(curveHelper, 0.0625); curveHelper->reset(); @@ -181,7 +211,10 @@ LPEBSpline::doEffect(SPCurve * curve) lineHelper->reset(); delete lineHelper; //Guardamos el principio de la curva - startNode = SBasisHelper.valueAt(0.5); + if(value) + startNode = path_it->begin()->initialPoint(); + else + startNode = SBasisHelper.valueAt(0.5); curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); nCurve->append_continuous(curveHelper, 0.0625); nCurve->move_endpoints(startNode,startNode); @@ -208,132 +241,37 @@ LPEBSpline::doEffect(SPCurve * curve) } } -std::vector -LPEBSpline::doEffect_path (std::vector const &path_in) +void +LPEBSpline::updateAllHandles(int value) { - Geom::PathVector const original_pathv = path_in; - SPCurve *curve = new SPCurve(); - //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... - if (path_it->empty()) - continue; - //Itreadores - - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing 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 - //dichos manejadores - SPCurve *nCurve = new SPCurve(); - Geom::Point previousNode(0,0); - Geom::Point node(0,0); - Geom::Point pointAt0(0,0); - Geom::Point pointAt1(0,0); - Geom::Point pointAt2(0,0); - Geom::Point pointAt3(0,0); - double pos1 = 0; - double pos2 = 0; - Geom::Point nextPointAt1(0,0); - Geom::Point nextPointAt2(0,0); - Geom::Point nextPointAt3(0,0); - Geom::D2< Geom::SBasis > SBasisIn; - Geom::D2< Geom::SBasis > SBasisOut; - Geom::D2< Geom::SBasis > SBasisHelper; - Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } - //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 - - //Recorremos todos los segmentos menos el último - while ( curve_it2 != curve_endit ) - { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - SPCurve * in = new SPCurve(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if(cubic){ - SBasisIn = in->first_segment()->toSBasis(); - pointAt0 = in->first_segment()->initialPoint(); - pos1 = unify_weights/100; - pos2 = 1-unify_weights/100; - pointAt1 = SBasisIn.valueAt(pos1); - pointAt2 = SBasisIn.valueAt(pos2); - pointAt3 = in->first_segment()->finalPoint(); - }else{ - pointAt0 = in->first_segment()->initialPoint(); - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - pointAt3 = in->first_segment()->finalPoint(); - } - in->reset(); - delete in; - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); - SPCurve * out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - cubic = dynamic_cast(&*curve_it2); - if(cubic){ - SBasisOut = out->first_segment()->toSBasis(); - pos1 = unify_weights/100; - pos2 = 1-unify_weights/100; - nextPointAt1 = SBasisOut.valueAt(pos1); - nextPointAt2 = SBasisOut.valueAt(pos2); - nextPointAt3 = (*cubic)[3]; - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - } - out->reset(); - delete out; - //Y este hará de final de curva - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(pointAt0); - curveHelper->curveto(pointAt1, pointAt2, pointAt3); - //añadimos la curva generada a la curva pricipal - nCurve->append_continuous(curveHelper, 0.0625); - curveHelper->reset(); - delete curveHelper; - //aumentamos los valores para el siguiente paso en el bucle - ++curve_it1; - ++curve_it2; - } - //Aberiguamos la ultima parte de la curva correspondiente al último segmento - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(node); - //Si está cerrada la curva, la cerramos sobre el valor guardado previamente - //Si no finalizamos en el punto final - Geom::Point startNode(0,0); - startNode = path_it->begin()->initialPoint(); - curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->append_continuous(curveHelper, 0.0625); - nCurve->move_endpoints(startNode,nextPointAt3); - curveHelper->reset(); - delete curveHelper; - //y cerramos la curva - if (path_it->closed()) { - nCurve->closepath_current(); - } - curve->append(nCurve,false); - nCurve->reset(); - delete nCurve; + SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop? + Inkscape::Selection *selection = sp_desktop_selection(desktop); + for (GSList *items = (GSList *) selection->itemList(); + items != NULL; + items = items->next) { + if (SP_IS_LPE_ITEM(items->data) && sp_lpe_item_has_path_effect(items->data)){ + PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path)); + lpe_bsp = dynamic_cast( effect_list.front()->lpeobject->get_lpe()); + if(lpe_bsp) + LPEBSpline::updateHandles((SPItem *) items->data,value); + } +} +void +LPEBSpline::updateHandles(SPItem * item,int value){ + + Inkscape::XML::Node *newitem = item->getRepr(); + Inkscape::XML::Node *path = sp_repr_lookup_child(newitem,"svg:path", -1); //unlimited search depth + if ( path != NULL ){ + gchar const *svgd = path->attribute("d"); } - return curve->get_pathvector(); + + SPCurve *original = new SPCurve(); + original = (SPPath *)item->original_curve(); + LPEBSpline::doEffect(original,value); + gchar *str = sp_svg_write_path( original->get_pathvector() ); + g_assert( str != NULL ); + path->setAttribute ("inkscaspe:original-d", str); + item->updateRepr(); } }; //namespace LivePathEffect diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 27c79f040..501b1fdaf 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -23,6 +23,12 @@ public: virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } virtual void doEffect(SPCurve * curve); + + virtual void doEffect(SPCurve * curve, int value); + + virtual void updateAllHandles(int value); + + virtual void updateHandles(SPItem * item , int value); private: ScalarParam unify_weights; diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 8615721b0..30414842d 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -128,7 +128,12 @@ ScalarParam::param_newWidget() { Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); - + //BSpline + lpe_bsp = dynamic_cast(param_effect->get_lpe()); + if(lpe_bsp){ + lpe_bsp->updateAllHandles(value/100); + } + //BSpline End rsu->setValue(value); rsu->setDigits(digits); rsu->setIncrements(inc_step, inc_page); -- cgit v1.2.3 From 732618cd7d6159ee47cc0dd8b86cf07790e3e724 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 17 Mar 2013 13:29:02 +0100 Subject: Working with widjets (bzr r11950.1.56) --- src/common-context.h | 4 +++ src/composite-undo-stack-observer.h | 2 +- src/desktop.h | 2 +- src/display/cairo-utils.cpp | 10 +++--- src/display/canvas-axonomgrid.h | 2 +- src/display/guideline.h | 2 +- src/display/nr-filter-diffuselighting.h | 8 ++--- src/display/nr-filter-flood.h | 2 +- src/display/nr-filter-specularlighting.h | 8 ++--- src/display/nr-style.h | 3 +- src/display/nr-svgfonts.cpp | 3 ++ src/display/nr-svgfonts.h | 4 +-- src/display/sp-ctrlcurve.h | 2 +- src/document-subset.h | 2 +- src/dom/events.h | 1 + src/dropper-context.cpp | 1 + src/dropper-context.h | 3 ++ src/dyna-draw-context.h | 3 ++ src/eraser-context.h | 3 ++ src/event-context.h | 2 +- src/extension/internal/cairo-render-context.h | 6 ++-- src/extension/internal/cairo-renderer.h | 2 +- src/extension/internal/pdfinput/pdf-input.cpp | 1 - src/extension/internal/pdfinput/svg-builder.h | 6 ++-- src/file.cpp | 3 ++ src/file.h | 2 +- src/filter-chemistry.h | 2 +- src/filters/blend.h | 2 ++ src/filters/colormatrix.h | 2 ++ src/filters/componenttransfer-funcnode.h | 6 +++- src/filters/componenttransfer.h | 2 ++ src/filters/composite.h | 2 ++ src/filters/convolvematrix.h | 2 ++ src/filters/diffuselighting.h | 4 ++- src/filters/displacementmap.h | 2 ++ src/filters/distantlight.h | 4 +++ src/filters/flood.h | 2 ++ src/filters/gaussian-blur.h | 4 ++- src/filters/image.h | 2 ++ src/filters/merge.h | 2 ++ src/filters/mergenode.h | 3 ++ src/filters/morphology.h | 2 ++ src/filters/offset.h | 2 ++ src/filters/pointlight.h | 6 ++++ src/filters/specularlighting.h | 4 ++- src/filters/spotlight.h | 6 ++++ src/filters/tile.h | 2 ++ src/filters/turbulence.h | 1 + src/flood-context.h | 3 ++ src/gradient-context.h | 3 ++ src/gradient-drag.h | 6 ++-- src/inkscape-private.h | 2 +- src/inkscape.cpp | 2 +- src/libgdl/Makefile_insert | 8 ----- src/libnrtype/Layout-TNG-Output.cpp | 1 + src/libnrtype/Layout-TNG.h | 2 +- src/libnrtype/font-lister.cpp | 1 + src/livarot/Path.h | 10 +++--- src/livarot/Shape.h | 6 ++-- src/live_effects/lpe-bspline.cpp | 48 ++++++++++----------------- src/live_effects/lpe-bspline.h | 32 ++++++++---------- src/live_effects/lpe-recursiveskeleton.cpp | 3 +- src/lpe-tool-context.h | 3 ++ src/marker.cpp | 12 +++---- src/marker.h | 4 ++- src/measure-context.h | 3 ++ src/menus-skeleton.h | 2 ++ src/mesh-context.h | 3 ++ src/pixmaps/cursor-dropper.xpm | 38 +++++++++++++++++++++ src/rect-context.h | 3 ++ src/select-context.h | 2 ++ src/selection.cpp | 1 + src/seltrans-handles.h | 2 +- src/seltrans.h | 2 +- src/snap.cpp | 1 + src/sp-clippath.h | 2 +- src/sp-desc.h | 3 ++ src/sp-filter-primitive.h | 2 ++ src/sp-filter.h | 2 +- src/sp-flowregion.cpp | 39 ++++++++++++---------- src/sp-font-face.cpp | 3 ++ src/sp-font-face.h | 2 ++ src/sp-font.cpp | 3 ++ src/sp-glyph-kerning.cpp | 2 ++ src/sp-glyph-kerning.h | 2 ++ src/sp-glyph.cpp | 2 ++ src/sp-glyph.h | 2 ++ src/sp-gradient.h | 4 +-- src/sp-image.h | 3 ++ src/sp-item.h | 4 +-- src/sp-linear-gradient-fns.h | 2 +- src/sp-mask.h | 4 ++- src/sp-metadata.cpp | 10 +++--- src/sp-metadata.h | 3 ++ src/sp-missing-glyph.cpp | 3 ++ src/sp-missing-glyph.h | 2 ++ src/sp-object-group.cpp | 4 ++- src/sp-object-repr.cpp | 14 +++++--- src/sp-offset.h | 2 ++ src/sp-pattern.h | 3 +- src/sp-polyline.cpp | 11 +++--- src/sp-radial-gradient-fns.h | 2 +- src/sp-rect.h | 3 ++ src/sp-spiral.h | 3 ++ src/sp-star.h | 5 +++ src/sp-stop.h | 1 + src/sp-switch.h | 2 +- src/sp-symbol.cpp | 33 +++++++----------- src/sp-symbol.h | 3 ++ src/sp-title.h | 3 ++ src/sp-tref.h | 3 ++ src/sp-use.h | 2 ++ src/spiral-context.h | 3 ++ src/splivarot.cpp | 36 ++++++++++++++++++-- src/spray-context.h | 3 ++ src/star-context.h | 3 ++ src/style.cpp | 2 +- src/style.h | 4 ++- src/svg-view-widget.h | 2 ++ src/svg-view.h | 2 +- src/svg/svg-color.h | 2 +- src/text-context.h | 2 ++ src/text-editing.cpp | 2 +- src/trace/siox.cpp | 4 +-- src/tweak-context.h | 3 ++ src/ui/dialog/dialog-manager.cpp | 7 ++++ src/ui/dialog/document-properties.cpp | 2 ++ src/ui/dialog/export.cpp | 26 +++------------ src/ui/dialog/export.h | 19 +++++++---- src/ui/dialog/fill-and-stroke.cpp | 15 --------- src/ui/dialog/find.cpp | 4 --- src/ui/dialog/find.h | 6 +--- src/ui/dialog/glyphs.h | 2 +- src/ui/dialog/icon-preview.cpp | 4 --- src/ui/dialog/input.cpp | 2 -- src/ui/dialog/layer-properties.h | 6 ++-- src/ui/dialog/object-properties.cpp | 6 ---- src/ui/dialog/object-properties.h | 10 ------ src/ui/dialog/svg-fonts-dialog.cpp | 4 +++ src/ui/dialog/svg-fonts-dialog.h | 4 +-- src/ui/dialog/text-edit.cpp | 1 - src/ui/dialog/text-edit.h | 2 +- src/ui/dialog/tracedialog.cpp | 1 - src/ui/dialog/xml-tree.h | 2 +- src/ui/tool/control-point.cpp | 2 +- src/ui/tool/node-tool.h | 3 ++ src/ui/tool/path-manipulator.h | 2 +- src/ui/widget/entry.cpp | 2 -- src/ui/widget/entry.h | 6 ++-- src/ui/widget/frame.h | 8 +++-- src/ui/widget/registered-widget.h | 2 +- src/ui/widget/selected-style.h | 2 +- src/ui/widget/style-swatch.h | 2 +- src/undo-stack-observer.h | 2 +- src/widgets/gradient-vector.h | 2 +- src/widgets/paint-selector.h | 2 +- src/widgets/swatch-selector.h | 6 ++-- src/xml/composite-node-observer.h | 2 +- src/zoom-context.h | 3 ++ 159 files changed, 483 insertions(+), 301 deletions(-) create mode 100644 src/pixmaps/cursor-dropper.xpm (limited to 'src') diff --git a/src/common-context.h b/src/common-context.h index 8903be391..ae0f398b2 100644 --- a/src/common-context.h +++ b/src/common-context.h @@ -29,8 +29,12 @@ #define SP_IS_COMMON_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_COMMON_CONTEXT)) #define SP_IS_COMMON_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_COMMON_CONTEXT)) +class SPCommonContext; +class SPCommonContextClass; + #define SAMPLING_SIZE 8 /* fixme: ?? */ + struct SPCommonContext : public SPEventContext { /** accumulated shape which ultimately goes in svg:path */ SPCurve *accumulated; diff --git a/src/composite-undo-stack-observer.h b/src/composite-undo-stack-observer.h index 669c39a86..c34ab7234 100644 --- a/src/composite-undo-stack-observer.h +++ b/src/composite-undo-stack-observer.h @@ -18,7 +18,7 @@ namespace Inkscape { -struct Event; +class Event; /** * Aggregates UndoStackObservers for management and triggering in an SPDocument's undo/redo diff --git a/src/desktop.h b/src/desktop.h index 56de56c65..d8d4e151d 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -77,7 +77,7 @@ namespace Inkscape { } namespace View { - struct EditWidgetInterface; + class EditWidgetInterface; } } namespace Whiteboard { diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index fc56c7b26..a55b05fe3 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -655,8 +655,8 @@ int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) cairo_surface_flush(surface); int width = cairo_image_surface_get_width(surface); int height = cairo_image_surface_get_height(surface); - // int stride = cairo_image_surface_get_stride(surface); - // unsigned char *data = cairo_image_surface_get_data(surface); + int stride = cairo_image_surface_get_stride(surface); + unsigned char *data = cairo_image_surface_get_data(surface); ink_cairo_surface_filter( surface, surface, SurfaceSrgbToLinear() ); @@ -698,8 +698,8 @@ int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) cairo_surface_flush(surface); int width = cairo_image_surface_get_width(surface); int height = cairo_image_surface_get_height(surface); - // int stride = cairo_image_surface_get_stride(surface); - // unsigned char *data = cairo_image_surface_get_data(surface); + int stride = cairo_image_surface_get_stride(surface); + unsigned char *data = cairo_image_surface_get_data(surface); ink_cairo_surface_filter( surface, surface, SurfaceLinearToSrgb() ); @@ -888,4 +888,4 @@ guint32 argb32_from_rgba(guint32 in) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/canvas-axonomgrid.h b/src/display/canvas-axonomgrid.h index f58ea3aca..0e24d3f56 100644 --- a/src/display/canvas-axonomgrid.h +++ b/src/display/canvas-axonomgrid.h @@ -12,7 +12,7 @@ #include "line-snapper.h" #include "canvas-grid.h" -struct SPCanvasBuf; +class SPCanvasBuf; class SPDesktop; struct SPNamedView; diff --git a/src/display/guideline.h b/src/display/guideline.h index 2d9a87d9b..164244c46 100644 --- a/src/display/guideline.h +++ b/src/display/guideline.h @@ -21,7 +21,7 @@ #define SP_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_GUIDELINE, SPGuideLine)) #define SP_IS_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_GUIDELINE)) -struct SPCtrlPoint; +class SPCtrlPoint; struct SPGuideLine { SPCanvasItem item; diff --git a/src/display/nr-filter-diffuselighting.h b/src/display/nr-filter-diffuselighting.h index 15cc8e1ff..315bf9f48 100644 --- a/src/display/nr-filter-diffuselighting.h +++ b/src/display/nr-filter-diffuselighting.h @@ -19,10 +19,10 @@ #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" -struct SPFeDistantLight; -struct SPFePointLight; -struct SPFeSpotLight; -struct SVGICCColor; +class SPFeDistantLight; +class SPFePointLight; +class SPFeSpotLight; +class SVGICCColor; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter-flood.h b/src/display/nr-filter-flood.h index 9a968047d..8568502ff 100644 --- a/src/display/nr-filter-flood.h +++ b/src/display/nr-filter-flood.h @@ -14,7 +14,7 @@ #include "display/nr-filter-primitive.h" -struct SVGICCColor; +class SVGICCColor; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter-specularlighting.h b/src/display/nr-filter-specularlighting.h index 0d1c0644f..4f8c2d112 100644 --- a/src/display/nr-filter-specularlighting.h +++ b/src/display/nr-filter-specularlighting.h @@ -17,10 +17,10 @@ #include "display/nr-light-types.h" #include "display/nr-filter-primitive.h" -struct SPFeDistantLight; -struct SPFePointLight; -struct SPFeSpotLight; -struct SVGICCColor; +class SPFeDistantLight; +class SPFePointLight; +class SPFeSpotLight; +class SVGICCColor; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-style.h b/src/display/nr-style.h index 80547c43e..597ae7a2c 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -16,7 +16,8 @@ #include <2geom/rect.h> #include "color.h" -struct SPPaintServer; +class SPColor; +class SPPaintServer; struct SPStyle; namespace Inkscape { diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 84b4bd080..0d1b56d54 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -1,4 +1,5 @@ #include "config.h" +#ifdef ENABLE_SVG_FONTS /* * SVGFonts rendering implementation * @@ -355,6 +356,8 @@ void SvgFont::refresh(){ this->userfont = NULL; } +#endif //#ifdef ENABLE_SVG_FONTS + /* Local Variables: mode:c++ diff --git a/src/display/nr-svgfonts.h b/src/display/nr-svgfonts.h index 1101f93f2..6138e2fbb 100644 --- a/src/display/nr-svgfonts.h +++ b/src/display/nr-svgfonts.h @@ -18,8 +18,8 @@ class SvgFont; struct SPFont; -struct SPGlyph; -struct SPMissingGlyph; +class SPGlyph; +class SPMissingGlyph; struct _GdkEventExpose; typedef _GdkEventExpose GdkEventExpose; diff --git a/src/display/sp-ctrlcurve.h b/src/display/sp-ctrlcurve.h index 90936185c..15de20161 100644 --- a/src/display/sp-ctrlcurve.h +++ b/src/display/sp-ctrlcurve.h @@ -17,7 +17,7 @@ #include "display/sp-ctrlline.h" -class SPItem; +struct SPItem; #define SP_TYPE_CTRLCURVE (SPCtrlCurve::getType()) #define SP_CTRLCURVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLCURVE, SPCtrlCurve)) diff --git a/src/document-subset.h b/src/document-subset.h index 298b7872d..5f87e6429 100644 --- a/src/document-subset.h +++ b/src/document-subset.h @@ -51,7 +51,7 @@ private: void _remove(SPObject *obj, bool subtree); - struct Relations; + class Relations; Relations *_relations; }; diff --git a/src/dom/events.h b/src/dom/events.h index e62c5d420..59d83afcf 100644 --- a/src/dom/events.h +++ b/src/dom/events.h @@ -66,6 +66,7 @@ typedef dom::NodePtr NodePtr ; //forward declarations +class Event; class EventTarget; class EventListener; class DocumentEvent; diff --git a/src/dropper-context.cpp b/src/dropper-context.cpp index d41e4059d..66dcf4ab9 100644 --- a/src/dropper-context.cpp +++ b/src/dropper-context.cpp @@ -39,6 +39,7 @@ #include "document.h" #include "document-undo.h" +#include "pixmaps/cursor-dropper.xpm" #include "pixmaps/cursor-dropper-f.xpm" #include "pixmaps/cursor-dropper-s.xpm" diff --git a/src/dropper-context.h b/src/dropper-context.h index be4b543ae..68ae3df07 100644 --- a/src/dropper-context.h +++ b/src/dropper-context.h @@ -20,6 +20,9 @@ G_BEGIN_DECLS #define SP_DROPPER_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_DROPPER_CONTEXT, SPDropperContext)) #define SP_IS_DROPPER_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_DROPPER_CONTEXT)) +class SPDropperContext; +class SPDropperContextClass; + enum { SP_DROPPER_PICK_VISIBLE, SP_DROPPER_PICK_ACTUAL diff --git a/src/dyna-draw-context.h b/src/dyna-draw-context.h index 8509e450b..af63bf653 100644 --- a/src/dyna-draw-context.h +++ b/src/dyna-draw-context.h @@ -27,6 +27,9 @@ #define SP_IS_DYNA_DRAW_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_DYNA_DRAW_CONTEXT)) #define SP_IS_DYNA_DRAW_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_DYNA_DRAW_CONTEXT)) +class SPDynaDrawContext; +class SPDynaDrawContextClass; + #define DDC_MIN_PRESSURE 0.0 #define DDC_MAX_PRESSURE 1.0 #define DDC_DEFAULT_PRESSURE 1.0 diff --git a/src/eraser-context.h b/src/eraser-context.h index bc4268aef..7c147c32f 100644 --- a/src/eraser-context.h +++ b/src/eraser-context.h @@ -29,6 +29,9 @@ G_BEGIN_DECLS #define SP_IS_ERASER_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_ERASER_CONTEXT)) #define SP_IS_ERASER_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_ERASER_CONTEXT)) +class SPEraserContext; +class SPEraserContextClass; + #define ERC_MIN_PRESSURE 0.0 #define ERC_MAX_PRESSURE 1.0 #define ERC_DEFAULT_PRESSURE 1.0 diff --git a/src/event-context.h b/src/event-context.h index e97a8ad8f..9936aa668 100644 --- a/src/event-context.h +++ b/src/event-context.h @@ -19,7 +19,7 @@ #include "2geom/forward.h" #include "preferences.h" -class GrDrag; +struct GrDrag; class SPDesktop; class SPItem; class ShapeEditor; diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 8829940c6..94c7bb294 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -29,7 +29,7 @@ #include class SPClipPath; -struct SPMask; +class SPMask; namespace Inkscape { namespace Extension { @@ -37,8 +37,8 @@ namespace Internal { class CairoRenderer; class CairoRenderContext; -struct CairoRenderState; -struct CairoGlyphInfo; +class CairoRenderState; +class CairoGlyphInfo; // Holds info for rendering a glyph struct CairoGlyphInfo { diff --git a/src/extension/internal/cairo-renderer.h b/src/extension/internal/cairo-renderer.h index c1482d82e..db3068fed 100644 --- a/src/extension/internal/cairo-renderer.h +++ b/src/extension/internal/cairo-renderer.h @@ -28,7 +28,7 @@ #include class SPClipPath; -struct SPMask; +class SPMask; namespace Inkscape { namespace Extension { diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index b04c9782f..531cda20a 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -32,7 +32,6 @@ #endif #include -#include #include #include #include diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h index 610822959..46cddd73b 100644 --- a/src/extension/internal/pdfinput/svg-builder.h +++ b/src/extension/internal/pdfinput/svg-builder.h @@ -31,10 +31,10 @@ namespace Inkscape { #include "CharTypes.h" class GooString; class Function; -class GfxState; -struct GfxColor; +struct GfxState; +class GfxColor; class GfxColorSpace; -struct GfxRGB; +class GfxRGB; class GfxPath; class GfxPattern; class GfxTilingPattern; diff --git a/src/file.cpp b/src/file.cpp index 5737f0a8a..97087c1a1 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1124,6 +1124,9 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, prevent_id_clashes(doc, in_doc); + SPObject *in_defs = in_doc->getDefs(); + Inkscape::XML::Node *last_def = in_defs->getRepr()->lastChild(); + SPCSSAttr *style = sp_css_attr_from_object(doc->getRoot()); // Count the number of top-level items in the imported document. diff --git a/src/file.h b/src/file.h index b173ca58c..b8e15bf3e 100644 --- a/src/file.h +++ b/src/file.h @@ -24,7 +24,7 @@ class SPObject; namespace Inkscape { namespace Extension { - class Extension; + struct Extension; } } diff --git a/src/filter-chemistry.h b/src/filter-chemistry.h index b00e33bcc..751885ad2 100644 --- a/src/filter-chemistry.h +++ b/src/filter-chemistry.h @@ -20,7 +20,7 @@ class SPDocument; struct SPFilter; -struct SPFilterPrimitive; +class SPFilterPrimitive; class SPItem; class SPObject; diff --git a/src/filters/blend.h b/src/filters/blend.h index 5d65c92fc..e7fc410e7 100644 --- a/src/filters/blend.h +++ b/src/filters/blend.h @@ -22,6 +22,8 @@ #define SP_IS_FEBLEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEBLEND)) #define SP_IS_FEBLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEBLEND)) +class SPFeBlendClass; + struct SPFeBlend : public SPFilterPrimitive { Inkscape::Filters::FilterBlendMode blend_mode; int in2; diff --git a/src/filters/colormatrix.h b/src/filters/colormatrix.h index 558f01070..8eb750ac1 100644 --- a/src/filters/colormatrix.h +++ b/src/filters/colormatrix.h @@ -21,6 +21,8 @@ #define SP_IS_FECOLORMATRIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FECOLORMATRIX)) #define SP_IS_FECOLORMATRIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FECOLORMATRIX)) +class SPFeColorMatrixClass; + struct SPFeColorMatrix : public SPFilterPrimitive { Inkscape::Filters::FilterColorMatrixType type; gdouble value; diff --git a/src/filters/componenttransfer-funcnode.h b/src/filters/componenttransfer-funcnode.h index ae1b2f8bb..d81e50577 100644 --- a/src/filters/componenttransfer-funcnode.h +++ b/src/filters/componenttransfer-funcnode.h @@ -34,6 +34,11 @@ #define SP_IS_FEFUNCNODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEFUNCNODE)) +/* Component Transfer funcNode class */ + +class SPFeFuncNode; +class SPFeFuncNodeClass; + struct SPFeFuncNode : public SPObject { Inkscape::Filters::FilterComponentTransferType type; std::vector tableValues; @@ -44,7 +49,6 @@ struct SPFeFuncNode : public SPObject { double offset; }; -/* Component Transfer funcNode class */ struct SPFeFuncNodeClass { SPObjectClass parent_class; }; diff --git a/src/filters/componenttransfer.h b/src/filters/componenttransfer.h index deb6fb740..2df64009f 100644 --- a/src/filters/componenttransfer.h +++ b/src/filters/componenttransfer.h @@ -24,6 +24,8 @@ namespace Filters { class FilterComponentTransfer; } } +class SPFeComponentTransferClass; + struct SPFeComponentTransfer : public SPFilterPrimitive { Inkscape::Filters::FilterComponentTransfer *renderer; }; diff --git a/src/filters/composite.h b/src/filters/composite.h index 4f2d1ff69..3eb62716f 100644 --- a/src/filters/composite.h +++ b/src/filters/composite.h @@ -32,6 +32,8 @@ enum FeCompositeOperator { COMPOSITE_ENDOPERATOR }; +class SPFeCompositeClass; + struct SPFeComposite : public SPFilterPrimitive { FeCompositeOperator composite_operator; double k1, k2, k3, k4; diff --git a/src/filters/convolvematrix.h b/src/filters/convolvematrix.h index cb2fbfb8d..4c5261e05 100644 --- a/src/filters/convolvematrix.h +++ b/src/filters/convolvematrix.h @@ -24,6 +24,8 @@ #define SP_IS_FECONVOLVEMATRIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FECONVOLVEMATRIX)) #define SP_IS_FECONVOLVEMATRIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FECONVOLVEMATRIX)) +class SPFeConvolveMatrixClass; + struct SPFeConvolveMatrix : public SPFilterPrimitive { NumberOptNumber order; std::vector kernelMatrix; diff --git a/src/filters/diffuselighting.h b/src/filters/diffuselighting.h index 1572385b9..99dccb394 100644 --- a/src/filters/diffuselighting.h +++ b/src/filters/diffuselighting.h @@ -21,13 +21,15 @@ #define SP_IS_FEDIFFUSELIGHTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEDIFFUSELIGHTING)) #define SP_IS_FEDIFFUSELIGHTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEDIFFUSELIGHTING)) -struct SVGICCColor; +class SVGICCColor; namespace Inkscape { namespace Filters { class FilterDiffuseLighting; } } +class SPFeDiffuseLightingClass; + struct SPFeDiffuseLighting : public SPFilterPrimitive { gfloat surfaceScale; guint surfaceScale_set : 1; diff --git a/src/filters/displacementmap.h b/src/filters/displacementmap.h index 93dc86d27..6232f0937 100644 --- a/src/filters/displacementmap.h +++ b/src/filters/displacementmap.h @@ -28,6 +28,8 @@ enum FilterDisplacementMapChannelSelector { DISPLACEMENTMAP_CHANNEL_ENDTYPE }; +class SPFeDisplacementMapClass; + struct SPFeDisplacementMap : public SPFilterPrimitive { int in2; double scale; diff --git a/src/filters/distantlight.h b/src/filters/distantlight.h index b1febf5d3..a68746334 100644 --- a/src/filters/distantlight.h +++ b/src/filters/distantlight.h @@ -25,6 +25,10 @@ /* Distant light class */ + +class SPFeDistantLight; +class SPFeDistantLightClass; + struct SPFeDistantLight : public SPObject { /** azimuth attribute */ diff --git a/src/filters/flood.h b/src/filters/flood.h index ab9f061d6..d60321689 100644 --- a/src/filters/flood.h +++ b/src/filters/flood.h @@ -23,6 +23,8 @@ G_BEGIN_DECLS #define SP_IS_FEFLOOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFLOOD)) #define SP_IS_FEFLOOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEFLOOD)) +class SPFeFloodClass; + struct SPFeFlood : public SPFilterPrimitive { guint32 color; SVGICCColor *icc; diff --git a/src/filters/gaussian-blur.h b/src/filters/gaussian-blur.h index 8929627ba..417f8a6f4 100644 --- a/src/filters/gaussian-blur.h +++ b/src/filters/gaussian-blur.h @@ -21,12 +21,14 @@ #define SP_IS_GAUSSIANBLUR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_GAUSSIANBLUR)) #define SP_IS_GAUSSIANBLUR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_GAUSSIANBLUR)) +/* GaussianBlur base class */ +class SPGaussianBlurClass; + struct SPGaussianBlur : public SPFilterPrimitive { /** stdDeviation attribute */ NumberOptNumber stdDeviation; }; -/* GaussianBlur base class */ struct SPGaussianBlurClass { SPFilterPrimitiveClass parent_class; }; diff --git a/src/filters/image.h b/src/filters/image.h index a96e650b7..b4081602a 100644 --- a/src/filters/image.h +++ b/src/filters/image.h @@ -24,6 +24,8 @@ #define SP_IS_FEIMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEIMAGE)) #define SP_IS_FEIMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEIMAGE)) +class SPFeImageClass; + struct SPFeImage : public SPFilterPrimitive { gchar *href; diff --git a/src/filters/merge.h b/src/filters/merge.h index 40a9bb848..3243073ca 100644 --- a/src/filters/merge.h +++ b/src/filters/merge.h @@ -18,6 +18,8 @@ #define SP_IS_FEMERGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEMERGE)) #define SP_IS_FEMERGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEMERGE)) +class SPFeMergeClass; + struct SPFeMerge : public SPFilterPrimitive { }; diff --git a/src/filters/mergenode.h b/src/filters/mergenode.h index edb35faec..8352632a6 100644 --- a/src/filters/mergenode.h +++ b/src/filters/mergenode.h @@ -21,6 +21,9 @@ #define SP_FEMERGENODE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_FEMERGENODE, SPFeMergeNode)) #define SP_IS_FEMERGENODE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_FEMERGENODE)) +class SPFeMergeNode; +class SPFeMergeNodeClass; + struct SPFeMergeNode : public SPObject { int input; }; diff --git a/src/filters/morphology.h b/src/filters/morphology.h index 9084d1b94..b7005a3d9 100644 --- a/src/filters/morphology.h +++ b/src/filters/morphology.h @@ -22,6 +22,8 @@ #define SP_IS_FEMORPHOLOGY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEMORPHOLOGY)) #define SP_IS_FEMORPHOLOGY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEMORPHOLOGY)) +class SPFeMorphologyClass; + struct SPFeMorphology : public SPFilterPrimitive { Inkscape::Filters::FilterMorphologyOperator Operator; NumberOptNumber radius; diff --git a/src/filters/offset.h b/src/filters/offset.h index 08954a8e4..dba7ed8ef 100644 --- a/src/filters/offset.h +++ b/src/filters/offset.h @@ -20,6 +20,8 @@ #define SP_IS_FEOFFSET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEOFFSET)) #define SP_IS_FEOFFSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEOFFSET)) +class SPFeOffsetClass; + struct SPFeOffset : public SPFilterPrimitive { double dx, dy; }; diff --git a/src/filters/pointlight.h b/src/filters/pointlight.h index 3ec5d5791..c0b272021 100644 --- a/src/filters/pointlight.h +++ b/src/filters/pointlight.h @@ -23,6 +23,12 @@ #define SP_IS_FEPOINTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEPOINTLIGHT)) #define SP_IS_FEPOINTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEPOINTLIGHT)) +/* Distant light class */ + + +class SPFePointLight; +class SPFePointLightClass; + struct SPFePointLight : public SPObject { /** x coordinate of the light source */ diff --git a/src/filters/specularlighting.h b/src/filters/specularlighting.h index 4b31eb4c4..44bd98c6c 100644 --- a/src/filters/specularlighting.h +++ b/src/filters/specularlighting.h @@ -23,7 +23,7 @@ #define SP_IS_FESPECULARLIGHTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FESPECULARLIGHTING)) #define SP_IS_FESPECULARLIGHTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FESPECULARLIGHTING)) -struct SVGICCColor; +class SVGICCColor; namespace Inkscape { namespace Filters { @@ -31,6 +31,8 @@ class FilterSpecularLighting; } } +class SPFeSpecularLightingClass; + struct SPFeSpecularLighting : public SPFilterPrimitive { gfloat surfaceScale; guint surfaceScale_set : 1; diff --git a/src/filters/spotlight.h b/src/filters/spotlight.h index 1750ca95b..6e2463c08 100644 --- a/src/filters/spotlight.h +++ b/src/filters/spotlight.h @@ -23,6 +23,12 @@ #define SP_IS_FESPOTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FESPOTLIGHT)) #define SP_IS_FESPOTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FESPOTLIGHT)) +/* Distant light class */ + + +class SPFeSpotLight; +class SPFeSpotLightClass; + struct SPFeSpotLight : public SPObject { /** x coordinate of the light source */ diff --git a/src/filters/tile.h b/src/filters/tile.h index 48a552fc8..a376a6e10 100644 --- a/src/filters/tile.h +++ b/src/filters/tile.h @@ -21,6 +21,8 @@ #define SP_IS_FETILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FETILE)) /* FeTile base class */ +class SPFeTileClass; + struct SPFeTile : public SPFilterPrimitive { }; diff --git a/src/filters/turbulence.h b/src/filters/turbulence.h index bad8315c1..cbc4fb082 100644 --- a/src/filters/turbulence.h +++ b/src/filters/turbulence.h @@ -24,6 +24,7 @@ #define SP_IS_FETURBULENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FETURBULENCE)) /* FeTurbulence base class */ +class SPFeTurbulenceClass; struct SPFeTurbulence : public SPFilterPrimitive { /** TURBULENCE ATTRIBUTES HERE */ diff --git a/src/flood-context.h b/src/flood-context.h index 3e81cd01e..0cab0f7c5 100644 --- a/src/flood-context.h +++ b/src/flood-context.h @@ -29,6 +29,9 @@ #define FLOOD_COLOR_CHANNEL_B 4 #define FLOOD_COLOR_CHANNEL_A 8 +class SPFloodContext; +class SPFloodContextClass; + struct SPFloodContext : public SPEventContext { SPItem *item; diff --git a/src/gradient-context.h b/src/gradient-context.h index 464b95ad4..9c08677ae 100644 --- a/src/gradient-context.h +++ b/src/gradient-context.h @@ -25,6 +25,9 @@ #define SP_IS_GRADIENT_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_GRADIENT_CONTEXT)) #define SP_IS_GRADIENT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_GRADIENT_CONTEXT)) +class SPGradientContext; +class SPGradientContextClass; + struct SPGradientContext : public SPEventContext { Geom::Point origin; diff --git a/src/gradient-drag.h b/src/gradient-drag.h index 2a2465590..cd76d8a3c 100644 --- a/src/gradient-drag.h +++ b/src/gradient-drag.h @@ -33,12 +33,12 @@ struct SPKnot; class SPDesktop; class SPCSSAttr; -struct SPLinearGradient; +class SPLinearGradient; struct SPMeshGradient; class SPItem; class SPObject; -struct SPRadialGradient; -struct SPStop; +class SPRadialGradient; +class SPStop; namespace Inkscape { class Selection; diff --git a/src/inkscape-private.h b/src/inkscape-private.h index 09bcef12b..470a1f5bd 100644 --- a/src/inkscape-private.h +++ b/src/inkscape-private.h @@ -22,7 +22,7 @@ #include "inkscape.h" -struct SPColor; +class SPColor; namespace Inkscape { class Selection; } GType inkscape_get_type (void); diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 491acd73e..449220357 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -91,7 +91,7 @@ enum { ################################*/ namespace Inkscape { -struct ApplicationClass; +class ApplicationClass; } static void inkscape_class_init (Inkscape::ApplicationClass *klass); diff --git a/src/libgdl/Makefile_insert b/src/libgdl/Makefile_insert index e92223f0b..3f5228a20 100644 --- a/src/libgdl/Makefile_insert +++ b/src/libgdl/Makefile_insert @@ -44,14 +44,6 @@ libgdl/all: libgdl/libgdl.a libgdl/clean: rm -f libgdl/libgdl.a $(libgdl_gdl_a_OBJECTS) -if CC_W_NO_SUPPORTED -# Suppress some non-critical warnings for libgdl. We will drop our forked copy -# of GDL once we upgrade to Gtk+ 3 so it's more important to minimise the number -# of changes we make to GDL than to fix these minor issues in trunk. - -libgdl_libgdl_a_CFLAGS = -Wno-unused-parameter -Wno-sign-compare -Wno-unused-variable -Wno-unused-but-set-variable $(AM_CFLAGS) -endif - libgdl_libgdl_a_SOURCES = \ libgdl/gdl-dock-object.h \ libgdl/gdl-dock-master.h \ diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 0f853c681..1d086b57b 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -26,6 +26,7 @@ namespace Inkscape { namespace Extension { namespace Internal { class CairoRenderContext; + class CairoGlyphInfo; } } } diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 0f5f08a53..488a974ea 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -36,7 +36,7 @@ using Inkscape::Extension::Internal::CairoRenderContext; struct SPStyle; class Shape; -struct SPPrintContext; +class SPPrintContext; class SVGLength; class Path; class SPCurve; diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 90900baba..712c17915 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -2,6 +2,7 @@ # include #endif +#include #include #include #include diff --git a/src/livarot/Path.h b/src/livarot/Path.h index a109298a2..cd939bf7d 100644 --- a/src/livarot/Path.h +++ b/src/livarot/Path.h @@ -14,11 +14,11 @@ #include <2geom/point.h> struct PathDescr; -struct PathDescrLineTo; -struct PathDescrArcTo; -struct PathDescrCubicTo; -struct PathDescrBezierTo; -struct PathDescrIntermBezierTo; +class PathDescrLineTo; +class PathDescrArcTo; +class PathDescrCubicTo; +class PathDescrBezierTo; +class PathDescrIntermBezierTo; struct SPStyle; diff --git a/src/livarot/Shape.h b/src/livarot/Shape.h index dcd172da2..1a804a48c 100644 --- a/src/livarot/Shape.h +++ b/src/livarot/Shape.h @@ -21,9 +21,9 @@ class Path; class FloatLigne; -class SweepTree; -class SweepTreeList; -class SweepEventQueue; +struct SweepTree; +struct SweepTreeList; +struct SweepEventQueue; enum { tweak_mode_grow, diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 785c545b5..b1e40655d 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -39,13 +39,18 @@ using Inkscape::DocumentUndo; - namespace Inkscape { namespace LivePathEffect { LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject) { + Glib::ustring title = Glib::ustring(_("Ignore cusp nodes")); + Glib::ustring tip = Glib::ustring(_("Ignore cusp nodes")); + LPEBSpline::Gtk::Widget *noCusp = new LPEBSpline::newCheckButton(title,tip); + title = Glib::ustring(_("Unify weights:")); + tip = Glib::ustring(_("Percent of the with for all poinrs")); + LPEBSpline::Gtk::Widget *scal = new LPEBSpline::newScalar(title,tip); } LPEBSpline::~LPEBSpline() @@ -239,25 +244,20 @@ Gtk::Widget * LPEBSpline::newWidget() { Gtk::VBox * vbox = dynamic_cast(Effect::newWidget()); - Glib::ustring title = Glib::ustring(_("Ignore cusp nodes")); - Glib::ustring tip = Glib::ustring(_("Ignore cusp nodes")); - this->setNoCuspWidget(this->newCheckButton(title)); - title = Glib::ustring(_("Unify weights:")); - tip = Glib::ustring(_("Percent of the with for all poinrs")); - this->setScalWidget(this->newScalar(title,tip)); vbox->set_border_width(5); - vbox->pack_start(*this->getNoCuspWidget(), true, true,2); - vbox->pack_start(*this->getScalWidget(),true,true,(guint)2); + vbox->pack_start(&noCusp,true,true,(guint)2); + vbox->pack_start(&scal, true, true,2); return dynamic_cast (vbox); } Gtk::Widget * LPEBSpline::newScalar(Glib::ustring title, Glib::ustring tip) { - Inkscape::UI::Widget::Scalar * scal = Gtk::manage( new Inkscape::UI::Widget::Scalar(title, tip, 2)); - scal->setRange(0.01, 100.); - scal->setIncrements(1., 5.); + scal = Gtk::manage( new Inkscape::UI::Widget::Scalar(title, tip)); scal->setValue(33.); + scal->setDigits(2); + scal->setIncrements(1., 5.); + scal->setRange(0, 100.); scal->setProgrammatically = false; scal->addSlider(); scal->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::updateAllHandles)); @@ -265,20 +265,17 @@ LPEBSpline::newScalar(Glib::ustring title, Glib::ustring tip) } Gtk::Widget * -LPEBSpline::newCheckButton(Glib::ustring title) +LPEBSpline::newCheckButton(Glib::ustring title, Glib::ustring tip) { - Gtk::CheckButton * noCusp = Gtk::manage( new Gtk::CheckButton(title,true)); - noCusp->set_alignment(1.0,0.0); + noCusp = Gtk::manage( new Gtk::CheckButton(title,tip)); return dynamic_cast(noCusp); } void LPEBSpline::updateAllHandles() { - Inkscape::UI::Widget::Scalar * scal = dynamic_cast(this->getScalWidget()); - double value = scal->getValue()/100; - Gtk::CheckButton * noCusp = dynamic_cast(this->getNoCuspWidget()); - bool noCuspValue = noCusp->get_active(); + double value = scal->setValue(33.); + bool noCusp = false; SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop? Inkscape::Selection *selection = sp_desktop_selection(desktop); for (GSList *items = (GSList *) selection->itemList(); @@ -291,7 +288,7 @@ LPEBSpline::updateAllHandles() SPItem *item = (SPItem *) items->data; SPPath *path = SP_PATH(item); SPCurve *curve = path->get_curve_for_edit(); - LPEBSpline::doBSplineFromWidget(curve,value,noCuspValue); + LPEBSpline::doBSplineFromWidget(curve,value,noCusp); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); g_free(str); @@ -313,8 +310,6 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double value , bool noCusp) // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); - using Geom::X; - using Geom::Y; //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) { @@ -368,20 +363,16 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double value , bool noCusp) if(cubic){ if(!noCusp || (*cubic)[1] != in->first_segment()->initialPoint()) pointAt1 = SBasisIn.valueAt(value); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); else pointAt1 = in->first_segment()->initialPoint(); if(!noCusp || (*cubic)[2] != in->first_segment()->finalPoint()) pointAt2 = SBasisIn.valueAt(1-value); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); else pointAt2 = in->first_segment()->finalPoint(); }else{ if(!noCusp){ pointAt1 = SBasisIn.valueAt(value); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); pointAt2 = SBasisIn.valueAt(1-value); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ pointAt1 = in->first_segment()->initialPoint(); pointAt2 = in->first_segment()->finalPoint(); @@ -400,20 +391,16 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double value , bool noCusp) if(cubic){ if(!noCusp || (*cubic)[1] != out->first_segment()->initialPoint()) nextPointAt1 = SBasisOut.valueAt(value); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); else nextPointAt1 = out->first_segment()->initialPoint(); if(!noCusp || (*cubic)[2] != out->first_segment()->finalPoint()) nextPointAt2 = SBasisOut.valueAt(1-value); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); else nextPointAt2 = out->first_segment()->finalPoint(); }else{ if(!noCusp){ nextPointAt1 = SBasisOut.valueAt(value); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); nextPointAt2 = SBasisOut.valueAt(1-value); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ nextPointAt1 = out->first_segment()->initialPoint(); nextPointAt2 = out->first_segment()->finalPoint(); @@ -422,7 +409,6 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double value , bool noCusp) nextPointAt3 = out->first_segment()->finalPoint(); out->reset(); delete out; - //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 diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index a0f1554d0..dbe0789f2 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -8,7 +8,9 @@ */ #include "live_effects/effect.h" - +#include "live_effects/parameter/parameter.h" +#include "ui/widget/scalar.h" +#include namespace Inkscape { namespace LivePathEffect { @@ -16,13 +18,6 @@ namespace LivePathEffect { class LPEBSpline : public Effect { - -private: - double scalWidget; - bool noCuspWidget; - LPEBSpline(const LPEBSpline&); - LPEBSpline& operator=(const LPEBSpline&); - public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); @@ -35,22 +30,21 @@ public: virtual void updateAllHandles(); - virtual Gtk::Widget* newScalar(Glib::ustring title, Glib::ustring tip); + virtual void newScalar(Glib::ustring title, Glib::ustring tip); + + virtual void newCheckButton(Glib::ustring title, Glib::ustring tip); - virtual Gtk::Widget* newCheckButton(Glib::ustring title); virtual void doBSplineFromWidget(SPCurve * curve, double value, bool noCusp); - virtual double getScal(){return scal;}; - - virtual double setScal(double setScal){scal = setScal;}; - - virtual bool getNoCusp(){return noCusp;}; - - virtual bool setNoCusp(bool setNoCusp){noCusp = setNoCusp;}; - - virtual Gtk::Widget* newWidget(); + virtual Gtk::Widget * newWidget(); + +private: + Gtk::Widget * scal; + Gtk::Widget * noCusp; + LPEBSpline(const LPEBSpline&); + LPEBSpline& operator=(const LPEBSpline&); }; }; //namespace LivePathEffect diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp index ac571d963..452139344 100644 --- a/src/live_effects/lpe-recursiveskeleton.cpp +++ b/src/live_effects/lpe-recursiveskeleton.cpp @@ -91,8 +91,7 @@ LPERecursiveSkeleton::doEffect_pwd2 (Geom::Piecewise > co double scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); // TODO investigate why pattWidth is not being used: - // - Doesn't appear to have been used anywhere in bzr history (Alex V: 2013-03-16) - // double pattWidth = pattBndsX->extent() * scaling; + double pattWidth = pattBndsX->extent() * scaling; if (scaling != 1.0) { x*=scaling; diff --git a/src/lpe-tool-context.h b/src/lpe-tool-context.h index fb3a5d4e2..12e4b3838 100644 --- a/src/lpe-tool-context.h +++ b/src/lpe-tool-context.h @@ -24,6 +24,9 @@ #define SP_IS_LPETOOL_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_LPETOOL_CONTEXT)) #define SP_IS_LPETOOL_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_LPETOOL_CONTEXT)) +class SPLPEToolContext; +class SPLPEToolContextClass; + /* This is the list of subtools from which the toolbar of the LPETool is built automatically */ extern const int num_subtools; diff --git a/src/marker.cpp b/src/marker.cpp index 9717160ed..ba5cd4b05 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -324,13 +324,13 @@ static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags) // Now set up viewbox transformation // Determine actual viewbox in viewport coordinates - // double x = 0; - // double y = 0; + double x = 0; + double y = 0; double width = 0; double height = 0; if (marker->aspect_align == SP_ASPECT_NONE) { - // x = 0.0; - // y = 0.0; + x = 0.0; + y = 0.0; width = rctx.viewport.width(); height = rctx.viewport.height(); } else { @@ -343,7 +343,7 @@ static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags) height = (vb.height()) * scale; // Now place viewbox to requested position - /*switch (marker->aspect_align) { + switch (marker->aspect_align) { case SP_ASPECT_XMIN_YMIN: x = 0.0; y = 0.0; @@ -384,7 +384,7 @@ static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags) x = 0.0; y = 0.0; break; - }*/ + } } // TODO fixme: all that work is done to figure out x and y, which are just ignored. Check why. diff --git a/src/marker.h b/src/marker.h index 147fafeb8..e8d2dd9a1 100644 --- a/src/marker.h +++ b/src/marker.h @@ -22,7 +22,9 @@ #define SP_MARKER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_MARKER, SPMarker)) #define SP_IS_MARKER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_MARKER)) -struct SPMarkerView; +class SPMarker; +class SPMarkerClass; +class SPMarkerView; #include <2geom/rect.h> #include <2geom/affine.h> diff --git a/src/measure-context.h b/src/measure-context.h index b7673ad0d..baf74d30e 100644 --- a/src/measure-context.h +++ b/src/measure-context.h @@ -18,6 +18,9 @@ #define SP_MEASURE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_MEASURE_CONTEXT, SPMeasureContext)) #define SP_IS_MEASURE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_MEASURE_CONTEXT)) +class SPMeasureContext; +class SPMeasureContextClass; + struct SPMeasureContext { SPEventContext event_context; SPCanvasItem *grabbed; diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 694619089..868b606a4 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -252,7 +252,9 @@ static char const menus_skeleton[] = " \n" " \n" " \n" +#ifdef ENABLE_SVG_FONTS " \n" +#endif // ENABLE_SVG_FONTS " \n" " \n" " \n" diff --git a/src/mesh-context.h b/src/mesh-context.h index e5d06ec0a..ed93e404f 100644 --- a/src/mesh-context.h +++ b/src/mesh-context.h @@ -27,6 +27,9 @@ #define SP_IS_MESH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_MESH_CONTEXT)) #define SP_IS_MESH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_MESH_CONTEXT)) +class SPMeshContext; +class SPMeshContextClass; + struct SPMeshContext : public SPEventContext { Geom::Point origin; diff --git a/src/pixmaps/cursor-dropper.xpm b/src/pixmaps/cursor-dropper.xpm new file mode 100644 index 000000000..21f96edd0 --- /dev/null +++ b/src/pixmaps/cursor-dropper.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static const char * cursor_dropper_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +" .+. ", +".... .... ", +".+++ +++. ", +".... .... ", +" .+. ", +" .+. .... ", +" .+. .+++. ", +" ... .+..+. ", +" .++..+. ", +" .++..+. ", +" .++..+. ", +" .++..+. . ", +" .++..+.+. ", +" .++..+++. ", +" .++++.+. ", +" .++++.+.. ", +" .++++++.++. ", +" .++++++..+. ", +" ..+++++.+. ", +" .++++++. ", +" .+++++. ", +" .+++. ", +" ... ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/rect-context.h b/src/rect-context.h index 5b6c5373e..b6fbb6854 100644 --- a/src/rect-context.h +++ b/src/rect-context.h @@ -25,6 +25,9 @@ #define SP_IS_RECT_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_RECT_CONTEXT)) #define SP_IS_RECT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_RECT_CONTEXT)) +class SPRectContext; +class SPRectContextClass; + struct SPRectContext : public SPEventContext { SPItem *item; Geom::Point center; diff --git a/src/select-context.h b/src/select-context.h index a6877f802..ce2039a2d 100644 --- a/src/select-context.h +++ b/src/select-context.h @@ -22,6 +22,8 @@ #define SP_IS_SELECT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SELECT_CONTEXT)) struct SPCanvasItem; +class SPSelectContext; +class SPSelectContextClass; namespace Inkscape { class MessageContext; diff --git a/src/selection.cpp b/src/selection.cpp index 564f1fdd3..72f50137c 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -418,6 +418,7 @@ Geom::OptRect Selection::documentBounds(SPItem::BBoxType type) const // will be returned; this is also the case in SelTrans::centerRequest() boost::optional Selection::center() const { GSList *items = (GSList *) const_cast(this)->itemList(); + Geom::Point center; if (items) { SPItem *first = reinterpret_cast(g_slist_last(items)->data); // from the first item in selection if (first->isCenterSet()) { // only if set explicitly diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h index 14f50d784..f625ebd68 100644 --- a/src/seltrans-handles.h +++ b/src/seltrans-handles.h @@ -21,7 +21,7 @@ namespace Inkscape class SelTrans; } -struct SPSelTransHandle; +class SPSelTransHandle; // request handlers gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, diff --git a/src/seltrans.h b/src/seltrans.h index effc767e3..55c109ed7 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -30,7 +30,7 @@ struct SPKnot; class SPDesktop; struct SPCanvasItem; struct SPCtrlLine; -struct SPSelTransHandle; +class SPSelTransHandle; namespace Inkscape { diff --git a/src/snap.cpp b/src/snap.cpp index 15f24ef53..695424194 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -500,6 +500,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( /* The current best metric for the best transformation; lower is better, Geom::infinity() ** means that we haven't snapped anything. */ + Geom::Point best_scale_metric(Geom::infinity(), Geom::infinity()); Inkscape::SnappedPoint best_snapped_point; g_assert(best_snapped_point.getAlwaysSnap() == false); // Check initialization of snapped point g_assert(best_snapped_point.getAtIntersection() == false); diff --git a/src/sp-clippath.h b/src/sp-clippath.h index 17546c6d3..a77383c63 100644 --- a/src/sp-clippath.h +++ b/src/sp-clippath.h @@ -21,7 +21,7 @@ #define SP_IS_CLIPPATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_CLIPPATH)) #define SP_IS_CLIPPATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_CLIPPATH)) -struct SPClipPathView; +class SPClipPathView; #include "sp-object-group.h" #include "uri-references.h" diff --git a/src/sp-desc.h b/src/sp-desc.h index 41ef08020..8c5a8a663 100644 --- a/src/sp-desc.h +++ b/src/sp-desc.h @@ -17,6 +17,9 @@ #define SP_TYPE_DESC (sp_desc_get_type ()) #define SP_IS_DESC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_DESC)) +class SPDesc; +class SPDescClass; + struct SPDesc : public SPObject { }; diff --git a/src/sp-filter-primitive.h b/src/sp-filter-primitive.h index f06df5611..60104047e 100644 --- a/src/sp-filter-primitive.h +++ b/src/sp-filter-primitive.h @@ -23,6 +23,8 @@ #define SP_IS_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FILTER_PRIMITIVE)) #define SP_IS_FILTER_PRIMITIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FILTER_PRIMITIVE)) +class SPFilterPrimitive; +class SPFilterPrimitiveClass; namespace Inkscape { namespace Filters { class Filter; diff --git a/src/sp-filter.h b/src/sp-filter.h index 5afe47438..a3e7cd35c 100644 --- a/src/sp-filter.h +++ b/src/sp-filter.h @@ -36,7 +36,7 @@ class Filter; } } class SPFilterReference; -struct SPFilterPrimitive; +class SPFilterPrimitive; struct ltstr { bool operator()(const char* s1, const char* s2) const; diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 627907cef..a8de68f9b 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -86,13 +86,15 @@ sp_flowregion_dispose(GObject *object) group->computed.~vector(); } -static void -sp_flowregion_child_added(SPObject *object, - Inkscape::XML::Node *child, - Inkscape::XML::Node *ref) +static void sp_flowregion_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { - SP_OBJECT_CLASS (sp_flowregion_parent_class)->child_added (object, child, ref); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + SP_ITEM(object); + + if (((SPObjectClass *) (sp_flowregion_parent_class))->child_added) { + (* ((SPObjectClass *) (sp_flowregion_parent_class))->child_added) (object, child, ref); + } + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); } /* fixme: hide (Lauris) */ @@ -162,10 +164,10 @@ void SPFlowregion::UpdateComputed(void) } } -static void -sp_flowregion_modified(SPObject *object, - guint flags) +static void sp_flowregion_modified(SPObject *object, guint flags) { + SP_FLOWREGION(object); // ensure it is the proper type. + if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } @@ -276,14 +278,15 @@ sp_flowregionexclude_dispose(GObject *object) } } -static void -sp_flowregionexclude_child_added(SPObject *object, - Inkscape::XML::Node *child, - Inkscape::XML::Node *ref) +static void sp_flowregionexclude_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { - SP_OBJECT_CLASS (sp_flowregionexclude_parent_class)->child_added (object, child, ref); + SP_ITEM(object); + + if (((SPObjectClass *) (sp_flowregionexclude_parent_class))->child_added) { + (* ((SPObjectClass *) (sp_flowregionexclude_parent_class))->child_added) (object, child, ref); + } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); } /* fixme: hide (Lauris) */ @@ -351,10 +354,10 @@ void SPFlowregionExclude::UpdateComputed(void) } } -static void -sp_flowregionexclude_modified(SPObject *object, - guint flags) +static void sp_flowregionexclude_modified(SPObject *object, guint flags) { + SP_FLOWREGIONEXCLUDE(object); // Ensure it is the proper type + if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } diff --git a/src/sp-font-face.cpp b/src/sp-font-face.cpp index 0a649b17f..4288a5d64 100644 --- a/src/sp-font-face.cpp +++ b/src/sp-font-face.cpp @@ -2,6 +2,8 @@ # include #endif +#ifdef ENABLE_SVG_FONTS + /* * SVG element implementation * @@ -847,6 +849,7 @@ static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::D return repr; } +#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-font-face.h b/src/sp-font-face.h index 968644556..57702b683 100644 --- a/src/sp-font-face.h +++ b/src/sp-font-face.h @@ -2,6 +2,7 @@ # include #endif +#ifdef ENABLE_SVG_FONTS #ifndef __SP_FONTFACE_H__ #define __SP_FONTFACE_H__ @@ -121,3 +122,4 @@ GType sp_fontface_get_type (void); G_END_DECLS #endif //#ifndef __SP_FONTFACE_H__ +#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-font.cpp b/src/sp-font.cpp index a03890fc7..6ebbd5218 100644 --- a/src/sp-font.cpp +++ b/src/sp-font.cpp @@ -2,6 +2,8 @@ # include #endif +#ifdef ENABLE_SVG_FONTS + /* * SVG element implementation * @@ -248,6 +250,7 @@ static Inkscape::XML::Node *sp_font_write(SPObject *object, Inkscape::XML::Docum return repr; } +#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-glyph-kerning.cpp b/src/sp-glyph-kerning.cpp index 10884fb81..652d965bb 100644 --- a/src/sp-glyph-kerning.cpp +++ b/src/sp-glyph-kerning.cpp @@ -2,6 +2,7 @@ # include #endif +#ifdef ENABLE_SVG_FONTS #define __SP_ANCHOR_C__ /* @@ -266,6 +267,7 @@ static Inkscape::XML::Node *sp_glyph_kerning_write(SPObject *object, Inkscape::X return repr; } +#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-glyph-kerning.h b/src/sp-glyph-kerning.h index b7f733cad..ce9b4bb15 100644 --- a/src/sp-glyph-kerning.h +++ b/src/sp-glyph-kerning.h @@ -2,6 +2,7 @@ # include #endif +#ifdef ENABLE_SVG_FONTS #ifndef __SP_GLYPH_KERNING_H__ #define __SP_GLYPH_KERNING_H__ @@ -59,3 +60,4 @@ GType sp_glyph_kerning_h_get_type (void); GType sp_glyph_kerning_v_get_type (void); #endif //#ifndef __SP_GLYPH_KERNING_H__ +#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-glyph.cpp b/src/sp-glyph.cpp index 0417ea8c1..e14ef8667 100644 --- a/src/sp-glyph.cpp +++ b/src/sp-glyph.cpp @@ -2,6 +2,7 @@ # include #endif +#ifdef ENABLE_SVG_FONTS #define __SP_GLYPH_C__ /* @@ -283,6 +284,7 @@ static Inkscape::XML::Node *sp_glyph_write(SPObject *object, Inkscape::XML::Docu return repr; } +#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-glyph.h b/src/sp-glyph.h index 7556b0e25..316204c23 100644 --- a/src/sp-glyph.h +++ b/src/sp-glyph.h @@ -2,6 +2,7 @@ # include #endif +#ifdef ENABLE_SVG_FONTS #ifndef __SP_GLYPH_H__ #define __SP_GLYPH_H__ @@ -57,3 +58,4 @@ struct SPGlyphClass { GType sp_glyph_get_type (void); #endif //#ifndef __SP_GLYPH_H__ +#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-gradient.h b/src/sp-gradient.h index 57ffa5570..a21a413f4 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -27,8 +27,8 @@ #include #include -class SPGradientReference; -struct SPStop; +struct SPGradientReference; +class SPStop; #define SP_TYPE_GRADIENT (SPGradient::getType()) #define SP_GRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_GRADIENT, SPGradient)) diff --git a/src/sp-image.h b/src/sp-image.h index d6fc82a59..c657d0a2f 100644 --- a/src/sp-image.h +++ b/src/sp-image.h @@ -20,6 +20,9 @@ #define SP_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_IMAGE)) #define SP_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_IMAGE)) +class SPImage; +class SPImageClass; + /* SPImage */ #include diff --git a/src/sp-item.h b/src/sp-item.h index e65ffc829..a3ba1dbe2 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -28,8 +28,8 @@ #include "snap-candidate.h" class SPGuideConstraint; -class SPClipPathReference; -class SPMaskReference; +struct SPClipPathReference; +struct SPMaskReference; class SPAvoidRef; struct SPPrintContext; diff --git a/src/sp-linear-gradient-fns.h b/src/sp-linear-gradient-fns.h index 14e575ebe..1bdf0b89e 100644 --- a/src/sp-linear-gradient-fns.h +++ b/src/sp-linear-gradient-fns.h @@ -14,7 +14,7 @@ class Node; } } -struct SPLinearGradient; +class SPLinearGradient; #define SP_TYPE_LINEARGRADIENT (sp_lineargradient_get_type()) #define SP_LINEARGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_LINEARGRADIENT, SPLinearGradient)) diff --git a/src/sp-mask.h b/src/sp-mask.h index 97cf95ae1..e249e0c76 100644 --- a/src/sp-mask.h +++ b/src/sp-mask.h @@ -24,7 +24,9 @@ #define SP_IS_MASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_MASK)) #define SP_IS_MASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_MASK)) -struct SPMaskView; +class SPMask; +class SPMaskClass; +class SPMaskView; namespace Inkscape { diff --git a/src/sp-metadata.cpp b/src/sp-metadata.cpp index 79953b708..9978d0a3a 100644 --- a/src/sp-metadata.cpp +++ b/src/sp-metadata.cpp @@ -116,17 +116,15 @@ static void sp_metadata_release(SPObject *object) /** * Sets a specific value in the SPMetadata. */ -static void -sp_metadata_set(SPObject *object, - unsigned int key, - const gchar *value) +static void sp_metadata_set(SPObject *object, unsigned int key, const gchar *value) { debug("0x%08x %s(%u): '%s'",(unsigned int)object, sp_attribute_name(key),key,value); + SP_METADATA(object); // ensures the object is of the proper type. // see if any parents need this value - if (SP_OBJECT_CLASS(sp_metadata_parent_class)->set) { - SP_OBJECT_CLASS(sp_metadata_parent_class)->set(object, key, value); + if (reinterpret_cast(sp_metadata_parent_class)->set) { + reinterpret_cast(sp_metadata_parent_class)->set(object, key, value); } } diff --git a/src/sp-metadata.h b/src/sp-metadata.h index 454fd8d18..82b7c4fc5 100644 --- a/src/sp-metadata.h +++ b/src/sp-metadata.h @@ -21,6 +21,9 @@ #define SP_METADATA(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_METADATA, SPMetadata)) #define SP_IS_METADATA(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_METADATA)) +class SPMetadata; +class SPMetadataClass; + struct SPMetadata : public SPObject { }; diff --git a/src/sp-missing-glyph.cpp b/src/sp-missing-glyph.cpp index 911c9be92..bdf993e5b 100644 --- a/src/sp-missing-glyph.cpp +++ b/src/sp-missing-glyph.cpp @@ -2,6 +2,8 @@ # include #endif +#ifdef ENABLE_SVG_FONTS + /* * SVG element implementation * @@ -162,6 +164,7 @@ static Inkscape::XML::Node *sp_missing_glyph_write(SPObject *object, Inkscape::X return repr; } +#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-missing-glyph.h b/src/sp-missing-glyph.h index 7930df513..0b3f74360 100644 --- a/src/sp-missing-glyph.h +++ b/src/sp-missing-glyph.h @@ -2,6 +2,7 @@ # include #endif +#ifdef ENABLE_SVG_FONTS #ifndef __SP_MISSING_GLYPH_H__ #define __SP_MISSING_GLYPH_H__ @@ -39,3 +40,4 @@ struct SPMissingGlyphClass { GType sp_missing_glyph_get_type (void); #endif //#ifndef __SP_MISSING_GLYPH_H__ +#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-object-group.cpp b/src/sp-object-group.cpp index e2b601ab9..5158ec70a 100644 --- a/src/sp-object-group.cpp +++ b/src/sp-object-group.cpp @@ -93,6 +93,8 @@ sp_objectgroup_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) { + SP_OBJECTGROUP(object); // Ensure we have the right type of SPObject + if (flags & SP_OBJECT_WRITE_BUILD) { if (!repr) { repr = xml_doc->createElement("svg:g"); @@ -116,7 +118,7 @@ sp_objectgroup_write(SPObject *object, } if ((SP_OBJECT_CLASS(sp_objectgroup_parent_class))->write) { - SP_OBJECT_CLASS(sp_objectgroup_parent_class)->write(object, xml_doc, repr, flags); + (SP_OBJECT_CLASS(sp_objectgroup_parent_class))->write(object, xml_doc, repr, flags); } return repr; diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp index eba38ec67..cd332cd34 100644 --- a/src/sp-object-repr.cpp +++ b/src/sp-object-repr.cpp @@ -48,11 +48,13 @@ #include "sp-script.h" #include "config.h" -#include "sp-font.h" -#include "sp-font-face.h" -#include "sp-glyph.h" -#include "sp-missing-glyph.h" -#include "sp-glyph-kerning.h" +#ifdef ENABLE_SVG_FONTS + #include "sp-font.h" + #include "sp-font-face.h" + #include "sp-glyph.h" + #include "sp-missing-glyph.h" + #include "sp-glyph-kerning.h" +#endif #include "sp-style-elem.h" #include "sp-switch.h" @@ -149,12 +151,14 @@ populate_dtables() { "svg:flowRegionExclude", SP_TYPE_FLOWREGIONEXCLUDE }, { "svg:flowRoot", SP_TYPE_FLOWTEXT }, { "svg:flowSpan", SP_TYPE_FLOWTSPAN }, +#ifdef ENABLE_SVG_FONTS { "svg:font", SP_TYPE_FONT }, { "svg:font-face", SP_TYPE_FONTFACE }, { "svg:glyph", SP_TYPE_GLYPH }, { "svg:missing-glyph", SP_TYPE_MISSING_GLYPH }, { "svg:hkern", SP_TYPE_HKERN }, { "svg:vkern", SP_TYPE_VKERN }, +#endif { "svg:g", SP_TYPE_GROUP }, { "svg:feBlend", SP_TYPE_FEBLEND }, { "svg:feColorMatrix", SP_TYPE_FECOLORMATRIX }, diff --git a/src/sp-offset.h b/src/sp-offset.h index 904f8607c..4e245f952 100644 --- a/src/sp-offset.h +++ b/src/sp-offset.h @@ -22,6 +22,8 @@ #define SP_IS_OFFSET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_OFFSET)) #define SP_IS_OFFSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_OFFSET)) +class SPOffset; +class SPOffsetClass; class SPUseReference; /** diff --git a/src/sp-pattern.h b/src/sp-pattern.h index bcf8dd520..e0a7dce54 100644 --- a/src/sp-pattern.h +++ b/src/sp-pattern.h @@ -24,7 +24,8 @@ GType sp_pattern_get_type (void); -struct SPPattern; +class SPPattern; +class SPPatternClass; #include "svg/svg-length.h" #include "sp-paint-server.h" diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index 2922b66ed..e5d89a802 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -116,11 +116,10 @@ sp_polyline_set(SPObject *object, unsigned int key, const gchar *value) } static Inkscape::XML::Node* -sp_polyline_write(SPObject *object, - Inkscape::XML::Document *xml_doc, - Inkscape::XML::Node *repr, - guint flags) +sp_polyline_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { + SP_POLYLINE(object); + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:polyline"); } @@ -129,7 +128,9 @@ sp_polyline_write(SPObject *object, repr->mergeFrom(object->getRepr(), "id"); } - SP_OBJECT_CLASS(sp_polyline_parent_class)->write (object, xml_doc, repr, flags); + if (((SPObjectClass *) (sp_polyline_parent_class))->write) { + ((SPObjectClass *) (sp_polyline_parent_class))->write (object, xml_doc, repr, flags); + } return repr; } diff --git a/src/sp-radial-gradient-fns.h b/src/sp-radial-gradient-fns.h index 43ed7bf03..912508a33 100644 --- a/src/sp-radial-gradient-fns.h +++ b/src/sp-radial-gradient-fns.h @@ -13,7 +13,7 @@ class Node; } } -struct SPRadialGradient; +class SPRadialGradient; #define SP_TYPE_RADIALGRADIENT (sp_radialgradient_get_type()) #define SP_RADIALGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_RADIALGRADIENT, SPRadialGradient)) diff --git a/src/sp-rect.h b/src/sp-rect.h index 1127889c1..5e518dcd7 100644 --- a/src/sp-rect.h +++ b/src/sp-rect.h @@ -26,6 +26,9 @@ G_BEGIN_DECLS #define SP_IS_RECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_RECT)) #define SP_IS_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_RECT)) +class SPRect; +class SPRectClass; + struct SPRect : public SPShape { SVGLength x; SVGLength y; diff --git a/src/sp-spiral.h b/src/sp-spiral.h index 64cb8521b..6da7c38a4 100644 --- a/src/sp-spiral.h +++ b/src/sp-spiral.h @@ -29,6 +29,9 @@ #define SP_IS_SPIRAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_SPIRAL)) #define SP_IS_SPIRAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SPIRAL)) +class SPSpiral; +class SPSpiralClass; + /** * A spiral Shape. * diff --git a/src/sp-star.h b/src/sp-star.h index 888eeb8d2..bd271ccc0 100644 --- a/src/sp-star.h +++ b/src/sp-star.h @@ -16,12 +16,17 @@ #include "sp-polygon.h" + + #define SP_TYPE_STAR (sp_star_get_type ()) #define SP_STAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_STAR, SPStar)) #define SP_STAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_STAR, SPStarClass)) #define SP_IS_STAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_STAR)) #define SP_IS_STAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_STAR)) +class SPStar; +class SPStarClass; + typedef enum { SP_STAR_POINT_KNOT1, SP_STAR_POINT_KNOT2 diff --git a/src/sp-stop.h b/src/sp-stop.h index b82dd0b13..c3b1e2753 100644 --- a/src/sp-stop.h +++ b/src/sp-stop.h @@ -14,6 +14,7 @@ #include "color.h" class SPObjectClass; +class SPColor; struct SPStop; struct SPStopClass; diff --git a/src/sp-switch.h b/src/sp-switch.h index 24a204731..f0442f27b 100644 --- a/src/sp-switch.h +++ b/src/sp-switch.h @@ -35,7 +35,7 @@ public: CSwitch(SPGroup *group); virtual ~CSwitch(); - friend struct SPSwitch; + friend class SPSwitch; virtual void onChildAdded(Inkscape::XML::Node *child); virtual void onChildRemoved(Inkscape::XML::Node *child); diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp index 989a5b7f3..d4db403e3 100644 --- a/src/sp-symbol.cpp +++ b/src/sp-symbol.cpp @@ -307,19 +307,19 @@ static void sp_symbol_update(SPObject *object, SPCtx *ctx, guint flags) } } -static void -sp_symbol_modified(SPObject *object, - guint flags) +static void sp_symbol_modified(SPObject *object, guint flags) { - SP_OBJECT_CLASS(sp_symbol_parent_class)->modified (object, flags); + SP_SYMBOL(object); + + if (((SPObjectClass *) (sp_symbol_parent_class))->modified) { + (* ((SPObjectClass *) (sp_symbol_parent_class))->modified) (object, flags); + } } -static Inkscape::XML::Node * -sp_symbol_write(SPObject *object, - Inkscape::XML::Document *xml_doc, - Inkscape::XML::Node *repr, - guint flags) +static Inkscape::XML::Node *sp_symbol_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { + SP_SYMBOL(object); + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:symbol"); } @@ -330,7 +330,9 @@ sp_symbol_write(SPObject *object, //XML Tree being used directly here while it shouldn't be. repr->setAttribute("preserveAspectRatio", object->getRepr()->attribute("preserveAspectRatio")); - SP_OBJECT_CLASS(sp_symbol_parent_class)->write (object, xml_doc, repr, flags); + if (((SPObjectClass *) (sp_symbol_parent_class))->write) { + ((SPObjectClass *) (sp_symbol_parent_class))->write (object, xml_doc, repr, flags); + } return repr; } @@ -402,14 +404,3 @@ static void sp_symbol_print(SPItem *item, SPPrintContext *ctx) sp_print_release (ctx); } } - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-symbol.h b/src/sp-symbol.h index 10d642e8b..59f343285 100644 --- a/src/sp-symbol.h +++ b/src/sp-symbol.h @@ -21,6 +21,9 @@ #define SP_SYMBOL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_SYMBOL, SPSymbol)) #define SP_IS_SYMBOL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_SYMBOL)) +class SPSymbol; +class SPSymbolClass; + #include <2geom/affine.h> #include "svg/svg-length.h" #include "enums.h" diff --git a/src/sp-title.h b/src/sp-title.h index d10d58188..a5f0a2fea 100644 --- a/src/sp-title.h +++ b/src/sp-title.h @@ -17,6 +17,9 @@ #define SP_TYPE_TITLE (sp_title_get_type ()) #define SP_IS_TITLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_TITLE)) +class SPTitle; +class SPTitleClass; + struct SPTitle : public SPObject { }; diff --git a/src/sp-tref.h b/src/sp-tref.h index 33a8138d1..cc80e48a8 100644 --- a/src/sp-tref.h +++ b/src/sp-tref.h @@ -28,6 +28,9 @@ #define SP_IS_TREF(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_TREF)) #define SP_IS_TREF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_TREF)) +class SPTRef; +class SPTRef; + struct SPTRef : public SPItem { // Attributes that are used in the same way they would be in a tspan TextTagAttributes attributes; diff --git a/src/sp-use.h b/src/sp-use.h index 3dd0726aa..399f30a4c 100644 --- a/src/sp-use.h +++ b/src/sp-use.h @@ -25,6 +25,8 @@ #define SP_IS_USE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_USE)) #define SP_IS_USE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_USE)) +class SPUse; +class SPUseClass; class SPUseReference; struct SPUse : public SPItem { diff --git a/src/spiral-context.h b/src/spiral-context.h index 7f696dfa2..12c0b5d68 100644 --- a/src/spiral-context.h +++ b/src/spiral-context.h @@ -27,6 +27,9 @@ #define SP_IS_SPIRAL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_SPIRAL_CONTEXT)) #define SP_IS_SPIRAL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SPIRAL_CONTEXT)) +class SPSpiralContext; +class SPSpiralContextClass; + struct SPSpiralContext : public SPEventContext { SPItem * item; Geom::Point center; diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 2015ffd27..061d32554 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -1369,18 +1369,48 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool Inkscape::XML::Node *parent = item->getRepr()->parent(); float o_width = 0; + JoinType o_join = join_straight; + ButtType o_butt = butt_straight; + float o_miter = 0; { SPStyle *i_style = item->style; + int jointype = i_style->stroke_linejoin.value; + int captype = i_style->stroke_linecap.value; o_width = i_style->stroke_width.computed; + if (jointype == SP_STROKE_LINEJOIN_MITER) + { + o_join = join_pointy; + } + else if (jointype == SP_STROKE_LINEJOIN_ROUND) + { + o_join = join_round; + } + else + { + o_join = join_straight; + } + if (captype == SP_STROKE_LINECAP_SQUARE) + { + o_butt = butt_square; + } + else if (captype == SP_STROKE_LINECAP_ROUND) + { + o_butt = butt_round; + } + else + { + o_butt = butt_straight; + } + { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); o_width = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px"); } - if (o_width < 0.01){ + if (o_width < 0.01) o_width = 0.01; - } + o_miter = i_style->stroke_miterlimit.value * o_width; } Path *orig = Path_for_item(item, true, false); @@ -1478,7 +1508,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *nitem = reinterpret_cast(sp_desktop_document(desktop)->getObjectByRepr(repr)); + SPItem *nitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); if ( !updating ) { // delete original, apply the transform to the offset diff --git a/src/spray-context.h b/src/spray-context.h index 781bbcce8..64368c7a6 100644 --- a/src/spray-context.h +++ b/src/spray-context.h @@ -27,6 +27,9 @@ #define SP_IS_SPRAY_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_SPRAY_CONTEXT)) #define SP_IS_SPRAY_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_SPRAY_CONTEXT)) +class SPSprayContext; +class SPSprayContextClass; + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/star-context.h b/src/star-context.h index 4daafb3e4..7bcb26c41 100644 --- a/src/star-context.h +++ b/src/star-context.h @@ -25,6 +25,9 @@ #define SP_IS_STAR_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_STAR_CONTEXT)) #define SP_IS_STAR_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_STAR_CONTEXT)) +class SPStarContext; +class SPStarContextClass; + struct SPStarContext : public SPEventContext { SPItem *item; Geom::Point center; diff --git a/src/style.cpp b/src/style.cpp index eef1c6ee5..650b08aea 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -63,7 +63,7 @@ using std::vector; #define SP_CSS_FONT_SIZE_DEFAULT 12.0; -struct SPStyleEnum; +class SPStyleEnum; /*######################### ## FORWARD DECLARATIONS diff --git a/src/style.h b/src/style.h index 0710f5c8e..1c8cb4774 100644 --- a/src/style.h +++ b/src/style.h @@ -134,6 +134,8 @@ struct SPILength { #define SP_STYLE_FILL_SERVER(s) ((const_cast (s))->getFillPaintServer()) #define SP_STYLE_STROKE_SERVER(s) ((const_cast (s))->getStrokePaintServer()) +class SVGICCColor; + /// Paint type internal to SPStyle. struct SPIPaint { unsigned set : 1; @@ -244,7 +246,7 @@ struct SPILengthOrNormal { float computed; }; -struct SPTextStyle; +class SPTextStyle; /// Stroke dash details. class NRVpathDash { diff --git a/src/svg-view-widget.h b/src/svg-view-widget.h index eab5be75b..d489ccbdd 100644 --- a/src/svg-view-widget.h +++ b/src/svg-view-widget.h @@ -15,6 +15,8 @@ #include "ui/view/view-widget.h" class SPDocument; +class SPSVGSPViewWidget; +class SPSVGSPViewWidgetClass; #define SP_TYPE_SVG_VIEW_WIDGET (sp_svg_view_widget_get_type ()) #define SP_SVG_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_SVG_VIEW_WIDGET, SPSVGSPViewWidget)) diff --git a/src/svg-view.h b/src/svg-view.h index 89f38ad34..aaaa8a9a5 100644 --- a/src/svg-view.h +++ b/src/svg-view.h @@ -13,7 +13,7 @@ #include "ui/view/view.h" -struct SPCanvasGroup; +class SPCanvasGroup; struct SPCanvasItem; diff --git a/src/svg/svg-color.h b/src/svg/svg-color.h index b8e317e3b..d1c7bee03 100644 --- a/src/svg/svg-color.h +++ b/src/svg/svg-color.h @@ -3,7 +3,7 @@ #include -struct SVGICCColor; +class SVGICCColor; guint32 sp_svg_read_color(gchar const *str, unsigned int dfl); guint32 sp_svg_read_color(gchar const *str, gchar const **end_ptr, guint32 def); diff --git a/src/text-context.h b/src/text-context.h index a33c69e0a..9915583eb 100644 --- a/src/text-context.h +++ b/src/text-context.h @@ -30,6 +30,8 @@ #define SP_IS_TEXT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_TEXT_CONTEXT)) struct SPCtrlLine; +class SPTextContext; +class SPTextContextClass; struct SPTextContext : public SPEventContext { diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 401f56bb2..47b4d35ac 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -69,7 +69,7 @@ void te_update_layout_now_recursive(SPItem *item) if (SP_IS_GROUP(item)) { GSList *item_list = sp_item_group_item_list(SP_GROUP(item)); for(GSList* elem = item_list; elem; elem = elem->next) { - SPItem* list_item = static_cast(elem->data); + SPItem* list_item = (SPItem*) elem->data; te_update_layout_now_recursive(list_item); } g_slist_free(item_list); diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp index 1a1426b83..9376fad66 100644 --- a/src/trace/siox.cpp +++ b/src/trace/siox.cpp @@ -591,7 +591,7 @@ bool SioxImage::writePPM(const std::string &fileName) if (!f) return false; - fprintf(f, "P6 %u %u 255\n", width, height); + fprintf(f, "P6 %d %d 255\n", width, height); for (unsigned int y=0 ; y); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); +#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); +#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); @@ -149,7 +154,9 @@ DialogManager::DialogManager() { registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); +#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); +#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index d335fb303..045b34814 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -792,6 +792,8 @@ void DocumentProperties::build_scripting() _page_external_scripts->table().attach(_external_remove_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0); #endif + row++; + //# Set up the External Scripts box _ExternalScriptsListStore = Gtk::ListStore::create(_ExternalScriptsListColumns); _ExternalScriptsList.set_model(_ExternalScriptsListStore); diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 086e52a6c..603786742 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -22,21 +22,14 @@ #include #include -#include +#include +#include +#include #include #include -#include -#include -#include #include -#if WITH_GTKMM_3_0 -# include -#else -# include -#endif -#include -#include - +#include +#include #ifdef WITH_GNOME_VFS # include // gnome_vfs_initialized #endif @@ -133,15 +126,6 @@ namespace Inkscape { namespace UI { namespace Dialog { -/** A list of strings that is used both in the preferences, and in the - data fields to describe the various values of \c selection_type. */ -static const char * selection_names[SELECTION_NUMBER_OF] = { - "page", "drawing", "selection", "custom"}; - -/** The names on the buttons for the various selection types. */ -static const char * selection_labels[SELECTION_NUMBER_OF] = { - N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; - Export::Export (void) : UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT), current_key(SELECTION_PAGE), diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index b10c98fd2..5dca9cfa5 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -14,12 +14,10 @@ #include #include - -#include #include #include -#include #include +#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" @@ -27,14 +25,11 @@ #include "ui/widget/button.h" #include "ui/widget/entry.h" -namespace Gtk { -class Dialog; -} - namespace Inkscape { namespace UI { namespace Dialog { + /** What type of button is being pressed */ enum selection_type { SELECTION_PAGE = 0, /**< Export the whole page */ @@ -44,6 +39,16 @@ enum selection_type { SELECTION_NUMBER_OF /**< A counter for the number of these guys */ }; +/** A list of strings that is used both in the preferences, and in the + data fields to describe the various values of \c selection_type. */ +static const char * selection_names[SELECTION_NUMBER_OF] = { + "page", "drawing", "selection", "custom"}; + +/** The names on the buttons for the various selection types. */ +static const char * selection_labels[SELECTION_NUMBER_OF] = { + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + + /** * A dialog widget to export to various image formats such as bitmap and png. * diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 19b873d54..8de2da18b 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -132,24 +132,14 @@ void FillAndStroke::_layoutPageFill() { fillWdgt = manage(sp_fill_style_widget_new()); - -#if WITH_GTKMM_3_0 _page_fill->table().attach(*fillWdgt, 0, 0, 1, 1); -#else - _page_fill->table().attach(*fillWdgt, 0, 1, 0, 1); -#endif } void FillAndStroke::_layoutPageStrokePaint() { strokeWdgt = manage(sp_stroke_style_paint_widget_new()); - -#if WITH_GTKMM_3_0 _page_stroke_paint->table().attach(*strokeWdgt, 0, 0, 1, 1); -#else - _page_stroke_paint->table().attach(*strokeWdgt, 0, 1, 0, 1); -#endif } void @@ -158,12 +148,7 @@ FillAndStroke::_layoutPageStrokeStyle() //Gtk::Widget *strokeStyleWdgt = manage(Glib::wrap(sp_stroke_style_line_widget_new())); //Gtk::Widget *strokeStyleWdgt = static_cast(sp_stroke_style_line_widget_new()); strokeStyleWdgt = sp_stroke_style_line_widget_new(); - -#if WITH_GTKMM_3_0 _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 0, 1, 1); -#else - _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 1, 0, 1); -#endif } void diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index def7b5bdb..d3ce99b00 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -15,10 +15,7 @@ #endif #include "find.h" - -#include #include - #include "verbs.h" #include "message-stack.h" @@ -59,7 +56,6 @@ #include "xml/attribute-record.h" #include -#include namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h index 14d54b8d4..77a6c9d02 100644 --- a/src/ui/dialog/find.h +++ b/src/ui/dialog/find.h @@ -21,11 +21,7 @@ #include "ui/widget/entry.h" #include "ui/widget/frame.h" #include - -#include -#include -#include -#include +#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h index 3d0571244..6571af0a4 100644 --- a/src/ui/dialog/glyphs.h +++ b/src/ui/dialog/glyphs.h @@ -20,7 +20,7 @@ class Label; class ListStore; } -struct SPFontSelector; +class SPFontSelector; class font_instance; diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index 801ab2922..de213ca85 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -20,11 +20,7 @@ #include #include #include - #include -#include -#include - #include #include #include diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 82e65435d..9c9f7faa3 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -17,9 +17,7 @@ #include #include - #include -#include #include #include #include diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index 0e2f8ed94..9de303f89 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -80,9 +80,9 @@ protected: void perform(LayerPropertiesDialog &dialog); }; - friend struct Rename; - friend struct Create; - friend struct Move; + friend class Rename; + friend class Create; + friend class Move; Strategy *_strategy; SPDesktop *_desktop; diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 8a2b0299a..114204961 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -38,12 +38,6 @@ #include "sp-item.h" #include -#if WITH_GTKMM_3_0 -# include -#else -# include -#endif - namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h index 624a18246..b49293ea1 100644 --- a/src/ui/dialog/object-properties.h +++ b/src/ui/dialog/object-properties.h @@ -35,8 +35,6 @@ #include "ui/widget/panel.h" #include "ui/widget/frame.h" - -#include #include #include #include @@ -48,14 +46,6 @@ class SPAttributeTable; class SPDesktop; class SPItem; -namespace Gtk { -#if WITH_GTKMM_3_0 -class Grid; -#else -class Table; -#endif -} - namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index bce63093d..0da39dd73 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -15,6 +15,8 @@ # include #endif +#ifdef ENABLE_SVG_FONTS + #include "svg-fonts-dialog.h" #include "document-private.h" #include "document-undo.h" @@ -943,6 +945,8 @@ SvgFontsDialog::~SvgFontsDialog(){} } // namespace UI } // namespace Inkscape +#endif //#ifdef ENABLE_SVG_FONTS + /* Local Variables: mode:c++ diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h index 01f70654a..9be984820 100644 --- a/src/ui/dialog/svg-fonts-dialog.h +++ b/src/ui/dialog/svg-fonts-dialog.h @@ -34,8 +34,8 @@ class HScale; #endif } -struct SPGlyph; -struct SPGlyphKerning; +class SPGlyph; +class SPGlyphKerning; class SvgFont; class SvgFontDrawingArea : Gtk::DrawingArea{ diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 67c6578f9..a71227861 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -57,7 +57,6 @@ extern "C" { #include "widgets/icon.h" #include "widgets/font-selector.h" #include -#include #include "unit-constants.h" diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h index f27fdfc87..3fdeea05d 100644 --- a/src/ui/dialog/text-edit.h +++ b/src/ui/dialog/text-edit.h @@ -30,7 +30,7 @@ #include "ui/dialog/desktop-tracker.h" class SPItem; -struct SPFontSelector; +class SPFontSelector; class font_instance; class SPCSSAttr; diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index bd467555e..1ad827a56 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -20,7 +20,6 @@ #include #include "ui/widget/spinbutton.h" #include "ui/widget/frame.h" -#include #include #include //for GTK_RESPONSE* types diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h index 58ef3aef8..0a6e3a786 100644 --- a/src/ui/dialog/xml-tree.h +++ b/src/ui/dialog/xml-tree.h @@ -29,7 +29,7 @@ #include "message.h" class SPDesktop; -class SPObject; +struct SPObject; struct SPXMLViewAttrList; struct SPXMLViewContent; struct SPXMLViewTree; diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index 069dcc67b..8c4924f26 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -7,8 +7,8 @@ */ #include -#include #include +#include #include <2geom/point.h> #include "desktop.h" #include "desktop-handles.h" diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index bc5267bb2..49b1496d4 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -25,6 +25,9 @@ #define INK_IS_NODE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INK_TYPE_NODE_TOOL)) #define INK_IS_NODE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INK_TYPE_NODE_TOOL)) +class InkNodeTool; +class InkNodeToolClass; + namespace Inkscape { namespace Display { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 8bc097ed6..a235a3b05 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -22,7 +22,7 @@ struct SPCanvasItem; class SPCurve; -class SPPath; +struct SPPath; namespace Inkscape { namespace XML { class Node; } diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp index 64d28119a..173e014d9 100644 --- a/src/ui/widget/entry.cpp +++ b/src/ui/widget/entry.cpp @@ -13,8 +13,6 @@ #include "entry.h" -#include - namespace Inkscape { namespace UI { namespace Widget { diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h index de5cceadd..53b848fc9 100644 --- a/src/ui/widget/entry.h +++ b/src/ui/widget/entry.h @@ -11,10 +11,10 @@ #define INKSCAPE_UI_WIDGET_ENTRY__H #include "labelled.h" +#include -namespace Gtk { -class Entry; -} +#include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/frame.h b/src/ui/widget/frame.h index a04666651..cf736d8a1 100644 --- a/src/ui/widget/frame.h +++ b/src/ui/widget/frame.h @@ -10,9 +10,11 @@ #ifndef INKSCAPE_UI_WIDGET_FRAME_H #define INKSCAPE_UI_WIDGET_FRAME_H -#include -#include -#include +#include + +namespace Gtk { +class Frame; +} namespace Inkscape { namespace UI { diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index fa35b815e..2a7843a51 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -32,7 +32,7 @@ #include -struct SPUnit; +class SPUnit; class SPDocument; namespace Gtk { diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index 9b78cb17f..6d5222429 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -40,7 +40,7 @@ #include "helper/units.h" class SPDesktop; -struct SPUnit; +class SPUnit; namespace Inkscape { namespace UI { diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index d7bab3732..2b9c32b2e 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -26,7 +26,7 @@ #include "button.h" #include "preferences.h" -struct SPUnit; +class SPUnit; struct SPStyle; class SPCSSAttr; diff --git a/src/undo-stack-observer.h b/src/undo-stack-observer.h index 1057ace8f..f4d67e841 100644 --- a/src/undo-stack-observer.h +++ b/src/undo-stack-observer.h @@ -14,7 +14,7 @@ namespace Inkscape { -struct Event; +class Event; /** * Observes changes made to the undo and redo stacks. diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index 6719691d1..1ed6c6c46 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -33,7 +33,7 @@ class SPDocument; class SPObject; class SPGradient; -struct SPStop; +class SPStop; struct SPGradientVectorSelector { GtkVBox vbox; diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index a66758434..d3b3f4116 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -22,7 +22,7 @@ class SPGradient; class SPDesktop; -struct SPPattern; +class SPPattern; struct SPStyle; #define SP_TYPE_PAINT_SELECTOR (sp_paint_selector_get_type ()) diff --git a/src/widgets/swatch-selector.h b/src/widgets/swatch-selector.h index 4b7aa483f..b97aac4f1 100644 --- a/src/widgets/swatch-selector.h +++ b/src/widgets/swatch-selector.h @@ -1,12 +1,14 @@ #ifndef SEEN_SP_SWATCH_SELECTOR_H #define SEEN_SP_SWATCH_SELECTOR_H + + #include class SPDocument; class SPGradient; -struct SPColorSelector; -struct SPGradientSelector; +class SPColorSelector; +class SPGradientSelector; namespace Inkscape { diff --git a/src/xml/composite-node-observer.h b/src/xml/composite-node-observer.h index 3e4b1673a..96825d607 100644 --- a/src/xml/composite-node-observer.h +++ b/src/xml/composite-node-observer.h @@ -23,7 +23,7 @@ namespace Inkscape { namespace XML { -struct NodeEventVector; +class NodeEventVector; /** * @brief An observer that relays notifications to multiple other observers diff --git a/src/zoom-context.h b/src/zoom-context.h index c09b5a1b3..e36dc3fbe 100644 --- a/src/zoom-context.h +++ b/src/zoom-context.h @@ -19,6 +19,9 @@ #define SP_ZOOM_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_ZOOM_CONTEXT, SPZoomContext)) #define SP_IS_ZOOM_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_ZOOM_CONTEXT)) +class SPZoomContext; +class SPZoomContextClass; + struct SPZoomContext { SPEventContext event_context; SPCanvasItem *grabbed; -- cgit v1.2.3 From a5fc5840c370d58f395b7b256a11fd11ef3a9a54 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 18 Mar 2013 02:53:59 +0100 Subject: working whith widgets (bzr r11950.1.57) --- src/live_effects/lpe-bspline.cpp | 94 +++++++++++++++++++++++++++++----------- src/live_effects/lpe-bspline.h | 47 +++++++++++++++----- src/ui/tool/node.cpp | 5 ++- src/ui/tool/node.h | 3 ++ src/ui/tool/path-manipulator.cpp | 16 +++++-- src/ui/tool/path-manipulator.h | 3 ++ 6 files changed, 127 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index b1e40655d..5d50eae87 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -31,7 +31,6 @@ #include "helper/geom-curves.h" #include "ui/widget/scalar.h" - // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -42,15 +41,20 @@ using Inkscape::DocumentUndo; namespace Inkscape { namespace LivePathEffect { + LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject) { - Glib::ustring title = Glib::ustring(_("Ignore cusp nodes")); - Glib::ustring tip = Glib::ustring(_("Ignore cusp nodes")); - LPEBSpline::Gtk::Widget *noCusp = new LPEBSpline::newCheckButton(title,tip); - title = Glib::ustring(_("Unify weights:")); - tip = Glib::ustring(_("Percent of the with for all poinrs")); - LPEBSpline::Gtk::Widget *scal = new LPEBSpline::newScalar(title,tip); + Glib::ustring title = Glib::ustring(_("Unify weights:")); + Glib::ustring tip = Glib::ustring(_("Percent of the with for all poinrs")); + registerScal(title,tip); + title = Glib::ustring(_("Ignore cusp nodes")); + registerNoCusp(title); + title = Glib::ustring(_("Reset")); + registerReset(title); + title = Glib::ustring(_("CTRL handle steps:")); + tip = Glib::ustring(_("CTRL handle steps")); + registerStepsHandles(title,tip); } LPEBSpline::~LPEBSpline() @@ -243,39 +247,79 @@ LPEBSpline::doEffect(SPCurve * curve) Gtk::Widget * LPEBSpline::newWidget() { - Gtk::VBox * vbox = dynamic_cast(Effect::newWidget()); + Gtk::VBox * vbox = Gtk::manage( dynamic_cast(LPEBSpline::newWidget())); vbox->set_border_width(5); - vbox->pack_start(&noCusp,true,true,(guint)2); - vbox->pack_start(&scal, true, true,2); + vbox->pack_start(*noCusp,true,true,2); + vbox->pack_start(*scal, true, true,2); + vbox->pack_start(*reset, true, true,2); + vbox->pack_start(*stepsHandles, true, true,2); return dynamic_cast (vbox); } Gtk::Widget * -LPEBSpline::newScalar(Glib::ustring title, Glib::ustring tip) +LPEBSpline::newScal(Glib::ustring title, Glib::ustring tip) +{ + Inkscape::UI::Widget::Scalar *scalIn = Gtk::manage( new Inkscape::UI::Widget::Scalar(title, tip)); + scalIn->setRange(0, 100.); + scalIn->setDigits(2); + scalIn->setIncrements(1., 5.); + scalIn->setValue(33.33); + scalIn->setProgrammatically = false; + scalIn->addSlider(); + scalIn->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::updateAllHandles)); + return dynamic_cast(scalIn); +} + +Gtk::Widget * +LPEBSpline::newNoCusp(Glib::ustring title) +{ + Gtk::CheckButton * noCuspIn = Gtk::manage( new Gtk::CheckButton(title,true)); + noCuspIn->set_alignment(0.0, 0.5); + return dynamic_cast(noCuspIn); +} + +Gtk::Widget * +LPEBSpline::newReset(Glib::ustring title) { - scal = Gtk::manage( new Inkscape::UI::Widget::Scalar(title, tip)); - scal->setValue(33.); - scal->setDigits(2); - scal->setIncrements(1., 5.); - scal->setRange(0, 100.); - scal->setProgrammatically = false; - scal->addSlider(); - scal->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::updateAllHandles)); - return dynamic_cast(scal); + Gtk::Button * resetIn = Gtk::manage(new Gtk::Button(title)); + resetIn->signal_clicked().connect(sigc::mem_fun (*this,&LPEBSpline::resetHandles)); + resetIn->set_alignment(0.0, 0.5); + return dynamic_cast(resetIn); } Gtk::Widget * -LPEBSpline::newCheckButton(Glib::ustring title, Glib::ustring tip) +LPEBSpline::newStepsHandles(Glib::ustring title, Glib::ustring tip) { - noCusp = Gtk::manage( new Gtk::CheckButton(title,tip)); - return dynamic_cast(noCusp); + Inkscape::UI::Widget::Scalar *stepsIn = Gtk::manage( new Inkscape::UI::Widget::Scalar(title, tip)); + stepsIn->setRange(1, 10); + stepsIn->setDigits(0); + stepsIn->setIncrements(1.,1.); + stepsIn->setValue(2); + stepsIn->setProgrammatically = false; + stepsIn->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::updateSteps)); + return dynamic_cast(stepsIn); +} + +void +LPEBSpline::resetHandles(){ + Inkscape::UI::Widget::Scalar * scalIn = dynamic_cast(scal); + scalIn->setValue(33.33); + updateAllHandles(); +} + +void +LPEBSpline::updateSteps(){ + Inkscape::UI::Widget::Scalar * stepsIn = dynamic_cast(stepsHandles); + updateStepsValue(stepsIn->getValue()); } void LPEBSpline::updateAllHandles() { - double value = scal->setValue(33.); - bool noCusp = false; + Inkscape::UI::Widget::Scalar * scalIn = dynamic_cast(scal); + double value = scalIn->getValue()/100; + Gtk::CheckButton * noCuspIn = dynamic_cast(noCusp); + bool noCusp = noCuspIn->get_active(); SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop? Inkscape::Selection *selection = sp_desktop_selection(desktop); for (GSList *items = (GSList *) selection->itemList(); diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index dbe0789f2..3915a476c 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -8,16 +8,12 @@ */ #include "live_effects/effect.h" -#include "live_effects/parameter/parameter.h" -#include "ui/widget/scalar.h" -#include namespace Inkscape { namespace LivePathEffect { - - class LPEBSpline : public Effect { + public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); @@ -28,23 +24,50 @@ public: virtual void doEffect(SPCurve * curve); - virtual void updateAllHandles(); + virtual void doBSplineFromWidget(SPCurve * curve, double value, bool noCusp); - virtual void newScalar(Glib::ustring title, Glib::ustring tip); + virtual Gtk::Widget * newWidget(); - virtual void newCheckButton(Glib::ustring title, Glib::ustring tip); + int steps; +protected: - virtual void doBSplineFromWidget(SPCurve * curve, double value, bool noCusp); + Gtk::Widget* scal; - virtual Gtk::Widget * newWidget(); + Gtk::Widget* noCusp; + + Gtk::Widget* reset; + + Gtk::Widget* stepsHandles; + + virtual void registerScal(Glib::ustring title, Glib::ustring tip){scal = LPEBSpline::newScal(title,tip);}; + + virtual void registerNoCusp(Glib::ustring title){noCusp = LPEBSpline::newNoCusp(title);}; + + virtual void registerReset(Glib::ustring title){reset = LPEBSpline::newReset(title);}; + + virtual void registerStepsHandles(Glib::ustring title, Glib::ustring tip){stepsHandles = LPEBSpline::newStepsHandles(title,tip);}; + + virtual Gtk::Widget* newScal(Glib::ustring title, Glib::ustring tip); + + virtual Gtk::Widget* newNoCusp(Glib::ustring title); + + virtual Gtk::Widget* newReset(Glib::ustring title); + + virtual Gtk::Widget* newStepsHandles(Glib::ustring title, Glib::ustring tip); + + virtual void updateAllHandles(); + + virtual void resetHandles(); + + virtual void updateSteps(); + virtual void updateStepsValue(int stepsValue){steps=stepsValue;}; private: - Gtk::Widget * scal; - Gtk::Widget * noCusp; LPEBSpline(const LPEBSpline&); LPEBSpline& operator=(const LPEBSpline&); + }; }; //namespace LivePathEffect diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index bee2cc477..b628d3500 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,6 +113,9 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _degenerate(true) { setVisible(false); + //BSpline + setControlBsplineSteps( _pm().getControlBsplineSteps()); + //BSpline End; } Handle::~Handle() @@ -391,7 +394,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) double pos = 0; h = this; setPosition(new_pos); - pos = ceilf(_pm().BSplineHandlePosition(h)*10)/10; + pos = ceilf(_pm().BSplineHandlePosition(h)*controlBsplineSteps)/controlBsplineSteps; new_pos=_pm().BSplineHandleReposition(h,pos); } //BSpline End diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index e74698b1a..953ac0061 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -109,12 +109,15 @@ protected: virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); //Bspline virtual void handle_2button_press(); + virtual void setControlBsplineSteps(int controlBsplineStepsValue){controlBsplineSteps = controlBsplineStepsValue;}; + int controlBsplineSteps; //BSpline End virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); virtual void ungrabbed(GdkEventButton *event); virtual bool clicked(GdkEventButton *event); + virtual Glib::ustring _getTip(unsigned state) const; virtual Glib::ustring _getDragTip(GdkEventMotion *event) const; virtual bool _hasDragTips() const { return true; } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 0a100ecfb..b46e85622 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -36,6 +36,7 @@ #include "live_effects/lpeobject-reference.h" #include "live_effects/parameter/path.h" #include "sp-path.h" +#include "sp-lpe-item.h" #include "helper/geom.h" #include "preferences.h" #include "style.h" @@ -1174,9 +1175,8 @@ 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( effect_list.front()->lpeobject->get_lpe()); + if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ + lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); }else{ lpe_bsp = NULL; } @@ -1186,6 +1186,16 @@ bool PathManipulator::isBSpline(){ return false; } +int PathManipulator::getControlBsplineSteps(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ + lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); + if(lpe_bsp){ + return lpe_bsp->steps; + } + } + return 2; +} double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index a235a3b05..04148592b 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -89,6 +89,9 @@ public: void updateHandles(); void setControlsTransform(Geom::Affine const &); void hideDragPoint(); + //BSpline + int getControlBsplineSteps(); + //BSpline End MultiPathManipulator &mpm() { return _multi_path_manipulator; } NodeList::iterator subdivideSegment(NodeList::iterator after, double t); -- cgit v1.2.3 From 4e41340374ba833e748ffbbc610a28c7c3559557 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 19 Mar 2013 04:35:35 +0100 Subject: Working width widgets (bzr r11950.1.58) --- src/live_effects/lpe-bspline.cpp | 236 +++++++++++++++++++-------------------- src/live_effects/lpe-bspline.h | 49 ++------ src/pen-context.cpp | 15 +-- src/ui/tool/node.cpp | 7 +- src/ui/tool/node.h | 5 +- src/ui/tool/path-manipulator.cpp | 2 +- 6 files changed, 132 insertions(+), 182 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 5d50eae87..e6461e94c 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -13,23 +13,20 @@ #include "style.h" #include "document.h" #include "document-undo.h" -#include "selection.h" -#include "desktop.h" -#include "verbs.h" #include "desktop-handles.h" -#include -#include -#include -#include +#include "verbs.h" #include "live_effects/lpe-bspline.h" -#include "live_effects/lpeobject.h" -#include "live_effects/lpeobject-reference.h" +#include +#include #include "sp-lpe-item.h" +#include "live_effects/lpeobject.h" +#include "live_effects/parameter/parameter.h" #include "display/sp-canvas.h" #include #include <2geom/bezier-curve.h> #include "helper/geom-curves.h" #include "ui/widget/scalar.h" +#include "selection.h" // For handling un-continuous paths: #include "message-stack.h" @@ -38,23 +35,29 @@ using Inkscape::DocumentUndo; + namespace Inkscape { namespace LivePathEffect { + LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : - Effect(lpeobject) + Effect(lpeobject), + // initialise your parameters here: + //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, Geom::Point(100,100)), + ignoreCusp(_("Ignore cusp nodes:"), _("Change ignoring cusp nodes"), "ignoreCusp", &wr, this, true), + weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, 33.33), + steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2) { - Glib::ustring title = Glib::ustring(_("Unify weights:")); - Glib::ustring tip = Glib::ustring(_("Percent of the with for all poinrs")); - registerScal(title,tip); - title = Glib::ustring(_("Ignore cusp nodes")); - registerNoCusp(title); - title = Glib::ustring(_("Reset")); - registerReset(title); - title = Glib::ustring(_("CTRL handle steps:")); - tip = Glib::ustring(_("CTRL handle steps")); - registerStepsHandles(title,tip); + registerParameter( dynamic_cast(&ignoreCusp) ); + registerParameter( dynamic_cast(&weight) ); + registerParameter( dynamic_cast(&steps) ); + weight.param_set_range(0.00, 100); + weight.param_set_increments(1., 1.); + weight.param_set_digits(2); + steps.param_set_range(1, 10); + steps.param_set_increments(1, 1); + steps.param_set_digits(0); } LPEBSpline::~LPEBSpline() @@ -247,108 +250,81 @@ LPEBSpline::doEffect(SPCurve * curve) Gtk::Widget * LPEBSpline::newWidget() { - Gtk::VBox * vbox = Gtk::manage( dynamic_cast(LPEBSpline::newWidget())); + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + vbox->set_border_width(5); - vbox->pack_start(*noCusp,true,true,2); - vbox->pack_start(*scal, true, true,2); - vbox->pack_start(*reset, true, true,2); - vbox->pack_start(*stepsHandles, true, true,2); - return dynamic_cast (vbox); -} -Gtk::Widget * -LPEBSpline::newScal(Glib::ustring title, Glib::ustring tip) -{ - Inkscape::UI::Widget::Scalar *scalIn = Gtk::manage( new Inkscape::UI::Widget::Scalar(title, tip)); - scalIn->setRange(0, 100.); - scalIn->setDigits(2); - scalIn->setIncrements(1., 5.); - scalIn->setValue(33.33); - scalIn->setProgrammatically = false; - scalIn->addSlider(); - scalIn->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::updateAllHandles)); - return dynamic_cast(scalIn); -} + Gtk::Button* defaultWeight = Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); + defaultWeight->set_alignment(0.0, 0.5); + Gtk::Widget* defaultWeightWidget = dynamic_cast(defaultWeight); + defaultWeight->signal_clicked().connect(sigc::mem_fun (*this,&LPEBSpline::toDefaultWeight)); + vbox->pack_start(*defaultWeightWidget, true, true,2); -Gtk::Widget * -LPEBSpline::newNoCusp(Glib::ustring title) -{ - Gtk::CheckButton * noCuspIn = Gtk::manage( new Gtk::CheckButton(title,true)); - noCuspIn->set_alignment(0.0, 0.5); - return dynamic_cast(noCuspIn); -} - -Gtk::Widget * -LPEBSpline::newReset(Glib::ustring title) -{ - Gtk::Button * resetIn = Gtk::manage(new Gtk::Button(title)); - resetIn->signal_clicked().connect(sigc::mem_fun (*this,&LPEBSpline::resetHandles)); - resetIn->set_alignment(0.0, 0.5); - return dynamic_cast(resetIn); -} + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = param->param_newWidget(); + if(param->param_key == "weight"){ + Inkscape::UI::Widget::Scalar * widgRegistered = dynamic_cast(widg); + widgRegistered->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::toWeight)); + } + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } -Gtk::Widget * -LPEBSpline::newStepsHandles(Glib::ustring title, Glib::ustring tip) -{ - Inkscape::UI::Widget::Scalar *stepsIn = Gtk::manage( new Inkscape::UI::Widget::Scalar(title, tip)); - stepsIn->setRange(1, 10); - stepsIn->setDigits(0); - stepsIn->setIncrements(1.,1.); - stepsIn->setValue(2); - stepsIn->setProgrammatically = false; - stepsIn->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::updateSteps)); - return dynamic_cast(stepsIn); + ++it; + } + return dynamic_cast(vbox); } -void -LPEBSpline::resetHandles(){ - Inkscape::UI::Widget::Scalar * scalIn = dynamic_cast(scal); - scalIn->setValue(33.33); - updateAllHandles(); +void +LPEBSpline::toDefaultWeight(){ +double weightValue = 0.3333; +changeWeight(weightValue); +weight.param_set_value(33.33); +gtk_widget_draw(GTK_WIDGET(LPEBSpline::newWidget()), NULL); } -void -LPEBSpline::updateSteps(){ - Inkscape::UI::Widget::Scalar * stepsIn = dynamic_cast(stepsHandles); - updateStepsValue(stepsIn->getValue()); +void +LPEBSpline::toWeight(){ +double weightValue = weight/100; +changeWeight(weightValue); } void -LPEBSpline::updateAllHandles() +LPEBSpline::changeWeight(double weightValue) { - Inkscape::UI::Widget::Scalar * scalIn = dynamic_cast(scal); - double value = scalIn->getValue()/100; - Gtk::CheckButton * noCuspIn = dynamic_cast(noCusp); - bool noCusp = noCuspIn->get_active(); - SPDesktop *desktop = inkscape_active_desktop(); // TODO: Is there a better method to find the item's desktop? + SPDesktop *desktop = inkscape_active_desktop(); Inkscape::Selection *selection = sp_desktop_selection(desktop); - for (GSList *items = (GSList *) selection->itemList(); - items != NULL; - items = items->next) { - if (SP_IS_LPE_ITEM((SPLPEItem *)items->data) && sp_lpe_item_has_path_effect((SPLPEItem *)items->data)){ - LivePathEffect::LPEBSpline *lpe_bsp = NULL; - lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM((SPLPEItem *)items->data),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); - if(lpe_bsp){ - SPItem *item = (SPItem *) items->data; - SPPath *path = SP_PATH(item); - SPCurve *curve = path->get_curve_for_edit(); - LPEBSpline::doBSplineFromWidget(curve,value,noCusp); - gchar *str = sp_svg_write_path(curve->get_pathvector()); - path->getRepr()->setAttribute("inkscape:original-d", str); - g_free(str); - curve->unref(); - SPDesktop *desktop = inkscape_active_desktop(); - desktop->clearWaitingCursor(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, - _("Modified the weight of the BSpline")); - } - } - } + GSList *items = (GSList *) selection->itemList(); + SPItem *item = (SPItem *)g_slist_nth(items,0)->data; + SPPath *path = SP_PATH(item); + SPCurve *curve = path->get_curve_for_edit(); + LPEBSpline::doBSplineFromWidget(curve,weightValue,ignoreCusp); + gchar *str = sp_svg_write_path(curve->get_pathvector()); + path->getRepr()->setAttribute("inkscape:original-d", str); + g_free(str); + curve->unref(); + desktop->clearWaitingCursor(); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, + _("Modified the weight of the BSpline")); } void -LPEBSpline::doBSplineFromWidget(SPCurve * curve, double value , bool noCusp) +LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignoreCusp) { + using Geom::X; + using Geom::Y; if(curve->get_segment_count() < 2) return; // Make copy of old path as it is changed during processing @@ -404,19 +380,25 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double value , bool noCusp) cubic = dynamic_cast(&*curve_it1); pointAt0 = in->first_segment()->initialPoint(); SBasisIn = in->first_segment()->toSBasis(); - if(cubic){ - if(!noCusp || (*cubic)[1] != in->first_segment()->initialPoint()) - pointAt1 = SBasisIn.valueAt(value); - else + if(cubic){ + if(!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())){ + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + }else{ pointAt1 = in->first_segment()->initialPoint(); - if(!noCusp || (*cubic)[2] != in->first_segment()->finalPoint()) - pointAt2 = SBasisIn.valueAt(1-value); - else + } + if(!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())){ + pointAt2 = SBasisIn.valueAt(1-weightValue); + pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + }else{ pointAt2 = in->first_segment()->finalPoint(); + } }else{ - if(!noCusp){ - pointAt1 = SBasisIn.valueAt(value); - pointAt2 = SBasisIn.valueAt(1-value); + if(!ignoreCusp){ + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + pointAt2 = SBasisIn.valueAt(1-weightValue); + pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ pointAt1 = in->first_segment()->initialPoint(); pointAt2 = in->first_segment()->finalPoint(); @@ -433,18 +415,24 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double value , bool noCusp) SBasisOut = out->first_segment()->toSBasis(); cubic = dynamic_cast(&*curve_it2); if(cubic){ - if(!noCusp || (*cubic)[1] != out->first_segment()->initialPoint()) - nextPointAt1 = SBasisOut.valueAt(value); - else + if(!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint())){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + }else{ nextPointAt1 = out->first_segment()->initialPoint(); - if(!noCusp || (*cubic)[2] != out->first_segment()->finalPoint()) - nextPointAt2 = SBasisOut.valueAt(1-value); - else + } + if(!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint())){ + nextPointAt2 = SBasisOut.valueAt(1-weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + }else{ nextPointAt2 = out->first_segment()->finalPoint(); + } }else{ - if(!noCusp){ - nextPointAt1 = SBasisOut.valueAt(value); - nextPointAt2 = SBasisOut.valueAt(1-value); + if(!ignoreCusp){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + nextPointAt2 = SBasisOut.valueAt(1-weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ nextPointAt1 = out->first_segment()->initialPoint(); nextPointAt2 = out->first_segment()->finalPoint(); diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 3915a476c..10d157ac1 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -8,12 +8,20 @@ */ #include "live_effects/effect.h" +#include "live_effects/parameter/bool.h" namespace Inkscape { namespace LivePathEffect { class LPEBSpline : public Effect { +private: + BoolParam ignoreCusp; + ScalarParam weight; + + LPEBSpline(const LPEBSpline&); + LPEBSpline& operator=(const LPEBSpline&); + public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); @@ -28,49 +36,16 @@ public: virtual Gtk::Widget * newWidget(); - int steps; - -protected: - - Gtk::Widget* scal; - - Gtk::Widget* noCusp; - - Gtk::Widget* reset; - - Gtk::Widget* stepsHandles; - - virtual void registerScal(Glib::ustring title, Glib::ustring tip){scal = LPEBSpline::newScal(title,tip);}; + virtual void changeWeight(double weightValue); - virtual void registerNoCusp(Glib::ustring title){noCusp = LPEBSpline::newNoCusp(title);}; + virtual void toDefaultWeight(); - virtual void registerReset(Glib::ustring title){reset = LPEBSpline::newReset(title);}; + virtual void toWeight(); - virtual void registerStepsHandles(Glib::ustring title, Glib::ustring tip){stepsHandles = LPEBSpline::newStepsHandles(title,tip);}; + ScalarParam steps; - virtual Gtk::Widget* newScal(Glib::ustring title, Glib::ustring tip); - - virtual Gtk::Widget* newNoCusp(Glib::ustring title); - - virtual Gtk::Widget* newReset(Glib::ustring title); - - virtual Gtk::Widget* newStepsHandles(Glib::ustring title, Glib::ustring tip); - - virtual void updateAllHandles(); - - virtual void resetHandles(); - - virtual void updateSteps(); - - virtual void updateStepsValue(int stepsValue){steps=stepsValue;}; - -private: - LPEBSpline(const LPEBSpline&); - LPEBSpline& operator=(const LPEBSpline&); - }; }; //namespace LivePathEffect }; //namespace Inkscape - #endif diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 79e4cbabf..6f61ceb99 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -19,7 +19,6 @@ #include #include #include - #include "pen-context.h" #include "sp-namedview.h" #include "sp-metrics.h" @@ -69,7 +68,6 @@ #define INKSCAPE_LPE_BSPLINE_C #include "live_effects/lpe-bspline.h" #include <2geom/nearest-point.h> - //BSpline End using Inkscape::ControlManager; @@ -1580,8 +1578,6 @@ static void bspline_spiro_start_anchor_on(SPPenContext *const pc) if (pc->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - pc->sa->curve->reset(); - pc->sa->curve = tmpCurve; } static void bspline_spiro_start_anchor_off(SPPenContext *const pc) @@ -1619,12 +1615,7 @@ static void bspline_spiro_motion(SPPenContext *const pc, bool shift){ using Geom::X; using Geom::Y; SPCurve *tmpCurve = new SPCurve(); - if(shift) - pc->p[2] = pc->p[3]; - else - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625); - + pc->p[2] = pc->p[3]; if(pc->green_curve->is_empty() && !pc->sa){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); }else if(!pc->green_curve->is_empty()){ @@ -1633,6 +1624,7 @@ static void bspline_spiro_motion(SPPenContext *const pc, bool shift){ tmpCurve = pc->sa->curve->copy(); if(pc->sa->start) tmpCurve = tmpCurve->create_reverse(); + } if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){ Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); @@ -1649,7 +1641,8 @@ static void bspline_spiro_motion(SPPenContext *const pc, bool shift){ SBasisWPower = WPower->first_segment()->toSBasis(); WPower->reset(); pc->p[1] = SBasisWPower.valueAt(WP); - pc->p[1] = Geom::Point(pc->p[1][X] + 0.0625,pc->p[1][Y] + 0.0625); + if(!Geom::are_near(pc->p[1],pc->p[0])) + pc->p[1] = Geom::Point(pc->p[1][X] + 0.0625,pc->p[1][Y] + 0.0625); }else{ pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] ); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index b628d3500..819f5db54 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -110,12 +110,9 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _handle_colors, data.handle_group), _parent(parent), _handle_line(ControlManager::getManager().createControlLine(data.handle_line_group)), - _degenerate(true) + _degenerate(true),controlBsplineSteps(2) { setVisible(false); - //BSpline - setControlBsplineSteps( _pm().getControlBsplineSteps()); - //BSpline End; } Handle::~Handle() @@ -394,7 +391,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) double pos = 0; h = this; setPosition(new_pos); - pos = ceilf(_pm().BSplineHandlePosition(h)*controlBsplineSteps)/controlBsplineSteps; + pos = ceilf(_pm().BSplineHandlePosition(h)*_pm().getControlBsplineSteps())/_pm().getControlBsplineSteps(); new_pos=_pm().BSplineHandleReposition(h,pos); } //BSpline End diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 953ac0061..7152f37fd 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -89,7 +89,6 @@ public: virtual void setVisible(bool); virtual void move(Geom::Point const &p); - virtual void setPosition(Geom::Point const &p); inline void setRelativePos(Geom::Point const &p); void setLength(double len); @@ -109,8 +108,6 @@ protected: virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event); //Bspline virtual void handle_2button_press(); - virtual void setControlBsplineSteps(int controlBsplineStepsValue){controlBsplineSteps = controlBsplineStepsValue;}; - int controlBsplineSteps; //BSpline End virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); @@ -129,7 +126,7 @@ private: // so a naked pointer is OK and allows setting it during Node's construction SPCtrlLine *_handle_line; bool _degenerate; // True if the handle is retracted, i.e. has zero length. This is used often internally so it makes sense to cache this - + int controlBsplineSteps; /** * Control point of a cubic Bezier curve in a path. * diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index b46e85622..853d9336a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1191,7 +1191,7 @@ int PathManipulator::getControlBsplineSteps(){ if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); if(lpe_bsp){ - return lpe_bsp->steps; + return lpe_bsp->steps+1; } } return 2; -- cgit v1.2.3 From fc95705f9d5761fe111a445c51afc505d08738a7 Mon Sep 17 00:00:00 2001 From: jtx Date: Tue, 19 Mar 2013 17:56:26 +0100 Subject: Fixing regression (bzr r11950.1.61) --- src/common-context.h | 4 --- src/composite-undo-stack-observer.h | 2 +- src/desktop.h | 2 +- src/display/cairo-utils.cpp | 10 +++---- src/display/canvas-axonomgrid.h | 2 +- src/display/guideline.h | 2 +- src/display/nr-filter-diffuselighting.h | 8 +++--- src/display/nr-filter-flood.h | 2 +- src/display/nr-filter-specularlighting.h | 8 +++--- src/display/nr-style.h | 3 +-- src/display/nr-svgfonts.cpp | 3 --- src/display/nr-svgfonts.h | 4 +-- src/display/sp-ctrlcurve.h | 2 +- src/document-subset.h | 2 +- src/dom/events.h | 1 - src/dropper-context.cpp | 1 - src/dropper-context.h | 3 --- src/dyna-draw-context.h | 3 --- src/eraser-context.h | 3 --- src/event-context.h | 2 +- src/extension/internal/cairo-render-context.h | 6 ++--- src/extension/internal/cairo-renderer.h | 2 +- src/extension/internal/pdfinput/pdf-input.cpp | 1 + src/extension/internal/pdfinput/svg-builder.h | 6 ++--- src/file.cpp | 3 --- src/file.h | 2 +- src/filter-chemistry.h | 2 +- src/filters/blend.h | 2 -- src/filters/colormatrix.h | 2 -- src/filters/componenttransfer-funcnode.h | 6 +---- src/filters/componenttransfer.h | 2 -- src/filters/composite.h | 2 -- src/filters/convolvematrix.h | 2 -- src/filters/diffuselighting.h | 4 +-- src/filters/displacementmap.h | 2 -- src/filters/distantlight.h | 4 --- src/filters/flood.h | 2 -- src/filters/gaussian-blur.h | 4 +-- src/filters/image.h | 2 -- src/filters/merge.h | 2 -- src/filters/mergenode.h | 3 --- src/filters/morphology.h | 2 -- src/filters/offset.h | 2 -- src/filters/pointlight.h | 6 ----- src/filters/specularlighting.h | 4 +-- src/filters/spotlight.h | 6 ----- src/filters/tile.h | 2 -- src/filters/turbulence.h | 1 - src/flood-context.h | 3 --- src/gradient-context.h | 3 --- src/gradient-drag.h | 6 ++--- src/inkscape-private.h | 2 +- src/inkscape.cpp | 2 +- src/libgdl/Makefile_insert | 1 - src/libnrtype/Layout-TNG-Output.cpp | 1 - src/libnrtype/Layout-TNG.h | 2 +- src/libnrtype/font-lister.cpp | 1 - src/livarot/Path.h | 10 +++---- src/livarot/Shape.h | 6 ++--- src/live_effects/lpe-recursiveskeleton.cpp | 3 ++- src/live_effects/parameter/parameter.cpp | 3 ++- src/lpe-tool-context.h | 3 --- src/marker.cpp | 12 ++++----- src/marker.h | 4 +-- src/measure-context.h | 3 --- src/menus-skeleton.h | 2 -- src/mesh-context.h | 3 --- src/pixmaps/cursor-dropper.xpm | 38 -------------------------- src/rect-context.h | 3 --- src/select-context.h | 2 -- src/selection.cpp | 1 - src/seltrans-handles.h | 2 +- src/seltrans.h | 2 +- src/snap.cpp | 1 - src/sp-clippath.h | 2 +- src/sp-desc.h | 3 --- src/sp-filter-primitive.h | 2 -- src/sp-filter.h | 2 +- src/sp-flowregion.cpp | 39 +++++++++++++-------------- src/sp-font-face.cpp | 3 --- src/sp-font-face.h | 2 -- src/sp-font.cpp | 3 --- src/sp-glyph-kerning.cpp | 2 -- src/sp-glyph-kerning.h | 2 -- src/sp-glyph.cpp | 2 -- src/sp-glyph.h | 2 -- src/sp-gradient.h | 4 +-- src/sp-image.h | 3 --- src/sp-item.h | 4 +-- src/sp-linear-gradient-fns.h | 2 +- src/sp-mask.h | 4 +-- src/sp-metadata.cpp | 10 ++++--- src/sp-metadata.h | 3 --- src/sp-missing-glyph.cpp | 3 --- src/sp-missing-glyph.h | 2 -- src/sp-object-group.cpp | 4 +-- src/sp-object-repr.cpp | 14 ++++------ src/sp-offset.h | 2 -- src/sp-pattern.h | 3 +-- src/sp-polyline.cpp | 11 ++++---- src/sp-radial-gradient-fns.h | 2 +- src/sp-rect.h | 3 --- src/sp-spiral.h | 3 --- src/sp-star.h | 5 ---- src/sp-stop.h | 1 - src/sp-switch.h | 2 +- src/sp-symbol.cpp | 33 ++++++++++++++--------- src/sp-symbol.h | 3 --- src/sp-title.h | 3 --- src/sp-tref.h | 3 --- src/sp-use.h | 2 -- src/spiral-context.h | 3 --- src/splivarot.cpp | 36 +++---------------------- src/spray-context.h | 3 --- src/star-context.h | 3 --- src/style.cpp | 2 +- src/style.h | 4 +-- src/svg-view-widget.h | 2 -- src/svg-view.h | 2 +- src/svg/svg-color.h | 2 +- src/text-context.h | 2 -- src/text-editing.cpp | 2 +- src/trace/siox.cpp | 4 +-- src/tweak-context.h | 3 --- src/ui/dialog/dialog-manager.cpp | 7 ----- src/ui/dialog/document-properties.cpp | 2 -- src/ui/dialog/export.cpp | 26 ++++++++++++++---- src/ui/dialog/export.h | 19 +++++-------- src/ui/dialog/fill-and-stroke.cpp | 15 +++++++++++ src/ui/dialog/find.cpp | 4 +++ src/ui/dialog/find.h | 6 ++++- src/ui/dialog/glyphs.h | 2 +- src/ui/dialog/icon-preview.cpp | 4 +++ src/ui/dialog/input.cpp | 2 ++ src/ui/dialog/layer-properties.h | 6 ++--- src/ui/dialog/object-properties.cpp | 6 +++++ src/ui/dialog/object-properties.h | 10 +++++++ src/ui/dialog/svg-fonts-dialog.cpp | 4 --- src/ui/dialog/svg-fonts-dialog.h | 4 +-- src/ui/dialog/text-edit.cpp | 1 + src/ui/dialog/text-edit.h | 2 +- src/ui/dialog/tracedialog.cpp | 1 + src/ui/dialog/xml-tree.h | 2 +- src/ui/tool/control-point.cpp | 2 +- src/ui/tool/node-tool.h | 3 --- src/ui/tool/path-manipulator.h | 2 +- src/ui/widget/entry.cpp | 2 ++ src/ui/widget/entry.h | 6 ++--- src/ui/widget/frame.h | 8 +++--- src/ui/widget/registered-widget.h | 2 +- src/ui/widget/selected-style.h | 2 +- src/ui/widget/style-swatch.h | 2 +- src/undo-stack-observer.h | 2 +- src/widgets/gradient-vector.h | 2 +- src/widgets/paint-selector.h | 2 +- src/widgets/swatch-selector.h | 6 ++--- src/xml/composite-node-observer.h | 2 +- src/zoom-context.h | 3 --- 158 files changed, 245 insertions(+), 455 deletions(-) delete mode 100644 src/pixmaps/cursor-dropper.xpm (limited to 'src') diff --git a/src/common-context.h b/src/common-context.h index ae0f398b2..8903be391 100644 --- a/src/common-context.h +++ b/src/common-context.h @@ -29,12 +29,8 @@ #define SP_IS_COMMON_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_COMMON_CONTEXT)) #define SP_IS_COMMON_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_COMMON_CONTEXT)) -class SPCommonContext; -class SPCommonContextClass; - #define SAMPLING_SIZE 8 /* fixme: ?? */ - struct SPCommonContext : public SPEventContext { /** accumulated shape which ultimately goes in svg:path */ SPCurve *accumulated; diff --git a/src/composite-undo-stack-observer.h b/src/composite-undo-stack-observer.h index c34ab7234..669c39a86 100644 --- a/src/composite-undo-stack-observer.h +++ b/src/composite-undo-stack-observer.h @@ -18,7 +18,7 @@ namespace Inkscape { -class Event; +struct Event; /** * Aggregates UndoStackObservers for management and triggering in an SPDocument's undo/redo diff --git a/src/desktop.h b/src/desktop.h index d8d4e151d..56de56c65 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -77,7 +77,7 @@ namespace Inkscape { } namespace View { - class EditWidgetInterface; + struct EditWidgetInterface; } } namespace Whiteboard { diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index a55b05fe3..fc56c7b26 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -655,8 +655,8 @@ int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) cairo_surface_flush(surface); int width = cairo_image_surface_get_width(surface); int height = cairo_image_surface_get_height(surface); - int stride = cairo_image_surface_get_stride(surface); - unsigned char *data = cairo_image_surface_get_data(surface); + // int stride = cairo_image_surface_get_stride(surface); + // unsigned char *data = cairo_image_surface_get_data(surface); ink_cairo_surface_filter( surface, surface, SurfaceSrgbToLinear() ); @@ -698,8 +698,8 @@ int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) cairo_surface_flush(surface); int width = cairo_image_surface_get_width(surface); int height = cairo_image_surface_get_height(surface); - int stride = cairo_image_surface_get_stride(surface); - unsigned char *data = cairo_image_surface_get_data(surface); + // int stride = cairo_image_surface_get_stride(surface); + // unsigned char *data = cairo_image_surface_get_data(surface); ink_cairo_surface_filter( surface, surface, SurfaceLinearToSrgb() ); @@ -888,4 +888,4 @@ guint32 argb32_from_rgba(guint32 in) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/display/canvas-axonomgrid.h b/src/display/canvas-axonomgrid.h index 0e24d3f56..f58ea3aca 100644 --- a/src/display/canvas-axonomgrid.h +++ b/src/display/canvas-axonomgrid.h @@ -12,7 +12,7 @@ #include "line-snapper.h" #include "canvas-grid.h" -class SPCanvasBuf; +struct SPCanvasBuf; class SPDesktop; struct SPNamedView; diff --git a/src/display/guideline.h b/src/display/guideline.h index 164244c46..2d9a87d9b 100644 --- a/src/display/guideline.h +++ b/src/display/guideline.h @@ -21,7 +21,7 @@ #define SP_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_GUIDELINE, SPGuideLine)) #define SP_IS_GUIDELINE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_GUIDELINE)) -class SPCtrlPoint; +struct SPCtrlPoint; struct SPGuideLine { SPCanvasItem item; diff --git a/src/display/nr-filter-diffuselighting.h b/src/display/nr-filter-diffuselighting.h index 315bf9f48..15cc8e1ff 100644 --- a/src/display/nr-filter-diffuselighting.h +++ b/src/display/nr-filter-diffuselighting.h @@ -19,10 +19,10 @@ #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" -class SPFeDistantLight; -class SPFePointLight; -class SPFeSpotLight; -class SVGICCColor; +struct SPFeDistantLight; +struct SPFePointLight; +struct SPFeSpotLight; +struct SVGICCColor; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter-flood.h b/src/display/nr-filter-flood.h index 8568502ff..9a968047d 100644 --- a/src/display/nr-filter-flood.h +++ b/src/display/nr-filter-flood.h @@ -14,7 +14,7 @@ #include "display/nr-filter-primitive.h" -class SVGICCColor; +struct SVGICCColor; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter-specularlighting.h b/src/display/nr-filter-specularlighting.h index 4f8c2d112..0d1c0644f 100644 --- a/src/display/nr-filter-specularlighting.h +++ b/src/display/nr-filter-specularlighting.h @@ -17,10 +17,10 @@ #include "display/nr-light-types.h" #include "display/nr-filter-primitive.h" -class SPFeDistantLight; -class SPFePointLight; -class SPFeSpotLight; -class SVGICCColor; +struct SPFeDistantLight; +struct SPFePointLight; +struct SPFeSpotLight; +struct SVGICCColor; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-style.h b/src/display/nr-style.h index 597ae7a2c..80547c43e 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -16,8 +16,7 @@ #include <2geom/rect.h> #include "color.h" -class SPColor; -class SPPaintServer; +struct SPPaintServer; struct SPStyle; namespace Inkscape { diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 0d1b56d54..84b4bd080 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -1,5 +1,4 @@ #include "config.h" -#ifdef ENABLE_SVG_FONTS /* * SVGFonts rendering implementation * @@ -356,8 +355,6 @@ void SvgFont::refresh(){ this->userfont = NULL; } -#endif //#ifdef ENABLE_SVG_FONTS - /* Local Variables: mode:c++ diff --git a/src/display/nr-svgfonts.h b/src/display/nr-svgfonts.h index 6138e2fbb..1101f93f2 100644 --- a/src/display/nr-svgfonts.h +++ b/src/display/nr-svgfonts.h @@ -18,8 +18,8 @@ class SvgFont; struct SPFont; -class SPGlyph; -class SPMissingGlyph; +struct SPGlyph; +struct SPMissingGlyph; struct _GdkEventExpose; typedef _GdkEventExpose GdkEventExpose; diff --git a/src/display/sp-ctrlcurve.h b/src/display/sp-ctrlcurve.h index 15de20161..90936185c 100644 --- a/src/display/sp-ctrlcurve.h +++ b/src/display/sp-ctrlcurve.h @@ -17,7 +17,7 @@ #include "display/sp-ctrlline.h" -struct SPItem; +class SPItem; #define SP_TYPE_CTRLCURVE (SPCtrlCurve::getType()) #define SP_CTRLCURVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLCURVE, SPCtrlCurve)) diff --git a/src/document-subset.h b/src/document-subset.h index 5f87e6429..298b7872d 100644 --- a/src/document-subset.h +++ b/src/document-subset.h @@ -51,7 +51,7 @@ private: void _remove(SPObject *obj, bool subtree); - class Relations; + struct Relations; Relations *_relations; }; diff --git a/src/dom/events.h b/src/dom/events.h index 59d83afcf..e62c5d420 100644 --- a/src/dom/events.h +++ b/src/dom/events.h @@ -66,7 +66,6 @@ typedef dom::NodePtr NodePtr ; //forward declarations -class Event; class EventTarget; class EventListener; class DocumentEvent; diff --git a/src/dropper-context.cpp b/src/dropper-context.cpp index 66dcf4ab9..d41e4059d 100644 --- a/src/dropper-context.cpp +++ b/src/dropper-context.cpp @@ -39,7 +39,6 @@ #include "document.h" #include "document-undo.h" -#include "pixmaps/cursor-dropper.xpm" #include "pixmaps/cursor-dropper-f.xpm" #include "pixmaps/cursor-dropper-s.xpm" diff --git a/src/dropper-context.h b/src/dropper-context.h index 68ae3df07..be4b543ae 100644 --- a/src/dropper-context.h +++ b/src/dropper-context.h @@ -20,9 +20,6 @@ G_BEGIN_DECLS #define SP_DROPPER_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_DROPPER_CONTEXT, SPDropperContext)) #define SP_IS_DROPPER_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_DROPPER_CONTEXT)) -class SPDropperContext; -class SPDropperContextClass; - enum { SP_DROPPER_PICK_VISIBLE, SP_DROPPER_PICK_ACTUAL diff --git a/src/dyna-draw-context.h b/src/dyna-draw-context.h index af63bf653..8509e450b 100644 --- a/src/dyna-draw-context.h +++ b/src/dyna-draw-context.h @@ -27,9 +27,6 @@ #define SP_IS_DYNA_DRAW_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_DYNA_DRAW_CONTEXT)) #define SP_IS_DYNA_DRAW_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_DYNA_DRAW_CONTEXT)) -class SPDynaDrawContext; -class SPDynaDrawContextClass; - #define DDC_MIN_PRESSURE 0.0 #define DDC_MAX_PRESSURE 1.0 #define DDC_DEFAULT_PRESSURE 1.0 diff --git a/src/eraser-context.h b/src/eraser-context.h index 7c147c32f..bc4268aef 100644 --- a/src/eraser-context.h +++ b/src/eraser-context.h @@ -29,9 +29,6 @@ G_BEGIN_DECLS #define SP_IS_ERASER_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_ERASER_CONTEXT)) #define SP_IS_ERASER_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_ERASER_CONTEXT)) -class SPEraserContext; -class SPEraserContextClass; - #define ERC_MIN_PRESSURE 0.0 #define ERC_MAX_PRESSURE 1.0 #define ERC_DEFAULT_PRESSURE 1.0 diff --git a/src/event-context.h b/src/event-context.h index 9936aa668..e97a8ad8f 100644 --- a/src/event-context.h +++ b/src/event-context.h @@ -19,7 +19,7 @@ #include "2geom/forward.h" #include "preferences.h" -struct GrDrag; +class GrDrag; class SPDesktop; class SPItem; class ShapeEditor; diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 94c7bb294..8829940c6 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -29,7 +29,7 @@ #include class SPClipPath; -class SPMask; +struct SPMask; namespace Inkscape { namespace Extension { @@ -37,8 +37,8 @@ namespace Internal { class CairoRenderer; class CairoRenderContext; -class CairoRenderState; -class CairoGlyphInfo; +struct CairoRenderState; +struct CairoGlyphInfo; // Holds info for rendering a glyph struct CairoGlyphInfo { diff --git a/src/extension/internal/cairo-renderer.h b/src/extension/internal/cairo-renderer.h index db3068fed..c1482d82e 100644 --- a/src/extension/internal/cairo-renderer.h +++ b/src/extension/internal/cairo-renderer.h @@ -28,7 +28,7 @@ #include class SPClipPath; -class SPMask; +struct SPMask; namespace Inkscape { namespace Extension { diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index 531cda20a..b04c9782f 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -32,6 +32,7 @@ #endif #include +#include #include #include #include diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h index 46cddd73b..610822959 100644 --- a/src/extension/internal/pdfinput/svg-builder.h +++ b/src/extension/internal/pdfinput/svg-builder.h @@ -31,10 +31,10 @@ namespace Inkscape { #include "CharTypes.h" class GooString; class Function; -struct GfxState; -class GfxColor; +class GfxState; +struct GfxColor; class GfxColorSpace; -class GfxRGB; +struct GfxRGB; class GfxPath; class GfxPattern; class GfxTilingPattern; diff --git a/src/file.cpp b/src/file.cpp index 97087c1a1..5737f0a8a 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1124,9 +1124,6 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, prevent_id_clashes(doc, in_doc); - SPObject *in_defs = in_doc->getDefs(); - Inkscape::XML::Node *last_def = in_defs->getRepr()->lastChild(); - SPCSSAttr *style = sp_css_attr_from_object(doc->getRoot()); // Count the number of top-level items in the imported document. diff --git a/src/file.h b/src/file.h index b8e15bf3e..b173ca58c 100644 --- a/src/file.h +++ b/src/file.h @@ -24,7 +24,7 @@ class SPObject; namespace Inkscape { namespace Extension { - struct Extension; + class Extension; } } diff --git a/src/filter-chemistry.h b/src/filter-chemistry.h index 751885ad2..b00e33bcc 100644 --- a/src/filter-chemistry.h +++ b/src/filter-chemistry.h @@ -20,7 +20,7 @@ class SPDocument; struct SPFilter; -class SPFilterPrimitive; +struct SPFilterPrimitive; class SPItem; class SPObject; diff --git a/src/filters/blend.h b/src/filters/blend.h index e7fc410e7..5d65c92fc 100644 --- a/src/filters/blend.h +++ b/src/filters/blend.h @@ -22,8 +22,6 @@ #define SP_IS_FEBLEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEBLEND)) #define SP_IS_FEBLEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEBLEND)) -class SPFeBlendClass; - struct SPFeBlend : public SPFilterPrimitive { Inkscape::Filters::FilterBlendMode blend_mode; int in2; diff --git a/src/filters/colormatrix.h b/src/filters/colormatrix.h index 8eb750ac1..558f01070 100644 --- a/src/filters/colormatrix.h +++ b/src/filters/colormatrix.h @@ -21,8 +21,6 @@ #define SP_IS_FECOLORMATRIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FECOLORMATRIX)) #define SP_IS_FECOLORMATRIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FECOLORMATRIX)) -class SPFeColorMatrixClass; - struct SPFeColorMatrix : public SPFilterPrimitive { Inkscape::Filters::FilterColorMatrixType type; gdouble value; diff --git a/src/filters/componenttransfer-funcnode.h b/src/filters/componenttransfer-funcnode.h index d81e50577..ae1b2f8bb 100644 --- a/src/filters/componenttransfer-funcnode.h +++ b/src/filters/componenttransfer-funcnode.h @@ -34,11 +34,6 @@ #define SP_IS_FEFUNCNODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEFUNCNODE)) -/* Component Transfer funcNode class */ - -class SPFeFuncNode; -class SPFeFuncNodeClass; - struct SPFeFuncNode : public SPObject { Inkscape::Filters::FilterComponentTransferType type; std::vector tableValues; @@ -49,6 +44,7 @@ struct SPFeFuncNode : public SPObject { double offset; }; +/* Component Transfer funcNode class */ struct SPFeFuncNodeClass { SPObjectClass parent_class; }; diff --git a/src/filters/componenttransfer.h b/src/filters/componenttransfer.h index 2df64009f..deb6fb740 100644 --- a/src/filters/componenttransfer.h +++ b/src/filters/componenttransfer.h @@ -24,8 +24,6 @@ namespace Filters { class FilterComponentTransfer; } } -class SPFeComponentTransferClass; - struct SPFeComponentTransfer : public SPFilterPrimitive { Inkscape::Filters::FilterComponentTransfer *renderer; }; diff --git a/src/filters/composite.h b/src/filters/composite.h index 3eb62716f..4f2d1ff69 100644 --- a/src/filters/composite.h +++ b/src/filters/composite.h @@ -32,8 +32,6 @@ enum FeCompositeOperator { COMPOSITE_ENDOPERATOR }; -class SPFeCompositeClass; - struct SPFeComposite : public SPFilterPrimitive { FeCompositeOperator composite_operator; double k1, k2, k3, k4; diff --git a/src/filters/convolvematrix.h b/src/filters/convolvematrix.h index 4c5261e05..cb2fbfb8d 100644 --- a/src/filters/convolvematrix.h +++ b/src/filters/convolvematrix.h @@ -24,8 +24,6 @@ #define SP_IS_FECONVOLVEMATRIX(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FECONVOLVEMATRIX)) #define SP_IS_FECONVOLVEMATRIX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FECONVOLVEMATRIX)) -class SPFeConvolveMatrixClass; - struct SPFeConvolveMatrix : public SPFilterPrimitive { NumberOptNumber order; std::vector kernelMatrix; diff --git a/src/filters/diffuselighting.h b/src/filters/diffuselighting.h index 99dccb394..1572385b9 100644 --- a/src/filters/diffuselighting.h +++ b/src/filters/diffuselighting.h @@ -21,15 +21,13 @@ #define SP_IS_FEDIFFUSELIGHTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEDIFFUSELIGHTING)) #define SP_IS_FEDIFFUSELIGHTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEDIFFUSELIGHTING)) -class SVGICCColor; +struct SVGICCColor; namespace Inkscape { namespace Filters { class FilterDiffuseLighting; } } -class SPFeDiffuseLightingClass; - struct SPFeDiffuseLighting : public SPFilterPrimitive { gfloat surfaceScale; guint surfaceScale_set : 1; diff --git a/src/filters/displacementmap.h b/src/filters/displacementmap.h index 6232f0937..93dc86d27 100644 --- a/src/filters/displacementmap.h +++ b/src/filters/displacementmap.h @@ -28,8 +28,6 @@ enum FilterDisplacementMapChannelSelector { DISPLACEMENTMAP_CHANNEL_ENDTYPE }; -class SPFeDisplacementMapClass; - struct SPFeDisplacementMap : public SPFilterPrimitive { int in2; double scale; diff --git a/src/filters/distantlight.h b/src/filters/distantlight.h index a68746334..b1febf5d3 100644 --- a/src/filters/distantlight.h +++ b/src/filters/distantlight.h @@ -25,10 +25,6 @@ /* Distant light class */ - -class SPFeDistantLight; -class SPFeDistantLightClass; - struct SPFeDistantLight : public SPObject { /** azimuth attribute */ diff --git a/src/filters/flood.h b/src/filters/flood.h index d60321689..ab9f061d6 100644 --- a/src/filters/flood.h +++ b/src/filters/flood.h @@ -23,8 +23,6 @@ G_BEGIN_DECLS #define SP_IS_FEFLOOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEFLOOD)) #define SP_IS_FEFLOOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEFLOOD)) -class SPFeFloodClass; - struct SPFeFlood : public SPFilterPrimitive { guint32 color; SVGICCColor *icc; diff --git a/src/filters/gaussian-blur.h b/src/filters/gaussian-blur.h index 417f8a6f4..8929627ba 100644 --- a/src/filters/gaussian-blur.h +++ b/src/filters/gaussian-blur.h @@ -21,14 +21,12 @@ #define SP_IS_GAUSSIANBLUR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_GAUSSIANBLUR)) #define SP_IS_GAUSSIANBLUR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_GAUSSIANBLUR)) -/* GaussianBlur base class */ -class SPGaussianBlurClass; - struct SPGaussianBlur : public SPFilterPrimitive { /** stdDeviation attribute */ NumberOptNumber stdDeviation; }; +/* GaussianBlur base class */ struct SPGaussianBlurClass { SPFilterPrimitiveClass parent_class; }; diff --git a/src/filters/image.h b/src/filters/image.h index b4081602a..a96e650b7 100644 --- a/src/filters/image.h +++ b/src/filters/image.h @@ -24,8 +24,6 @@ #define SP_IS_FEIMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEIMAGE)) #define SP_IS_FEIMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEIMAGE)) -class SPFeImageClass; - struct SPFeImage : public SPFilterPrimitive { gchar *href; diff --git a/src/filters/merge.h b/src/filters/merge.h index 3243073ca..40a9bb848 100644 --- a/src/filters/merge.h +++ b/src/filters/merge.h @@ -18,8 +18,6 @@ #define SP_IS_FEMERGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEMERGE)) #define SP_IS_FEMERGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEMERGE)) -class SPFeMergeClass; - struct SPFeMerge : public SPFilterPrimitive { }; diff --git a/src/filters/mergenode.h b/src/filters/mergenode.h index 8352632a6..edb35faec 100644 --- a/src/filters/mergenode.h +++ b/src/filters/mergenode.h @@ -21,9 +21,6 @@ #define SP_FEMERGENODE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_FEMERGENODE, SPFeMergeNode)) #define SP_IS_FEMERGENODE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_FEMERGENODE)) -class SPFeMergeNode; -class SPFeMergeNodeClass; - struct SPFeMergeNode : public SPObject { int input; }; diff --git a/src/filters/morphology.h b/src/filters/morphology.h index b7005a3d9..9084d1b94 100644 --- a/src/filters/morphology.h +++ b/src/filters/morphology.h @@ -22,8 +22,6 @@ #define SP_IS_FEMORPHOLOGY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEMORPHOLOGY)) #define SP_IS_FEMORPHOLOGY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEMORPHOLOGY)) -class SPFeMorphologyClass; - struct SPFeMorphology : public SPFilterPrimitive { Inkscape::Filters::FilterMorphologyOperator Operator; NumberOptNumber radius; diff --git a/src/filters/offset.h b/src/filters/offset.h index dba7ed8ef..08954a8e4 100644 --- a/src/filters/offset.h +++ b/src/filters/offset.h @@ -20,8 +20,6 @@ #define SP_IS_FEOFFSET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEOFFSET)) #define SP_IS_FEOFFSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEOFFSET)) -class SPFeOffsetClass; - struct SPFeOffset : public SPFilterPrimitive { double dx, dy; }; diff --git a/src/filters/pointlight.h b/src/filters/pointlight.h index c0b272021..3ec5d5791 100644 --- a/src/filters/pointlight.h +++ b/src/filters/pointlight.h @@ -23,12 +23,6 @@ #define SP_IS_FEPOINTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FEPOINTLIGHT)) #define SP_IS_FEPOINTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FEPOINTLIGHT)) -/* Distant light class */ - - -class SPFePointLight; -class SPFePointLightClass; - struct SPFePointLight : public SPObject { /** x coordinate of the light source */ diff --git a/src/filters/specularlighting.h b/src/filters/specularlighting.h index 44bd98c6c..4b31eb4c4 100644 --- a/src/filters/specularlighting.h +++ b/src/filters/specularlighting.h @@ -23,7 +23,7 @@ #define SP_IS_FESPECULARLIGHTING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FESPECULARLIGHTING)) #define SP_IS_FESPECULARLIGHTING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FESPECULARLIGHTING)) -class SVGICCColor; +struct SVGICCColor; namespace Inkscape { namespace Filters { @@ -31,8 +31,6 @@ class FilterSpecularLighting; } } -class SPFeSpecularLightingClass; - struct SPFeSpecularLighting : public SPFilterPrimitive { gfloat surfaceScale; guint surfaceScale_set : 1; diff --git a/src/filters/spotlight.h b/src/filters/spotlight.h index 6e2463c08..1750ca95b 100644 --- a/src/filters/spotlight.h +++ b/src/filters/spotlight.h @@ -23,12 +23,6 @@ #define SP_IS_FESPOTLIGHT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_FESPOTLIGHT)) #define SP_IS_FESPOTLIGHT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FESPOTLIGHT)) -/* Distant light class */ - - -class SPFeSpotLight; -class SPFeSpotLightClass; - struct SPFeSpotLight : public SPObject { /** x coordinate of the light source */ diff --git a/src/filters/tile.h b/src/filters/tile.h index a376a6e10..48a552fc8 100644 --- a/src/filters/tile.h +++ b/src/filters/tile.h @@ -21,8 +21,6 @@ #define SP_IS_FETILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FETILE)) /* FeTile base class */ -class SPFeTileClass; - struct SPFeTile : public SPFilterPrimitive { }; diff --git a/src/filters/turbulence.h b/src/filters/turbulence.h index cbc4fb082..bad8315c1 100644 --- a/src/filters/turbulence.h +++ b/src/filters/turbulence.h @@ -24,7 +24,6 @@ #define SP_IS_FETURBULENCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_FETURBULENCE)) /* FeTurbulence base class */ -class SPFeTurbulenceClass; struct SPFeTurbulence : public SPFilterPrimitive { /** TURBULENCE ATTRIBUTES HERE */ diff --git a/src/flood-context.h b/src/flood-context.h index 0cab0f7c5..3e81cd01e 100644 --- a/src/flood-context.h +++ b/src/flood-context.h @@ -29,9 +29,6 @@ #define FLOOD_COLOR_CHANNEL_B 4 #define FLOOD_COLOR_CHANNEL_A 8 -class SPFloodContext; -class SPFloodContextClass; - struct SPFloodContext : public SPEventContext { SPItem *item; diff --git a/src/gradient-context.h b/src/gradient-context.h index 9c08677ae..464b95ad4 100644 --- a/src/gradient-context.h +++ b/src/gradient-context.h @@ -25,9 +25,6 @@ #define SP_IS_GRADIENT_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_GRADIENT_CONTEXT)) #define SP_IS_GRADIENT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_GRADIENT_CONTEXT)) -class SPGradientContext; -class SPGradientContextClass; - struct SPGradientContext : public SPEventContext { Geom::Point origin; diff --git a/src/gradient-drag.h b/src/gradient-drag.h index cd76d8a3c..2a2465590 100644 --- a/src/gradient-drag.h +++ b/src/gradient-drag.h @@ -33,12 +33,12 @@ struct SPKnot; class SPDesktop; class SPCSSAttr; -class SPLinearGradient; +struct SPLinearGradient; struct SPMeshGradient; class SPItem; class SPObject; -class SPRadialGradient; -class SPStop; +struct SPRadialGradient; +struct SPStop; namespace Inkscape { class Selection; diff --git a/src/inkscape-private.h b/src/inkscape-private.h index 470a1f5bd..09bcef12b 100644 --- a/src/inkscape-private.h +++ b/src/inkscape-private.h @@ -22,7 +22,7 @@ #include "inkscape.h" -class SPColor; +struct SPColor; namespace Inkscape { class Selection; } GType inkscape_get_type (void); diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 449220357..491acd73e 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -91,7 +91,7 @@ enum { ################################*/ namespace Inkscape { -class ApplicationClass; +struct ApplicationClass; } static void inkscape_class_init (Inkscape::ApplicationClass *klass); diff --git a/src/libgdl/Makefile_insert b/src/libgdl/Makefile_insert index 7cfeaa8a2..6669a28fa 100644 --- a/src/libgdl/Makefile_insert +++ b/src/libgdl/Makefile_insert @@ -44,7 +44,6 @@ libgdl/all: libgdl/libgdl.a libgdl/clean: rm -f libgdl/libgdl.a $(libgdl_gdl_a_OBJECTS) - # Suppress some non-critical warnings for libgdl. We will drop our forked copy # of GDL once we upgrade to Gtk+ 3 so it's more important to minimise the number # of changes we make to GDL than to fix these minor issues in trunk. diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 1d086b57b..0f853c681 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -26,7 +26,6 @@ namespace Inkscape { namespace Extension { namespace Internal { class CairoRenderContext; - class CairoGlyphInfo; } } } diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index 488a974ea..0f5f08a53 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -36,7 +36,7 @@ using Inkscape::Extension::Internal::CairoRenderContext; struct SPStyle; class Shape; -class SPPrintContext; +struct SPPrintContext; class SVGLength; class Path; class SPCurve; diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 8401c227f..5b495d14d 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -2,7 +2,6 @@ # include #endif -#include #include #include #include diff --git a/src/livarot/Path.h b/src/livarot/Path.h index cd939bf7d..a109298a2 100644 --- a/src/livarot/Path.h +++ b/src/livarot/Path.h @@ -14,11 +14,11 @@ #include <2geom/point.h> struct PathDescr; -class PathDescrLineTo; -class PathDescrArcTo; -class PathDescrCubicTo; -class PathDescrBezierTo; -class PathDescrIntermBezierTo; +struct PathDescrLineTo; +struct PathDescrArcTo; +struct PathDescrCubicTo; +struct PathDescrBezierTo; +struct PathDescrIntermBezierTo; struct SPStyle; diff --git a/src/livarot/Shape.h b/src/livarot/Shape.h index 1a804a48c..dcd172da2 100644 --- a/src/livarot/Shape.h +++ b/src/livarot/Shape.h @@ -21,9 +21,9 @@ class Path; class FloatLigne; -struct SweepTree; -struct SweepTreeList; -struct SweepEventQueue; +class SweepTree; +class SweepTreeList; +class SweepEventQueue; enum { tweak_mode_grow, diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp index 452139344..ac571d963 100644 --- a/src/live_effects/lpe-recursiveskeleton.cpp +++ b/src/live_effects/lpe-recursiveskeleton.cpp @@ -91,7 +91,8 @@ LPERecursiveSkeleton::doEffect_pwd2 (Geom::Piecewise > co double scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); // TODO investigate why pattWidth is not being used: - double pattWidth = pattBndsX->extent() * scaling; + // - Doesn't appear to have been used anywhere in bzr history (Alex V: 2013-03-16) + // double pattWidth = pattBndsX->extent() * scaling; if (scaling != 1.0) { x*=scaling; diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 7e155cb92..8615721b0 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -5,7 +5,7 @@ */ #include -#include "live_effects/lpe-bspline.h" + #include "live_effects/parameter/parameter.h" #include "live_effects/effect.h" #include "svg/svg.h" @@ -128,6 +128,7 @@ ScalarParam::param_newWidget() { Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); + rsu->setValue(value); rsu->setDigits(digits); rsu->setIncrements(inc_step, inc_page); diff --git a/src/lpe-tool-context.h b/src/lpe-tool-context.h index 12e4b3838..fb3a5d4e2 100644 --- a/src/lpe-tool-context.h +++ b/src/lpe-tool-context.h @@ -24,9 +24,6 @@ #define SP_IS_LPETOOL_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_LPETOOL_CONTEXT)) #define SP_IS_LPETOOL_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_LPETOOL_CONTEXT)) -class SPLPEToolContext; -class SPLPEToolContextClass; - /* This is the list of subtools from which the toolbar of the LPETool is built automatically */ extern const int num_subtools; diff --git a/src/marker.cpp b/src/marker.cpp index 1c8542695..b3b493b00 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -324,13 +324,13 @@ static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags) // Now set up viewbox transformation // Determine actual viewbox in viewport coordinates - double x = 0; - double y = 0; + // double x = 0; + // double y = 0; double width = 0; double height = 0; if (marker->aspect_align == SP_ASPECT_NONE) { - x = 0.0; - y = 0.0; + // x = 0.0; + // y = 0.0; width = rctx.viewport.width(); height = rctx.viewport.height(); } else { @@ -343,7 +343,7 @@ static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags) height = (vb.height()) * scale; // Now place viewbox to requested position - switch (marker->aspect_align) { + /*switch (marker->aspect_align) { case SP_ASPECT_XMIN_YMIN: x = 0.0; y = 0.0; @@ -384,7 +384,7 @@ static void sp_marker_update(SPObject *object, SPCtx *ctx, guint flags) x = 0.0; y = 0.0; break; - } + }*/ } // TODO fixme: all that work is done to figure out x and y, which are just ignored. Check why. diff --git a/src/marker.h b/src/marker.h index e8d2dd9a1..147fafeb8 100644 --- a/src/marker.h +++ b/src/marker.h @@ -22,9 +22,7 @@ #define SP_MARKER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_MARKER, SPMarker)) #define SP_IS_MARKER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_MARKER)) -class SPMarker; -class SPMarkerClass; -class SPMarkerView; +struct SPMarkerView; #include <2geom/rect.h> #include <2geom/affine.h> diff --git a/src/measure-context.h b/src/measure-context.h index baf74d30e..b7673ad0d 100644 --- a/src/measure-context.h +++ b/src/measure-context.h @@ -18,9 +18,6 @@ #define SP_MEASURE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_MEASURE_CONTEXT, SPMeasureContext)) #define SP_IS_MEASURE_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_MEASURE_CONTEXT)) -class SPMeasureContext; -class SPMeasureContextClass; - struct SPMeasureContext { SPEventContext event_context; SPCanvasItem *grabbed; diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 868b606a4..694619089 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -252,9 +252,7 @@ static char const menus_skeleton[] = " \n" " \n" " \n" -#ifdef ENABLE_SVG_FONTS " \n" -#endif // ENABLE_SVG_FONTS " \n" " \n" " \n" diff --git a/src/mesh-context.h b/src/mesh-context.h index ed93e404f..e5d06ec0a 100644 --- a/src/mesh-context.h +++ b/src/mesh-context.h @@ -27,9 +27,6 @@ #define SP_IS_MESH_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_MESH_CONTEXT)) #define SP_IS_MESH_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_MESH_CONTEXT)) -class SPMeshContext; -class SPMeshContextClass; - struct SPMeshContext : public SPEventContext { Geom::Point origin; diff --git a/src/pixmaps/cursor-dropper.xpm b/src/pixmaps/cursor-dropper.xpm deleted file mode 100644 index 21f96edd0..000000000 --- a/src/pixmaps/cursor-dropper.xpm +++ /dev/null @@ -1,38 +0,0 @@ -/* XPM */ -static const char * cursor_dropper_xpm[] = { -"32 32 3 1", -" c None", -". c #FFFFFF", -"+ c #000000", -" ... ", -" .+. ", -" .+. ", -" .+. ", -".... .... ", -".+++ +++. ", -".... .... ", -" .+. ", -" .+. .... ", -" .+. .+++. ", -" ... .+..+. ", -" .++..+. ", -" .++..+. ", -" .++..+. ", -" .++..+. . ", -" .++..+.+. ", -" .++..+++. ", -" .++++.+. ", -" .++++.+.. ", -" .++++++.++. ", -" .++++++..+. ", -" ..+++++.+. ", -" .++++++. ", -" .+++++. ", -" .+++. ", -" ... ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/src/rect-context.h b/src/rect-context.h index b6fbb6854..5b6c5373e 100644 --- a/src/rect-context.h +++ b/src/rect-context.h @@ -25,9 +25,6 @@ #define SP_IS_RECT_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_RECT_CONTEXT)) #define SP_IS_RECT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_RECT_CONTEXT)) -class SPRectContext; -class SPRectContextClass; - struct SPRectContext : public SPEventContext { SPItem *item; Geom::Point center; diff --git a/src/select-context.h b/src/select-context.h index ce2039a2d..a6877f802 100644 --- a/src/select-context.h +++ b/src/select-context.h @@ -22,8 +22,6 @@ #define SP_IS_SELECT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SELECT_CONTEXT)) struct SPCanvasItem; -class SPSelectContext; -class SPSelectContextClass; namespace Inkscape { class MessageContext; diff --git a/src/selection.cpp b/src/selection.cpp index 72f50137c..564f1fdd3 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -418,7 +418,6 @@ Geom::OptRect Selection::documentBounds(SPItem::BBoxType type) const // will be returned; this is also the case in SelTrans::centerRequest() boost::optional Selection::center() const { GSList *items = (GSList *) const_cast(this)->itemList(); - Geom::Point center; if (items) { SPItem *first = reinterpret_cast(g_slist_last(items)->data); // from the first item in selection if (first->isCenterSet()) { // only if set explicitly diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h index f625ebd68..14f50d784 100644 --- a/src/seltrans-handles.h +++ b/src/seltrans-handles.h @@ -21,7 +21,7 @@ namespace Inkscape class SelTrans; } -class SPSelTransHandle; +struct SPSelTransHandle; // request handlers gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, diff --git a/src/seltrans.h b/src/seltrans.h index 55c109ed7..effc767e3 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -30,7 +30,7 @@ struct SPKnot; class SPDesktop; struct SPCanvasItem; struct SPCtrlLine; -class SPSelTransHandle; +struct SPSelTransHandle; namespace Inkscape { diff --git a/src/snap.cpp b/src/snap.cpp index 695424194..15f24ef53 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -500,7 +500,6 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( /* The current best metric for the best transformation; lower is better, Geom::infinity() ** means that we haven't snapped anything. */ - Geom::Point best_scale_metric(Geom::infinity(), Geom::infinity()); Inkscape::SnappedPoint best_snapped_point; g_assert(best_snapped_point.getAlwaysSnap() == false); // Check initialization of snapped point g_assert(best_snapped_point.getAtIntersection() == false); diff --git a/src/sp-clippath.h b/src/sp-clippath.h index a77383c63..17546c6d3 100644 --- a/src/sp-clippath.h +++ b/src/sp-clippath.h @@ -21,7 +21,7 @@ #define SP_IS_CLIPPATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_CLIPPATH)) #define SP_IS_CLIPPATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_CLIPPATH)) -class SPClipPathView; +struct SPClipPathView; #include "sp-object-group.h" #include "uri-references.h" diff --git a/src/sp-desc.h b/src/sp-desc.h index 8c5a8a663..41ef08020 100644 --- a/src/sp-desc.h +++ b/src/sp-desc.h @@ -17,9 +17,6 @@ #define SP_TYPE_DESC (sp_desc_get_type ()) #define SP_IS_DESC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_DESC)) -class SPDesc; -class SPDescClass; - struct SPDesc : public SPObject { }; diff --git a/src/sp-filter-primitive.h b/src/sp-filter-primitive.h index 60104047e..f06df5611 100644 --- a/src/sp-filter-primitive.h +++ b/src/sp-filter-primitive.h @@ -23,8 +23,6 @@ #define SP_IS_FILTER_PRIMITIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FILTER_PRIMITIVE)) #define SP_IS_FILTER_PRIMITIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FILTER_PRIMITIVE)) -class SPFilterPrimitive; -class SPFilterPrimitiveClass; namespace Inkscape { namespace Filters { class Filter; diff --git a/src/sp-filter.h b/src/sp-filter.h index a3e7cd35c..5afe47438 100644 --- a/src/sp-filter.h +++ b/src/sp-filter.h @@ -36,7 +36,7 @@ class Filter; } } class SPFilterReference; -class SPFilterPrimitive; +struct SPFilterPrimitive; struct ltstr { bool operator()(const char* s1, const char* s2) const; diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index a8de68f9b..627907cef 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -86,15 +86,13 @@ sp_flowregion_dispose(GObject *object) group->computed.~vector(); } -static void sp_flowregion_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +static void +sp_flowregion_child_added(SPObject *object, + Inkscape::XML::Node *child, + Inkscape::XML::Node *ref) { - SP_ITEM(object); - - if (((SPObjectClass *) (sp_flowregion_parent_class))->child_added) { - (* ((SPObjectClass *) (sp_flowregion_parent_class))->child_added) (object, child, ref); - } - - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + SP_OBJECT_CLASS (sp_flowregion_parent_class)->child_added (object, child, ref); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); } /* fixme: hide (Lauris) */ @@ -164,10 +162,10 @@ void SPFlowregion::UpdateComputed(void) } } -static void sp_flowregion_modified(SPObject *object, guint flags) +static void +sp_flowregion_modified(SPObject *object, + guint flags) { - SP_FLOWREGION(object); // ensure it is the proper type. - if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } @@ -278,15 +276,14 @@ sp_flowregionexclude_dispose(GObject *object) } } -static void sp_flowregionexclude_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +static void +sp_flowregionexclude_child_added(SPObject *object, + Inkscape::XML::Node *child, + Inkscape::XML::Node *ref) { - SP_ITEM(object); - - if (((SPObjectClass *) (sp_flowregionexclude_parent_class))->child_added) { - (* ((SPObjectClass *) (sp_flowregionexclude_parent_class))->child_added) (object, child, ref); - } + SP_OBJECT_CLASS (sp_flowregionexclude_parent_class)->child_added (object, child, ref); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); } /* fixme: hide (Lauris) */ @@ -354,10 +351,10 @@ void SPFlowregionExclude::UpdateComputed(void) } } -static void sp_flowregionexclude_modified(SPObject *object, guint flags) +static void +sp_flowregionexclude_modified(SPObject *object, + guint flags) { - SP_FLOWREGIONEXCLUDE(object); // Ensure it is the proper type - if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } diff --git a/src/sp-font-face.cpp b/src/sp-font-face.cpp index 4288a5d64..0a649b17f 100644 --- a/src/sp-font-face.cpp +++ b/src/sp-font-face.cpp @@ -2,8 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS - /* * SVG element implementation * @@ -849,7 +847,6 @@ static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::D return repr; } -#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-font-face.h b/src/sp-font-face.h index 57702b683..968644556 100644 --- a/src/sp-font-face.h +++ b/src/sp-font-face.h @@ -2,7 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS #ifndef __SP_FONTFACE_H__ #define __SP_FONTFACE_H__ @@ -122,4 +121,3 @@ GType sp_fontface_get_type (void); G_END_DECLS #endif //#ifndef __SP_FONTFACE_H__ -#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-font.cpp b/src/sp-font.cpp index 6ebbd5218..a03890fc7 100644 --- a/src/sp-font.cpp +++ b/src/sp-font.cpp @@ -2,8 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS - /* * SVG element implementation * @@ -250,7 +248,6 @@ static Inkscape::XML::Node *sp_font_write(SPObject *object, Inkscape::XML::Docum return repr; } -#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-glyph-kerning.cpp b/src/sp-glyph-kerning.cpp index 652d965bb..10884fb81 100644 --- a/src/sp-glyph-kerning.cpp +++ b/src/sp-glyph-kerning.cpp @@ -2,7 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS #define __SP_ANCHOR_C__ /* @@ -267,7 +266,6 @@ static Inkscape::XML::Node *sp_glyph_kerning_write(SPObject *object, Inkscape::X return repr; } -#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-glyph-kerning.h b/src/sp-glyph-kerning.h index ce9b4bb15..b7f733cad 100644 --- a/src/sp-glyph-kerning.h +++ b/src/sp-glyph-kerning.h @@ -2,7 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS #ifndef __SP_GLYPH_KERNING_H__ #define __SP_GLYPH_KERNING_H__ @@ -60,4 +59,3 @@ GType sp_glyph_kerning_h_get_type (void); GType sp_glyph_kerning_v_get_type (void); #endif //#ifndef __SP_GLYPH_KERNING_H__ -#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-glyph.cpp b/src/sp-glyph.cpp index e14ef8667..0417ea8c1 100644 --- a/src/sp-glyph.cpp +++ b/src/sp-glyph.cpp @@ -2,7 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS #define __SP_GLYPH_C__ /* @@ -284,7 +283,6 @@ static Inkscape::XML::Node *sp_glyph_write(SPObject *object, Inkscape::XML::Docu return repr; } -#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-glyph.h b/src/sp-glyph.h index 316204c23..7556b0e25 100644 --- a/src/sp-glyph.h +++ b/src/sp-glyph.h @@ -2,7 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS #ifndef __SP_GLYPH_H__ #define __SP_GLYPH_H__ @@ -58,4 +57,3 @@ struct SPGlyphClass { GType sp_glyph_get_type (void); #endif //#ifndef __SP_GLYPH_H__ -#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-gradient.h b/src/sp-gradient.h index a21a413f4..57ffa5570 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -27,8 +27,8 @@ #include #include -struct SPGradientReference; -class SPStop; +class SPGradientReference; +struct SPStop; #define SP_TYPE_GRADIENT (SPGradient::getType()) #define SP_GRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_GRADIENT, SPGradient)) diff --git a/src/sp-image.h b/src/sp-image.h index c657d0a2f..d6fc82a59 100644 --- a/src/sp-image.h +++ b/src/sp-image.h @@ -20,9 +20,6 @@ #define SP_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_IMAGE)) #define SP_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_IMAGE)) -class SPImage; -class SPImageClass; - /* SPImage */ #include diff --git a/src/sp-item.h b/src/sp-item.h index a93206414..31b7ac034 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -28,8 +28,8 @@ #include "snap-candidate.h" class SPGuideConstraint; -struct SPClipPathReference; -struct SPMaskReference; +class SPClipPathReference; +class SPMaskReference; class SPAvoidRef; struct SPPrintContext; diff --git a/src/sp-linear-gradient-fns.h b/src/sp-linear-gradient-fns.h index 1bdf0b89e..14e575ebe 100644 --- a/src/sp-linear-gradient-fns.h +++ b/src/sp-linear-gradient-fns.h @@ -14,7 +14,7 @@ class Node; } } -class SPLinearGradient; +struct SPLinearGradient; #define SP_TYPE_LINEARGRADIENT (sp_lineargradient_get_type()) #define SP_LINEARGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_LINEARGRADIENT, SPLinearGradient)) diff --git a/src/sp-mask.h b/src/sp-mask.h index e249e0c76..97cf95ae1 100644 --- a/src/sp-mask.h +++ b/src/sp-mask.h @@ -24,9 +24,7 @@ #define SP_IS_MASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_MASK)) #define SP_IS_MASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_MASK)) -class SPMask; -class SPMaskClass; -class SPMaskView; +struct SPMaskView; namespace Inkscape { diff --git a/src/sp-metadata.cpp b/src/sp-metadata.cpp index 9978d0a3a..79953b708 100644 --- a/src/sp-metadata.cpp +++ b/src/sp-metadata.cpp @@ -116,15 +116,17 @@ static void sp_metadata_release(SPObject *object) /** * Sets a specific value in the SPMetadata. */ -static void sp_metadata_set(SPObject *object, unsigned int key, const gchar *value) +static void +sp_metadata_set(SPObject *object, + unsigned int key, + const gchar *value) { debug("0x%08x %s(%u): '%s'",(unsigned int)object, sp_attribute_name(key),key,value); - SP_METADATA(object); // ensures the object is of the proper type. // see if any parents need this value - if (reinterpret_cast(sp_metadata_parent_class)->set) { - reinterpret_cast(sp_metadata_parent_class)->set(object, key, value); + if (SP_OBJECT_CLASS(sp_metadata_parent_class)->set) { + SP_OBJECT_CLASS(sp_metadata_parent_class)->set(object, key, value); } } diff --git a/src/sp-metadata.h b/src/sp-metadata.h index 82b7c4fc5..454fd8d18 100644 --- a/src/sp-metadata.h +++ b/src/sp-metadata.h @@ -21,9 +21,6 @@ #define SP_METADATA(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_METADATA, SPMetadata)) #define SP_IS_METADATA(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_METADATA)) -class SPMetadata; -class SPMetadataClass; - struct SPMetadata : public SPObject { }; diff --git a/src/sp-missing-glyph.cpp b/src/sp-missing-glyph.cpp index bdf993e5b..911c9be92 100644 --- a/src/sp-missing-glyph.cpp +++ b/src/sp-missing-glyph.cpp @@ -2,8 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS - /* * SVG element implementation * @@ -164,7 +162,6 @@ static Inkscape::XML::Node *sp_missing_glyph_write(SPObject *object, Inkscape::X return repr; } -#endif //#ifdef ENABLE_SVG_FONTS /* Local Variables: mode:c++ diff --git a/src/sp-missing-glyph.h b/src/sp-missing-glyph.h index 0b3f74360..7930df513 100644 --- a/src/sp-missing-glyph.h +++ b/src/sp-missing-glyph.h @@ -2,7 +2,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS #ifndef __SP_MISSING_GLYPH_H__ #define __SP_MISSING_GLYPH_H__ @@ -40,4 +39,3 @@ struct SPMissingGlyphClass { GType sp_missing_glyph_get_type (void); #endif //#ifndef __SP_MISSING_GLYPH_H__ -#endif //#ifdef ENABLE_SVG_FONTS diff --git a/src/sp-object-group.cpp b/src/sp-object-group.cpp index 5158ec70a..e2b601ab9 100644 --- a/src/sp-object-group.cpp +++ b/src/sp-object-group.cpp @@ -93,8 +93,6 @@ sp_objectgroup_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) { - SP_OBJECTGROUP(object); // Ensure we have the right type of SPObject - if (flags & SP_OBJECT_WRITE_BUILD) { if (!repr) { repr = xml_doc->createElement("svg:g"); @@ -118,7 +116,7 @@ sp_objectgroup_write(SPObject *object, } if ((SP_OBJECT_CLASS(sp_objectgroup_parent_class))->write) { - (SP_OBJECT_CLASS(sp_objectgroup_parent_class))->write(object, xml_doc, repr, flags); + SP_OBJECT_CLASS(sp_objectgroup_parent_class)->write(object, xml_doc, repr, flags); } return repr; diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp index cd332cd34..eba38ec67 100644 --- a/src/sp-object-repr.cpp +++ b/src/sp-object-repr.cpp @@ -48,13 +48,11 @@ #include "sp-script.h" #include "config.h" -#ifdef ENABLE_SVG_FONTS - #include "sp-font.h" - #include "sp-font-face.h" - #include "sp-glyph.h" - #include "sp-missing-glyph.h" - #include "sp-glyph-kerning.h" -#endif +#include "sp-font.h" +#include "sp-font-face.h" +#include "sp-glyph.h" +#include "sp-missing-glyph.h" +#include "sp-glyph-kerning.h" #include "sp-style-elem.h" #include "sp-switch.h" @@ -151,14 +149,12 @@ populate_dtables() { "svg:flowRegionExclude", SP_TYPE_FLOWREGIONEXCLUDE }, { "svg:flowRoot", SP_TYPE_FLOWTEXT }, { "svg:flowSpan", SP_TYPE_FLOWTSPAN }, -#ifdef ENABLE_SVG_FONTS { "svg:font", SP_TYPE_FONT }, { "svg:font-face", SP_TYPE_FONTFACE }, { "svg:glyph", SP_TYPE_GLYPH }, { "svg:missing-glyph", SP_TYPE_MISSING_GLYPH }, { "svg:hkern", SP_TYPE_HKERN }, { "svg:vkern", SP_TYPE_VKERN }, -#endif { "svg:g", SP_TYPE_GROUP }, { "svg:feBlend", SP_TYPE_FEBLEND }, { "svg:feColorMatrix", SP_TYPE_FECOLORMATRIX }, diff --git a/src/sp-offset.h b/src/sp-offset.h index 4e245f952..904f8607c 100644 --- a/src/sp-offset.h +++ b/src/sp-offset.h @@ -22,8 +22,6 @@ #define SP_IS_OFFSET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_OFFSET)) #define SP_IS_OFFSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_OFFSET)) -class SPOffset; -class SPOffsetClass; class SPUseReference; /** diff --git a/src/sp-pattern.h b/src/sp-pattern.h index e0a7dce54..bcf8dd520 100644 --- a/src/sp-pattern.h +++ b/src/sp-pattern.h @@ -24,8 +24,7 @@ GType sp_pattern_get_type (void); -class SPPattern; -class SPPatternClass; +struct SPPattern; #include "svg/svg-length.h" #include "sp-paint-server.h" diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp index e5d89a802..2922b66ed 100644 --- a/src/sp-polyline.cpp +++ b/src/sp-polyline.cpp @@ -116,10 +116,11 @@ sp_polyline_set(SPObject *object, unsigned int key, const gchar *value) } static Inkscape::XML::Node* -sp_polyline_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +sp_polyline_write(SPObject *object, + Inkscape::XML::Document *xml_doc, + Inkscape::XML::Node *repr, + guint flags) { - SP_POLYLINE(object); - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:polyline"); } @@ -128,9 +129,7 @@ sp_polyline_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape:: repr->mergeFrom(object->getRepr(), "id"); } - if (((SPObjectClass *) (sp_polyline_parent_class))->write) { - ((SPObjectClass *) (sp_polyline_parent_class))->write (object, xml_doc, repr, flags); - } + SP_OBJECT_CLASS(sp_polyline_parent_class)->write (object, xml_doc, repr, flags); return repr; } diff --git a/src/sp-radial-gradient-fns.h b/src/sp-radial-gradient-fns.h index 912508a33..43ed7bf03 100644 --- a/src/sp-radial-gradient-fns.h +++ b/src/sp-radial-gradient-fns.h @@ -13,7 +13,7 @@ class Node; } } -class SPRadialGradient; +struct SPRadialGradient; #define SP_TYPE_RADIALGRADIENT (sp_radialgradient_get_type()) #define SP_RADIALGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_RADIALGRADIENT, SPRadialGradient)) diff --git a/src/sp-rect.h b/src/sp-rect.h index 5e518dcd7..1127889c1 100644 --- a/src/sp-rect.h +++ b/src/sp-rect.h @@ -26,9 +26,6 @@ G_BEGIN_DECLS #define SP_IS_RECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_RECT)) #define SP_IS_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_RECT)) -class SPRect; -class SPRectClass; - struct SPRect : public SPShape { SVGLength x; SVGLength y; diff --git a/src/sp-spiral.h b/src/sp-spiral.h index 6da7c38a4..64cb8521b 100644 --- a/src/sp-spiral.h +++ b/src/sp-spiral.h @@ -29,9 +29,6 @@ #define SP_IS_SPIRAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_SPIRAL)) #define SP_IS_SPIRAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SPIRAL)) -class SPSpiral; -class SPSpiralClass; - /** * A spiral Shape. * diff --git a/src/sp-star.h b/src/sp-star.h index bd271ccc0..888eeb8d2 100644 --- a/src/sp-star.h +++ b/src/sp-star.h @@ -16,17 +16,12 @@ #include "sp-polygon.h" - - #define SP_TYPE_STAR (sp_star_get_type ()) #define SP_STAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_STAR, SPStar)) #define SP_STAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_STAR, SPStarClass)) #define SP_IS_STAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_STAR)) #define SP_IS_STAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_STAR)) -class SPStar; -class SPStarClass; - typedef enum { SP_STAR_POINT_KNOT1, SP_STAR_POINT_KNOT2 diff --git a/src/sp-stop.h b/src/sp-stop.h index c3b1e2753..b82dd0b13 100644 --- a/src/sp-stop.h +++ b/src/sp-stop.h @@ -14,7 +14,6 @@ #include "color.h" class SPObjectClass; -class SPColor; struct SPStop; struct SPStopClass; diff --git a/src/sp-switch.h b/src/sp-switch.h index f0442f27b..24a204731 100644 --- a/src/sp-switch.h +++ b/src/sp-switch.h @@ -35,7 +35,7 @@ public: CSwitch(SPGroup *group); virtual ~CSwitch(); - friend class SPSwitch; + friend struct SPSwitch; virtual void onChildAdded(Inkscape::XML::Node *child); virtual void onChildRemoved(Inkscape::XML::Node *child); diff --git a/src/sp-symbol.cpp b/src/sp-symbol.cpp index d4db403e3..989a5b7f3 100644 --- a/src/sp-symbol.cpp +++ b/src/sp-symbol.cpp @@ -307,19 +307,19 @@ static void sp_symbol_update(SPObject *object, SPCtx *ctx, guint flags) } } -static void sp_symbol_modified(SPObject *object, guint flags) +static void +sp_symbol_modified(SPObject *object, + guint flags) { - SP_SYMBOL(object); - - if (((SPObjectClass *) (sp_symbol_parent_class))->modified) { - (* ((SPObjectClass *) (sp_symbol_parent_class))->modified) (object, flags); - } + SP_OBJECT_CLASS(sp_symbol_parent_class)->modified (object, flags); } -static Inkscape::XML::Node *sp_symbol_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +static Inkscape::XML::Node * +sp_symbol_write(SPObject *object, + Inkscape::XML::Document *xml_doc, + Inkscape::XML::Node *repr, + guint flags) { - SP_SYMBOL(object); - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = xml_doc->createElement("svg:symbol"); } @@ -330,9 +330,7 @@ static Inkscape::XML::Node *sp_symbol_write(SPObject *object, Inkscape::XML::Doc //XML Tree being used directly here while it shouldn't be. repr->setAttribute("preserveAspectRatio", object->getRepr()->attribute("preserveAspectRatio")); - if (((SPObjectClass *) (sp_symbol_parent_class))->write) { - ((SPObjectClass *) (sp_symbol_parent_class))->write (object, xml_doc, repr, flags); - } + SP_OBJECT_CLASS(sp_symbol_parent_class)->write (object, xml_doc, repr, flags); return repr; } @@ -404,3 +402,14 @@ static void sp_symbol_print(SPItem *item, SPPrintContext *ctx) sp_print_release (ctx); } } + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-symbol.h b/src/sp-symbol.h index 59f343285..10d642e8b 100644 --- a/src/sp-symbol.h +++ b/src/sp-symbol.h @@ -21,9 +21,6 @@ #define SP_SYMBOL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_SYMBOL, SPSymbol)) #define SP_IS_SYMBOL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_SYMBOL)) -class SPSymbol; -class SPSymbolClass; - #include <2geom/affine.h> #include "svg/svg-length.h" #include "enums.h" diff --git a/src/sp-title.h b/src/sp-title.h index a5f0a2fea..d10d58188 100644 --- a/src/sp-title.h +++ b/src/sp-title.h @@ -17,9 +17,6 @@ #define SP_TYPE_TITLE (sp_title_get_type ()) #define SP_IS_TITLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_TITLE)) -class SPTitle; -class SPTitleClass; - struct SPTitle : public SPObject { }; diff --git a/src/sp-tref.h b/src/sp-tref.h index cc80e48a8..33a8138d1 100644 --- a/src/sp-tref.h +++ b/src/sp-tref.h @@ -28,9 +28,6 @@ #define SP_IS_TREF(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_TREF)) #define SP_IS_TREF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_TREF)) -class SPTRef; -class SPTRef; - struct SPTRef : public SPItem { // Attributes that are used in the same way they would be in a tspan TextTagAttributes attributes; diff --git a/src/sp-use.h b/src/sp-use.h index 399f30a4c..3dd0726aa 100644 --- a/src/sp-use.h +++ b/src/sp-use.h @@ -25,8 +25,6 @@ #define SP_IS_USE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_USE)) #define SP_IS_USE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_USE)) -class SPUse; -class SPUseClass; class SPUseReference; struct SPUse : public SPItem { diff --git a/src/spiral-context.h b/src/spiral-context.h index 12c0b5d68..7f696dfa2 100644 --- a/src/spiral-context.h +++ b/src/spiral-context.h @@ -27,9 +27,6 @@ #define SP_IS_SPIRAL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_SPIRAL_CONTEXT)) #define SP_IS_SPIRAL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SPIRAL_CONTEXT)) -class SPSpiralContext; -class SPSpiralContextClass; - struct SPSpiralContext : public SPEventContext { SPItem * item; Geom::Point center; diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 061d32554..2015ffd27 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -1369,48 +1369,18 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool Inkscape::XML::Node *parent = item->getRepr()->parent(); float o_width = 0; - JoinType o_join = join_straight; - ButtType o_butt = butt_straight; - float o_miter = 0; { SPStyle *i_style = item->style; - int jointype = i_style->stroke_linejoin.value; - int captype = i_style->stroke_linecap.value; o_width = i_style->stroke_width.computed; - if (jointype == SP_STROKE_LINEJOIN_MITER) - { - o_join = join_pointy; - } - else if (jointype == SP_STROKE_LINEJOIN_ROUND) - { - o_join = join_round; - } - else - { - o_join = join_straight; - } - if (captype == SP_STROKE_LINECAP_SQUARE) - { - o_butt = butt_square; - } - else if (captype == SP_STROKE_LINECAP_ROUND) - { - o_butt = butt_round; - } - else - { - o_butt = butt_straight; - } - { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); o_width = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px"); } - if (o_width < 0.01) + if (o_width < 0.01){ o_width = 0.01; - o_miter = i_style->stroke_miterlimit.value * o_width; + } } Path *orig = Path_for_item(item, true, false); @@ -1508,7 +1478,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - SPItem *nitem = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr); + SPItem *nitem = reinterpret_cast(sp_desktop_document(desktop)->getObjectByRepr(repr)); if ( !updating ) { // delete original, apply the transform to the offset diff --git a/src/spray-context.h b/src/spray-context.h index 64368c7a6..781bbcce8 100644 --- a/src/spray-context.h +++ b/src/spray-context.h @@ -27,9 +27,6 @@ #define SP_IS_SPRAY_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_SPRAY_CONTEXT)) #define SP_IS_SPRAY_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_SPRAY_CONTEXT)) -class SPSprayContext; -class SPSprayContextClass; - namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/star-context.h b/src/star-context.h index 7bcb26c41..4daafb3e4 100644 --- a/src/star-context.h +++ b/src/star-context.h @@ -25,9 +25,6 @@ #define SP_IS_STAR_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_STAR_CONTEXT)) #define SP_IS_STAR_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_STAR_CONTEXT)) -class SPStarContext; -class SPStarContextClass; - struct SPStarContext : public SPEventContext { SPItem *item; Geom::Point center; diff --git a/src/style.cpp b/src/style.cpp index 650b08aea..eef1c6ee5 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -63,7 +63,7 @@ using std::vector; #define SP_CSS_FONT_SIZE_DEFAULT 12.0; -class SPStyleEnum; +struct SPStyleEnum; /*######################### ## FORWARD DECLARATIONS diff --git a/src/style.h b/src/style.h index 1c8cb4774..0710f5c8e 100644 --- a/src/style.h +++ b/src/style.h @@ -134,8 +134,6 @@ struct SPILength { #define SP_STYLE_FILL_SERVER(s) ((const_cast (s))->getFillPaintServer()) #define SP_STYLE_STROKE_SERVER(s) ((const_cast (s))->getStrokePaintServer()) -class SVGICCColor; - /// Paint type internal to SPStyle. struct SPIPaint { unsigned set : 1; @@ -246,7 +244,7 @@ struct SPILengthOrNormal { float computed; }; -class SPTextStyle; +struct SPTextStyle; /// Stroke dash details. class NRVpathDash { diff --git a/src/svg-view-widget.h b/src/svg-view-widget.h index d489ccbdd..eab5be75b 100644 --- a/src/svg-view-widget.h +++ b/src/svg-view-widget.h @@ -15,8 +15,6 @@ #include "ui/view/view-widget.h" class SPDocument; -class SPSVGSPViewWidget; -class SPSVGSPViewWidgetClass; #define SP_TYPE_SVG_VIEW_WIDGET (sp_svg_view_widget_get_type ()) #define SP_SVG_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_SVG_VIEW_WIDGET, SPSVGSPViewWidget)) diff --git a/src/svg-view.h b/src/svg-view.h index aaaa8a9a5..89f38ad34 100644 --- a/src/svg-view.h +++ b/src/svg-view.h @@ -13,7 +13,7 @@ #include "ui/view/view.h" -class SPCanvasGroup; +struct SPCanvasGroup; struct SPCanvasItem; diff --git a/src/svg/svg-color.h b/src/svg/svg-color.h index d1c7bee03..b8e317e3b 100644 --- a/src/svg/svg-color.h +++ b/src/svg/svg-color.h @@ -3,7 +3,7 @@ #include -class SVGICCColor; +struct SVGICCColor; guint32 sp_svg_read_color(gchar const *str, unsigned int dfl); guint32 sp_svg_read_color(gchar const *str, gchar const **end_ptr, guint32 def); diff --git a/src/text-context.h b/src/text-context.h index 9915583eb..a33c69e0a 100644 --- a/src/text-context.h +++ b/src/text-context.h @@ -30,8 +30,6 @@ #define SP_IS_TEXT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_TEXT_CONTEXT)) struct SPCtrlLine; -class SPTextContext; -class SPTextContextClass; struct SPTextContext : public SPEventContext { diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 47b4d35ac..401f56bb2 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -69,7 +69,7 @@ void te_update_layout_now_recursive(SPItem *item) if (SP_IS_GROUP(item)) { GSList *item_list = sp_item_group_item_list(SP_GROUP(item)); for(GSList* elem = item_list; elem; elem = elem->next) { - SPItem* list_item = (SPItem*) elem->data; + SPItem* list_item = static_cast(elem->data); te_update_layout_now_recursive(list_item); } g_slist_free(item_list); diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp index 9376fad66..1a1426b83 100644 --- a/src/trace/siox.cpp +++ b/src/trace/siox.cpp @@ -591,7 +591,7 @@ bool SioxImage::writePPM(const std::string &fileName) if (!f) return false; - fprintf(f, "P6 %d %d 255\n", width, height); + fprintf(f, "P6 %u %u 255\n", width, height); for (unsigned int y=0 ; y); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); -#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); -#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); @@ -154,9 +149,7 @@ DialogManager::DialogManager() { registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("Script", &create); -#ifdef ENABLE_SVG_FONTS registerFactory("SvgFontsDialog", &create); -#endif registerFactory("Swatches", &create); registerFactory("Symbols", &create); registerFactory("TileDialog", &create); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 045b34814..d335fb303 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -792,8 +792,6 @@ void DocumentProperties::build_scripting() _page_external_scripts->table().attach(_external_remove_btn, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, 0, 0); #endif - row++; - //# Set up the External Scripts box _ExternalScriptsListStore = Gtk::ListStore::create(_ExternalScriptsListColumns); _ExternalScriptsList.set_model(_ExternalScriptsListStore); diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index ac039bf77..99a8c08d2 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -22,14 +22,21 @@ #include #include -#include -#include -#include +#include #include #include -#include +#include +#include #include -#include +#include +#if WITH_GTKMM_3_0 +# include +#else +# include +#endif +#include +#include + #ifdef WITH_GNOME_VFS # include // gnome_vfs_initialized #endif @@ -126,6 +133,15 @@ namespace Inkscape { namespace UI { namespace Dialog { +/** A list of strings that is used both in the preferences, and in the + data fields to describe the various values of \c selection_type. */ +static const char * selection_names[SELECTION_NUMBER_OF] = { + "page", "drawing", "selection", "custom"}; + +/** The names on the buttons for the various selection types. */ +static const char * selection_labels[SELECTION_NUMBER_OF] = { + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + Export::Export (void) : UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT), current_key(SELECTION_PAGE), diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 5dca9cfa5..b10c98fd2 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -14,10 +14,12 @@ #include #include + +#include #include #include +#include #include -#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" @@ -25,11 +27,14 @@ #include "ui/widget/button.h" #include "ui/widget/entry.h" +namespace Gtk { +class Dialog; +} + namespace Inkscape { namespace UI { namespace Dialog { - /** What type of button is being pressed */ enum selection_type { SELECTION_PAGE = 0, /**< Export the whole page */ @@ -39,16 +44,6 @@ enum selection_type { SELECTION_NUMBER_OF /**< A counter for the number of these guys */ }; -/** A list of strings that is used both in the preferences, and in the - data fields to describe the various values of \c selection_type. */ -static const char * selection_names[SELECTION_NUMBER_OF] = { - "page", "drawing", "selection", "custom"}; - -/** The names on the buttons for the various selection types. */ -static const char * selection_labels[SELECTION_NUMBER_OF] = { - N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; - - /** * A dialog widget to export to various image formats such as bitmap and png. * diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 8de2da18b..19b873d54 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -132,14 +132,24 @@ void FillAndStroke::_layoutPageFill() { fillWdgt = manage(sp_fill_style_widget_new()); + +#if WITH_GTKMM_3_0 _page_fill->table().attach(*fillWdgt, 0, 0, 1, 1); +#else + _page_fill->table().attach(*fillWdgt, 0, 1, 0, 1); +#endif } void FillAndStroke::_layoutPageStrokePaint() { strokeWdgt = manage(sp_stroke_style_paint_widget_new()); + +#if WITH_GTKMM_3_0 _page_stroke_paint->table().attach(*strokeWdgt, 0, 0, 1, 1); +#else + _page_stroke_paint->table().attach(*strokeWdgt, 0, 1, 0, 1); +#endif } void @@ -148,7 +158,12 @@ FillAndStroke::_layoutPageStrokeStyle() //Gtk::Widget *strokeStyleWdgt = manage(Glib::wrap(sp_stroke_style_line_widget_new())); //Gtk::Widget *strokeStyleWdgt = static_cast(sp_stroke_style_line_widget_new()); strokeStyleWdgt = sp_stroke_style_line_widget_new(); + +#if WITH_GTKMM_3_0 _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 0, 1, 1); +#else + _page_stroke_style->table().attach(*strokeStyleWdgt, 0, 1, 0, 1); +#endif } void diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index d3ce99b00..def7b5bdb 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -15,7 +15,10 @@ #endif #include "find.h" + +#include #include + #include "verbs.h" #include "message-stack.h" @@ -56,6 +59,7 @@ #include "xml/attribute-record.h" #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h index 77a6c9d02..14d54b8d4 100644 --- a/src/ui/dialog/find.h +++ b/src/ui/dialog/find.h @@ -21,7 +21,11 @@ #include "ui/widget/entry.h" #include "ui/widget/frame.h" #include -#include + +#include +#include +#include +#include #include "desktop.h" #include "ui/dialog/desktop-tracker.h" diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h index 6571af0a4..3d0571244 100644 --- a/src/ui/dialog/glyphs.h +++ b/src/ui/dialog/glyphs.h @@ -20,7 +20,7 @@ class Label; class ListStore; } -class SPFontSelector; +struct SPFontSelector; class font_instance; diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index de213ca85..801ab2922 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -20,7 +20,11 @@ #include #include #include + #include +#include +#include + #include #include #include diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 9c9f7faa3..82e65435d 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -17,7 +17,9 @@ #include #include + #include +#include #include #include #include diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index 9de303f89..0e2f8ed94 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -80,9 +80,9 @@ protected: void perform(LayerPropertiesDialog &dialog); }; - friend class Rename; - friend class Create; - friend class Move; + friend struct Rename; + friend struct Create; + friend struct Move; Strategy *_strategy; SPDesktop *_desktop; diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 114204961..8a2b0299a 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -38,6 +38,12 @@ #include "sp-item.h" #include +#if WITH_GTKMM_3_0 +# include +#else +# include +#endif + namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h index b49293ea1..624a18246 100644 --- a/src/ui/dialog/object-properties.h +++ b/src/ui/dialog/object-properties.h @@ -35,6 +35,8 @@ #include "ui/widget/panel.h" #include "ui/widget/frame.h" + +#include #include #include #include @@ -46,6 +48,14 @@ class SPAttributeTable; class SPDesktop; class SPItem; +namespace Gtk { +#if WITH_GTKMM_3_0 +class Grid; +#else +class Table; +#endif +} + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 0da39dd73..bce63093d 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -15,8 +15,6 @@ # include #endif -#ifdef ENABLE_SVG_FONTS - #include "svg-fonts-dialog.h" #include "document-private.h" #include "document-undo.h" @@ -945,8 +943,6 @@ SvgFontsDialog::~SvgFontsDialog(){} } // namespace UI } // namespace Inkscape -#endif //#ifdef ENABLE_SVG_FONTS - /* Local Variables: mode:c++ diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h index 9be984820..01f70654a 100644 --- a/src/ui/dialog/svg-fonts-dialog.h +++ b/src/ui/dialog/svg-fonts-dialog.h @@ -34,8 +34,8 @@ class HScale; #endif } -class SPGlyph; -class SPGlyphKerning; +struct SPGlyph; +struct SPGlyphKerning; class SvgFont; class SvgFontDrawingArea : Gtk::DrawingArea{ diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 84d469750..c87e94fc6 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -57,6 +57,7 @@ extern "C" { #include "widgets/icon.h" #include "widgets/font-selector.h" #include +#include #include "unit-constants.h" diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h index 3fdeea05d..f27fdfc87 100644 --- a/src/ui/dialog/text-edit.h +++ b/src/ui/dialog/text-edit.h @@ -30,7 +30,7 @@ #include "ui/dialog/desktop-tracker.h" class SPItem; -class SPFontSelector; +struct SPFontSelector; class font_instance; class SPCSSAttr; diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index 1ad827a56..bd467555e 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -20,6 +20,7 @@ #include #include "ui/widget/spinbutton.h" #include "ui/widget/frame.h" +#include #include #include //for GTK_RESPONSE* types diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h index 0a6e3a786..58ef3aef8 100644 --- a/src/ui/dialog/xml-tree.h +++ b/src/ui/dialog/xml-tree.h @@ -29,7 +29,7 @@ #include "message.h" class SPDesktop; -struct SPObject; +class SPObject; struct SPXMLViewAttrList; struct SPXMLViewContent; struct SPXMLViewTree; diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index 8c4924f26..069dcc67b 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -7,8 +7,8 @@ */ #include +#include #include -#include #include <2geom/point.h> #include "desktop.h" #include "desktop-handles.h" diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index 49b1496d4..bc5267bb2 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -25,9 +25,6 @@ #define INK_IS_NODE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INK_TYPE_NODE_TOOL)) #define INK_IS_NODE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INK_TYPE_NODE_TOOL)) -class InkNodeTool; -class InkNodeToolClass; - namespace Inkscape { namespace Display { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 04148592b..79db1a1c1 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -22,7 +22,7 @@ struct SPCanvasItem; class SPCurve; -struct SPPath; +class SPPath; namespace Inkscape { namespace XML { class Node; } diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp index 173e014d9..64d28119a 100644 --- a/src/ui/widget/entry.cpp +++ b/src/ui/widget/entry.cpp @@ -13,6 +13,8 @@ #include "entry.h" +#include + namespace Inkscape { namespace UI { namespace Widget { diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h index 53b848fc9..de5cceadd 100644 --- a/src/ui/widget/entry.h +++ b/src/ui/widget/entry.h @@ -11,10 +11,10 @@ #define INKSCAPE_UI_WIDGET_ENTRY__H #include "labelled.h" -#include -#include -#include +namespace Gtk { +class Entry; +} namespace Inkscape { namespace UI { diff --git a/src/ui/widget/frame.h b/src/ui/widget/frame.h index cf736d8a1..a04666651 100644 --- a/src/ui/widget/frame.h +++ b/src/ui/widget/frame.h @@ -10,11 +10,9 @@ #ifndef INKSCAPE_UI_WIDGET_FRAME_H #define INKSCAPE_UI_WIDGET_FRAME_H -#include - -namespace Gtk { -class Frame; -} +#include +#include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index 2a7843a51..fa35b815e 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -32,7 +32,7 @@ #include -class SPUnit; +struct SPUnit; class SPDocument; namespace Gtk { diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index 6d5222429..9b78cb17f 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -40,7 +40,7 @@ #include "helper/units.h" class SPDesktop; -class SPUnit; +struct SPUnit; namespace Inkscape { namespace UI { diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index 2b9c32b2e..d7bab3732 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -26,7 +26,7 @@ #include "button.h" #include "preferences.h" -class SPUnit; +struct SPUnit; struct SPStyle; class SPCSSAttr; diff --git a/src/undo-stack-observer.h b/src/undo-stack-observer.h index f4d67e841..1057ace8f 100644 --- a/src/undo-stack-observer.h +++ b/src/undo-stack-observer.h @@ -14,7 +14,7 @@ namespace Inkscape { -class Event; +struct Event; /** * Observes changes made to the undo and redo stacks. diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index 1ed6c6c46..6719691d1 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -33,7 +33,7 @@ class SPDocument; class SPObject; class SPGradient; -class SPStop; +struct SPStop; struct SPGradientVectorSelector { GtkVBox vbox; diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index d3b3f4116..a66758434 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -22,7 +22,7 @@ class SPGradient; class SPDesktop; -class SPPattern; +struct SPPattern; struct SPStyle; #define SP_TYPE_PAINT_SELECTOR (sp_paint_selector_get_type ()) diff --git a/src/widgets/swatch-selector.h b/src/widgets/swatch-selector.h index b97aac4f1..4b7aa483f 100644 --- a/src/widgets/swatch-selector.h +++ b/src/widgets/swatch-selector.h @@ -1,14 +1,12 @@ #ifndef SEEN_SP_SWATCH_SELECTOR_H #define SEEN_SP_SWATCH_SELECTOR_H - - #include class SPDocument; class SPGradient; -class SPColorSelector; -class SPGradientSelector; +struct SPColorSelector; +struct SPGradientSelector; namespace Inkscape { diff --git a/src/xml/composite-node-observer.h b/src/xml/composite-node-observer.h index 96825d607..3e4b1673a 100644 --- a/src/xml/composite-node-observer.h +++ b/src/xml/composite-node-observer.h @@ -23,7 +23,7 @@ namespace Inkscape { namespace XML { -class NodeEventVector; +struct NodeEventVector; /** * @brief An observer that relays notifications to multiple other observers diff --git a/src/zoom-context.h b/src/zoom-context.h index e36dc3fbe..c09b5a1b3 100644 --- a/src/zoom-context.h +++ b/src/zoom-context.h @@ -19,9 +19,6 @@ #define SP_ZOOM_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_ZOOM_CONTEXT, SPZoomContext)) #define SP_IS_ZOOM_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_ZOOM_CONTEXT)) -class SPZoomContext; -class SPZoomContextClass; - struct SPZoomContext { SPEventContext event_context; SPCanvasItem *grabbed; -- cgit v1.2.3 From b887e821e03cae71b2116d58e64efb62eb9be0be Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 20 Mar 2013 01:47:49 +0100 Subject: For testing, widget added, regression fixed (bzr r11950.1.62) --- src/live_effects/lpe-bspline.cpp | 35 ++++++++++++++++++++++++----------- src/live_effects/lpe-bspline.h | 18 +++++++++--------- src/pen-context.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 7 ++++++- 4 files changed, 40 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index e6461e94c..d3c64bb67 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -11,6 +11,7 @@ #include #include "sp-path.h" #include "style.h" +#include "document-private.h" #include "document.h" #include "document-undo.h" #include "desktop-handles.h" @@ -45,9 +46,9 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, Geom::Point(100,100)), + steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2), ignoreCusp(_("Ignore cusp nodes:"), _("Change ignoring cusp nodes"), "ignoreCusp", &wr, this, true), - weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, 33.33), - steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2) + weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, 33.33) { registerParameter( dynamic_cast(&ignoreCusp) ); registerParameter( dynamic_cast(&weight) ); @@ -64,11 +65,24 @@ LPEBSpline::~LPEBSpline() { } -void -LPEBSpline::doOnApply(SPLPEItem const* lpeitem) +void +LPEBSpline::createAndApply(const char* name, SPDocument *doc, SPItem *item) { - if (!SP_IS_SHAPE(lpeitem)) { + if (!SP_IS_SHAPE(item)) { g_warning("LPE BSpline can only be applied to shapes (not groups)."); + }else{ + // Path effect definition + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); + repr->setAttribute("effect", name); + + doc->getDefs()->getRepr()->addChild(repr, NULL); // adds to and assigns the 'id' attribute + const gchar * repr_id = repr->attribute("id"); + Inkscape::GC::release(repr); + + gchar *href = g_strdup_printf("#%s", repr_id); + sp_lpe_item_add_path_effect(SP_LPE_ITEM(item), href, true); + g_free(href); } } @@ -289,16 +303,15 @@ LPEBSpline::newWidget() void LPEBSpline::toDefaultWeight(){ -double weightValue = 0.3333; -changeWeight(weightValue); -weight.param_set_value(33.33); -gtk_widget_draw(GTK_WIDGET(LPEBSpline::newWidget()), NULL); + double weightValue = 0.3334; + weight.param_set_value(33.33); + changeWeight(weightValue); } void LPEBSpline::toWeight(){ -double weightValue = weight/100; -changeWeight(weightValue); + double weightValue = weight/100; + changeWeight(weightValue); } void diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 10d157ac1..44c3f451c 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -15,20 +15,13 @@ namespace LivePathEffect { class LPEBSpline : public Effect { -private: - BoolParam ignoreCusp; - ScalarParam weight; - - LPEBSpline(const LPEBSpline&); - LPEBSpline& operator=(const LPEBSpline&); - public: LPEBSpline(LivePathEffectObject *lpeobject); virtual ~LPEBSpline(); - virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } + virtual void createAndApply(const char* name, SPDocument *doc, SPItem *item); - virtual void doOnApply(SPLPEItem const* lpeitem); + virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } virtual void doEffect(SPCurve * curve); @@ -44,6 +37,13 @@ public: ScalarParam steps; +private: + BoolParam ignoreCusp; + ScalarParam weight; + + LPEBSpline(const LPEBSpline&); + LPEBSpline& operator=(const LPEBSpline&); + }; }; //namespace LivePathEffect diff --git a/src/pen-context.cpp b/src/pen-context.cpp index b43c2ff19..6f61ceb99 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1791,7 +1791,7 @@ static void bspline_spiro_build(SPPenContext *const pc) //We create the base curve SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start - if(pc->sa && !pc->sa->curve->is_empty() &&1>2){ + if(pc->sa && !pc->sa->curve->is_empty()){ curve = pc->sa->curve->copy(); if (pc->sa->start) { curve = curve->create_reverse(); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 853d9336a..c3ab19a4e 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1176,7 +1176,12 @@ void PathManipulator::_createControlPointsFromGeometry() bool PathManipulator::isBSpline(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ - lpe_bsp = dynamic_cast(sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE)->getLPEObj()->get_lpe()); + Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + }else{ + lpe_bsp = NULL; + } }else{ lpe_bsp = NULL; } -- cgit v1.2.3 From 49c304e53558c96b2442c06c9beccf5082bb8fe2 Mon Sep 17 00:00:00 2001 From: jtx Date: Wed, 20 Mar 2013 18:12:37 +0100 Subject: Fixing node fault (bzr r11950.4.2) --- src/ui/tool/multi-path-manipulator.cpp | 2 +- src/ui/tool/node.cpp | 47 +++++++++++++--------------------- src/ui/tool/node.h | 8 ++++-- 3 files changed, 25 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 3623bb006..94860093d 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -307,7 +307,7 @@ void MultiPathManipulator::setNodeType(NodeType type) Node *node = dynamic_cast(*i); if (node) { retract_handles &= (node->type() == NODE_CUSP); - node->setType(type,true); + node->setType(type); } } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index e0aec8bb5..738d98e82 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,6 +113,7 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _degenerate(true),controlBsplineSteps(2) { setVisible(false); + isBSpline = _pm().isBSpline; } Handle::~Handle() @@ -143,8 +144,7 @@ void Handle::move(Geom::Point const &new_pos) double pos = 0; Handle *h = NULL; Handle *h2 = NULL; - if(_pm().isBSpline){ - isBSpline = true; + if(isBSpline){ typedef ControlPointSelection::Set Set; Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -324,7 +324,7 @@ bool Handle::_eventHandler(SPEventContext *event_context, GdkEvent *event) //BSpline void Handle::handle_2button_press(){ - if(_pm().isBSpline){ + if(isBSpline){ Handle *h = NULL; Handle *h2 = NULL; double pos = 0; @@ -386,7 +386,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } new_pos = result; //BSpline - if(_pm().isBSpline){ + if(isBSpline){ Handle *h = NULL; double pos = 0; h = this; @@ -398,7 +398,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - if (snap && ( (!held_control(*event) && _pm().isBSpline) || !_pm().isBSpline)) { + if (snap && ( (!held_control(*event) && isBSpline) || !isBSpline)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -580,6 +580,7 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { // NOTE we do not set type here, because the handles are still degenerate + isBSpline = _pm().isBSpline; } Node const *Node::_next() const @@ -625,7 +626,7 @@ void Node::move(Geom::Point const &new_pos) Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - if(_pm().isBSpline){ + if(isBSpline){ if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); pos = _pm().BSplineHandlePosition(n->front()); @@ -637,7 +638,7 @@ void Node::move(Geom::Point const &new_pos) //BSpline End setPosition(new_pos); //BSpline - if(_pm().isBSpline){ + if(isBSpline){ if(prevNode) prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); if(nextNode) @@ -651,7 +652,7 @@ void Node::move(Geom::Point const &new_pos) // with the segment _fixNeighbors(old_pos, new_pos); //BSpline - if(_pm().isBSpline){ + if(isBSpline){ Handle* front = &_front; Handle* back = &_back; _front.setPosition(_pm().BSplineHandleReposition(front,pos)); @@ -773,27 +774,6 @@ void Node::setType(NodeType type, bool update_handles) return; } - //BSpline - if(_pm().isBSpline){ - if (isEndNode()) return; - Handle* front = &_front; - Handle* back = &_back; - double pos = 0.3334; - switch (type) { - case NODE_CUSP: - if(update_handles) - pos = 0; - else - pos = _pm().BSplineHandlePosition(front);; - break; - default: break; - } - type = NODE_CUSP; - _front.setPosition(_pm().BSplineHandleReposition(front,pos)); - _back.setPosition(_pm().BSplineHandleReposition(back,pos)); - } - //BSpline End - // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -882,6 +862,15 @@ void Node::setType(NodeType type, bool update_handles) _setControlType(nodeTypeToCtrlType(_type)); updateState(); + //BSpline + if(isBSpline){ + Handle* front = &_front; + Handle* back = &_back; + double pos = _pm().BSplineHandlePosition(front); + _front.setPosition(_pm().BSplineHandleReposition(front,pos)); + _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + } + //BSpline End } void Node::pickBestType() diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 7152f37fd..a384db7cc 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -120,7 +120,9 @@ protected: virtual bool _hasDragTips() const { return true; } private: - + //BSpline + bool isBSpline; + //BSpline End inline PathManipulator &_pm(); Node *_parent; // the handle's lifetime does not extend beyond that of the parent node, // so a naked pointer is OK and allows setting it during Node's construction @@ -236,7 +238,9 @@ protected: virtual bool _hasDragTips() const { return true; } private: - + //BSpline + bool isBSpline; + //BSpline End Node(Node const &); void _fixNeighbors(Geom::Point const &old_pos, Geom::Point const &new_pos); void _updateAutoHandles(); -- cgit v1.2.3 From d8278200b80518c4a7c2f4fda642102ff268851d Mon Sep 17 00:00:00 2001 From: jtx Date: Wed, 20 Mar 2013 18:50:31 +0100 Subject: Fixing node fault (bzr r11950.4.3) --- src/ui/tool/node.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 738d98e82..93b45bde7 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,7 +113,12 @@ Handle::Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node _degenerate(true),controlBsplineSteps(2) { setVisible(false); - isBSpline = _pm().isBSpline; + std::string strPathManipulatorName = "PathManipulator"; + if(std::string(typeid(_pm()).name()) == strPathManipulatorName) + isBSpline = _pm().isBSpline; + else + //Esto no es cierto realmente pero evita que casque al crear nodos + isBSpline = false; } Handle::~Handle() @@ -580,7 +585,12 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { // NOTE we do not set type here, because the handles are still degenerate - isBSpline = _pm().isBSpline; + std::string strPathManipulatorName = "PathManipulator"; + if(std::string(typeid(_pm()).name()) == strPathManipulatorName) + isBSpline = _pm().isBSpline; + else + //Esto no es cierto realmente pero evita que casque al crear nodos + isBSpline = false; } Node const *Node::_next() const -- cgit v1.2.3 From f99e35afe4c7d572a5e3a98b12571e577c1b3d14 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 21 Mar 2013 02:39:16 +0100 Subject: Fixed redraw handles at node delete (bzr r11950.1.64) --- src/ui/tool/path-manipulator.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fc4439711..431cc2d96 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -664,12 +664,6 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite start.prev()->front()->setPosition(result[1]); end->back()->setPosition(result[2]); - //BSpline - if(isBSpline){ - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front())); - end->back()->setPosition(BSplineHandleReposition(end->back())); - } - //BSpline End } // We can't use nl->erase(start, end), because it would break when the stretch @@ -680,6 +674,12 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } + //BSpline + if(isBSpline){ + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front())); + end->back()->setPosition(BSplineHandleReposition(end->back())); + } + //BSpline End return del_len; } -- cgit v1.2.3 From a60fc5880c9bab8bf471c2ef808499182201b621 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 21 Mar 2013 10:53:39 +0100 Subject: Fixing errors at delete extrewmiuns nodes (bzr r11950.1.65) --- src/ui/tool/path-manipulator.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 431cc2d96..571e6dd7a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1197,13 +1197,19 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ double pos = 0; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); - Node * nextNode = n->nodeToward(h); - Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); - if(nextNode && n->position() != h->position()){ - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); + Node * nextNode = NULL; + try{ + nextNode = n->nodeToward(h); + }catch( char * str ) { + } + if(nextNode){ + Geom::Point positionH = h->position(); + positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + if(nextNode && n->position() != h->position()){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); + } } return pos; } @@ -1220,7 +1226,11 @@ 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); + Node * nextNode = NULL; + try{ + nextNode = n->nodeToward(h); + }catch( char * str ) { + } if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); -- cgit v1.2.3 From d142ebe8740c40922c1a6aa423ca4e0e7d2335d6 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 22 Mar 2013 01:50:18 +0100 Subject: Fixed end extremium node delete fault, ready for testing (bzr r11950.1.66) --- src/live_effects/lpe-bspline.h | 1 + src/ui/tool/path-manipulator.cpp | 36 +++++++++++++++++++++++------------- src/ui/tool/path-manipulator.h | 6 +++++- src/widgets/toolbox.cpp | 6 +++--- 4 files changed, 32 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 44c3f451c..20012f894 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -38,6 +38,7 @@ public: ScalarParam steps; private: + BoolParam ignoreCusp; ScalarParam weight; diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 571e6dd7a..8f6651dee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -9,9 +9,7 @@ * Copyright (C) 2009 Authors * Released under GNU GPL, read the file 'COPYING' for more information */ -//BSpline -#include "live_effects/lpe-bspline.h" -//BSpline end + #include "live_effects/lpe-powerstroke.h" #include #include @@ -46,6 +44,9 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" +//BSpline +#include "live_effects/lpe-bspline.h" +//BSpline end namespace Inkscape { namespace UI { @@ -149,8 +150,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - - LivePathEffect::LPEBSpline *lpe_bsp = NULL; + //BSpline + lpe_bsp = NULL; if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ @@ -162,6 +163,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, isBSpline = true; controlBSplineSteps = lpe_bsp->steps+1; } + //BSpline End } PathManipulator::~PathManipulator() @@ -676,8 +678,15 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite } //BSpline if(isBSpline){ - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front())); - end->back()->setPosition(BSplineHandleReposition(end->back())); + double pos = 0; + if(start.prev()){ + pos = BSplineHandlePosition(start.prev()->back()); + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),pos)); + } + if(end){ + pos = BSplineHandlePosition(end->front()); + end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); + } } //BSpline End @@ -1192,16 +1201,19 @@ void PathManipulator::_createControlPointsFromGeometry() } double PathManipulator::BSplineHandlePosition(Handle *h){ + //BSpline + if(lpe_bsp){ + controlBSplineSteps = lpe_bsp->steps+1; + } + //BSpline End using Geom::X; using Geom::Y; double pos = 0; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - try{ + if(!n->isEndNode()) nextNode = n->nodeToward(h); - }catch( char * str ) { - } if(nextNode){ Geom::Point positionH = h->position(); positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); @@ -1227,10 +1239,8 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - try{ + if(!n->isEndNode()) nextNode = n->nodeToward(h); - }catch( char * str ) { - } if(nextNode && pos != 0){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 948d4544b..496bd957c 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -19,6 +19,9 @@ #include #include "ui/tool/node.h" #include "ui/tool/manipulator.h" +//BSpline +#include "live_effects/lpe-bspline.h" +//BSpline end struct SPCanvasItem; class SPCurve; @@ -96,6 +99,7 @@ public: bool search_unselected, bool closest); //BSpline bool isBSpline; + int controlBSplineSteps; //BSpline End // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -107,7 +111,7 @@ private: void _createControlPointsFromGeometry(); //BSpline - int controlBSplineSteps; + LivePathEffect::LPEBSpline *lpe_bsp; double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 3a7eb6b9c..99978c019 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -514,9 +514,9 @@ static gchar const * ui_descr = " " " " " " -// " " -// " " -// " " + " " + " " + " " " " " " -- cgit v1.2.3 From ce36f79a45c3ce7e520c14b6cab965c0bd9a32fa Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 22 Mar 2013 09:48:09 +0100 Subject: Enabling Mesh (bzr r11950.1.67) --- src/widgets/toolbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 99978c019..3ffeff1fd 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -113,7 +113,7 @@ enum BarId { #define BAR_ID_KEY "BarIdValue" #define HANDLE_POS_MARK "x-inkscape-pos" - +#define WITH_MESH static GtkWidget *sp_empty_toolbox_new(SPDesktop *desktop); -- cgit v1.2.3 From c34969161a38e67408b654a8b308b45ca638811f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 23 Mar 2013 15:57:26 +0100 Subject: Remove extra code (bzr r11950.1.69) --- src/ui/tool/path-manipulator.cpp | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 84e300306..f8c5deea2 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -841,11 +841,6 @@ void PathManipulator::scaleHandle(Node *n, int which, int dir, bool pixel) relpos *= ((rellen + length_change) / rellen); } h->setRelativePos(relpos); - - if(isBSpline){ - double pos = BSplineHandlePosition(h); - h->setPosition(BSplineHandleReposition(h,pos)); - } update(); gchar const *key = which < 0 ? "handle:scale:left" : "handle:scale:right"; _commit(_("Scale handle"), key); @@ -870,12 +865,6 @@ void PathManipulator::rotateHandle(Node *n, int which, int dir, bool pixel) } h->setRelativePos(h->relativePos() * Geom::Rotate(angle)); - - if(isBSpline){ - double pos = BSplineHandlePosition(h); - h->setPosition(BSplineHandleReposition(h,pos)); - } - update(); gchar const *key = which < 0 ? "handle:rotate:left" : "handle:rotate:right"; -- cgit v1.2.3 From 37d99686ec9b0a49c1ef07483967571da674e65e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 23 Mar 2013 20:09:28 +0100 Subject: Fix weight 0 by widget now give a full cusp node (bzr r11950.1.70) --- src/live_effects/lpe-bspline.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 0a13c17b2..ee771a54e 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -399,20 +399,20 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignor pointAt0 = in->first_segment()->initialPoint(); SBasisIn = in->first_segment()->toSBasis(); if(cubic){ - if(!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())){ + if((!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())) && weightValue !=0){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); }else{ pointAt1 = in->first_segment()->initialPoint(); } - if(!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())){ + if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ pointAt2 = SBasisIn.valueAt(1-weightValue); pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ pointAt2 = in->first_segment()->finalPoint(); } }else{ - if(!ignoreCusp){ + if(!ignoreCusp && weightValue !=0){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); pointAt2 = SBasisIn.valueAt(1-weightValue); @@ -433,20 +433,20 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignor SBasisOut = out->first_segment()->toSBasis(); cubic = dynamic_cast(&*curve_it2); if(cubic){ - if(!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint())){ + if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint()))&& weightValue !=0){ nextPointAt1 = SBasisOut.valueAt(weightValue); nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); }else{ nextPointAt1 = out->first_segment()->initialPoint(); } - if(!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint())){ + if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint()))&& weightValue !=0){ nextPointAt2 = SBasisOut.valueAt(1-weightValue); nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ nextPointAt2 = out->first_segment()->finalPoint(); } }else{ - if(!ignoreCusp){ + if(!ignoreCusp && weightValue !=0){ nextPointAt1 = SBasisOut.valueAt(weightValue); nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); nextPointAt2 = SBasisOut.valueAt(1-weightValue); -- cgit v1.2.3 From dc09bd5bbbacdf10d28ee9053ce3c74f87753f3e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 29 Mar 2013 12:34:40 +0100 Subject: Fix bspline icon show (bzr r11950.1.77) --- src/widgets/mappings.xml | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/widgets/mappings.xml b/src/widgets/mappings.xml index 2de3ff545..089bf76ea 100644 --- a/src/widgets/mappings.xml +++ b/src/widgets/mappings.xml @@ -197,6 +197,7 @@ + -- cgit v1.2.3 From a7ced41f3fa6933d0da0151ef42e82e0862581fb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 1 Apr 2013 01:09:52 +0200 Subject: Fix scale and rotate some nodes (bzr r11950.1.78) --- src/live_effects/lpe-bspline.cpp | 22 ++++++++++++++++++++- src/ui/tool/node.cpp | 41 ++++++++++++++++++++-------------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 26 ++++++++++++++++--------- src/ui/tool/path-manipulator.h | 1 + 5 files changed, 60 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index ee771a54e..37d6a86a5 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -29,6 +29,7 @@ #include "ui/widget/scalar.h" #include "selection.h" #include "gtkmm/checkbutton.h" +#include "ui/tool/node.h" // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -337,15 +338,34 @@ LPEBSpline::changeWeight(double weightValue) DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, _("Modified the weight of the BSpline")); } - +//bool +//LPEBspline::selectedPoint(Geom::Point p){ +// for (SubpathList::iterator i = NodeIterator.begin(); i != NodeIterator.end(); ++i) { +// if (i->selected() && i.ptr()->getPosition() == p) { +// return true; +// } +// } +// return false; +//} +//bool +//LPEBspline::hasNodesSelected(){ +// for (SubpathList::iterator i = NodeIterator.begin(); i != NodeIterator.end(); ++i) { +// if (i->selected() && i.ptr()->getPosition() == p) { +// return true; +// } +// } +// return false; +//} void LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignoreCusp) { using Geom::X; using Geom::Y; + //bool hasNodesSelected = LPEBspline::hasNodesSelected(); if(curve->get_segment_count() < 2) return; // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index b4976bde5..dfa9c5d84 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -139,7 +139,6 @@ void Handle::move(Geom::Point const &new_pos) Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; //BSpline - double pos = 0; Handle *h = NULL; Handle *h2 = NULL; if(_pm().isBSpline){ @@ -189,9 +188,9 @@ void Handle::move(Geom::Point const &new_pos) if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); - pos = _pm().BSplineHandlePosition(h); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } //BSpline End return; @@ -228,9 +227,9 @@ void Handle::move(Geom::Point const &new_pos) if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); - pos = _pm().BSplineHandlePosition(h); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } //BSpline End } @@ -325,12 +324,12 @@ void Handle::handle_2button_press(){ if(_pm().isBSpline){ Handle *h = NULL; Handle *h2 = NULL; - double pos = 0; + _parent->bsplineWeight = 0; h = this; setPosition(_pm().BSplineHandleReposition(h,0.3334)); - pos = _pm().BSplineHandlePosition(h); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos)); + this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); _pm().update(); } } @@ -386,12 +385,12 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) //BSpline if(_pm().isBSpline){ Handle *h = NULL; - double pos = 0; + _parent->bsplineWeight = 0; h = this; setPosition(new_pos); int steps = _pm().getSteps(); - pos = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; - new_pos=_pm().BSplineHandleReposition(h,pos); + _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; + new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); } //BSpline End } @@ -579,6 +578,7 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { // NOTE we do not set type here, because the handles are still degenerate + this->bsplineWeight = 0.3334; } Node const *Node::_next() const @@ -619,7 +619,6 @@ void Node::move(Geom::Point const &new_pos) Geom::Point delta = new_pos - position(); //BSpline double prevPos = 0; - double pos = 0; double nextPos = 0; Node *n = this; Node * nextNode = n->nodeToward(n->front()); @@ -627,9 +626,9 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline){ if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); - pos = _pm().BSplineHandlePosition(n->front()); - if(pos == 0) - pos = _pm().BSplineHandlePosition(n->back()); + n->bsplineWeight = _pm().BSplineHandlePosition(n->front()); + if(n->bsplineWeight == 0) + n->bsplineWeight = _pm().BSplineHandlePosition(n->back()); if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); } @@ -653,8 +652,8 @@ void Node::move(Geom::Point const &new_pos) if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; - _front.setPosition(_pm().BSplineHandleReposition(front,pos)); - _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + _front.setPosition(_pm().BSplineHandleReposition(front,n->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(back,n->bsplineWeight)); } } @@ -864,10 +863,10 @@ void Node::setType(NodeType type, bool update_handles) if(isBSpline){ Handle* front = &_front; Handle* back = &_back; - double pos = _pm().BSplineHandlePosition(front); - if(pos !=0) pos = 0.3334; - _front.setPosition(_pm().BSplineHandleReposition(front,pos)); - _back.setPosition(_pm().BSplineHandleReposition(back,pos)); + this->bsplineWeight = _pm().BSplineHandlePosition(front); + if(this->bsplineWeight !=0) this->bsplineWeight = 0.3334; + _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); } //BSpline End } diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 2b547256b..f6d5beadc 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -180,7 +180,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - + double bsplineWeight; /** * Gets the handle that faces the given adjacent node. * Will abort with error if the given node is not adjacent. diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1607585c5..be5514e1f 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -862,7 +862,6 @@ void PathManipulator::rotateHandle(Node *n, int which, int dir, bool pixel) int snaps = prefs->getIntLimited("/options/rotationsnapsperpi/value", 12, 1, 1000); angle = M_PI * dir / snaps; } - h->setRelativePos(h->relativePos() * Geom::Rotate(angle)); update(); @@ -1211,14 +1210,12 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ Node * nextNode = NULL; if(!n->isEndNode()) nextNode = n->nodeToward(h); - if(nextNode){ - Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); - if(nextNode && n->position() != h->position()){ - lineInsideNodes->moveto(n->position()); - lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); - } + Geom::Point positionH = h->position(); + positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + if(nextNode && n->position() != h->position()){ + lineInsideNodes->moveto(n->position()); + lineInsideNodes->lineto(nextNode->position()); + pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); } return pos; } @@ -1250,6 +1247,11 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } +void PathManipulator::BSplineNodeHandlesReposition(Node *n){ + n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); + n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); +} + /** 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 @@ -1264,8 +1266,14 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); + if(isBSpline){ + BSplineNodeHandlesReposition(prev.ptr()); + } builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { + if(isBSpline){ + BSplineNodeHandlesReposition(i.ptr()); + } build_segment(builder, prev.ptr(), i.ptr()); prev = i; } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index e68cabef1..743d70b96 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -115,6 +115,7 @@ private: double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); + void BSplineNodeHandlesReposition(Node *n); //BSpline End void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); -- cgit v1.2.3 From 6ffc63f4ecd0550225a6fc752aba128575733a22 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 1 Apr 2013 10:03:19 +0200 Subject: Fixed scale-rotate isue with paths multiples (bzr r11950.1.80) --- src/ui/tool/node.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index dfa9c5d84..1f609dfa0 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1118,6 +1118,12 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); + //BSpline + if(_pm().isBSpline){ + this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); + _pm().BSplineNodeHandlesReposition(this); + } + //BSpline End break; } SelectableControlPoint::_setState(state); -- cgit v1.2.3 From 0b6a723f67700368d3585fc9b8009a3db30b5473 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 4 Apr 2013 19:34:41 +0200 Subject: Changing width only to selected nodes (bzr r11950.1.81) --- src/live_effects/lpe-bspline.cpp | 282 ++++++++++++++++++++++++++++----------- src/live_effects/lpe-bspline.h | 9 +- 2 files changed, 214 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 37d6a86a5..389c11a23 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -3,12 +3,25 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ - -#include "xml/repr.h" -#include "svg/svg.h" -#include "display/curve.h" +#include +#include +#include #include #include +#include "display/curve.h" +#include <2geom/bezier-curve.h> +#include "helper/geom-curves.h" +#include "live_effects/lpe-bspline.h" +#include "live_effects/lpeobject.h" +#include "live_effects/parameter/parameter.h" +#include "ui/widget/scalar.h" +#include "ui/tool/node.h" +#include "ui/tool/node-tool.h" +#include "ui/tool/control-point-selection.h" +#include "ui/tool/selectable-control-point.h" +#include "selection.h" +#include "xml/repr.h" +#include "svg/svg.h" #include "sp-path.h" #include "style.h" #include "document-private.h" @@ -16,20 +29,10 @@ #include "document-undo.h" #include "desktop-handles.h" #include "verbs.h" -#include "live_effects/lpe-bspline.h" -#include -#include #include "sp-lpe-item.h" -#include "live_effects/lpeobject.h" -#include "live_effects/parameter/parameter.h" #include "display/sp-canvas.h" #include -#include <2geom/bezier-curve.h> -#include "helper/geom-curves.h" -#include "ui/widget/scalar.h" -#include "selection.h" -#include "gtkmm/checkbutton.h" -#include "ui/tool/node.h" +#include // For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" @@ -49,9 +52,11 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, Geom::Point(100,100)), steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2), ignoreCusp(_("Ignore cusp nodes:"), _("Change ignoring cusp nodes"), "ignoreCusp", &wr, this, true), + onlySelected(_("Change only selected nodes:"), _("Change only selected nodes"), "onlySelected", &wr, this, false), weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, 0.3334) { registerParameter( dynamic_cast(&ignoreCusp) ); + registerParameter( dynamic_cast(&onlySelected) ); registerParameter( dynamic_cast(&weight) ); registerParameter( dynamic_cast(&steps) ); weight.param_set_range(0.0000, 1); @@ -279,6 +284,10 @@ LPEBSpline::newWidget() widgRegistered->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::toWeight)); widg = dynamic_cast(widgRegistered); } + if(param->param_key == "onlySelected"){ + Gtk::CheckButton * widgRegistered = Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widgRegistered); + } if(param->param_key == "ignoreCusp"){ Gtk::CheckButton * widgRegistered = Gtk::manage(dynamic_cast(widg)); widg = dynamic_cast(widgRegistered); @@ -307,7 +316,7 @@ LPEBSpline::newWidget() void LPEBSpline::toDefaultWeight(){ - Gtk::Widget * widg = dynamic_cast(param_vector[2]->param_newWidget()); + Gtk::Widget * widg = dynamic_cast(param_vector[3]->param_newWidget()); Inkscape::UI::Widget::Scalar * widgRegistered = Gtk::manage(dynamic_cast(widg)); widgRegistered->setValue(0.3334); widgRegistered->update(); @@ -329,7 +338,7 @@ LPEBSpline::changeWeight(double weightValue) SPItem *item = (SPItem *)g_slist_nth(items,0)->data; SPPath *path = SP_PATH(item); SPCurve *curve = path->get_curve_for_edit(); - LPEBSpline::doBSplineFromWidget(curve,weightValue,ignoreCusp); + LPEBSpline::doBSplineFromWidget(curve,weightValue); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); g_free(str); @@ -338,34 +347,42 @@ LPEBSpline::changeWeight(double weightValue) DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, _("Modified the weight of the BSpline")); } -//bool -//LPEBspline::selectedPoint(Geom::Point p){ -// for (SubpathList::iterator i = NodeIterator.begin(); i != NodeIterator.end(); ++i) { -// if (i->selected() && i.ptr()->getPosition() == p) { -// return true; -// } -// } -// return false; -//} -//bool -//LPEBspline::hasNodesSelected(){ -// for (SubpathList::iterator i = NodeIterator.begin(); i != NodeIterator.end(); ++i) { -// if (i->selected() && i.ptr()->getPosition() == p) { -// return true; -// } -// } -// return false; -//} + +bool +LPEBSpline::nodeIsSelected(Geom::Point nodePoint, int index){ + volatile int index2 = index; + volatile Geom::Point aa = nodePoint; + volatile std::vector x2 = points; + if(points.size() > 0){ + volatile double dist = Geom::distance(points[index], nodePoint); + if(dist == 0 ){ + return true; + } + } + return false; +} + void -LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignoreCusp) +LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) { using Geom::X; using Geom::Y; + SPDesktop *desktop = inkscape_active_desktop(); + if(INK_IS_NODE_TOOL(desktop->event_context)){ + InkNodeTool *nt = INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::ControlPointSelection::Set &selection = nt->_selected_nodes->allPoints(); + points.clear(); + for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i){ + if ((*i)->selected()) { + Inkscape::UI::Node *n = static_cast(*i); + points.push_back(n->position()); + } + } + } //bool hasNodesSelected = LPEBspline::hasNodesSelected(); if(curve->get_segment_count() < 2) return; // Make copy of old path as it is changed during processing - Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); @@ -388,12 +405,14 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignor Geom::Point pointAt1(0,0); Geom::Point pointAt2(0,0); Geom::Point pointAt3(0,0); + Geom::Point nextPointAt0(0,0); Geom::Point nextPointAt1(0,0); Geom::Point nextPointAt2(0,0); Geom::Point nextPointAt3(0,0); Geom::D2< Geom::SBasis > SBasisIn; Geom::D2< Geom::SBasis > SBasisOut; Geom::CubicBezier const *cubic = NULL; + int i = 0; if (path_it->closed()) { // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. @@ -417,32 +436,88 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignor in->lineto(curve_it1->finalPoint()); cubic = dynamic_cast(&*curve_it1); pointAt0 = in->first_segment()->initialPoint(); + pointAt3 = in->first_segment()->finalPoint(); SBasisIn = in->first_segment()->toSBasis(); - if(cubic){ - if((!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())) && weightValue !=0){ - pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + if(!onlySelected){ + if(cubic){ + if((!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())) && weightValue !=0){ + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + } + if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ + pointAt2 = SBasisIn.valueAt(1-weightValue); + pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ - pointAt1 = in->first_segment()->initialPoint(); - } - if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ - pointAt2 = SBasisIn.valueAt(1-weightValue); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); - }else{ - pointAt2 = in->first_segment()->finalPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } + }else{ + if(!ignoreCusp && weightValue !=0){ + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + pointAt2 = SBasisIn.valueAt(1-weightValue); + pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } } }else{ - if(!ignoreCusp && weightValue !=0){ - pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); - pointAt2 = SBasisIn.valueAt(1-weightValue); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + if(cubic){ + if((!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())) && weightValue !=0){ + if(nodeIsSelected(pointAt0,i)){ + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + }else{ + pointAt1 = (*cubic)[1]; + } + }else{ + if(nodeIsSelected(pointAt0,i)){ + pointAt1 = in->first_segment()->initialPoint(); + }else{ + pointAt1 = (*cubic)[1]; + } + } + i++; + if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ + if(nodeIsSelected(pointAt3,i)){ + pointAt2 = SBasisIn.valueAt(1-weightValue); + pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + }else{ + pointAt2 = (*cubic)[2]; + i--; + } + }else{ + if(nodeIsSelected(pointAt3,i)){ + pointAt2 = in->first_segment()->finalPoint(); + }else{ + pointAt2 = (*cubic)[2]; + i--; + } + } }else{ - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); + if(!ignoreCusp && weightValue !=0){ + if(nodeIsSelected(pointAt0,i)){ + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + }else{ + pointAt1 = in->first_segment()->initialPoint(); + } + i++; + if(nodeIsSelected(pointAt3,i)){ + pointAt2 = SBasisIn.valueAt(weightValue); + pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + }else{ + pointAt2 = in->first_segment()->finalPoint(); + i--; + } + }else{ + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } } } - pointAt3 = in->first_segment()->finalPoint(); in->reset(); delete in; //Y hacemos lo propio con el path de salida @@ -451,32 +526,89 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue , bool ignor out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); SBasisOut = out->first_segment()->toSBasis(); + nextPointAt0 = out->first_segment()->initialPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); cubic = dynamic_cast(&*curve_it2); - if(cubic){ - if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint()))&& weightValue !=0){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + if(!onlySelected){ + if(cubic){ + if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint()))&& weightValue !=0){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + } + if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint()))&& weightValue !=0){ + nextPointAt2 = SBasisOut.valueAt(1-weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + }else{ + nextPointAt2 = out->first_segment()->finalPoint(); + } }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - } - if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint()))&& weightValue !=0){ - nextPointAt2 = SBasisOut.valueAt(1-weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); - }else{ - nextPointAt2 = out->first_segment()->finalPoint(); + if(!ignoreCusp && weightValue !=0){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + nextPointAt2 = SBasisOut.valueAt(1-weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + } } }else{ - if(!ignoreCusp && weightValue !=0){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); - nextPointAt2 = SBasisOut.valueAt(1-weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + if(cubic){ + if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint())) && weightValue !=0){ + if(nodeIsSelected(nextPointAt0,i)){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + }else{ + nextPointAt1 = (*cubic)[1]; + } + }else{ + if(nodeIsSelected(nextPointAt0,i)){ + nextPointAt1 = out->first_segment()->initialPoint(); + }else{ + nextPointAt1 = (*cubic)[1]; + } + } + i++; + if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint())) && weightValue !=0){ + if(nodeIsSelected(nextPointAt3,i)){ + nextPointAt2 = SBasisOut.valueAt(1-weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + }else{ + nextPointAt2 = (*cubic)[2]; + i--; + } + }else{ + if(nodeIsSelected(nextPointAt3,i)){ + nextPointAt2 = out->first_segment()->finalPoint(); + }else{ + nextPointAt2 = (*cubic)[2]; + i--; + } + } }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); + if(!ignoreCusp && weightValue !=0){ + if(nodeIsSelected(nextPointAt0,i)){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + } + i++; + if(nodeIsSelected(nextPointAt3,i)){ + nextPointAt2 = SBasisOut.valueAt(weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + }else{ + nextPointAt2 = out->first_segment()->finalPoint(); + i--; + } + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + } } } - nextPointAt3 = out->first_segment()->finalPoint(); out->reset(); delete out; //La curva BSpline se forma calculando el centro del segmanto de unión diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 20012f894..2361c10d0 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -9,6 +9,8 @@ #include "live_effects/effect.h" #include "live_effects/parameter/bool.h" +#include + namespace Inkscape { namespace LivePathEffect { @@ -25,7 +27,9 @@ public: virtual void doEffect(SPCurve * curve); - virtual void doBSplineFromWidget(SPCurve * curve, double value, bool noCusp); + virtual void doBSplineFromWidget(SPCurve * curve, double value); + + virtual bool nodeIsSelected(Geom::Point nodePoint, int index); virtual Gtk::Widget * newWidget(); @@ -38,8 +42,9 @@ public: ScalarParam steps; private: - + std::vector points; BoolParam ignoreCusp; + BoolParam onlySelected; ScalarParam weight; LPEBSpline(const LPEBSpline&); -- cgit v1.2.3 From 30858428c74d1fa0f119f40b99fa5e51836d8599 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 8 Apr 2013 00:50:31 +0200 Subject: Change width only for selected nodes by widget (bzr r11950.1.83) --- src/libavoid/makefile | 17 --------------- src/live_effects/lpe-bspline.cpp | 46 ++++++++++++++++++++++------------------ src/ui/tool/node.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 18 ++++++++++++++-- 4 files changed, 42 insertions(+), 41 deletions(-) delete mode 100644 src/libavoid/makefile (limited to 'src') diff --git a/src/libavoid/makefile b/src/libavoid/makefile deleted file mode 100644 index e4f83a52d..000000000 --- a/src/libavoid/makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Convenience stub makefile to call the real Makefile. - - - -OBJEXT = o - -# Explicit so that it's the default rule. -all: - cd .. && $(MAKE) libavoid/all - -clean %.a %.$(OBJEXT): - cd .. && $(MAKE) libavoid/$@ - -.PHONY: all clean - -.SUFFIXES: -.SUFFIXES: .a .$(OBJEXT) diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 389c11a23..e93fd62d2 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -10,6 +10,7 @@ #include #include "display/curve.h" #include <2geom/bezier-curve.h> +#include <2geom/point.h> #include "helper/geom-curves.h" #include "live_effects/lpe-bspline.h" #include "live_effects/lpeobject.h" @@ -341,6 +342,10 @@ LPEBSpline::changeWeight(double weightValue) LPEBSpline::doBSplineFromWidget(curve,weightValue); gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); + if(INK_IS_NODE_TOOL(desktop->event_context)){ + InkNodeTool *nt = INK_NODE_TOOL(desktop->event_context); + nt->desktop->updateNow(); + } g_free(str); curve->unref(); desktop->clearWaitingCursor(); @@ -350,12 +355,8 @@ LPEBSpline::changeWeight(double weightValue) bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint, int index){ - volatile int index2 = index; - volatile Geom::Point aa = nodePoint; - volatile std::vector x2 = points; if(points.size() > 0){ - volatile double dist = Geom::distance(points[index], nodePoint); - if(dist == 0 ){ + if(Geom::are_near(points[index], nodePoint)){ return true; } } @@ -373,9 +374,12 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) Inkscape::UI::ControlPointSelection::Set &selection = nt->_selected_nodes->allPoints(); points.clear(); for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i){ - if ((*i)->selected()) { - Inkscape::UI::Node *n = static_cast(*i); - points.push_back(n->position()); + if(onlySelected){ + if ((*i)->selected()) { + Inkscape::UI::Node *n = static_cast(*i); + n->bsplineWeight = weightValue; + points.insert(points.begin(),desktop->doc2dt(n->position())); + } } } } @@ -469,31 +473,30 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) if(nodeIsSelected(pointAt0,i)){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + i++; }else{ pointAt1 = (*cubic)[1]; } }else{ if(nodeIsSelected(pointAt0,i)){ pointAt1 = in->first_segment()->initialPoint(); + i++; }else{ pointAt1 = (*cubic)[1]; } } - i++; if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ if(nodeIsSelected(pointAt3,i)){ pointAt2 = SBasisIn.valueAt(1-weightValue); pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ pointAt2 = (*cubic)[2]; - i--; } }else{ if(nodeIsSelected(pointAt3,i)){ pointAt2 = in->first_segment()->finalPoint(); }else{ pointAt2 = (*cubic)[2]; - i--; } } }else{ @@ -501,20 +504,22 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) if(nodeIsSelected(pointAt0,i)){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + i++; }else{ pointAt1 = in->first_segment()->initialPoint(); } - i++; if(nodeIsSelected(pointAt3,i)){ pointAt2 = SBasisIn.valueAt(weightValue); pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ pointAt2 = in->first_segment()->finalPoint(); - i--; } }else{ pointAt1 = in->first_segment()->initialPoint(); pointAt2 = in->first_segment()->finalPoint(); + if(nodeIsSelected(pointAt0,i)){ + i++; + } } } } @@ -560,51 +565,50 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) if(nodeIsSelected(nextPointAt0,i)){ nextPointAt1 = SBasisOut.valueAt(weightValue); nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + if (path_it->closed()) i++; }else{ nextPointAt1 = (*cubic)[1]; } }else{ if(nodeIsSelected(nextPointAt0,i)){ - nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt1 = out->first_segment()->initialPoint(); + if (path_it->closed()) i++; }else{ nextPointAt1 = (*cubic)[1]; } } - i++; if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint())) && weightValue !=0){ if(nodeIsSelected(nextPointAt3,i)){ nextPointAt2 = SBasisOut.valueAt(1-weightValue); nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ nextPointAt2 = (*cubic)[2]; - i--; - } + } }else{ if(nodeIsSelected(nextPointAt3,i)){ nextPointAt2 = out->first_segment()->finalPoint(); }else{ nextPointAt2 = (*cubic)[2]; - i--; - } + } } }else{ if(!ignoreCusp && weightValue !=0){ if(nodeIsSelected(nextPointAt0,i)){ nextPointAt1 = SBasisOut.valueAt(weightValue); nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + if (path_it->closed()) i++; }else{ nextPointAt1 = out->first_segment()->initialPoint(); } - i++; if(nodeIsSelected(nextPointAt3,i)){ nextPointAt2 = SBasisOut.valueAt(weightValue); nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ nextPointAt2 = out->first_segment()->finalPoint(); - i--; } }else{ nextPointAt1 = out->first_segment()->initialPoint(); + if (path_it->closed()&&nodeIsSelected(nextPointAt0,i)) i++; nextPointAt2 = out->first_segment()->finalPoint(); } } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1f609dfa0..8f1c37649 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -577,8 +577,8 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _type(NODE_CUSP), _handles_shown(false) { - // NOTE we do not set type here, because the handles are still degenerate this->bsplineWeight = 0.3334; + // NOTE we do not set type here, because the handles are still degenerate } Node const *Node::_next() const diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index be5514e1f..6cad60fee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1248,8 +1248,22 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ } void PathManipulator::BSplineNodeHandlesReposition(Node *n){ - n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); - n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); + if(n->selected()){ + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + double prevPos = 0; + double nextPos = 0; + if(prevNode) + prevPos = BSplineHandlePosition(prevNode->front()); + if(nextNode) + nextPos = BSplineHandlePosition(nextNode->back()); + n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); + n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); + if(prevNode) + prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); + if(nextNode) + nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); + } } /** Construct the geometric representation of nodes and handles, update the outline -- cgit v1.2.3 From 2a873d7b420826f8d0e19d8a03f2b0efbbcac5c9 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 8 Apr 2013 00:55:28 +0200 Subject: adding fixed files from trunk (bzr r11950.1.84) --- src/libavoid/makefile | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/libavoid/makefile (limited to 'src') diff --git a/src/libavoid/makefile b/src/libavoid/makefile new file mode 100644 index 000000000..e4f83a52d --- /dev/null +++ b/src/libavoid/makefile @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + + + +OBJEXT = o + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) libavoid/all + +clean %.a %.$(OBJEXT): + cd .. && $(MAKE) libavoid/$@ + +.PHONY: all clean + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) -- cgit v1.2.3 From d2e58f51d29c5da3f82d29883c0a07ce9573f8ca Mon Sep 17 00:00:00 2001 From: root Date: Wed, 10 Apr 2013 06:08:17 +0200 Subject: fixing error moving selected nodes (bzr r11950.1.86) --- src/libavoid/makefile | 17 ------- src/live_effects/lpe-bspline.cpp | 102 +++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 69 deletions(-) delete mode 100644 src/libavoid/makefile (limited to 'src') diff --git a/src/libavoid/makefile b/src/libavoid/makefile deleted file mode 100644 index e4f83a52d..000000000 --- a/src/libavoid/makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Convenience stub makefile to call the real Makefile. - - - -OBJEXT = o - -# Explicit so that it's the default rule. -all: - cd .. && $(MAKE) libavoid/all - -clean %.a %.$(OBJEXT): - cd .. && $(MAKE) libavoid/$@ - -.PHONY: all clean - -.SUFFIXES: -.SUFFIXES: .a .$(OBJEXT) diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index e93fd62d2..657b2ded3 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -374,13 +374,10 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) Inkscape::UI::ControlPointSelection::Set &selection = nt->_selected_nodes->allPoints(); points.clear(); for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i){ - if(onlySelected){ if ((*i)->selected()) { Inkscape::UI::Node *n = static_cast(*i); - n->bsplineWeight = weightValue; points.insert(points.begin(),desktop->doc2dt(n->position())); } - } } } //bool hasNodesSelected = LPEBspline::hasNodesSelected(); @@ -416,7 +413,7 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) Geom::D2< Geom::SBasis > SBasisIn; Geom::D2< Geom::SBasis > SBasisOut; Geom::CubicBezier const *cubic = NULL; - int i = 0; + int j = 0; if (path_it->closed()) { // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. @@ -470,30 +467,30 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) }else{ if(cubic){ if((!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())) && weightValue !=0){ - if(nodeIsSelected(pointAt0,i)){ + if(nodeIsSelected(pointAt0,j)){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); - i++; + j++; }else{ pointAt1 = (*cubic)[1]; } }else{ - if(nodeIsSelected(pointAt0,i)){ + if(nodeIsSelected(pointAt0,j)){ pointAt1 = in->first_segment()->initialPoint(); - i++; + j++; }else{ pointAt1 = (*cubic)[1]; } } if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ - if(nodeIsSelected(pointAt3,i)){ + if(nodeIsSelected(pointAt3,j)){ pointAt2 = SBasisIn.valueAt(1-weightValue); pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ pointAt2 = (*cubic)[2]; } }else{ - if(nodeIsSelected(pointAt3,i)){ + if(nodeIsSelected(pointAt3,j)){ pointAt2 = in->first_segment()->finalPoint(); }else{ pointAt2 = (*cubic)[2]; @@ -501,14 +498,14 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) } }else{ if(!ignoreCusp && weightValue !=0){ - if(nodeIsSelected(pointAt0,i)){ + if(nodeIsSelected(pointAt0,j)){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); - i++; + j++; }else{ pointAt1 = in->first_segment()->initialPoint(); } - if(nodeIsSelected(pointAt3,i)){ + if(nodeIsSelected(pointAt3,j)){ pointAt2 = SBasisIn.valueAt(weightValue); pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ @@ -517,24 +514,42 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) }else{ pointAt1 = in->first_segment()->initialPoint(); pointAt2 = in->first_segment()->finalPoint(); - if(nodeIsSelected(pointAt0,i)){ - i++; + if(nodeIsSelected(pointAt0,j)){ + j++; } } } } in->reset(); delete in; - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); - SPCurve * out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt0 = out->first_segment()->initialPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - cubic = dynamic_cast(&*curve_it2); - if(!onlySelected){ + + //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 + SPCurve *curveHelper = new SPCurve(); + curveHelper->moveto(pointAt0); + curveHelper->curveto(pointAt1, pointAt2, pointAt3); + //añadimos la curva generada a la curva pricipal + nCurve->append_continuous(curveHelper, 0.0625); + curveHelper->reset(); + delete curveHelper; + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + } + //Aberiguamos la ultima parte de la curva correspondiente al último segmento + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + SPCurve * out = new SPCurve(); + out->moveto(curve_it1->initialPoint()); + out->lineto(curve_it1->finalPoint()); + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt0 = out->first_segment()->initialPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + cubic = dynamic_cast(&*curve_it1); + if(!onlySelected){ if(cubic){ if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint()))&& weightValue !=0){ nextPointAt1 = SBasisOut.valueAt(weightValue); @@ -562,30 +577,30 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) }else{ if(cubic){ if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint())) && weightValue !=0){ - if(nodeIsSelected(nextPointAt0,i)){ + if(nodeIsSelected(nextPointAt0,j)){ nextPointAt1 = SBasisOut.valueAt(weightValue); nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); - if (path_it->closed()) i++; + j++; }else{ nextPointAt1 = (*cubic)[1]; } }else{ - if(nodeIsSelected(nextPointAt0,i)){ + if(nodeIsSelected(nextPointAt0,j)){ nextPointAt1 = out->first_segment()->initialPoint(); - if (path_it->closed()) i++; + j++; }else{ nextPointAt1 = (*cubic)[1]; } } if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint())) && weightValue !=0){ - if(nodeIsSelected(nextPointAt3,i)){ + if(nodeIsSelected(nextPointAt3,j)){ nextPointAt2 = SBasisOut.valueAt(1-weightValue); nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ nextPointAt2 = (*cubic)[2]; } }else{ - if(nodeIsSelected(nextPointAt3,i)){ + if(nodeIsSelected(nextPointAt3,j)){ nextPointAt2 = out->first_segment()->finalPoint(); }else{ nextPointAt2 = (*cubic)[2]; @@ -593,14 +608,14 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) } }else{ if(!ignoreCusp && weightValue !=0){ - if(nodeIsSelected(nextPointAt0,i)){ + if(nodeIsSelected(nextPointAt0,j)){ nextPointAt1 = SBasisOut.valueAt(weightValue); nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); - if (path_it->closed()) i++; + j++; }else{ nextPointAt1 = out->first_segment()->initialPoint(); } - if(nodeIsSelected(nextPointAt3,i)){ + if(nodeIsSelected(nextPointAt3,j)){ nextPointAt2 = SBasisOut.valueAt(weightValue); nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ @@ -608,30 +623,13 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) } }else{ nextPointAt1 = out->first_segment()->initialPoint(); - if (path_it->closed()&&nodeIsSelected(nextPointAt0,i)) i++; + if(nodeIsSelected(nextPointAt0,j)) j++; nextPointAt2 = out->first_segment()->finalPoint(); } } } out->reset(); delete out; - //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 - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(pointAt0); - curveHelper->curveto(pointAt1, pointAt2, pointAt3); - //añadimos la curva generada a la curva pricipal - nCurve->append_continuous(curveHelper, 0.0625); - curveHelper->reset(); - delete curveHelper; - //aumentamos los valores para el siguiente paso en el bucle - ++curve_it1; - ++curve_it2; - } - //Aberiguamos la ultima parte de la curva correspondiente al último segmento SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(pointAt3); if (path_it->closed()) { -- cgit v1.2.3 From 1290320ca882992345418ce8572af053f1659628 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 10 Apr 2013 21:45:15 +0200 Subject: Fixed bug moving selected nodes (bzr r11950.1.88) --- src/live_effects/lpe-bspline.cpp | 168 ++++++++++++++------------------------- src/live_effects/lpe-bspline.h | 2 +- 2 files changed, 61 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index e7adab071..37bf24021 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -140,7 +140,7 @@ LPEBSpline::doEffect(SPCurve * curve) //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 - + nCurve->moveto(curve_it1->initialPoint()); //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { @@ -193,20 +193,11 @@ LPEBSpline::doEffect(SPCurve * curve) previousNode = node; //Y este hará de final de curva node = SBasisHelper.valueAt(0.5); - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(previousNode); - curveHelper->curveto(pointAt1, pointAt2, node); - //añadimos la curva generada a la curva pricipal - nCurve->append_continuous(curveHelper, 0.0625); - curveHelper->reset(); - delete curveHelper; + nCurve->curveto(pointAt1, pointAt2, node); //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; } - //Aberiguamos la ultima parte de la curva correspondiente al último segmento - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(node); //Si está cerrada la curva, la cerramos sobre el valor guardado previamente //Si no finalizamos en el punto final Geom::Point startNode(0,0); @@ -242,8 +233,7 @@ LPEBSpline::doEffect(SPCurve * curve) lineHelper->reset(); delete lineHelper; startNode = SBasisHelper.valueAt(0.5); - curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); - nCurve->append_continuous(curveHelper, 0.0625); + nCurve->curveto(nextPointAt1, nextPointAt2, startNode); nCurve->move_endpoints(startNode,startNode); }else{ SPCurve * start = new SPCurve(); @@ -252,12 +242,9 @@ LPEBSpline::doEffect(SPCurve * curve) startNode = start->first_segment()->initialPoint(); start->reset(); delete start; - curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->append_continuous(curveHelper, 0.0625); + nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); nCurve->move_endpoints(startNode,nextPointAt3); } - curveHelper->reset(); - delete curveHelper; //y cerramos la curva if (path_it->closed()) { nCurve->closepath_current(); @@ -354,10 +341,15 @@ LPEBSpline::changeWeight(double weightValue) } bool -LPEBSpline::nodeIsSelected(Geom::Point nodePoint, int index){ +LPEBSpline::nodeIsSelected(Geom::Point nodePoint){ if(points.size() > 0){ - if(Geom::are_near(points[index], nodePoint)){ - return true; + for(std::vector::iterator i = points.begin(); i != points.end();){ + Geom::Point p = static_cast(*i); + if(Geom::are_near(p, nodePoint)){ + return true; + points.erase(i); + } + i++; } } return false; @@ -415,7 +407,6 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) Geom::D2< Geom::SBasis > SBasisIn; Geom::D2< Geom::SBasis > SBasisOut; Geom::CubicBezier const *cubic = NULL; - int j = 0; if (path_it->closed()) { // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. @@ -428,7 +419,7 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) //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 - + nCurve->moveto(curve_it1->initialPoint()); //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { @@ -443,7 +434,7 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) SBasisIn = in->first_segment()->toSBasis(); if(!onlySelected){ if(cubic){ - if((!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())) && weightValue !=0){ + if(!ignoreCusp || (!Geom::are_near((*cubic)[1],in->first_segment()->initialPoint()) && weightValue !=0)){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); }else{ @@ -468,46 +459,35 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) } }else{ if(cubic){ - if((!ignoreCusp || !Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())) && weightValue !=0){ - if(nodeIsSelected(pointAt0,j)){ + if(!ignoreCusp || (!Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())&& weightValue !=0)){ + if(nodeIsSelected(pointAt0)){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); - j++; }else{ pointAt1 = (*cubic)[1]; } }else{ - if(nodeIsSelected(pointAt0,j)){ pointAt1 = in->first_segment()->initialPoint(); - j++; - }else{ - pointAt1 = (*cubic)[1]; - } } - if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ - if(nodeIsSelected(pointAt3,j)){ + if(!ignoreCusp || (!Geom::are_near((*cubic)[2],in->first_segment()->finalPoint()) && weightValue !=0)){ + if(nodeIsSelected(pointAt3)){ pointAt2 = SBasisIn.valueAt(1-weightValue); pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ pointAt2 = (*cubic)[2]; } }else{ - if(nodeIsSelected(pointAt3,j)){ pointAt2 = in->first_segment()->finalPoint(); - }else{ - pointAt2 = (*cubic)[2]; - } } }else{ if(!ignoreCusp && weightValue !=0){ - if(nodeIsSelected(pointAt0,j)){ + if(nodeIsSelected(pointAt0)){ pointAt1 = SBasisIn.valueAt(weightValue); pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); - j++; }else{ pointAt1 = in->first_segment()->initialPoint(); } - if(nodeIsSelected(pointAt3,j)){ + if(nodeIsSelected(pointAt3)){ pointAt2 = SBasisIn.valueAt(weightValue); pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); }else{ @@ -516,34 +496,21 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) }else{ pointAt1 = in->first_segment()->initialPoint(); pointAt2 = in->first_segment()->finalPoint(); - if(nodeIsSelected(pointAt0,j)){ - j++; - } } } } in->reset(); delete in; - //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 - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(pointAt0); - curveHelper->curveto(pointAt1, pointAt2, pointAt3); - //añadimos la curva generada a la curva pricipal - nCurve->append_continuous(curveHelper, 0.0625); - curveHelper->reset(); - delete curveHelper; + nCurve->curveto(pointAt1, pointAt2, pointAt3); //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; } - //Aberiguamos la ultima parte de la curva correspondiente al último segmento - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); SPCurve * out = new SPCurve(); out->moveto(curve_it1->initialPoint()); out->lineto(curve_it1->finalPoint()); @@ -576,75 +543,60 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) nextPointAt2 = out->first_segment()->finalPoint(); } } - }else{ - if(cubic){ - if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint())) && weightValue !=0){ - if(nodeIsSelected(nextPointAt0,j)){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); - j++; - }else{ - nextPointAt1 = (*cubic)[1]; - } + }else{ + if(cubic){ + if(!ignoreCusp || (!Geom::are_near((*cubic)[1],out->first_segment()->initialPoint()) && weightValue !=0)){ + if(nodeIsSelected(nextPointAt0)){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); }else{ - if(nodeIsSelected(nextPointAt0,j)){ - nextPointAt1 = out->first_segment()->initialPoint(); - j++; - }else{ - nextPointAt1 = (*cubic)[1]; - } + nextPointAt1 = (*cubic)[1]; } - if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint())) && weightValue !=0){ - if(nodeIsSelected(nextPointAt3,j)){ - nextPointAt2 = SBasisOut.valueAt(1-weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); - }else{ - nextPointAt2 = (*cubic)[2]; - } + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + } + if(!ignoreCusp || (!Geom::are_near((*cubic)[2],out->first_segment()->finalPoint()) && weightValue !=0)){ + if(nodeIsSelected(nextPointAt3)){ + nextPointAt2 = SBasisOut.valueAt(1-weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); }else{ - if(nodeIsSelected(nextPointAt3,j)){ - nextPointAt2 = out->first_segment()->finalPoint(); - }else{ - nextPointAt2 = (*cubic)[2]; - } - } + nextPointAt2 = (*cubic)[2]; + } }else{ - if(!ignoreCusp && weightValue !=0){ - if(nodeIsSelected(nextPointAt0,j)){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); - j++; - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - } - if(nodeIsSelected(nextPointAt3,j)){ - nextPointAt2 = SBasisOut.valueAt(weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); - }else{ - nextPointAt2 = out->first_segment()->finalPoint(); - } + nextPointAt2 = out->first_segment()->finalPoint(); + } + }else{ + if(!ignoreCusp && weightValue !=0){ + if(nodeIsSelected(nextPointAt0)){ + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); }else{ nextPointAt1 = out->first_segment()->initialPoint(); - if(nodeIsSelected(nextPointAt0,j)) j++; + } + if(nodeIsSelected(nextPointAt3)){ + nextPointAt2 = SBasisOut.valueAt(weightValue); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + }else{ nextPointAt2 = out->first_segment()->finalPoint(); } + }else{ + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); } } - out->reset(); - delete out; - SPCurve *curveHelper = new SPCurve(); - curveHelper->moveto(pointAt3); + } + out->reset(); + delete out; + //Aberiguamos la ultima parte de la curva correspondiente al último segmento + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); if (path_it->closed()) { - curveHelper->curveto(nextPointAt1, nextPointAt2, path_it->begin()->initialPoint()); - nCurve->append_continuous(curveHelper, 0.0625); + nCurve->curveto(nextPointAt1, nextPointAt2, path_it->begin()->initialPoint()); nCurve->move_endpoints(path_it->begin()->initialPoint(),path_it->begin()->initialPoint()); }else{ - curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->append_continuous(curveHelper, 0.0625); + nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); nCurve->move_endpoints(path_it->begin()->initialPoint(),nextPointAt3); } - curveHelper->reset(); - delete curveHelper; //y cerramos la curva if (path_it->closed()) { nCurve->closepath_current(); diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 2361c10d0..103f09338 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -29,7 +29,7 @@ public: virtual void doBSplineFromWidget(SPCurve * curve, double value); - virtual bool nodeIsSelected(Geom::Point nodePoint, int index); + virtual bool nodeIsSelected(Geom::Point nodePoint); virtual Gtk::Widget * newWidget(); -- cgit v1.2.3 From ef68a900e61298c46c079b047310558fb37a21ae Mon Sep 17 00:00:00 2001 From: jtx Date: Fri, 12 Apr 2013 18:04:58 +0200 Subject: changing colors (bzr r11950.1.89) --- src/display/canvas-bpath.cpp | 8 +++++++- src/pen-context.cpp | 36 ++++++++++++++---------------------- 2 files changed, 21 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index ee9e14f10..cbc93948f 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -145,7 +145,7 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) bool dostroke = ((cbp->stroke_rgba & 0xff) != 0); cairo_set_tolerance(buf->ct, 0.5); - cairo_new_path(buf->ct); + //cairo_new_path(buf->ct); feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, /* optimized_stroke = */ !dofill, 1); @@ -164,7 +164,13 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) if (cbp->dashes[0] != 0 && cbp->dashes[1] != 0) { cairo_set_dash (buf->ct, cbp->dashes, 2, 0); } + //cairo_t buf2 = cairo_reference(buf->ct); cairo_stroke(buf->ct); + //cairo_set_source_rgba(buf2,1,1,1,0.2); + //cairo_set_line_width(buf2, 3); + //cairo_stroke(buf2); + + } else { cairo_new_path(buf->ct); } diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 851a5f629..bcaf7c893 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1456,34 +1456,26 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void bspline_spiro_color(SPPenContext *const pc) { - bool remake_green_bpaths = false; if(pc->spiro){ - //If the colour is not defined as trasparent, por example when changing - //from drawing to spiro mode or when selecting the pen tool - if(pc->green_color != 0x00ff000){ - //We change the green and red colours to transparent, so this lines are not necessary - //to the drawing with spiro - pc->red_color = 0xff00000; - pc->green_color = 0x00ff000; - remake_green_bpaths = true; - } + pc->red_color = 0xae901f00; + pc->green_color = 0xae901f00; + pc->blue_color = 0x3dc29bb1; + }else if (pc->bspline){ + pc->red_color = 0xae901fce; + pc->green_color = 0xae901fce; + pc->blue_color = 0x3dc29bb1; }else{ - //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent - if(pc->green_color != 0x00ff007f){ - //since we are not im spiro mode, we assign the original colours - //to the red and the green curve, removing their transparency - pc->red_color = 0xff00007f; - pc->green_color = 0x00ff007f; - remake_green_bpaths = true; - } + pc->red_color = 0xff000098; + pc->green_color = 0x00ff0098; + pc->blue_color = 0x0000ff98; + } //we hide the spiro/bspline rests - if(!pc->bspline){ - sp_canvas_item_hide(pc->blue_bpath); - } + if(!pc->bspline){ + sp_canvas_item_hide(pc->blue_bpath); } //We erase all the "green_bpaths" to recreate them after with the colour //transparency recently modified - if (pc->green_bpaths && remake_green_bpaths) { + if (pc->green_bpaths) { // remove old piecewise green canvasitems while (pc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data)); -- cgit v1.2.3 From 0bc8f7e103d7c2e09400fb95a695231587a1868f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 13 Apr 2013 23:30:13 +0200 Subject: testing halo (bzr r11950.1.90) --- src/display/canvas-bpath.cpp | 16 +++++++++------- src/pen-context.cpp | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index cbc93948f..061ff7676 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -145,10 +145,11 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) bool dostroke = ((cbp->stroke_rgba & 0xff) != 0); cairo_set_tolerance(buf->ct, 0.5); - //cairo_new_path(buf->ct); + cairo_new_path(buf->ct); feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, /* optimized_stroke = */ !dofill, 1); + cairo_save(buf->ct); if (dofill) { // RGB / BGR @@ -164,13 +165,14 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) if (cbp->dashes[0] != 0 && cbp->dashes[1] != 0) { cairo_set_dash (buf->ct, cbp->dashes, 2, 0); } - //cairo_t buf2 = cairo_reference(buf->ct); cairo_stroke(buf->ct); - //cairo_set_source_rgba(buf2,1,1,1,0.2); - //cairo_set_line_width(buf2, 3); - //cairo_stroke(buf2); - - + cairo_restore(buf->ct); + //feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, + ///* optimized_stroke = */ !dofill, 1); + ink_cairo_set_source_rgba32(buf->ct, 0xffffff20); + cairo_set_line_width(buf->ct, 7); + cairo_set_line_cap(buf->ct,CAIRO_LINE_CAP_ROUND); + cairo_stroke(buf->ct); } else { cairo_new_path(buf->ct); } diff --git a/src/pen-context.cpp b/src/pen-context.cpp index bcaf7c893..c5c54925e 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1,4 +1,4 @@ -/** \file + /** \file * Pen event context implementation. */ @@ -1457,17 +1457,17 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G static void bspline_spiro_color(SPPenContext *const pc) { if(pc->spiro){ - pc->red_color = 0xae901f00; - pc->green_color = 0xae901f00; - pc->blue_color = 0x3dc29bb1; + pc->red_color = 0xc80000c8; + pc->green_color = 0xc80000c8; + pc->blue_color = 0x323296c8; }else if (pc->bspline){ - pc->red_color = 0xae901fce; - pc->green_color = 0xae901fce; - pc->blue_color = 0x3dc29bb1; + pc->red_color = 0x963232c8; + pc->green_color = 0x963232c8; + pc->blue_color = 0x323296c8; }else{ - pc->red_color = 0xff000098; - pc->green_color = 0x00ff0098; - pc->blue_color = 0x0000ff98; + pc->red_color = 0xff0000c8; + pc->green_color = 0x00ff00c8; + pc->blue_color = 0x0000ffc8; } //we hide the spiro/bspline rests if(!pc->bspline){ -- cgit v1.2.3 From 08acf66f4df391ff3289b59b80bc770397860343 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 14 Apr 2013 22:54:08 +0200 Subject: halo (bzr r11950.1.92) --- src/display/canvas-bpath.cpp | 42 ++++++++++++++++++-------- src/draw-context.cpp | 3 +- src/draw-context.h | 1 + src/pen-context.cpp | 70 ++++++++++++-------------------------------- 4 files changed, 52 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index 6ac69a325..defd95b45 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -16,8 +16,9 @@ #endif #include #include -#include "desktop.h" +#include "document.h" +#include <2geom/pathvector.h> #include "color.h" #include "display/sp-canvas-group.h" #include "display/sp-canvas-util.h" @@ -146,10 +147,6 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) cairo_set_tolerance(buf->ct, 0.5); cairo_new_path(buf->ct); - feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, - /* optimized_stroke = */ !dofill, 1); - - if (dofill) { // RGB / BGR ink_cairo_set_source_rgba32(buf->ct, cbp->fill_rgba); @@ -159,16 +156,37 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) } if (dostroke) { - ink_cairo_set_source_rgba32(buf->ct, cbp->stroke_rgba); - if(cbp->stroke_rgba == 0xffffff10){ - cairo_set_line_width(buf->ct, 3); + SPCurve* orig = new SPCurve(cbp->curve->get_pathvector()); + Geom::Point origPoint(orig->first_path()->initialPoint()); + if(cbp->stroke_rgba == 0x12345678){ + cairo_save(buf->ct); + orig->moveto(origPoint[Geom::X]+1,origPoint[Geom::Y]+1); + feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, + /* optimized_stroke = */ !dofill, 1); + ink_cairo_set_source_rgba32(buf->ct, 0x00000020); + cairo_set_line_width(buf->ct, 1); + cairo_move_to(buf->ct, origPoint[Geom::X] + 1, origPoint[Geom::Y] + 1); + cairo_stroke_preserve(buf->ct); + cairo_restore(buf->ct); + cairo_save(buf->ct); + feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, + /* optimized_stroke = */ !dofill, 1); + ink_cairo_set_source_rgba32(buf->ct, 0xffffff20); + cairo_set_line_width(buf->ct, 1); + cairo_move_to(buf->ct, origPoint[Geom::X] - 1, origPoint[Geom::Y] - 1); + cairo_stroke_preserve(buf->ct); + cairo_restore(buf->ct); }else{ + feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, + /* optimized_stroke = */ !dofill, 1); + ink_cairo_set_source_rgba32(buf->ct, cbp->stroke_rgba); cairo_set_line_width(buf->ct, 1); + cairo_move_to(buf->ct, origPoint[Geom::X], origPoint[Geom::Y]); + if (cbp->dashes[0] != 0 && cbp->dashes[1] != 0) { + cairo_set_dash (buf->ct, cbp->dashes, 2, 0); + } + cairo_stroke(buf->ct); } - if (cbp->dashes[0] != 0 && cbp->dashes[1] != 0) { - cairo_set_dash (buf->ct, cbp->dashes, 2, 0); - } - cairo_stroke(buf->ct); } else { cairo_new_path(buf->ct); } diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 33e9b4a5d..459137cc0 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -99,7 +99,7 @@ static void sp_draw_context_init(SPDrawContext *dc) dc->red_color = 0xff00007f; dc->blue_color = 0x0000ff7f; dc->green_color = 0x00ff007f; - dc->halo_color = 0xffffff10; + dc->halo_color = 0x12345678; dc->red_curve_is_valid = false; dc->red_bpath = NULL; @@ -867,3 +867,4 @@ void spdc_create_single_dot(SPEventContext *ec, Geom::Point const &pt, char cons End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + diff --git a/src/draw-context.h b/src/draw-context.h index 5a2db5ae0..1b4d04773 100644 --- a/src/draw-context.h +++ b/src/draw-context.h @@ -137,3 +137,4 @@ G_END_DECLS End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 70d9f8ae1..4a1384657 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -48,7 +48,7 @@ #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" -#include "display/curve.h" + #include #include <2geom/pathvector.h> #include <2geom/affine.h> @@ -964,16 +964,6 @@ static gint pen_handle_2button_press(SPPenContext *const pc, GdkEventButton cons static void pen_redraw_all (SPPenContext *const pc) { - //halo - SPCurve *halo = new SPCurve(); - if(!pc->bspline && !pc->spiro){ - if(!pc->green_curve->is_empty()) - halo->append_continuous(pc->green_curve, 0.0625); - if(!pc->red_curve->is_empty()) - halo->append_continuous(pc->red_curve, 0.0625); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), halo); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->halo_bpath), pc->halo_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - } // green if (pc->green_bpaths) { // remove old piecewise green canvasitems @@ -1470,17 +1460,17 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G static void bspline_spiro_color(SPPenContext *const pc) { if(pc->spiro){ - pc->red_color = 0xc8000000; - pc->green_color = 0xc8000000; - pc->blue_color = 0x963232c8; + pc->red_color = 0xdf202000; + pc->green_color = 0x21df2100; + pc->blue_color = 0x2020dfe6; }else if (pc->bspline){ - pc->red_color = 0x323296c8; - pc->green_color = 0x323296c8; - pc->blue_color = 0x963232c8; + pc->red_color = 0xdf2020e6; + pc->green_color = 0xdf2020e6; + pc->blue_color = 0x2020dfe6; }else{ - pc->red_color = 0xff0000c8; - pc->green_color = 0x00ff00c8; - pc->blue_color = 0x0000ffc8; + pc->red_color = 0xdf2020e6; + pc->green_color = 0x21df21e6; + pc->blue_color = 0x0000ffe6; } //we hide the spiro/bspline rests if(!pc->bspline){ @@ -1792,16 +1782,8 @@ static void bspline_spiro_end_anchor_off(SPPenContext *const pc) //preparates the curves for its trasformation into BSline curves. static void bspline_spiro_build(SPPenContext *const pc) { - if(!pc->spiro && !pc->bspline){ - SPCurve *halo = new SPCurve(); - if(!pc->green_curve->is_empty()) - halo->append_continuous(pc->green_curve, 0.0625); - if(!pc->red_curve->is_empty()) - halo->append_continuous(pc->red_curve, 0.0625); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), halo); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->halo_bpath), pc->halo_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + if(!pc->spiro && !pc->bspline) return; - } //We create the base curve SPCurve *curve = new SPCurve(); @@ -1839,21 +1821,23 @@ static void bspline_spiro_build(SPPenContext *const pc) SPCurve *halo = new SPCurve(); if(pc->bspline){ bspline_doEffect(curve); + halo = curve->copy()->create_reverse(); if(!pc->green_curve->is_empty()) halo->append_continuous(pc->green_curve, 0.0625); if(!pc->red_curve->is_empty()) halo->append_continuous(pc->red_curve, 0.0625); - halo->append(curve->copy(),false); + if(Geom::are_near(halo->first_path()->initialPoint(), halo->last_path()->finalPoint())){ + halo->closepath_current(); + } }else{ spiro_doEffect(curve); halo = curve->copy(); } + sp_canvas_item_show(pc->blue_bpath); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), halo); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->halo_bpath), pc->halo_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->blue_bpath), pc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_item_show(pc->halo_bpath); - sp_canvas_item_show(pc->blue_bpath); curve->unref(); pc->blue_curve->reset(); //We hide the holders that doesn't contribute anything @@ -1868,7 +1852,7 @@ static void bspline_spiro_build(SPPenContext *const pc) }else{ //if the curve is empty sp_canvas_item_hide(pc->blue_bpath); - sp_canvas_item_hide(pc->halo_bpath); + } } @@ -2196,15 +2180,7 @@ static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point co is_curve = false; } } - SPCurve *halo = new SPCurve(); - if(!pc->bspline && !pc->spiro){ - if(!pc->green_curve->is_empty()) - halo->append_continuous(pc->green_curve, 0.0625); - if(!pc->red_curve->is_empty()) - halo->append_continuous(pc->red_curve, 0.0625); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), halo); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->halo_bpath), pc->halo_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - } + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); if (statusbar) { @@ -2247,15 +2223,6 @@ static void spdc_pen_set_ctrl(SPPenContext *const pc, Geom::Point const p, guint pc->red_curve->reset(); pc->red_curve->moveto(pc->p[0]); pc->red_curve->curveto(pc->p[1], pc->p[2], pc->p[3]); - SPCurve *halo = new SPCurve(); - if(!pc->bspline && !pc->spiro){ - if(!pc->green_curve->is_empty()) - halo->append_continuous(pc->green_curve, 0.0625); - if(!pc->red_curve->is_empty()) - halo->append_continuous(pc->red_curve, 0.0625); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), halo); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->halo_bpath), pc->halo_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); } SP_CTRL(pc->c0)->moveto(pc->p[2]); @@ -2430,3 +2397,4 @@ void pen_set_to_nearest_horiz_vert(const SPPenContext *const pc, Geom::Point &pt */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + -- cgit v1.2.3 From 224bac8cddd8960f65cf08202c4f40e74c8fc1ae Mon Sep 17 00:00:00 2001 From: root Date: Sun, 14 Apr 2013 23:08:45 +0200 Subject: Go back (bzr r11950.1.93) --- src/display/canvas-bpath.cpp | 38 ++++++++------------------------------ src/draw-context.cpp | 14 -------------- src/draw-context.h | 3 --- src/pen-context.cpp | 17 ++--------------- 4 files changed, 10 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index defd95b45..8faf8947f 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -147,6 +147,9 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) cairo_set_tolerance(buf->ct, 0.5); cairo_new_path(buf->ct); + + feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, + /* optimized_stroke = */ !dofill, 1); if (dofill) { // RGB / BGR ink_cairo_set_source_rgba32(buf->ct, cbp->fill_rgba); @@ -156,37 +159,12 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) } if (dostroke) { - SPCurve* orig = new SPCurve(cbp->curve->get_pathvector()); - Geom::Point origPoint(orig->first_path()->initialPoint()); - if(cbp->stroke_rgba == 0x12345678){ - cairo_save(buf->ct); - orig->moveto(origPoint[Geom::X]+1,origPoint[Geom::Y]+1); - feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, - /* optimized_stroke = */ !dofill, 1); - ink_cairo_set_source_rgba32(buf->ct, 0x00000020); - cairo_set_line_width(buf->ct, 1); - cairo_move_to(buf->ct, origPoint[Geom::X] + 1, origPoint[Geom::Y] + 1); - cairo_stroke_preserve(buf->ct); - cairo_restore(buf->ct); - cairo_save(buf->ct); - feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, - /* optimized_stroke = */ !dofill, 1); - ink_cairo_set_source_rgba32(buf->ct, 0xffffff20); - cairo_set_line_width(buf->ct, 1); - cairo_move_to(buf->ct, origPoint[Geom::X] - 1, origPoint[Geom::Y] - 1); - cairo_stroke_preserve(buf->ct); - cairo_restore(buf->ct); - }else{ - feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area, - /* optimized_stroke = */ !dofill, 1); - ink_cairo_set_source_rgba32(buf->ct, cbp->stroke_rgba); - cairo_set_line_width(buf->ct, 1); - cairo_move_to(buf->ct, origPoint[Geom::X], origPoint[Geom::Y]); - if (cbp->dashes[0] != 0 && cbp->dashes[1] != 0) { - cairo_set_dash (buf->ct, cbp->dashes, 2, 0); - } - cairo_stroke(buf->ct); + ink_cairo_set_source_rgba32(buf->ct, cbp->stroke_rgba); + cairo_set_line_width(buf->ct, 1); + if (cbp->dashes[0] != 0 && cbp->dashes[1] != 0) { + cairo_set_dash (buf->ct, cbp->dashes, 2, 0); } + cairo_stroke(buf->ct); } else { cairo_new_path(buf->ct); } diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 459137cc0..69e394aaa 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -99,7 +99,6 @@ static void sp_draw_context_init(SPDrawContext *dc) dc->red_color = 0xff00007f; dc->blue_color = 0x0000ff7f; dc->green_color = 0x00ff007f; - dc->halo_color = 0x12345678; dc->red_curve_is_valid = false; dc->red_bpath = NULL; @@ -108,8 +107,6 @@ static void sp_draw_context_init(SPDrawContext *dc) dc->blue_bpath = NULL; dc->blue_curve = NULL; - dc->halo_bpath = NULL; - dc->green_bpaths = NULL; dc->green_curve = NULL; dc->green_anchor = NULL; @@ -179,10 +176,6 @@ static void sp_draw_context_setup(SPEventContext *ec) dc->blue_bpath = sp_canvas_bpath_new(sp_desktop_sketch(ec->desktop), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->blue_bpath), dc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - // Create halo bpath - dc->halo_bpath = sp_canvas_bpath_new(sp_desktop_sketch(ec->desktop), NULL); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->halo_bpath), dc->halo_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - // Create blue curve dc->blue_curve = new SPCurve(); @@ -539,7 +532,6 @@ void spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->halo_bpath), NULL); if (c->is_empty()) { c->unref(); @@ -761,12 +753,6 @@ static void spdc_free_colors(SPDrawContext *dc) dc->blue_curve = dc->blue_curve->unref(); } - // Halo - if (dc->halo_bpath) { - sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->halo_bpath)); - dc->halo_bpath = NULL; - } - // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/draw-context.h b/src/draw-context.h index 1b4d04773..f930fa858 100644 --- a/src/draw-context.h +++ b/src/draw-context.h @@ -44,7 +44,6 @@ struct SPDrawContext : public SPEventContext{ guint32 red_color; guint32 blue_color; guint32 green_color; - guint32 halo_color; // Red SPCanvasItem *red_bpath; @@ -54,8 +53,6 @@ struct SPDrawContext : public SPEventContext{ SPCanvasItem *blue_bpath; SPCurve *blue_curve; - // Halo - SPCanvasItem *halo_bpath; // Green GSList *green_bpaths; diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 4a1384657..43f2fd76e 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1401,7 +1401,6 @@ static void spdc_reset_colors(SPPenContext *pc) pc->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), NULL); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), NULL); // Green while (pc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data)); @@ -1426,7 +1425,6 @@ static void spdc_pen_set_initial_point(SPPenContext *const pc, Geom::Point const pc->p[1] = p; pc->npoints = 2; sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), NULL); pc->desktop->canvas->forceFullRedrawAfterInterruptions(5); } @@ -1818,26 +1816,15 @@ static void bspline_spiro_build(SPPenContext *const pc) //LivePathEffectObject *lpeobj = static_cast (curve); //Effect *spr = static_cast ( new LPEbspline(lpeobj) ); //spr->doEffect(curve); - SPCurve *halo = new SPCurve(); if(pc->bspline){ bspline_doEffect(curve); - halo = curve->copy()->create_reverse(); - if(!pc->green_curve->is_empty()) - halo->append_continuous(pc->green_curve, 0.0625); - if(!pc->red_curve->is_empty()) - halo->append_continuous(pc->red_curve, 0.0625); - if(Geom::are_near(halo->first_path()->initialPoint(), halo->last_path()->finalPoint())){ - halo->closepath_current(); - } }else{ spiro_doEffect(curve); - halo = curve->copy(); } - sp_canvas_item_show(pc->blue_bpath); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->halo_bpath), halo); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->halo_bpath), pc->halo_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->blue_bpath), pc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_item_show(pc->blue_bpath); curve->unref(); pc->blue_curve->reset(); //We hide the holders that doesn't contribute anything -- cgit v1.2.3 From 25ea29de646f639eb445a8dbef533ed3d1c35b14 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 16 Apr 2013 00:44:13 +0200 Subject: adding composite (bzr r11950.1.94) --- src/display/canvas-bpath.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index 8faf8947f..9135774c1 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -133,7 +133,9 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) SPCanvasBPath *cbp = SP_CANVAS_BPATH (item); Geom::Rect area = buf->rect; - + double width = 0.5; + Geom::Rect viewbox = item->canvas->getViewbox(); + viewbox.expandBy (width); if ( !cbp->curve || ((cbp->stroke_rgba & 0xff) == 0 && (cbp->fill_rgba & 0xff) == 0 ) || cbp->curve->get_segment_count() < 1) @@ -144,7 +146,14 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) bool dofill = ((cbp->fill_rgba & 0xff) != 0); bool dostroke = ((cbp->stroke_rgba & 0xff) != 0); - + + if (dostroke) { + const cairo_rectangle_int_t *rectangle = new cairo_rectangle_int_t {viewbox.left(),viewbox.top(),viewbox.width(),viewbox.height()}; + cairo_region_create_rectangle(rectangle); + cairo_paint(buf->ct); + cairo_set_operator(buf->ct,CAIRO_OPERATOR_OVERLAY); + } + cairo_set_tolerance(buf->ct, 0.5); cairo_new_path(buf->ct); @@ -165,6 +174,7 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) cairo_set_dash (buf->ct, cbp->dashes, 2, 0); } cairo_stroke(buf->ct); + cairo_destroy(buf->ct); } else { cairo_new_path(buf->ct); } -- cgit v1.2.3 From 458ca2842297a5eae7e4f6fc394b227d61881c8d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 17 Apr 2013 23:03:51 +0200 Subject: Update color lines overlay, with halo of 1 px matched by Gez. Fix some crash snapping. Added new button widget to make cusp node (bzr r11950.1.96) --- src/display/canvas-bpath.cpp | 2 +- src/live_effects/lpe-bspline.cpp | 95 +++++++++++++++++++++++++--------------- src/live_effects/lpe-bspline.h | 2 + src/pen-context.cpp | 62 ++++++++++++++++---------- src/pencil-context.cpp | 8 ++-- src/ui/tool/node.cpp | 17 +++++-- src/ui/tool/path-manipulator.cpp | 12 ++--- 7 files changed, 126 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index 651440512..a53b88efb 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -159,7 +159,7 @@ sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) } if (dostroke) { - ink_cairo_set_source_rgba32(buf->ct, 0xffffff4c); + ink_cairo_set_source_rgba32(buf->ct, 0xffffff42); cairo_set_line_width(buf->ct, 3); cairo_stroke_preserve(buf->ct); cairo_restore(buf->ct); diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 37bf24021..cc1b86e72 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -170,7 +170,7 @@ LPEBSpline::doEffect(SPCurve * curve) SBasisOut = out->first_segment()->toSBasis(); nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; - nextPointAt3 = (*cubic)[3]; + nextPointAt3 = out->first_segment()->finalPoint(); }else{ nextPointAt1 = out->first_segment()->initialPoint(); nextPointAt2 = out->first_segment()->finalPoint(); @@ -299,19 +299,24 @@ LPEBSpline::newWidget() defaultWeight->signal_clicked().connect(sigc::mem_fun (*this,&LPEBSpline::toDefaultWeight)); Gtk::Widget* defaultWeightWidget = dynamic_cast(defaultWeight); vbox->pack_start(*defaultWeightWidget, true, true,2); + Gtk::Button* makeCusp = Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); + makeCusp->set_alignment(0.0, 0.5); + makeCusp->signal_clicked().connect(sigc::mem_fun (*this,&LPEBSpline::toMakeCusp)); + Gtk::Widget* makeCuspWidget = dynamic_cast(makeCusp); + vbox->pack_start(*makeCuspWidget, true, true,2); return dynamic_cast(vbox); } void LPEBSpline::toDefaultWeight(){ - Gtk::Widget * widg = dynamic_cast(param_vector[3]->param_newWidget()); - Inkscape::UI::Widget::Scalar * widgRegistered = Gtk::manage(dynamic_cast(widg)); - widgRegistered->setValue(0.3334); - widgRegistered->update(); - weight.param_set_value(0.3334); changeWeight(0.3334); } +void +LPEBSpline::toMakeCusp(){ + changeWeight(0.0000); +} + void LPEBSpline::toWeight(){ changeWeight(weight); @@ -434,24 +439,32 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) SBasisIn = in->first_segment()->toSBasis(); if(!onlySelected){ if(cubic){ - if(!ignoreCusp || (!Geom::are_near((*cubic)[1],in->first_segment()->initialPoint()) && weightValue !=0)){ + if(!ignoreCusp || !Geom::are_near((*cubic)[1],pointAt0)){ pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + if(weightValue !=0.0000){ + pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); + } }else{ pointAt1 = in->first_segment()->initialPoint(); } - if((!ignoreCusp || !Geom::are_near((*cubic)[2],in->first_segment()->finalPoint())) && weightValue !=0){ + if(!ignoreCusp || !Geom::are_near((*cubic)[2],pointAt3)){ pointAt2 = SBasisIn.valueAt(1-weightValue); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); - }else{ + if(weightValue !=0.0000){ + pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); + } + }else{ pointAt2 = in->first_segment()->finalPoint(); } }else{ - if(!ignoreCusp && weightValue !=0){ + if(!ignoreCusp && weightValue !=0.0000){ pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + if(weightValue !=0.0000){ + pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); + } pointAt2 = SBasisIn.valueAt(1-weightValue); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + if(weightValue !=0.0000){ + pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); + } }else{ pointAt1 = in->first_segment()->initialPoint(); pointAt2 = in->first_segment()->finalPoint(); @@ -459,20 +472,24 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) } }else{ if(cubic){ - if(!ignoreCusp || (!Geom::are_near((*cubic)[1],in->first_segment()->initialPoint())&& weightValue !=0)){ + if(!ignoreCusp || !Geom::are_near((*cubic)[1],pointAt0)){ if(nodeIsSelected(pointAt0)){ pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + if(weightValue !=0.0000){ + pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); + } }else{ pointAt1 = (*cubic)[1]; } }else{ pointAt1 = in->first_segment()->initialPoint(); } - if(!ignoreCusp || (!Geom::are_near((*cubic)[2],in->first_segment()->finalPoint()) && weightValue !=0)){ + if(!ignoreCusp || !Geom::are_near((*cubic)[2],pointAt3)){ if(nodeIsSelected(pointAt3)){ pointAt2 = SBasisIn.valueAt(1-weightValue); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + if(weightValue !=0.0000){ + pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); + } }else{ pointAt2 = (*cubic)[2]; } @@ -480,16 +497,16 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) pointAt2 = in->first_segment()->finalPoint(); } }else{ - if(!ignoreCusp && weightValue !=0){ + if(!ignoreCusp && weightValue !=0.000){ if(nodeIsSelected(pointAt0)){ pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = Geom::Point(pointAt1[X] + 0.0625,pointAt1[Y] + 0.0625); + pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); }else{ pointAt1 = in->first_segment()->initialPoint(); } if(nodeIsSelected(pointAt3)){ pointAt2 = SBasisIn.valueAt(weightValue); - pointAt2 = Geom::Point(pointAt2[X] + 0.0625,pointAt2[Y] + 0.0625); + pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); }else{ pointAt2 = in->first_segment()->finalPoint(); } @@ -520,24 +537,28 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) cubic = dynamic_cast(&*curve_it1); if(!onlySelected){ if(cubic){ - if((!ignoreCusp || !Geom::are_near((*cubic)[1],out->first_segment()->initialPoint()))&& weightValue !=0){ + if(!ignoreCusp || !Geom::are_near((*cubic)[1],nextPointAt0)){ nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + if(weightValue !=0.0000){ + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); + } }else{ nextPointAt1 = out->first_segment()->initialPoint(); } - if((!ignoreCusp || !Geom::are_near((*cubic)[2],out->first_segment()->finalPoint()))&& weightValue !=0){ + if(!ignoreCusp || !Geom::are_near((*cubic)[2],nextPointAt3)){ nextPointAt2 = SBasisOut.valueAt(1-weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + if(weightValue !=0.0000){ + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); + } }else{ nextPointAt2 = out->first_segment()->finalPoint(); } }else{ - if(!ignoreCusp && weightValue !=0){ + if(!ignoreCusp && weightValue !=0.0000){ nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); nextPointAt2 = SBasisOut.valueAt(1-weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); }else{ nextPointAt1 = out->first_segment()->initialPoint(); nextPointAt2 = out->first_segment()->finalPoint(); @@ -545,20 +566,24 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) } }else{ if(cubic){ - if(!ignoreCusp || (!Geom::are_near((*cubic)[1],out->first_segment()->initialPoint()) && weightValue !=0)){ + if(!ignoreCusp || !Geom::are_near((*cubic)[1],nextPointAt0)){ if(nodeIsSelected(nextPointAt0)){ nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + if(weightValue !=0.0000){ + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); + } }else{ nextPointAt1 = (*cubic)[1]; } }else{ nextPointAt1 = out->first_segment()->initialPoint(); } - if(!ignoreCusp || (!Geom::are_near((*cubic)[2],out->first_segment()->finalPoint()) && weightValue !=0)){ + if(!ignoreCusp || !Geom::are_near((*cubic)[2],nextPointAt3)){ if(nodeIsSelected(nextPointAt3)){ nextPointAt2 = SBasisOut.valueAt(1-weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + if(weightValue !=0.0000){ + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); + } }else{ nextPointAt2 = (*cubic)[2]; } @@ -566,16 +591,16 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) nextPointAt2 = out->first_segment()->finalPoint(); } }else{ - if(!ignoreCusp && weightValue !=0){ + if(!ignoreCusp && weightValue !=0.0000){ if(nodeIsSelected(nextPointAt0)){ nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0625,nextPointAt1[Y] + 0.0625); + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); }else{ nextPointAt1 = out->first_segment()->initialPoint(); } if(nodeIsSelected(nextPointAt3)){ nextPointAt2 = SBasisOut.valueAt(weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0625,nextPointAt2[Y] + 0.0625); + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); }else{ nextPointAt2 = out->first_segment()->finalPoint(); } diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 103f09338..510f9c989 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -37,6 +37,8 @@ public: virtual void toDefaultWeight(); + virtual void toMakeCusp(); + virtual void toWeight(); ScalarParam steps; diff --git a/src/pen-context.cpp b/src/pen-context.cpp index c0fc908f0..181579fa2 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -656,7 +656,6 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); //"spiro_color" lo ejecutamos siempre sea o no spiro - bspline_spiro_color(pc); if (pen_within_tolerance) { if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance) { return FALSE; // Do not drag if we're within tolerance from origin. @@ -781,6 +780,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons //BSpline //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + bspline_spiro_color(pc); bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); pen_drag_origin_w = event_w; } @@ -1452,31 +1452,48 @@ static void spdc_pen_set_angle_distance_status_message(SPPenContext *const pc, G g_string_free(dist, FALSE); } - - //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void bspline_spiro_color(SPPenContext *const pc) { + bool remake_green_bpaths = false; if(pc->spiro){ - pc->red_color = 0xffffff00; - pc->green_color = 0xffffff00; - pc->blue_color = 0x23abcdff; - }else if (pc->bspline){ - pc->red_color = 0xe68024ff; - pc->green_color = 0xe68024ff; - pc->blue_color = 0x23abcdff; - }else{ - pc->red_color = 0xe68024ff; - pc->green_color = 0xf372ebff; - pc->blue_color = 0x23abcdff; - } + //If the colour is not defined as trasparent, por example when changing + //from drawing to spiro mode or when selecting the pen tool + if(pc->green_color != 0x00ff000){ + //We change the green and red colours to transparent, so this lines are not necessary + //to the drawing with spiro + pc->red_color = 0x00ff000; + pc->green_color = 0x00ff000; + pc->blue_color = 0x23abcdff; + remake_green_bpaths = true; + } + }else if(pc->bspline){ + //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent + if(pc->green_color != 0xe68024ff){ + //since we are not im spiro mode, we assign the original colours + //to the red and the green curve, removing their transparency + pc->red_color = 0xe68024ff; + pc->green_color = 0xe68024ff; + pc->blue_color = 0x23abcdff; + remake_green_bpaths = true; + } //we hide the spiro/bspline rests + }else{ + if(pc->green_color != 0xf372ebff){ + //since we are not im spiro mode, we assign the original colours + //to the red and the green curve, removing their transparency + pc->red_color = 0xe68024ff; + pc->green_color = 0xf372ebff; + pc->blue_color = 0x23abcdff; + remake_green_bpaths = true; + } + } if(!pc->bspline){ sp_canvas_item_hide(pc->blue_bpath); } //We erase all the "green_bpaths" to recreate them after with the colour //transparency recently modified - if (pc->green_bpaths) { + if (pc->green_bpaths && remake_green_bpaths) { // remove old piecewise green canvasitems while (pc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data)); @@ -1491,6 +1508,7 @@ static void bspline_spiro_color(SPPenContext *const pc) sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(pc->red_bpath), pc->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); } + static void bspline_spiro(SPPenContext *const pc, bool shift) { if(!pc->spiro && !pc->bspline) @@ -1511,7 +1529,7 @@ static void bspline_spiro_on(SPPenContext *const pc) pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[3] = pc->red_curve->first_segment()->finalPoint(); pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.0001,pc->p[2][Y] + 0.0001); } } @@ -1552,7 +1570,7 @@ static void bspline_spiro_start_anchor_on(SPPenContext *const pc) Geom::Point A = tmpCurve->last_segment()->initialPoint(); Geom::Point D = tmpCurve->last_segment()->finalPoint(); Geom::Point C = D + (1./3)*(A - D); - C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625); + C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); if(cubic){ lastSeg->moveto(A); lastSeg->curveto((*cubic)[1],C,D); @@ -1637,7 +1655,7 @@ static void bspline_spiro_motion(SPPenContext *const pc, bool shift){ WPower->reset(); pc->p[1] = SBasisWPower.valueAt(WP); if(!Geom::are_near(pc->p[1],pc->p[0])) - pc->p[1] = Geom::Point(pc->p[1][X] + 0.0625,pc->p[1][Y] + 0.0625); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.0001,pc->p[1][Y] + 0.0001); }else{ pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] ); } @@ -1662,7 +1680,7 @@ static void bspline_spiro_end_anchor_on(SPPenContext *const pc) using Geom::X; using Geom::Y; pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X] + 0.0625,pc->p[2][Y] + 0.0625); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.0001,pc->p[2][Y] + 0.0001); SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); @@ -1671,7 +1689,7 @@ static void bspline_spiro_end_anchor_on(SPPenContext *const pc) Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625); + C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); }else{ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] ); } @@ -1700,7 +1718,7 @@ static void bspline_spiro_end_anchor_on(SPPenContext *const pc) Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625); + C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); }else{ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] ); } diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index a7fa5e111..304f81890 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -766,9 +766,9 @@ interpolate(SPPencilContext *pc) //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); - BP = Geom::Point(BP[X] + 0.0625,BP[Y] + 0.0625); + BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); Geom::Point CP = b[4*c+3] + (1./3)*(b[4*c+0] - b[4*c+3]); - CP = Geom::Point(CP[X] + 0.0625,CP[Y] + 0.0625); + CP = Geom::Point(CP[X] + 0.0001,CP[Y] + 0.0001); pc->green_curve->curveto(BP,CP,b[4*c+3]); }else{ pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); @@ -922,9 +922,9 @@ fit_and_split(SPPencilContext *pc) guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ Geom::Point B = b[0] + (1./3)*(b[3] - b[0]); - B = Geom::Point(B[X] + 0.0625,B[Y] + 0.0625); + B = Geom::Point(B[X] + 0.0001,B[Y] + 0.0001); Geom::Point C = b[3] + (1./3)*(b[0] - b[3]); - C = Geom::Point(C[X] + 0.0625,C[Y] + 0.0625); + C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); pc->red_curve->curveto(B,C,b[3]); }else{ pc->red_curve->curveto(b[1], b[2], b[3]); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 8f1c37649..011d0d296 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -146,10 +146,8 @@ void Handle::move(Geom::Point const &new_pos) Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); - if(n != _parent) - _parent->_selection.erase(n); + _parent->_selection.erase(n); } - if(!_parent->selected()) _parent->_selection.insert(_parent); } //BSpline End @@ -187,8 +185,8 @@ void Handle::move(Geom::Point const &new_pos) //BSpline if(_pm().isBSpline){ h = this; - setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); + setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); h2 = this->other(); this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } @@ -422,6 +420,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); + //BSpline + if(_pm().isBSpline){ + Handle *h = NULL; + _parent->bsplineWeight = 0; + h = this; + setPosition(new_pos); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); + new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); + } + //BSpline End } @@ -452,6 +460,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); + _parent->bsplineWeight = 0; } } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 6cad60fee..9da27e807 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1204,14 +1204,14 @@ int PathManipulator::getSteps(){ double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; - double pos = 0; + double pos = 0.0000; Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; if(!n->isEndNode()) nextNode = n->nodeToward(h); Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] - 0.0625,positionH[Y] - 0.0625); + positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); @@ -1235,12 +1235,12 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ Node * nextNode = NULL; if(!n->isEndNode()) nextNode = n->nodeToward(h); - if(nextNode && pos != 0){ + if(nextNode && pos != 0.0000){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); ret = SBasisInsideNodes.valueAt(pos); - ret = Geom::Point(ret[X] + 0.0625,ret[Y] + 0.0625); + ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); }else{ ret = n->position(); } @@ -1251,8 +1251,8 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ if(n->selected()){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - double prevPos = 0; - double nextPos = 0; + double prevPos = 0.0000; + double nextPos = 0.0000; if(prevNode) prevPos = BSplineHandlePosition(prevNode->front()); if(nextNode) -- cgit v1.2.3 From 865b863409353b45ceadb317a80a75a4409e07a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 18 Apr 2013 20:17:28 +0200 Subject: updates to colors (bzr r11950.1.97) --- src/display/canvas-bpath.cpp | 2 +- src/sp-guide.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index a53b88efb..502bf440e 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -16,7 +16,7 @@ #endif #include #include -#include "document.h" +#include "desktop.h" #include "color.h" #include "display/sp-canvas-group.h" diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 48596cbc0..3266d8819 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -95,8 +95,8 @@ static void sp_guide_init(SPGuide *guide) { guide->normal_to_line = Geom::Point(0.,1.); guide->point_on_line = Geom::Point(0.,0.); - guide->color = 0x0000ff7f; - guide->hicolor = 0xff00007f; + guide->color = 0x23abcd7f; + guide->hicolor = 0xf372eb7f; } static void sp_guide_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec */*pspec*/) -- cgit v1.2.3 From 9555c8e9051ba5b5d80912a6fd79f85cf12829d6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 18 Apr 2013 21:55:41 +0200 Subject: Back to original colors (bzr r11950.1.99) --- src/pen-context.cpp | 25 +++++++------------------ src/sp-guide.cpp | 4 ++-- src/ui/control-manager.cpp | 6 +++--- 3 files changed, 12 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 181579fa2..7fb99e32e 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1462,34 +1462,23 @@ static void bspline_spiro_color(SPPenContext *const pc) if(pc->green_color != 0x00ff000){ //We change the green and red colours to transparent, so this lines are not necessary //to the drawing with spiro - pc->red_color = 0x00ff000; + pc->red_color = 0xff00000; pc->green_color = 0x00ff000; - pc->blue_color = 0x23abcdff; remake_green_bpaths = true; } - }else if(pc->bspline){ + }else{ //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent - if(pc->green_color != 0xe68024ff){ + if(pc->green_color != 0x00ff007f){ //since we are not im spiro mode, we assign the original colours //to the red and the green curve, removing their transparency - pc->red_color = 0xe68024ff; - pc->green_color = 0xe68024ff; - pc->blue_color = 0x23abcdff; + pc->red_color = 0xff00007f; + pc->green_color = 0x00ff007f; remake_green_bpaths = true; } //we hide the spiro/bspline rests - }else{ - if(pc->green_color != 0xf372ebff){ - //since we are not im spiro mode, we assign the original colours - //to the red and the green curve, removing their transparency - pc->red_color = 0xe68024ff; - pc->green_color = 0xf372ebff; - pc->blue_color = 0x23abcdff; - remake_green_bpaths = true; + if(!pc->bspline){ + sp_canvas_item_hide(pc->blue_bpath); } - } - if(!pc->bspline){ - sp_canvas_item_hide(pc->blue_bpath); } //We erase all the "green_bpaths" to recreate them after with the colour //transparency recently modified diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 3266d8819..48596cbc0 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -95,8 +95,8 @@ static void sp_guide_init(SPGuide *guide) { guide->normal_to_line = Geom::Point(0.,1.); guide->point_on_line = Geom::Point(0.,0.); - guide->color = 0x23abcd7f; - guide->hicolor = 0xf372eb7f; + guide->color = 0x0000ff7f; + guide->hicolor = 0xff00007f; } static void sp_guide_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec */*pspec*/) diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp index 9425bc3f0..5a3c5a496 100644 --- a/src/ui/control-manager.cpp +++ b/src/ui/control-manager.cpp @@ -59,9 +59,9 @@ ControlFlags& operator ^=(ControlFlags &lhs, ControlFlags rhs) #define FILL_COLOR_MOUSEOVER 0xff0000ff // Default color for line: -#define LINE_COLOR_PRIMARY 0x23abcdff -#define LINE_COLOR_SECONDARY 0xf372ebff -#define LINE_COLOR_TERTIARY 0xe68024ff +#define LINE_COLOR_PRIMARY 0x0000ff7f +#define LINE_COLOR_SECONDARY 0xff00007f +#define LINE_COLOR_TERTIARY 0xffff007f namespace Inkscape { -- cgit v1.2.3 From fc5f8b8694f2b583f08fc423787319193097c9ca Mon Sep 17 00:00:00 2001 From: root Date: Thu, 18 Apr 2013 22:56:50 +0200 Subject: Remove mesh tool active from source (bzr r11950.1.101) --- src/widgets/toolbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index f9f13fa3a..88821b69b 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -110,7 +110,7 @@ enum BarId { BAR_COMMANDS, BAR_SNAP, }; -#define WITH_MESH +//#define WITH_MESH #define BAR_ID_KEY "BarIdValue" #define HANDLE_POS_MARK "x-inkscape-pos" -- cgit v1.2.3 From b61a6eab38cd9a97aebec641c4484b872ca2905b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 19 Apr 2013 08:48:12 +0200 Subject: Adding automatic removed files, Why it? I put again becasue are in branch (bzr r11950.1.102) --- src/libavoid/makefile | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/libavoid/makefile (limited to 'src') diff --git a/src/libavoid/makefile b/src/libavoid/makefile new file mode 100644 index 000000000..e4f83a52d --- /dev/null +++ b/src/libavoid/makefile @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + + + +OBJEXT = o + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) libavoid/all + +clean %.a %.$(OBJEXT): + cd .. && $(MAKE) libavoid/$@ + +.PHONY: all clean + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) -- cgit v1.2.3 From 56d9d0a05e24697275ebcfcbbabe46a401e8df31 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 26 Apr 2013 19:06:13 +0200 Subject: update icons (bzr r11950.1.108) --- src/widgets/icon.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 7580d9602..977b1badf 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -679,6 +679,7 @@ void IconImpl::setupLegacyNaming() { legacyNames["draw-star"] ="star_angled"; legacyNames["path-mode-bezier"] ="bezier_mode"; legacyNames["path-mode-spiro"] ="spiro_splines_mode"; + legacyNames["path-mode-bspline"] ="bspline_mode"; legacyNames["path-mode-polyline"] ="polylines_mode"; legacyNames["path-mode-polyline-paraxial"] ="paraxial_lines_mode"; legacyNames["draw-use-tilt"] ="guse_tilt"; -- cgit v1.2.3 From be4b46000a9a9f29d79b2e939c0669f6ddf0c59f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 27 Apr 2013 02:01:11 +0200 Subject: Fixed important selection bug when changing to cusp nodes (bzr r11950.1.109) --- src/ui/tool/node.cpp | 69 +++++++++++++++++++++++----------------- src/ui/tool/path-manipulator.cpp | 6 ++-- 2 files changed, 44 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 011d0d296..d342d6c3d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -141,17 +141,7 @@ void Handle::move(Geom::Point const &new_pos) //BSpline Handle *h = NULL; Handle *h2 = NULL; - if(_pm().isBSpline){ - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - _parent->_selection.insert(_parent); - } //BSpline End - if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -322,7 +312,7 @@ void Handle::handle_2button_press(){ if(_pm().isBSpline){ Handle *h = NULL; Handle *h2 = NULL; - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; h = this; setPosition(_pm().BSplineHandleReposition(h,0.3334)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); @@ -343,6 +333,7 @@ bool Handle::grabbed(GdkEventMotion *) void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) { + Geom::Point parent_pos = _parent->position(); Geom::Point origin = _last_drag_origin(); SnapManager &sm = _desktop->namedview->snap_manager; @@ -383,7 +374,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) //BSpline if(_pm().isBSpline){ Handle *h = NULL; - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; h = this; setPosition(new_pos); int steps = _pm().getSteps(); @@ -423,7 +414,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) //BSpline if(_pm().isBSpline){ Handle *h = NULL; - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; h = this; setPosition(new_pos); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); @@ -460,7 +451,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - _parent->bsplineWeight = 0; + _parent->bsplineWeight = 0.0000; } } @@ -472,11 +463,33 @@ void Handle::ungrabbed(GdkEventButton *event) _drag_out = false; _pm()._handleUngrabbed(); + //BSpline + if(_pm().isBSpline){ + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + _parent->_selection.erase(n); + } + _parent->_selection.insert(_parent); + } + //BSpline End } bool Handle::clicked(GdkEventButton *event) { _pm()._handleClicked(this, event); + //BSpline + if(_pm().isBSpline){ + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + _parent->_selection.erase(n); + } + _parent->_selection.insert(_parent); + } + //BSpline End return true; } @@ -627,8 +640,8 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); //BSpline - double prevPos = 0; - double nextPos = 0; + double prevPos = 0.0000; + double nextPos = 0.0000; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); @@ -636,7 +649,7 @@ void Node::move(Geom::Point const &new_pos) if(prevNode) prevPos = _pm().BSplineHandlePosition(prevNode->front()); n->bsplineWeight = _pm().BSplineHandlePosition(n->front()); - if(n->bsplineWeight == 0) + if(n->bsplineWeight == 0.0000) n->bsplineWeight = _pm().BSplineHandlePosition(n->back()); if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); @@ -770,7 +783,7 @@ void Node::updateHandles() _front._handleControlStyling(); _back._handleControlStyling(); } - + void Node::setType(NodeType type, bool update_handles) { @@ -779,7 +792,14 @@ void Node::setType(NodeType type, bool update_handles) updateState(); // The size of the control might have changed return; } - + //BSpline + bool isBSpline = false; + try { + isBSpline = nodeList().subpathList().pm().isBSpline; + } + catch( char * str ) { + } + //BSpline End // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -863,28 +883,19 @@ void Node::setType(NodeType type, bool update_handles) default: break; } //BSpline - bool isBSpline = false; - try { - isBSpline = nodeList().subpathList().pm().isBSpline; - } - catch( char * str ) { - } if(isBSpline){ Handle* front = &_front; Handle* back = &_back; this->bsplineWeight = _pm().BSplineHandlePosition(front); - if(this->bsplineWeight !=0) this->bsplineWeight = 0.3334; + if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); } //BSpline End } - _type = type; - _setControlType(nodeTypeToCtrlType(_type)); updateState(); - } void Node::pickBestType() diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 9da27e807..cad794860 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1239,9 +1239,11 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); + n->bsplineWeight = pos; ret = SBasisInsideNodes.valueAt(pos); ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); }else{ + n->bsplineWeight = 0.0000; ret = n->position(); } return ret; @@ -1257,8 +1259,8 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ prevPos = BSplineHandlePosition(prevNode->front()); if(nextNode) nextPos = BSplineHandlePosition(nextNode->back()); - n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); - n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); + n->front()->setPosition(BSplineHandleReposition(n->front())); + n->back()->setPosition(BSplineHandleReposition(n->back())); if(prevNode) prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); if(nextNode) -- cgit v1.2.3 From dd30de233b38518008030c2c0a2366332422b236 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 6 May 2013 02:54:50 +0200 Subject: Removed auto select nodes, not decide for the user. Added auto update all selected handles when drag (bzr r11950.1.111) --- src/ui/tool/node.cpp | 33 +++++++++------------------------ 1 file changed, 9 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index d342d6c3d..1d7b5850f 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -216,8 +216,15 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } //BSpline End } @@ -463,33 +470,11 @@ void Handle::ungrabbed(GdkEventButton *event) _drag_out = false; _pm()._handleUngrabbed(); - //BSpline - if(_pm().isBSpline){ - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - _parent->_selection.insert(_parent); - } - //BSpline End } bool Handle::clicked(GdkEventButton *event) { _pm()._handleClicked(this, event); - //BSpline - if(_pm().isBSpline){ - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - _parent->_selection.erase(n); - } - _parent->_selection.insert(_parent); - } - //BSpline End return true; } -- cgit v1.2.3 From 417a1e079bbc94ac0d8c6631832e47a35098ba98 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 May 2013 03:36:46 +0200 Subject: Change only selected nodes (bzr r11950.1.113) --- src/ui/tool/node.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1d7b5850f..5362a6c45 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -219,11 +219,13 @@ void Handle::move(Geom::Point const &new_pos) typedef ControlPointSelection::Set Set; Set &nodes = _parent->_selection.allPoints(); for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + if((*i)->selected()){ + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } } //BSpline End -- cgit v1.2.3 From e17c04bd7386e2e346b7f4f760f6e6ba3c24b886 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 17 May 2013 00:53:42 +0200 Subject: Fix error with try-catch (bzr r11950.1.115) --- src/ui/tool/node.cpp | 61 ++++++++++++++++++++++++++++++++-------- src/ui/tool/path-manipulator.cpp | 2 +- src/ui/tool/path-manipulator.h | 2 +- 3 files changed, 51 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 5362a6c45..89a0f4163 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -175,10 +175,25 @@ void Handle::move(Geom::Point const &new_pos) //BSpline if(_pm().isBSpline){ h = this; + setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + if((*i)->selected()){ + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } + } + if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } //BSpline End return; @@ -192,6 +207,30 @@ void Handle::move(Geom::Point const &new_pos) Geom::Point new_delta = (Geom::dot(delta, direction) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); + //BSpline + if(_pm().isBSpline){ + h = this; + setPosition(_pm().BSplineHandleReposition(h)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(h); + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + if((*i)->selected()){ + Node *n = static_cast(*i); + h = n->front(); + h2 = n->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } + } + if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } + } + //BSpline End return; } @@ -227,6 +266,12 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); } } + if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + } } //BSpline End } @@ -779,14 +824,6 @@ void Node::setType(NodeType type, bool update_handles) updateState(); // The size of the control might have changed return; } - //BSpline - bool isBSpline = false; - try { - isBSpline = nodeList().subpathList().pm().isBSpline; - } - catch( char * str ) { - } - //BSpline End // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -870,7 +907,7 @@ void Node::setType(NodeType type, bool update_handles) default: break; } //BSpline - if(isBSpline){ + if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; this->bsplineWeight = _pm().BSplineHandlePosition(front); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index cad794860..7785dd685 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -110,6 +110,7 @@ void build_segment(Geom::PathBuilder &, Node *, Node *); PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) + , isBSpline(true) , _subpaths(*this) , _multi_path_manipulator(mpm) , _path(path) @@ -157,7 +158,6 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } - isBSpline = false; if(lpe_bsp){ isBSpline = true; } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 743d70b96..2fc0b90da 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -96,7 +96,7 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, - bool search_unselected, bool closest); + bool search_unselected, bool closest); //BSpline bool isBSpline; int getSteps(); -- cgit v1.2.3 From 9291d4e3a3ad22bef4669b74568ee6d43ba74547 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 18 May 2013 10:38:35 +0200 Subject: Fix error with envelope lpe (bzr r11950.1.117) --- src/live_effects/effect.cpp | 2 +- src/ui/tool/path-manipulator.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 8bf8bab6c..b84403495 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -8,7 +8,7 @@ //#define LPE_ENABLE_TEST_EFFECTS #ifdef HAVE_CONFIG_H -#include "config.h" +# include "config.h" #endif // include effects: diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7785dd685..eb60abe2a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -152,7 +152,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); //BSpline lpe_bsp = NULL; - if (SP_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ + if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); -- cgit v1.2.3 From d67294affd2f6b0f71c67b75cf521bfe308500f9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 29 May 2013 01:33:43 +0200 Subject: Fixed a error that handles all kinds of pathas as bsplines (bzr r11950.1.119) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index eb60abe2a..ea007dfee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -110,7 +110,7 @@ void build_segment(Geom::PathBuilder &, Node *, Node *); PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) - , isBSpline(true) + , isBSpline(false) , _subpaths(*this) , _multi_path_manipulator(mpm) , _path(path) -- cgit v1.2.3 From 0bd0fa66b7825f0d4e0c9051aa527ba91e415683 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 19 Aug 2013 01:10:42 +0200 Subject: Reverted po files to master branch, now the diff of launchpad is more usable (bzr r11950.1.136) --- src/live_effects/lpe-bspline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index cc1b86e72..c2749e393 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -2,7 +2,7 @@ /* * Released under GNU GPL, read the file 'COPYING' for more information */ - + #include #include #include -- cgit v1.2.3 From 62ccb3999c5a5ec6f94de993d5b8a903f98adb5c Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 20 Sep 2013 02:29:43 +0200 Subject: Fixed ~sub advertising for a compile problem (bzr r11950.1.143) --- src/ui/tool/node-tool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index ce022cec6..4500c5de0 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "event-context.h" +#include "selection.h" namespace Inkscape { namespace Display { -- cgit v1.2.3 From 987dd0e7eae4dded4049771af56b72889d05c461 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 26 Sep 2013 18:28:28 +0200 Subject: Compiling problem solved thaks to ~suv (bzr r11950.1.149) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e08a36e2e..dac67295a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -152,12 +152,14 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); //BSpline lpe_bsp = NULL; - if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))){ - Inkscape::LivePathEffect::Effect* thisEffect = sp_lpe_item_has_path_effect_of_type(SP_LPE_ITEM(_path),Inkscape::LivePathEffect::BSPLINE); + + if (_path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } + if(lpe_bsp){ isBSpline = true; } -- cgit v1.2.3 From 9737c8d04d0ad85bf6a61d36edf7d717419b30f2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 27 Sep 2013 01:39:44 +0200 Subject: update to trunk (bzr r11950.1.152) --- src/live_effects/lpe-bendpath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 16b8c6137..d3564bac4 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -39,9 +39,9 @@ public: virtual void resetDefaults(SPItem const* item); + PathParam bend_path; private: - PathParam bend_path; ScalarParam prop_scale; BoolParam scale_y_rel; BoolParam vertical_pattern; -- cgit v1.2.3 From f3a885546d1bd971c5bd4a6bbdbaedb59557007d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 27 Sep 2013 01:42:10 +0200 Subject: error bend lpe (bzr r11950.1.153) --- src/live_effects/lpe-bendpath.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index d3564bac4..38b1a1446 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -39,9 +39,8 @@ public: virtual void resetDefaults(SPItem const* item); - PathParam bend_path; - private: + PathParam bend_path; ScalarParam prop_scale; BoolParam scale_y_rel; BoolParam vertical_pattern; -- cgit v1.2.3 From debe6f792f37d4ca3acb297eea230503cc3522a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 27 Sep 2013 12:21:37 +0200 Subject: Fix editing paths in live effect (bzr r11950.1.154) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1add4d176..3690efdad 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -153,7 +153,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, //BSpline lpe_bsp = NULL; - if (_path->hasPathEffect()){ + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); -- cgit v1.2.3 From 514675a4b3eeb5835ad2466b692b3d00c6333c4a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Sep 2013 17:58:15 +0200 Subject: Fixed a bug editing paths in others LPE -envelope- (bzr r11950.1.157) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 3690efdad..910f75258 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1312,7 +1312,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); _spcurve->set_pathvector(pathv); if (alert_LPE) { - if (_path->hasPathEffect()) { + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()) { PathEffectList effect_list = sp_lpe_item_get_effect_list(_path); LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast( effect_list.front()->lpeobject->get_lpe() ); if (lpe_pwr) { -- cgit v1.2.3 From 5ef4eb74cfdec7aad437518db0ab99414bd3eae6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Oct 2013 23:20:25 +0200 Subject: Fix moving handles (bzr r11950.1.160) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f72313315..18ad45f72 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1268,10 +1268,12 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ nextPos = BSplineHandlePosition(nextNode->back()); n->front()->setPosition(BSplineHandleReposition(n->front())); n->back()->setPosition(BSplineHandleReposition(n->back())); - if(prevNode) + if(prevNode && !prevNode->isEndNode()) prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); - if(nextNode) + prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); + if(nextNode && !nextNode->isEndNode()) nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),prevPos)); } } -- cgit v1.2.3 From bc37c9b9c4663786b04a65ba6a27d55b2395eeb9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 5 Oct 2013 23:56:02 +0200 Subject: fix whith bspline handles (bzr r11950.1.162) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 18ad45f72..fd286873b 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1268,12 +1268,14 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ nextPos = BSplineHandlePosition(nextNode->back()); n->front()->setPosition(BSplineHandleReposition(n->front())); n->back()->setPosition(BSplineHandleReposition(n->back())); - if(prevNode && !prevNode->isEndNode()) + if(prevNode && !prevNode->isEndNode()){ prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); - if(nextNode && !nextNode->isEndNode()) + } + if(nextNode && !nextNode->isEndNode()){ nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),prevPos)); + } } } -- cgit v1.2.3 From cdc3d492add4c4bd63d96dcb53c406f9ef631ec9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Oct 2013 09:27:04 +0200 Subject: Fix in BSpline (bzr r11950.1.163) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fd286873b..e9372aef3 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1274,7 +1274,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ } if(nextNode && !nextNode->isEndNode()){ nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),prevPos)); + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); } } } -- cgit v1.2.3 From 202528bb3f6f9e90b8651bb81bb017af46787933 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 6 Oct 2013 09:57:14 +0200 Subject: Fix in bsplines (bzr r11950.1.165) --- src/ui/tool/curve-drag-point.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index fce19f9ad..f4628fb8f 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -94,8 +94,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(!_pm.isBSpline){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8)second->back()->move(new_pos); - else if(weight<=0.2)first->front()->move(new_pos); + }else if(weight>=0.8 && !second->isEndNode())second->back()->move(new_pos); + else if(weight<=0.2 && !first->isEndNode())first->front()->move(new_pos); //BSpline End _pm.update(); } -- cgit v1.2.3 From 3111608afecf747627810a6222cb7ca1eded6962 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 6 Oct 2013 12:18:59 +0200 Subject: UX improvements (bzr r11950.1.166) --- src/pen-context.cpp | 6 +++++- src/ui/tool/path-manipulator.cpp | 36 ++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index a9bd09c51..936afe4e0 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -1573,7 +1573,7 @@ static void bspline_spiro_motion(SPPenContext *const pc, bool shift){ using Geom::X; using Geom::Y; SPCurve *tmpCurve = new SPCurve(); - pc->p[2] = pc->p[3]; + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); if(pc->green_curve->is_empty() && !pc->sa){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); }else if(!pc->green_curve->is_empty()){ @@ -1601,6 +1601,10 @@ static void bspline_spiro_motion(SPPenContext *const pc, bool shift){ pc->p[1] = SBasisWPower.valueAt(WP); if(!Geom::are_near(pc->p[1],pc->p[0])) pc->p[1] = Geom::Point(pc->p[1][X] + 0.0001,pc->p[1][Y] + 0.0001); + if(shift) + pc->p[2]=pc->p[3]; + else + pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); }else{ pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] ); } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e9372aef3..809d2628f 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -683,7 +683,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite } //BSpline if(isBSpline){ - double pos = 0; + double pos = 0.0000; if(start.prev()){ pos = BSplineHandlePosition(start.prev()->back()); start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),pos)); @@ -1215,8 +1215,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ Node *n = h->parent(); SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - if(!n->isEndNode()) - nextNode = n->nodeToward(h); + nextNode = n->nodeToward(h); Geom::Point positionH = h->position(); positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ @@ -1235,13 +1234,12 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; - Geom::Point ret(0,0); + Geom::Point ret = h->position(); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; - if(!n->isEndNode()) - nextNode = n->nodeToward(h); + nextNode = n->nodeToward(h); if(nextNode && pos != 0.0000){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); @@ -1250,8 +1248,10 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ ret = SBasisInsideNodes.valueAt(pos); ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); }else{ - n->bsplineWeight = 0.0000; - ret = n->position(); + if(pos == 0.0000){ + n->bsplineWeight = 0.0000; + ret = n->position(); + } } return ret; } @@ -1262,19 +1262,23 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * prevNode = n->nodeToward(n->back()); double prevPos = 0.0000; double nextPos = 0.0000; - if(prevNode) + if(prevNode){ prevPos = BSplineHandlePosition(prevNode->front()); - if(nextNode) + n->back()->setPosition(BSplineHandleReposition(n->back())); + } + if(nextNode){ nextPos = BSplineHandlePosition(nextNode->back()); - n->front()->setPosition(BSplineHandleReposition(n->front())); - n->back()->setPosition(BSplineHandleReposition(n->back())); - if(prevNode && !prevNode->isEndNode()){ + n->front()->setPosition(BSplineHandleReposition(n->front())); + } + if(prevNode){ + if(!prevNode->isEndNode()) + prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); - prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); } - if(nextNode && !nextNode->isEndNode()){ + if(nextNode){ + if(!nextNode->isEndNode()) + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); } } } -- cgit v1.2.3 From e8e2929ccb133b015db1de73de0efbb982d455a4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 00:36:15 +0200 Subject: Fix bspline and strip multi node bspline power editing whith node tool because UX (bzr r11950.1.168) --- src/ui/tool/node.cpp | 102 +++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 5f5757a14..1151dc41b 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -176,23 +176,23 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - if((*i)->selected()){ - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } - } - if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } + //typedef ControlPointSelection::Set Set; + //Set &nodes = _parent->_selection.allPoints(); + //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + // if((*i)->selected()){ + // Node *n = static_cast(*i); + // h = n->front(); + // h2 = n->back(); + // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} + //} + //if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} } //BSpline End return; @@ -211,23 +211,23 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - if((*i)->selected()){ - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } - } - if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } + //typedef ControlPointSelection::Set Set; + //Set &nodes = _parent->_selection.allPoints(); + //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + // if((*i)->selected()){ + // Node *n = static_cast(*i); + // h = n->front(); + // h2 = n->back(); + // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + // } + //} + //if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} } //BSpline End return; @@ -254,23 +254,23 @@ void Handle::move(Geom::Point const &new_pos) h = this; setPosition(_pm().BSplineHandleReposition(h)); _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - typedef ControlPointSelection::Set Set; - Set &nodes = _parent->_selection.allPoints(); - for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - if((*i)->selected()){ - Node *n = static_cast(*i); - h = n->front(); - h2 = n->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } - } - if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - } + //typedef ControlPointSelection::Set Set; + //Set &nodes = _parent->_selection.allPoints(); + //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + // if((*i)->selected()){ + // Node *n = static_cast(*i); + // h = n->front(); + // h2 = n->back(); + // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + // } + //} + //if(!_parent->selected()){ + h = _parent->front(); + h2 = _parent->back(); + h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); + h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + //} } //BSpline End } -- cgit v1.2.3 From f26927f8891498ca9466ea865f17a790b73ccff6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 01:39:48 +0200 Subject: Fix scaling handles (bzr r11950.1.170) --- src/ui/tool/path-manipulator.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 809d2628f..620c52e34 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1213,12 +1213,12 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::Y; double pos = 0.0000; Node *n = h->parent(); - SPCurve *lineInsideNodes = new SPCurve(); Node * nextNode = NULL; nextNode = n->nodeToward(h); Geom::Point positionH = h->position(); positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ + SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); @@ -1263,11 +1263,11 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ double prevPos = 0.0000; double nextPos = 0.0000; if(prevNode){ - prevPos = BSplineHandlePosition(prevNode->front()); + prevPos = BSplineHandlePosition(prevNode->front(),prevNode->bsplineWeight); n->back()->setPosition(BSplineHandleReposition(n->back())); } if(nextNode){ - nextPos = BSplineHandlePosition(nextNode->back()); + nextPos = BSplineHandlePosition(nextNode->back(),nextNode->bsplineWeight); n->front()->setPosition(BSplineHandleReposition(n->front())); } if(prevNode){ -- cgit v1.2.3 From c2d73f1a14e1d461553465892bc9a3767313878a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 01:54:04 +0200 Subject: Fix scaling handles (bzr r11950.1.171) --- src/ui/tool/path-manipulator.cpp | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 620c52e34..27def4cb1 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1257,29 +1257,19 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ } void PathManipulator::BSplineNodeHandlesReposition(Node *n){ - if(n->selected()){ - Node * nextNode = n->nodeToward(n->front()); - Node * prevNode = n->nodeToward(n->back()); - double prevPos = 0.0000; - double nextPos = 0.0000; - if(prevNode){ - prevPos = BSplineHandlePosition(prevNode->front(),prevNode->bsplineWeight); - n->back()->setPosition(BSplineHandleReposition(n->back())); - } - if(nextNode){ - nextPos = BSplineHandlePosition(nextNode->back(),nextNode->bsplineWeight); - n->front()->setPosition(BSplineHandleReposition(n->front())); - } - if(prevNode){ - if(!prevNode->isEndNode()) - prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevPos)); - prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevPos)); - } - if(nextNode){ - if(!nextNode->isEndNode()) - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextPos)); - nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextPos)); - } + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + if(prevNode){ + n->back()->setPosition(BSplineHandleReposition(n->back())); + if(!prevNode->isEndNode()) + prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); + prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); + } + if(nextNode){ + n->front()->setPosition(BSplineHandleReposition(n->front())); + if(!nextNode->isEndNode()) + nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); + nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); } } -- cgit v1.2.3 From 6255e3bc1ad8c5c3824483e55e6f3c9de6941e5f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 15:42:58 +0200 Subject: fix in nodes (bzr r11950.1.172) --- src/ui/tool/node.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1151dc41b..7506a54a8 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -635,6 +635,8 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { this->bsplineWeight = 0.3334; + if(_front->position() == this->position() && _back->position() == this->position()) + this->bsplineWeight = 0.0000; // NOTE we do not set type here, because the handles are still degenerate } -- cgit v1.2.3 From 0eb0148cade3cc19d1cf85fadd5928c8c8ee1674 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 15:47:51 +0200 Subject: update to trunk (bzr r11950.1.173) --- src/ui/tool/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 7506a54a8..c5ab2f316 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -635,7 +635,7 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { this->bsplineWeight = 0.3334; - if(_front->position() == this->position() && _back->position() == this->position()) + if(this->front()->position() == this->position() && this->back()->position() == this->position()) this->bsplineWeight = 0.0000; // NOTE we do not set type here, because the handles are still degenerate } -- cgit v1.2.3 From f238a7004752e4e56b7e6d602f675c97c0ce4733 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:09:32 +0200 Subject: Fixing BSplines (bzr r11950.1.174) --- src/ui/tool/node.cpp | 1 + src/ui/tool/path-manipulator.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index c5ab2f316..c6d4537dd 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -726,6 +726,7 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); + _pm().BSplineNodeHandlesReposition(this); } Geom::Rect Node::bounds() const diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 27def4cb1..b90fa4ac7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1261,12 +1261,16 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * prevNode = n->nodeToward(n->back()); if(prevNode){ n->back()->setPosition(BSplineHandleReposition(n->back())); + if(prevNode->front()->position() == prevNode->position()) + prevNode->bsplineWeight = 0.000; if(!prevNode->isEndNode()) prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); } if(nextNode){ n->front()->setPosition(BSplineHandleReposition(n->front())); + if(nextNode->front()->position() == nextNode->position()) + nextNode->bsplineWeight = 0.000; if(!nextNode->isEndNode()) nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); @@ -1287,14 +1291,14 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); - if(isBSpline){ - BSplineNodeHandlesReposition(prev.ptr()); - } + //if(isBSpline){ + // BSplineNodeHandlesReposition(prev.ptr()); + //} builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - if(isBSpline){ - BSplineNodeHandlesReposition(i.ptr()); - } + //if(isBSpline){ + // BSplineNodeHandlesReposition(i.ptr()); + //} build_segment(builder, prev.ptr(), i.ptr()); prev = i; } -- cgit v1.2.3 From 46699ed807e748453d6aaa054f87c0582c38d72e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:24:27 +0200 Subject: fix bsplines (bzr r11950.1.175) --- src/ui/tool/node.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index c6d4537dd..cbfd3ec0d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -635,8 +635,6 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _handles_shown(false) { this->bsplineWeight = 0.3334; - if(this->front()->position() == this->position() && this->back()->position() == this->position()) - this->bsplineWeight = 0.0000; // NOTE we do not set type here, because the handles are still degenerate } -- cgit v1.2.3 From a4dcddb133064faf3f24f8f1a3f664f4d3d700b9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:46:13 +0200 Subject: fix bsplines (bzr r11950.1.176) --- src/ui/tool/node.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index cbfd3ec0d..f6d100b57 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -724,7 +724,10 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - _pm().BSplineNodeHandlesReposition(this); + if(_pm().isBSpline){ + this->front().setPosition(BSplineHandleReposition(this->front(),this->bsplineWeight)); + this->back().setPosition(BSplineHandleReposition(this->back(),this->bsplineWeight)); + } } Geom::Rect Node::bounds() const -- cgit v1.2.3 From db5de41dd8f09821561a14db45192a76479e2536 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:50:52 +0200 Subject: fix bsplines (bzr r11950.1.177) --- src/ui/tool/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index f6d100b57..91f8e8a54 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -725,8 +725,8 @@ void Node::transform(Geom::Affine const &m) * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); if(_pm().isBSpline){ - this->front().setPosition(BSplineHandleReposition(this->front(),this->bsplineWeight)); - this->back().setPosition(BSplineHandleReposition(this->back(),this->bsplineWeight)); + _front.setPosition(BSplineHandleReposition(_front,this->bsplineWeight)); + _back.setPosition(BSplineHandleReposition(_back,this->bsplineWeight)); } } -- cgit v1.2.3 From c868eae8e1cc980621791d982c519fc14139f906 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 17:56:26 +0200 Subject: fix bsplines (bzr r11950.1.178) --- src/ui/tool/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 91f8e8a54..933bfe0ca 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -725,8 +725,8 @@ void Node::transform(Geom::Affine const &m) * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); if(_pm().isBSpline){ - _front.setPosition(BSplineHandleReposition(_front,this->bsplineWeight)); - _back.setPosition(BSplineHandleReposition(_back,this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(_front,this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(_back,this->bsplineWeight)); } } -- cgit v1.2.3 From bae8160a80e84129b87846e09dee0a0aa0c08e0e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Oct 2013 18:52:27 +0200 Subject: fix bsplines (bzr r11950.1.179) --- src/ui/tool/node.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 933bfe0ca..8564f1f1a 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -725,8 +725,9 @@ void Node::transform(Geom::Affine const &m) * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); if(_pm().isBSpline){ - _front.setPosition(_pm().BSplineHandleReposition(_front,this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(_back,this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + _pm().BSplineNodeHandlesReposition(this); } } -- cgit v1.2.3 From 0aa9ccce32f60c55b35348fe14da33950ca4517f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 16 Oct 2013 11:39:52 +0200 Subject: Update motion redraw of bsplines (bzr r11950.1.183) --- src/pen-context.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pen-context.cpp b/src/pen-context.cpp index 0d4b5df7e..e251c1125 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -733,10 +733,15 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons } //BSpline //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. - if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + if(pc->bspline){ bspline_spiro_color(pc); bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); - pen_drag_origin_w = event_w; + }else{ + if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + bspline_spiro_color(pc); + bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); + pen_drag_origin_w = event_w; + } } //BSpline End return ret; -- cgit v1.2.3 From cdf6320ab752de234f986031bfdd7dcb8e705e69 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 8 Nov 2013 10:13:22 +0100 Subject: Fixing bugs on update to trunk (bzr r11950.1.194) --- src/live_effects/lpe-bspline.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 84f3fbb33..ef03d8ef0 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -335,7 +335,7 @@ LPEBSpline::changeWeight(double weightValue) gchar *str = sp_svg_write_path(curve->get_pathvector()); path->getRepr()->setAttribute("inkscape:original-d", str); if(INK_IS_NODE_TOOL(desktop->event_context)){ - InkNodeTool *nt = INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); nt->desktop->updateNow(); } g_free(str); @@ -367,7 +367,7 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) using Geom::Y; SPDesktop *desktop = inkscape_active_desktop(); if(INK_IS_NODE_TOOL(desktop->event_context)){ - InkNodeTool *nt = INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); Inkscape::UI::ControlPointSelection::Set &selection = nt->_selected_nodes->allPoints(); points.clear(); std::vector::iterator pbegin; -- cgit v1.2.3 From 3ed9b4ff7ebbae3ba6446d911001688bcbbdc847 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 10 Nov 2013 12:17:23 +0100 Subject: Update to trunk (bzr r11950.1.196) --- src/live_effects/lpe-bspline.cpp | 2 +- src/ui/tools/node-tool.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index ef03d8ef0..c19eda8f0 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -17,7 +17,7 @@ #include "live_effects/parameter/parameter.h" #include "ui/widget/scalar.h" #include "ui/tool/node.h" -#include "ui/tool/node-tool.h" +#include "ui/tools/node-tool.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/selectable-control-point.h" #include "selection.h" diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 4d15ab70e..b3acb79ad 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "ui/tools/tool-base.h" +#include "selection.h" namespace Inkscape { namespace Display { -- cgit v1.2.3 From ebc5ac2b758155192114ea1bec8b3d32820a18d3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 3 Dec 2013 16:55:14 +0100 Subject: Fix a bug delete BSpline LPE from a path retain some BSpline properties (bzr r11950.1.206) --- src/ui/tool/node.cpp | 63 +++++++++++++++++++++------------------- src/ui/tool/path-manipulator.cpp | 52 +++++++++++++++++++-------------- src/ui/tool/path-manipulator.h | 16 +++++----- 3 files changed, 72 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 230d39e2e..af823a787 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,9 +28,9 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include -//BSpline + #include -//BSpline End; +; namespace { @@ -137,10 +137,10 @@ 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 + Handle *h = NULL; Handle *h2 = NULL; - //BSpline End + _pm().BSpline(); if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -171,7 +171,7 @@ void Handle::move(Geom::Point const &new_pos) } } setPosition(new_pos); - //BSpline + if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); @@ -194,7 +194,7 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); //} } - //BSpline End + return; } @@ -206,7 +206,7 @@ void Handle::move(Geom::Point const &new_pos) Geom::Point new_delta = (Geom::dot(delta, direction) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //BSpline + if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); @@ -229,7 +229,7 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); //} } - //BSpline End + return; } @@ -249,7 +249,7 @@ void Handle::move(Geom::Point const &new_pos) default: break; } setPosition(new_pos); - //BSpline + if(_pm().isBSpline){ h = this; setPosition(_pm().BSplineHandleReposition(h)); @@ -272,7 +272,7 @@ void Handle::move(Geom::Point const &new_pos) h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); //} } - //BSpline End + } void Handle::setPosition(Geom::Point const &p) @@ -349,19 +349,20 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - //BSpline + case GDK_2BUTTON_PRESS: handle_2button_press(); break; - //BSpline End + default: break; } return ControlPoint::_eventHandler(event_context, event); } -//BSpline + void Handle::handle_2button_press(){ + _pm().BSpline(); if(_pm().isBSpline){ Handle *h = NULL; Handle *h2 = NULL; @@ -374,7 +375,7 @@ void Handle::handle_2button_press(){ _pm().update(); } } -//BSpline End + bool Handle::grabbed(GdkEventMotion *) { @@ -392,7 +393,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) SnapManager &sm = _desktop->namedview->snap_manager; bool snap = held_shift(*event) ? false : sm.someSnapperMightSnap(); boost::optional ctrl_constraint; - + _pm().BSpline(); // with Alt, preserve length if (held_alt(*event)) { new_pos = parent_pos + Geom::unit_vector(new_pos - parent_pos) * _saved_length; @@ -424,17 +425,17 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - //BSpline + if(_pm().isBSpline){ Handle *h = NULL; _parent->bsplineWeight = 0.0000; h = this; setPosition(new_pos); - int steps = _pm().getSteps(); + int steps = _pm().BSplineGetSteps(); _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); } - //BSpline End + } std::vector unselected; @@ -464,7 +465,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); - //BSpline + if(_pm().isBSpline){ Handle *h = NULL; _parent->bsplineWeight = 0.0000; @@ -473,7 +474,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) _parent->bsplineWeight = _pm().BSplineHandlePosition(h); new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); } - //BSpline End + } @@ -674,9 +675,10 @@ 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 prevPos = 0.0000; double nextPos = 0.0000; + _pm().BSpline(); Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); @@ -689,23 +691,23 @@ void Node::move(Geom::Point const &new_pos) if(nextNode) nextPos = _pm().BSplineHandlePosition(nextNode->back()); } - //BSpline End + setPosition(new_pos); - //BSpline + if(_pm().isBSpline){ if(prevNode) prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); if(nextNode) nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); } - //BSpline End + _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); - //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); - //BSpline + if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; @@ -724,6 +726,7 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); + _pm().BSpline(); if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); @@ -914,7 +917,7 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - //BSpline + _pm().BSpline(); if(_pm().isBSpline){ Handle* front = &_front; Handle* back = &_back; @@ -923,7 +926,7 @@ void Node::setType(NodeType type, bool update_handles) _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); } - //BSpline End + } _type = type; _setControlType(nodeTypeToCtrlType(_type)); @@ -1170,12 +1173,12 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //BSpline + _pm().BSpline(); if(_pm().isBSpline){ this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); _pm().BSplineNodeHandlesReposition(this); } - //BSpline End + break; } SelectableControlPoint::_setState(state); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e66c6a899..fd421e587 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -43,9 +43,9 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" -//BSpline + #include "live_effects/lpe-bspline.h" -//BSpline end + namespace Inkscape { namespace UI { @@ -150,20 +150,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - //BSpline - lpe_bsp = NULL; - - if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); - if(thisEffect){ - lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); - } - } - - if(lpe_bsp){ - isBSpline = true; - } - //BSpline End + BSpline(); } PathManipulator::~PathManipulator() @@ -681,7 +668,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - //BSpline + if(isBSpline){ double pos = 0.0000; if(start.prev()){ @@ -693,7 +680,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); } } - //BSpline End + return del_len; } @@ -928,9 +915,9 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - //BSpline + if(isBSpline) show = true; - //BSpline + if (show == _show_outline) return; _show_outline = show; _updateOutline(); @@ -1204,10 +1191,33 @@ void PathManipulator::_createControlPointsFromGeometry() } } -int PathManipulator::getSteps(){ +int PathManipulator::BSplineGetSteps(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } return lpe_bsp->steps+1; } +void PathManipulator::BSpline(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } + isBSpline = false; + if(lpe_bsp){ + isBSpline = true; + } +} + double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index b40a479f7..2a59df464 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -19,9 +19,9 @@ #include #include "ui/tool/node.h" #include "ui/tool/manipulator.h" -//BSpline + #include "live_effects/lpe-bspline.h" -//BSpline end + struct SPCanvasItem; class SPCurve; @@ -97,10 +97,10 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - //BSpline + bool isBSpline; - int getSteps(); - //BSpline End + int BSplineGetSteps(); + // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -110,13 +110,13 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - //BSpline - LivePathEffect::LPEBSpline *lpe_bsp; + + void BSpline(); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); void BSplineNodeHandlesReposition(Node *n); - //BSpline End + void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); -- cgit v1.2.3 From fb006b59b6d7b6d059dffe3389a829d2213f648d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 28 Dec 2013 23:34:45 +0100 Subject: Fix crash bug continuing empty paths (bzr r11950.1.210) --- src/ui/tools/pen-tool.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index ebbc533b8..178a940a2 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1648,6 +1648,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) Geom::Point C(0,0); if(!pc->sa || pc->sa->curve->is_empty()){ tmpCurve = pc->green_curve->create_reverse(); + if(pc->green_curve->get_segment_count()==0)return; Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); @@ -1715,6 +1716,7 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) SPCurve *lastSeg = new SPCurve(); if(!pc->sa || pc->sa->curve->is_empty()){ tmpCurve = pc->green_curve->create_reverse(); + if(pc->green_curve->get_segment_count()==0)return; Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(cubic){ lastSeg->moveto((*cubic)[0]); -- cgit v1.2.3 From 57865cd8a96b1b5c72f44c9b97d1a828caf09f95 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 19:45:52 +0100 Subject: Refactorizing (bzr r11950.1.211) --- src/ui/tool/curve-drag-point.cpp | 6 +- src/ui/tool/node.cpp | 210 +++++++++++++++------------------------ src/ui/tool/path-manipulator.cpp | 7 +- src/ui/tool/path-manipulator.h | 2 +- 4 files changed, 82 insertions(+), 143 deletions(-) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index c25fa2d52..f847a6ab3 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -90,13 +90,11 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - //BSpline if(!_pm.isBSpline){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8 && !second->isEndNode())second->back()->move(new_pos); - else if(weight<=0.2 && !first->isEndNode())first->front()->move(new_pos); - //BSpline End + }else if(weight>=0.8 && !second->isEndNode() && held_shift(*event))second->back()->move(new_pos); + else if(weight<=0.2 && !first->isEndNode() && held_shift(*event))first->front()->move(new_pos); _pm.update(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index af823a787..70e374424 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -138,9 +138,6 @@ void Handle::move(Geom::Point const &new_pos) Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL; Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; - Handle *h = NULL; - Handle *h2 = NULL; - _pm().BSpline(); if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -171,30 +168,13 @@ void Handle::move(Geom::Point const &new_pos) } } setPosition(new_pos); - + + //If is bspline move other handle if(_pm().isBSpline){ - h = this; - setPosition(_pm().BSplineHandleReposition(h)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - //typedef ControlPointSelection::Set Set; - //Set &nodes = _parent->_selection.allPoints(); - //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - // if((*i)->selected()){ - // Node *n = static_cast(*i); - // h = n->front(); - // h2 = n->back(); - // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} - //} - //if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} + setPosition(_pm().BSplineHandleReposition(this)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } - return; } @@ -206,28 +186,12 @@ void Handle::move(Geom::Point const &new_pos) Geom::Point new_delta = (Geom::dot(delta, direction) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - + + //If is bspline move both handles if(_pm().isBSpline){ - h = this; - setPosition(_pm().BSplineHandleReposition(h)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - //typedef ControlPointSelection::Set Set; - //Set &nodes = _parent->_selection.allPoints(); - //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - // if((*i)->selected()){ - // Node *n = static_cast(*i); - // h = n->front(); - // h2 = n->back(); - // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - // } - //} - //if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} + setPosition(_pm().BSplineHandleReposition(this)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } return; @@ -249,28 +213,12 @@ void Handle::move(Geom::Point const &new_pos) default: break; } setPosition(new_pos); - + + //If is bspline move other handle if(_pm().isBSpline){ - h = this; - setPosition(_pm().BSplineHandleReposition(h)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - //typedef ControlPointSelection::Set Set; - //Set &nodes = _parent->_selection.allPoints(); - //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { - // if((*i)->selected()){ - // Node *n = static_cast(*i); - // h = n->front(); - // h2 = n->back(); - // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - // } - //} - //if(!_parent->selected()){ - h = _parent->front(); - h2 = _parent->back(); - h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight)); - h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); - //} + setPosition(_pm().BSplineHandleReposition(this)); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } } @@ -362,16 +310,10 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven void Handle::handle_2button_press(){ - _pm().BSpline(); if(_pm().isBSpline){ - Handle *h = NULL; - Handle *h2 = NULL; - _parent->bsplineWeight = 0.0000; - h = this; - setPosition(_pm().BSplineHandleReposition(h,0.3334)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - h2 = this->other(); - this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight)); + setPosition(_pm().BSplineHandleReposition(this,0.3334)); + _parent->bsplineWeight = 0.3334; + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); _pm().update(); } } @@ -393,7 +335,6 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) SnapManager &sm = _desktop->namedview->snap_manager; bool snap = held_shift(*event) ? false : sm.someSnapperMightSnap(); boost::optional ctrl_constraint; - _pm().BSpline(); // with Alt, preserve length if (held_alt(*event)) { new_pos = parent_pos + Geom::unit_vector(new_pos - parent_pos) * _saved_length; @@ -427,19 +368,18 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) new_pos = result; if(_pm().isBSpline){ - Handle *h = NULL; - _parent->bsplineWeight = 0.0000; - h = this; setPosition(new_pos); int steps = _pm().BSplineGetSteps(); - _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps; - new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); + _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; + new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); } } std::vector unselected; - if (snap && ( (!held_control(*event) && _pm().isBSpline) || !_pm().isBSpline)) { + + //IF Snap and Not CTRL && BSpline or BSPLINE is false + if (snap && (((!held_control(*event) && _pm().isBSpline) && (!held_shift(*event) && _pm().isBSpline)) || !_pm().isBSpline)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -465,16 +405,11 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); - if(_pm().isBSpline){ - Handle *h = NULL; - _parent->bsplineWeight = 0.0000; - h = this; setPosition(new_pos); - _parent->bsplineWeight = _pm().BSplineHandlePosition(h); - new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight); + _parent->bsplineWeight = _pm().BSplineHandlePosition(this); + new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); } - } @@ -489,6 +424,10 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } + + if(_pm().isBSpline && !held_shift(*event) && !held_control(*event)){ + new_pos=_last_drag_origin(); + } move(new_pos); // needed for correct update, even though it's redundant _pm().update(); } @@ -505,7 +444,9 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - _parent->bsplineWeight = 0.0000; + if(_pm().isBSpline){ + _parent->bsplineWeight = 0.0000; + } } } @@ -548,13 +489,18 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; + bool isBSpline = false; + if( _parent->bsplineWeight != 0.0000) + isBSpline = true; bool can_shift_rotate = _parent->type() == NODE_CUSP && !other()->isDegenerate(); - if (can_shift_rotate) { + if (can_shift_rotate && !isBSpline) { more = C_("Path handle tip", "more: Shift, Ctrl, Alt"); - } else { + } else if(isBSpline){ + more = C_("Path handle tip", "move:Shift, reset:double click, more: Ctrl"); + }else { more = C_("Path handle tip", "more: Ctrl, Alt"); } - if (state_held_alt(state)) { + if (state_held_alt(state) && !isBSpline) { if (state_held_control(state)) { if (state_held_shift(state) && can_shift_rotate) { return format_tip(C_("Path handle tip", @@ -577,18 +523,24 @@ Glib::ustring Handle::_getTip(unsigned state) const } } else { if (state_held_control(state)) { - if (state_held_shift(state) && can_shift_rotate) { + if (state_held_shift(state) && can_shift_rotate && !isBSpline) { return format_tip(C_("Path handle tip", "Shift+Ctrl: snap rotation angle to %g° increments and rotate both handles"), snap_increment_degrees()); - } else { + } else if(isBSpline){ + return format_tip(C_("Path handle tip", + "Ctrl: Move handle by his actual steps in BSpline Live Effect")); + }else{ return format_tip(C_("Path handle tip", "Ctrl: snap rotation angle to %g° increments, click to retract"), snap_increment_degrees()); } - } else if (state_held_shift(state) && can_shift_rotate) { + } else if (state_held_shift(state) && can_shift_rotate && !isBSpline) { return C_("Path hande tip", "Shift: rotate both handles by the same angle"); + } else if(state_held_shift(state) && isBSpline){ + return C_("Path hande tip", + "Shift: move handle"); } } @@ -676,31 +628,14 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - double prevPos = 0.0000; - double nextPos = 0.0000; - _pm().BSpline(); + double oldPos = 0.0000; Node *n = this; - Node * nextNode = n->nodeToward(n->front()); - Node * prevNode = n->nodeToward(n->back()); if(_pm().isBSpline){ - if(prevNode) - prevPos = _pm().BSplineHandlePosition(prevNode->front()); - n->bsplineWeight = _pm().BSplineHandlePosition(n->front()); - if(n->bsplineWeight == 0.0000) - n->bsplineWeight = _pm().BSplineHandlePosition(n->back()); - if(nextNode) - nextPos = _pm().BSplineHandlePosition(nextNode->back()); + oldPos = n->bsplineWeight; } setPosition(new_pos); - - if(_pm().isBSpline){ - if(prevNode) - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos)); - if(nextNode) - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos)); - } - + _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); @@ -709,15 +644,18 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); if(_pm().isBSpline){ - Handle* front = &_front; - Handle* back = &_back; - _front.setPosition(_pm().BSplineHandleReposition(front,n->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(back,n->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); + _pm().BSplineNodeHandlesReposition(this); } } void Node::transform(Geom::Affine const &m) { + double oldPos = 0.0000; + if(_pm().isBSpline){ + oldPos = this->bsplineWeight; + } Geom::Point old_pos = position(); setPosition(position() * m); _front.setPosition(_front.position() * m); @@ -726,10 +664,9 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - _pm().BSpline(); if(_pm().isBSpline){ - _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); _pm().BSplineNodeHandlesReposition(this); } } @@ -817,6 +754,8 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } + if(!_pm().isBSpline) + this->bsplineWeight = 0.0000; } void Node::updateHandles() @@ -917,14 +856,10 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - _pm().BSpline(); if(_pm().isBSpline){ - Handle* front = &_front; - Handle* back = &_back; - this->bsplineWeight = _pm().BSplineHandlePosition(front); if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; - _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight)); + _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); } } @@ -1175,8 +1110,19 @@ void Node::_setState(State state) mgr.setPrelight(_canvas_item, false); _pm().BSpline(); if(_pm().isBSpline){ - this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); - _pm().BSplineNodeHandlesReposition(this); + if(!this->back()->isDegenerate()){ + this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); + }else if (!this->front()->isDegenerate()){ + this->bsplineWeight = _pm().BSplineHandlePosition(this->front()); + }else{ + this->bsplineWeight = 0.0000; + } + if(!this->front()->isDegenerate()){ + this->front()->setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); + } + if(!this->back()->isDegenerate()){ + this->back()->setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + } } break; diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index fd421e587..4aec42100 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1294,6 +1294,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; + BSpline(); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { @@ -1301,14 +1302,8 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) continue; } NodeList::iterator prev = subpath->begin(); - //if(isBSpline){ - // BSplineNodeHandlesReposition(prev.ptr()); - //} builder.moveTo(prev->position()); for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) { - //if(isBSpline){ - // BSplineNodeHandlesReposition(i.ptr()); - //} build_segment(builder, prev.ptr(), i.ptr()); prev = i; } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 2a59df464..547e687a7 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -116,7 +116,7 @@ private: Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); void BSplineNodeHandlesReposition(Node *n); - + void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); -- cgit v1.2.3 From 4c6918c72721a35e0347e9e087396238e72eb62e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 20:41:32 +0100 Subject: Refactorizing (bzr r11950.1.212) --- src/live_effects/effect-enum.h | 2 - src/live_effects/effect.cpp | 6 --- src/live_effects/lpe-bendpath.h | 1 - src/ui/tool/curve-drag-point.cpp | 2 - src/ui/tool/multi-path-manipulator.cpp | 3 -- src/ui/tool/multi-path-manipulator.h | 2 +- src/ui/tool/node.cpp | 21 ++++------ src/ui/tool/node.h | 9 ++--- src/ui/tool/path-manipulator.cpp | 11 +---- src/ui/tool/path-manipulator.h | 7 +--- src/ui/tools/freehand-base.cpp | 8 ---- src/ui/tools/freehand-base.h | 2 - src/ui/tools/node-tool.h | 1 - src/ui/tools/pen-tool.cpp | 74 ++++++---------------------------- src/ui/tools/pen-tool.h | 2 - src/ui/tools/pencil-tool.cpp | 8 ---- src/widgets/pencil-toolbar.cpp | 2 - src/widgets/toolbox.cpp | 1 - 18 files changed, 29 insertions(+), 133 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index cf97dd87f..342a2c849 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -45,9 +45,7 @@ enum EffectType { PATH_LENGTH, LINE_SEGMENT, DOEFFECTSTACK_TEST, - //BSpline BSPLINE, - //BSpline End DYNASTROKE, RECURSIVE_SKELETON, EXTRUDE, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 3289c239e..29da403e8 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -21,9 +21,7 @@ #include "live_effects/lpe-rough-hatches.h" #include "live_effects/lpe-dynastroke.h" #include "live_effects/lpe-test-doEffect-stack.h" -//BSpline #include "live_effects/lpe-bspline.h" -//BSpline End #include "live_effects/lpe-gears.h" #include "live_effects/lpe-curvestitch.h" #include "live_effects/lpe-circle_with_radius.h" @@ -125,9 +123,7 @@ const Util::EnumData LPETypeData[] = { /* 0.49 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, - //BSpline {BSPLINE, N_("BSpline"), "bspline"}, - //BSpline End }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -236,11 +232,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case DOEFFECTSTACK_TEST: neweffect = static_cast ( new LPEdoEffectStackTest(lpeobj) ); break; - //BSpline case BSPLINE: neweffect = static_cast ( new LPEBSpline(lpeobj) ); break; - //BSpline End case DYNASTROKE: neweffect = static_cast ( new LPEDynastroke(lpeobj) ); break; diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 38b1a1446..554f20413 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -38,7 +38,6 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); virtual void resetDefaults(SPItem const* item); - private: PathParam bend_path; ScalarParam prop_scale; diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index f847a6ab3..5387e597d 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,12 +53,10 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - //BSpline if(!_pm.isBSpline){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); } - //BSpline End _pm.update(); } else { _segment_was_degenerate = false; diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 6da8b4104..3612f9c56 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -298,7 +298,6 @@ void MultiPathManipulator::invertSelectionInSubpaths() invokeForAll(&PathManipulator::invertSelectionInSubpaths); } - void MultiPathManipulator::setNodeType(NodeType type) { if (_selection.empty()) return; @@ -327,7 +326,6 @@ void MultiPathManipulator::setNodeType(NodeType type) _done(retract_handles ? _("Retract handles") : _("Change node type")); } - void MultiPathManipulator::setSegmentType(SegmentType type) { if (_selection.empty()) return; @@ -691,7 +689,6 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G deleteNodes(true); } else - //BSpline end deleteNodes(del_preserves_shape ^ held_control(event->key)); // Delete any selected gradient nodes as well diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index 4566a7a98..1328372c6 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -71,7 +71,7 @@ public: void setLiveObjects(bool set); void updateOutlineColors(); void updateHandles(); - + sigc::signal signal_coords_changed; /// Emitted whenever the coordinates /// shown in the status bar need updating private: diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 70e374424..7266c85bb 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,9 +28,7 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include - #include -; namespace { @@ -137,7 +135,7 @@ 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; - + if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. // Adjust node type as necessary. @@ -308,7 +306,6 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } - void Handle::handle_2button_press(){ if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -318,7 +315,6 @@ void Handle::handle_2button_press(){ } } - bool Handle::grabbed(GdkEventMotion *) { _saved_other_pos = other()->position(); @@ -335,6 +331,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) SnapManager &sm = _desktop->namedview->snap_manager; bool snap = held_shift(*event) ? false : sm.someSnapperMightSnap(); boost::optional ctrl_constraint; + // with Alt, preserve length if (held_alt(*event)) { new_pos = parent_pos + Geom::unit_vector(new_pos - parent_pos) * _saved_length; @@ -366,14 +363,13 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - + if(_pm().isBSpline){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); } - } std::vector unselected; @@ -627,22 +623,22 @@ 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(); - + double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline){ oldPos = n->bsplineWeight; } - + setPosition(new_pos); _front.setPosition(_front.position() + delta); _back.setPosition(_back.position() + delta); - + // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - + if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -774,6 +770,7 @@ void Node::setType(NodeType type, bool update_handles) updateState(); // The size of the control might have changed return; } + // if update_handles is true, adjust handle positions to match the node type // handle degenerate handles appropriately if (update_handles) { @@ -861,7 +858,6 @@ void Node::setType(NodeType type, bool update_handles) _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); } - } _type = type; _setControlType(nodeTypeToCtrlType(_type)); @@ -1124,7 +1120,6 @@ void Node::_setState(State state) this->back()->setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); } } - break; } SelectableControlPoint::_setState(state); diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index d257db86a..01159e6a0 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -97,6 +97,7 @@ public: virtual void setVisible(bool); virtual void move(Geom::Point const &p); + virtual void setPosition(Geom::Point const &p); inline void setRelativePos(Geom::Point const &p); void setLength(double len); @@ -112,28 +113,25 @@ public: protected: Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); - //Bspline virtual void handle_2button_press(); - //BSpline End - virtual bool _eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEvent *event); - virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event); virtual bool grabbed(GdkEventMotion *event); virtual void ungrabbed(GdkEventButton *event); virtual bool clicked(GdkEventButton *event); - virtual Glib::ustring _getTip(unsigned state) const; virtual Glib::ustring _getDragTip(GdkEventMotion *event) const; virtual bool _hasDragTips() const { return true; } private: + inline PathManipulator &_pm(); Node *_parent; // the handle's lifetime does not extend beyond that of the parent node, // so a naked pointer is OK and allows setting it during Node's construction SPCtrlLine *_handle_line; bool _degenerate; // True if the handle is retracted, i.e. has zero length. This is used often internally so it makes sense to cache this + /** * Control point of a cubic Bezier curve in a path. * @@ -190,6 +188,7 @@ public: Handle *front() { return &_front; } Handle *back() { return &_back; } double bsplineWeight; + /** * Gets the handle that faces the given adjacent node. * Will abort with error if the given node is not adjacent. diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 4aec42100..4cb6ce296 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -43,10 +43,8 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" - #include "live_effects/lpe-bspline.h" - namespace Inkscape { namespace UI { @@ -668,7 +666,6 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - if(isBSpline){ double pos = 0.0000; if(start.prev()){ @@ -680,7 +677,6 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); } } - return del_len; } @@ -856,9 +852,9 @@ void PathManipulator::rotateHandle(Node *n, int which, int dir, bool pixel) int snaps = prefs->getIntLimited("/options/rotationsnapsperpi/value", 12, 1, 1000); angle = M_PI * dir / snaps; } + h->setRelativePos(h->relativePos() * Geom::Rotate(angle)); update(); - gchar const *key = which < 0 ? "handle:rotate:left" : "handle:rotate:right"; _commit(_("Rotate handle"), key); } @@ -915,9 +911,7 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - if(isBSpline) show = true; - if (show == _show_outline) return; _show_outline = show; _updateOutline(); @@ -1307,7 +1301,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) 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. @@ -1319,7 +1312,6 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) } ++spi; } - builder.finish(); Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse(); _spcurve->set_pathvector(pathv); @@ -1380,6 +1372,7 @@ void PathManipulator::_updateOutline() sp_canvas_item_hide(_outline); return; } + Geom::PathVector pv = _spcurve->get_pathvector(); pv *= (_edit_transform * _i2d_transform); // This SPCurve thing has to be killed with extreme prejudice diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 547e687a7..31cc0d1fd 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -19,10 +19,8 @@ #include #include "ui/tool/node.h" #include "ui/tool/manipulator.h" - #include "live_effects/lpe-bspline.h" - struct SPCanvasItem; class SPCurve; class SPPath; @@ -97,10 +95,9 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - + bool isBSpline; int BSplineGetSteps(); - // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -110,13 +107,11 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - void BSpline(); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); void BSplineNodeHandlesReposition(Node *n); - void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 14a5b5b35..b6efaebd9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -247,12 +247,10 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //BSpline //Añadimos el modo BSpline a los efectos en espera if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } - //BSPline End int shape = prefs->getInt(tool_name(dc) + "/shape", 0); bool shape_applied = false; @@ -489,7 +487,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); - if (c->is_empty()) { c->unref(); return; @@ -520,7 +517,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - //BSpline //Si la curva tiene un LPE del tipo BSpline ejecutamos spdc_flush_white //pasándole la curva de inicio necesaria Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -529,7 +525,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); spdc_flush_white(dc, dc->sa->curve); }else - //BSpline End spdc_flush_white(dc, NULL); return; } @@ -657,7 +652,6 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //BSpline //Modificamos la curva del "anchor" final para que sea igual que la curva de inicio. //Esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en //la que cerramos el trazado. @@ -670,7 +664,6 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) active->curve->ref(); } } - //BSpline End return active; } @@ -815,4 +808,3 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 7d60e217f..7e53684e3 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -57,7 +57,6 @@ public: SPCanvasItem *blue_bpath; SPCurve *blue_curve; - // Green GSList *green_bpaths; SPCurve *green_curve; @@ -143,4 +142,3 @@ void spdc_create_single_dot(ToolBase *ec, Geom::Point const &pt, char const *too End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index b3acb79ad..4d15ab70e 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,7 +14,6 @@ #include #include #include "ui/tools/tool-base.h" -#include "selection.h" namespace Inkscape { namespace Display { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 178a940a2..f8d8d4c90 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1,4 +1,4 @@ - /** \file +/** \file * Pen event context implementation. */ @@ -20,7 +20,6 @@ #include #include - #include "ui/tools/pen-tool.h" #include "sp-namedview.h" #include "desktop.h" @@ -43,7 +42,6 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//BSpline //Incluimos los archivos necesarios para las BSpline y Spiro #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" @@ -64,11 +62,9 @@ #include "live_effects/spiro.h" - #define INKSCAPE_LPE_BSPLINE_C #include "live_effects/lpe-bspline.h" #include <2geom/nearest-point.h> -//BSpline End #include "tool-factory.h" @@ -80,10 +76,6 @@ namespace UI { namespace Tools { static void spdc_pen_set_initial_point(PenTool *pc, Geom::Point const p); -/* - *BSpline - *Added functions -*/ //Añade los modos spiro y bspline static void sp_pen_context_set_mode(PenTool *const pc, guint mode); //Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro @@ -112,7 +104,7 @@ static void bspline_spiro_build(PenTool *const pc); static void bspline_doEffect(SPCurve * curve); //function spiro cloned from lpe-spiro.cpp static void spiro_doEffect(SPCurve * curve); -//BSpline end + static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status = 0); static void spdc_pen_set_ctrl(PenTool *pc, Geom::Point const p, guint state); static void spdc_pen_finish_segment(PenTool *pc, Geom::Point p, guint state); @@ -205,14 +197,11 @@ void sp_pen_context_set_polyline_mode(PenTool *const pc) { guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); pc->polylines_only = (mode == 3 || mode == 4); pc->polylines_paraxial = (mode == 4); - //BSpline //we call the function which defines the Spiro modes and the BSpline //todo: merge to one function only sp_pen_context_set_mode(pc, mode); - //BSpline End } -//BSpline /* *.Set the mode of draw spiro, and bsplines */ @@ -220,7 +209,6 @@ void sp_pen_context_set_mode(PenTool *const pc, guint mode) { pc->spiro = (mode == 1); pc->bspline = (mode == 2); } -//BSpline End /** * Callback to initialize PenTool object. @@ -422,12 +410,11 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev if(!bevent.button == 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ return FALSE; } - //BSpline end gint ret = FALSE; if (bevent.button == 1 && !event_context->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) - && (pc->expecting_clicks_for_LPE != 1)) { + && pc->expecting_clicks_for_LPE != 1) { if (Inkscape::have_viable_layer(desktop, dc->message_context) == false) { return TRUE; @@ -487,12 +474,10 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev // Set start anchor pc->sa = anchor; - //BSpline //Continuamos una curva existente if(anchor){ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); } - //BSpline End if (anchor && !sp_pen_context_has_waiting_LPE(pc)) { // Adjust point to anchor if needed; if we have a waiting LPE, we need // a fresh path to be created so don't continue an existing one @@ -544,10 +529,8 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev } } - //BSpline //Evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar pc->state = (pc->spiro || pc->bspline || pc->polylines_only) ? PenTool::POINT : PenTool::CONTROL; - //BSpline End ret = TRUE; break; @@ -585,6 +568,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev if (pc->expecting_clicks_for_LPE > 0) { --pc->expecting_clicks_for_LPE; } + return ret; } @@ -609,8 +593,7 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me } Geom::Point const event_w(mevent.x, - mevent.y); - //BSpline + mevent.y); //we take out the function the const "tolerance" because we need it later Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -620,7 +603,6 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me return FALSE; // Do not drag if we're within tolerance from origin. } } - //BSpline END // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the // motion notify coordinates as given (no snapping back to origin) @@ -736,7 +718,6 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me default: break; } - //BSpline //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(pc->bspline){ bspline_spiro_color(pc); @@ -748,7 +729,7 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me pen_drag_origin_w = event_w; } } - //BSpline End + return ret; } @@ -761,7 +742,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // skip event processing if events are disabled return FALSE; } - + gint ret = FALSE; ToolBase *event_context = SP_EVENT_CONTEXT(pc); @@ -776,7 +757,6 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); - //BSpline //with this we avoid creating a new point over the existing one if(pc->spiro || pc->bspline){ //Si intentamos crear un nodo en el mismo sitio que el origen, paramos. @@ -784,7 +764,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r return FALSE; } } - //BSpline End + switch (pc->mode) { case PenTool::MODE_CLICK: switch (pc->state) { @@ -795,14 +775,12 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r p = anchor->dp; } pc->sa = anchor; - //BSpline //continuamos una curva existente if (anchor) { if(pc->bspline || pc->spiro){ bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK)); } } - //BSpline End spdc_pen_set_initial_point(pc, p); } else { // Set end anchor here @@ -827,12 +805,10 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r spdc_endpoint_snap(pc, p, revent.state); } spdc_pen_finish_segment(pc, p, revent.state); - //BSpline //Ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } - //BSpline End spdc_pen_finish(pc, TRUE); pc->state = PenTool::POINT; ret = TRUE; @@ -856,12 +832,10 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r case PenTool::CLOSE: spdc_endpoint_snap(pc, p, revent.state); spdc_pen_finish_segment(pc, p, revent.state); - //BSpline //Ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } - //BSpline End if (pc->green_closed) { // finishing at the start anchor, close curve spdc_pen_finish(pc, TRUE); @@ -873,7 +847,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r case PenTool::STOP: // This is allowed, if we just cancelled curve break; - default: + default: break; } pc->state = PenTool::POINT; @@ -911,6 +885,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // handled in spdc_check_for_and_apply_waiting_LPE() in draw-context.cpp } } + return ret; } @@ -938,20 +913,20 @@ static void pen_redraw_all (PenTool *const pc) SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), pc->green_curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); } if (pc->green_anchor) SP_CTRL(pc->green_anchor->ctrl)->moveto(pc->green_anchor->dp); + pc->red_curve->reset(); pc->red_curve->moveto(pc->p[0]); pc->red_curve->curveto(pc->p[1], pc->p[2], pc->p[3]); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); // handles - //BSpline //Ocultamos los tiradores en modo BSpline y spiro if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { - //BSpline End SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); sp_canvas_item_show(pc->c1); @@ -964,12 +939,10 @@ static void pen_redraw_all (PenTool *const pc) Geom::Curve const * last_seg = pc->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //BSpline //Ocultamos los tiradores en modo BSpline y spiro if ( cubic && (*cubic)[2] != pc->p[0] && !pc->spiro && !pc->bspline ) { - //BSpline End Geom::Point p2 = (*cubic)[2]; SP_CTRL(pc->c0)->moveto(p2); pc->cl0->setCoords(p2, pc->p[0]); @@ -980,15 +953,12 @@ static void pen_redraw_all (PenTool *const pc) sp_canvas_item_hide(pc->cl0); } } - //BSpline + //Simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. //como es un redibujo simplemente no llamamos a la función global //sino al final de esta - - //BSpline //Lanzamos solamente el redibujado bspline_spiro_build(pc); - //BSpline End } static void pen_lastpoint_move (PenTool *const pc, gdouble x, gdouble y) @@ -1019,11 +989,9 @@ static void pen_lastpoint_move_screen (PenTool *const pc, gdouble x, gdouble y) static void pen_lastpoint_tocurve (PenTool *const pc) { - //BSpline //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->spiro && !pc->bspline) return; - //BSpline Geom::CubicBezier const * cubic; pc->p[1] = pc->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(pc->red_curve->last_segment()->finalPoint() - pc->red_curve->last_segment()->initialPoint()); //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos @@ -1070,13 +1038,11 @@ static void pen_lastpoint_tocurve (PenTool *const pc) } } - //Spiro Live pen_redraw_all(pc); } static void pen_lastpoint_toline (PenTool *const pc) { - //BSpline //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->bspline) return; @@ -1312,7 +1278,6 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) : pc->p[3])); pc->npoints = 2; - //BSpline //Eliminamos el último segmento de la curva verde if( pc->green_curve->get_segment_count() == 1){ pc->npoints = 5; @@ -1335,16 +1300,13 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) pc->p[1] = pc->p[0]; } } - //BSpline End sp_canvas_item_hide(pc->cl0); sp_canvas_item_hide(pc->cl1); pc->state = PenTool::POINT; spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //BSpline //Redibujamos bspline_spiro_build(pc); - //BSpline End ret = TRUE; } break; @@ -1358,12 +1320,10 @@ static void spdc_reset_colors(PenTool *pc) { // Red pc->red_curve->reset(); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); // Blue pc->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), NULL); - // Green while (pc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(pc->green_bpaths->data)); @@ -2111,8 +2071,6 @@ static void spiro_doEffect(SPCurve * curve) g_free (path); } -//BSpline end - static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status) { g_assert( pc->npoints != 0 ); @@ -2139,9 +2097,7 @@ static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p is_curve = false; } else { // one of the 'regular' modes - //SpiroLive if (pc->p[1] != pc->p[0] || pc->spiro) { - //SpiroLive End pc->red_curve->curveto(pc->p[1], p, p); is_curve = true; } else { @@ -2156,13 +2112,11 @@ static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p gchar *message = is_curve ? _("Curve segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path" ): _("Line segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"); - //BSpline if(pc->spiro || pc->bspline){ message = is_curve ? _("Curve segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path" ): _("Line segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path"); } - //BSpline End spdc_pen_set_angle_distance_status_message(pc, p, 0, message); } } @@ -2369,5 +2323,3 @@ void pen_set_to_nearest_horiz_vert(const PenTool *const pc, Geom::Point &pt, gui End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - - diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 553e4c557..b0b56feb4 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -48,11 +48,9 @@ public: bool polylines_only; bool polylines_paraxial; - //SpiroLive //Propiedad que guarda si el modo Spiro está activo o no bool spiro; bool bspline; - //SpiroLIve End int num_clicks; unsigned int expecting_clicks_for_LPE; // if positive, finish the path after this many clicks diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index c10bd15a3..2027f0981 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -692,10 +692,8 @@ interpolate(PencilTool *pc) return; } - //BSpline using Geom::X; using Geom::Y; - //BSpline end Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4; @@ -727,12 +725,9 @@ interpolate(PencilTool *pc) { /* Fit and draw and reset state */ pc->green_curve->moveto(b[0]); - //BSpline Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); - //BSpline End for (int c = 0; c < n_segs; c++) { - //BSpline //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); @@ -743,7 +738,6 @@ interpolate(PencilTool *pc) }else{ pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]); } - //BSpline } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve); @@ -884,7 +878,6 @@ fit_and_split(PencilTool *pc) /* Fit and draw and reset state */ pc->red_curve->reset(); pc->red_curve->moveto(b[0]); - //BSpline using Geom::X; using Geom::Y; //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc @@ -899,7 +892,6 @@ fit_and_split(PencilTool *pc) }else{ pc->red_curve->curveto(b[1], b[2], b[3]); } - //BSpline End sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); pc->red_curve_is_valid = true; } else { diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index d9d53117c..3289ed181 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -133,14 +133,12 @@ static void sp_add_freehand_mode_toggle(GtkActionGroup* mainActions, GObject* ho 1, _("Create Spiro path"), 2, INKSCAPE_ICON("path-mode-spiro"), -1 ); - //BSpline gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, 0, _("BSpline"), 1, _("Create BSpline path"), 2, INKSCAPE_ICON("path-mode-bspline"), -1 ); - //BSpline if (!tool_is_pencil) { gtk_list_store_append( model, &iter ); gtk_list_store_set( model, &iter, diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 9f64f6336..901276620 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -115,7 +115,6 @@ enum BarId { BAR_COMMANDS, BAR_SNAP, }; -//#define WITH_MESH #define BAR_ID_KEY "BarIdValue" #define HANDLE_POS_MARK "x-inkscape-pos" -- cgit v1.2.3 From f2063b21523998891d43de384ef4ec4ec93c5516 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 20:42:06 +0100 Subject: Refactorizing (bzr r11950.1.213) --- src/libavoid/makefile | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 src/libavoid/makefile (limited to 'src') diff --git a/src/libavoid/makefile b/src/libavoid/makefile deleted file mode 100644 index e4f83a52d..000000000 --- a/src/libavoid/makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Convenience stub makefile to call the real Makefile. - - - -OBJEXT = o - -# Explicit so that it's the default rule. -all: - cd .. && $(MAKE) libavoid/all - -clean %.a %.$(OBJEXT): - cd .. && $(MAKE) libavoid/$@ - -.PHONY: all clean - -.SUFFIXES: -.SUFFIXES: .a .$(OBJEXT) -- cgit v1.2.3 From 8c6ae51081f4d1d63ba84f9dd339b9f530f06c87 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 21:30:44 +0100 Subject: Start refactor, simplify node.cpp operations,general cleanup, changed brehabiour to need 'Shift' Key to move handles because it handle better operations with small zoom (bzr r11950.1.214) --- src/ui/tools/node-tool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 4d15ab70e..b3acb79ad 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "ui/tools/tool-base.h" +#include "selection.h" namespace Inkscape { namespace Display { -- cgit v1.2.3 From 8d781fb629a07fdbd828b2eeb18694bb32e88768 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 21:45:48 +0100 Subject: Updated tip strings (bzr r11950.1.215) --- src/ui/tool/node.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 7266c85bb..305dd6798 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -492,7 +492,7 @@ Glib::ustring Handle::_getTip(unsigned state) const if (can_shift_rotate && !isBSpline) { more = C_("Path handle tip", "more: Shift, Ctrl, Alt"); } else if(isBSpline){ - more = C_("Path handle tip", "move:Shift, reset:double click, more: Ctrl"); + more = C_("Path handle tip", "more: Ctrl"); }else { more = C_("Path handle tip", "more: Ctrl, Alt"); } @@ -545,9 +545,13 @@ Glib::ustring Handle::_getTip(unsigned state) const return format_tip(C_("Path handle tip", "Auto node handle: drag to convert to smooth node (%s)"), more); default: - return format_tip(C_("Path handle tip", - "%s: drag to shape the segment (%s)"), - handle_type_to_localized_string(_parent->type()), more); + if(!isBSpline){ + return format_tip(C_("Path handle tip", + "Auto node handle: drag to convert to smooth node (%s)"), more); + }else{ + return format_tip(C_("Path handle tip", + "BSpline node handle: Shift to drag, double click to reset (%s)"), more); + } } } -- cgit v1.2.3 From 140267c64cd9d19e372328d6f30c072102c2dd33 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 22:04:13 +0100 Subject: Refact (bzr r11950.1.216) --- src/ui/tool/node.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 305dd6798..85a407384 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -974,6 +974,7 @@ bool Node::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEvent _selection.spatialGrow(this, dir); } return true; + default: break; } -- cgit v1.2.3 From 1abfd51451a3df8a46ec9e23332aff72208ac942 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:19:31 +0100 Subject: Spanish comment of node.cpp (bzr r11950.1.217) --- src/ui/tool/node.cpp | 53 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 85a407384..9eab1d7dc 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //If is bspline move other handle + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); _parent->bsplineWeight = _pm().BSplineHandlePosition(this); @@ -185,7 +185,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //If is bspline move both handles + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); _parent->bsplineWeight = _pm().BSplineHandlePosition(this); @@ -212,7 +212,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //If is bspline move other handle + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); _parent->bsplineWeight = _pm().BSplineHandlePosition(this); @@ -295,7 +295,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - + //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -306,6 +306,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } +//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -363,7 +364,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - + //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el + //parametro "steps whith control" del efecto en vivo BSpline if(_pm().isBSpline){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -373,9 +375,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - - //IF Snap and Not CTRL && BSpline or BSPLINE is false - if (snap && (((!held_control(*event) && _pm().isBSpline) && (!held_shift(*event) && _pm().isBSpline)) || !_pm().isBSpline)) { + //spanish: si está activado el ajuste (snap) y no es bspline + if (snap && !_pm().isBSpline) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -401,11 +402,6 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } sm.unSetup(); - if(_pm().isBSpline){ - setPosition(new_pos); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); - new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); - } } @@ -420,7 +416,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - + //spanish: si es bspline pero no está presionado SHIFT o CONTROL + //lo fija en la posición original if(_pm().isBSpline && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -440,6 +437,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); + //spanish: marca la fuerza del bspline como 0.0000 if(_pm().isBSpline){ _parent->bsplineWeight = 0.0000; } @@ -485,6 +483,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; + //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -587,7 +588,6 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : _type(NODE_CUSP), _handles_shown(false) { - this->bsplineWeight = 0.3334; // NOTE we do not set type here, because the handles are still degenerate } @@ -627,7 +627,8 @@ 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(); - + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline){ @@ -642,7 +643,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -652,6 +654,8 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; if(_pm().isBSpline){ oldPos = this->bsplineWeight; @@ -664,6 +668,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -754,8 +760,12 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - if(!_pm().isBSpline) - this->bsplineWeight = 0.0000; + //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. + //Cada vez que actuemos sobre dichos tiradores en un trazado + //bspline esta fuerza se tiene que actualizar + this->bsplineWeight = 0.0000; + if(_pm().isBSpline) + this->bsplineWeight = 0.3334; } void Node::updateHandles() @@ -857,6 +867,9 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } + //spanish: en los cambios de tipo de nodo, sobre trazados bspline, + //o bien los mantenemos con potencia 0.0000 en modo esquina + //o les damos la potencia por defecto en modo de curva if(_pm().isBSpline){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1109,7 +1122,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - _pm().BSpline(); + //spanish: esto muestra los tiradores al seleccionar los nodos if(_pm().isBSpline){ if(!this->back()->isDegenerate()){ this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); -- cgit v1.2.3 From 1866742fce895e2306c4e0bc032f9b73bfce2925 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:23:56 +0100 Subject: Spanish comment of node.h (bzr r11950.1.218) --- src/ui/tool/node.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 01159e6a0..b7d6951d0 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,6 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } + //spanish: creamos valor de potencia bspline asociado a cada nodo double bsplineWeight; /** -- cgit v1.2.3 From df2cf6584407ae3744aac917039681fb3a04a678 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:32:51 +0100 Subject: refactor, fixing some diff diferences (bzr r11950.1.219) --- src/live_effects/lpe-bendpath.h | 2 ++ src/seltrans.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 554f20413..16b8c6137 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -38,6 +38,8 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); virtual void resetDefaults(SPItem const* item); + + private: PathParam bend_path; ScalarParam prop_scale; diff --git a/src/seltrans.cpp b/src/seltrans.cpp index d1d39532c..4d0a09c6d 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1461,7 +1461,7 @@ Geom::Point Inkscape::SelTrans::_getGeomHandlePos(Geom::Point const &visual_hand Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool transform_stroke = prefs->getBool("/options/transform/stroke", true); bool preserve = prefs->getBool("/options/preservetransform/value", false); - Geom::Affine abs_affine = get_scale_transform_for_uniform_stroke (*_bbox, _strokewidth, transform_stroke, preserve, + Geom::Affine abs_affine = get_scale_transform_for_uniform_stroke (*_bbox, _strokewidth, _strokewidth, transform_stroke, preserve, new_bbox.min()[Geom::X], new_bbox.min()[Geom::Y], new_bbox.max()[Geom::X], new_bbox.max()[Geom::Y]); // Calculate the scaled geometrical bbox -- cgit v1.2.3 From 58638901bd9d7408c4bd053673e3f7934adcb668 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:41:04 +0100 Subject: Spanish comment of curve-drag-point-cpp (bzr r11950.1.221) --- src/ui/tool/curve-drag-point.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index 5387e597d..0ee848f15 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,6 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; + //spanish: solo actualizamos los nodos si no es bspline if(!_pm.isBSpline){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -88,6 +89,7 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; + //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT if(!_pm.isBSpline){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); -- cgit v1.2.3 From 118a1dbf3b1b7145928aeb106d94b77f7f1cdfda Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 30 Dec 2013 23:50:51 +0100 Subject: Spanish comment of multi-path-manipulator-cpp (bzr r11950.1.222) --- src/ui/tool/multi-path-manipulator.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 3612f9c56..c77d2d795 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -682,7 +682,9 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); + //spanish: si es trazado bspline (mode 2) if(mode==2){ + //spanish: ¿correcto? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else -- cgit v1.2.3 From bfc330ddc8564d132f885378f428fab10692edbb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 00:21:57 +0100 Subject: Spanish comment of path-manipulator-cpp (bzr r11950.1.223) --- src/ui/tool/path-manipulator.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 4cb6ce296..47f736fcb 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -33,7 +33,6 @@ #include "live_effects/lpeobject-reference.h" #include "live_effects/parameter/path.h" #include "sp-path.h" -#include "sp-lpe-item.h" #include "helper/geom.h" #include "preferences.h" #include "style.h" @@ -43,6 +42,7 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" +#include "sp-lpe-item.h" #include "live_effects/lpe-bspline.h" namespace Inkscape { @@ -104,7 +104,7 @@ private: }; void build_segment(Geom::PathBuilder &, Node *, Node *); - +//spanish: una propiedad isBSpline, por defecto falsa y una función al final de la función (BSpline()) que la define realmente PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) @@ -666,6 +666,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } + //spanish: si se borra, reajustamos los tiradores if(isBSpline){ double pos = 0.0000; if(start.prev()){ @@ -1185,7 +1186,9 @@ void PathManipulator::_createControlPointsFromGeometry() } } +//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza int PathManipulator::BSplineGetSteps(){ + LivePathEffect::LPEBSpline *lpe_bsp = NULL; if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ @@ -1194,24 +1197,22 @@ int PathManipulator::BSplineGetSteps(){ lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } - return lpe_bsp->steps+1; + int steps = 0; + if(lpe_bsp){ + steps = lpe_bsp->steps+1; + } + return steps; } +//spanish: determina si el trazado tiene efecto bspline void PathManipulator::BSpline(){ - LivePathEffect::LPEBSpline *lpe_bsp = NULL; - - if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); - if(thisEffect){ - lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); - } - } isBSpline = false; - if(lpe_bsp){ + if(this->BSplineGetSteps()>0){ isBSpline = true; } } +//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1230,11 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } +//spanish: mueve el tirador a la posición que le corresponda Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } +//spanish: mueve el tirador a una posición específica Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1260,11 +1263,12 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } +//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); if(prevNode){ - n->back()->setPosition(BSplineHandleReposition(n->back())); + n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); if(prevNode->front()->position() == prevNode->position()) prevNode->bsplineWeight = 0.000; if(!prevNode->isEndNode()) @@ -1272,7 +1276,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); } if(nextNode){ - n->front()->setPosition(BSplineHandleReposition(n->front())); + n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); if(nextNode->front()->position() == nextNode->position()) nextNode->bsplineWeight = 0.000; if(!nextNode->isEndNode()) -- cgit v1.2.3 From c288aa062e611031f54f6ad8e5e3ee2f581cc783 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 00:29:07 +0100 Subject: Spanish comment of freehand-base.cpp (bzr r11950.1.224) --- src/ui/tool/path-manipulator.cpp | 1 - src/ui/tool/path-manipulator.h | 2 +- src/ui/tools/freehand-base.cpp | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 47f736fcb..e70717728 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -42,7 +42,6 @@ #include "ui/tool/multi-path-manipulator.h" #include "xml/node.h" #include "xml/node-observer.h" -#include "sp-lpe-item.h" #include "live_effects/lpe-bspline.h" namespace Inkscape { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 31cc0d1fd..5f075834e 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -94,7 +94,7 @@ public: NodeList::iterator subdivideSegment(NodeList::iterator after, double t); NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, - bool search_unselected, bool closest); + bool search_unselected, bool closest); bool isBSpline; int BSplineGetSteps(); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index b6efaebd9..5825a149c 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -247,7 +247,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //Añadimos el modo BSpline a los efectos en espera + //spanish: añadimos el modo bspline a los efectos en espera if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -517,7 +517,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - //Si la curva tiene un LPE del tipo BSpline ejecutamos spdc_flush_white + //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white //pasándole la curva de inicio necesaria Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || @@ -652,8 +652,8 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //Modificamos la curva del "anchor" final para que sea igual que la curva de inicio. - //Esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en + //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. + //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en //la que cerramos el trazado. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || -- cgit v1.2.3 From cb0d2fad1fa3b8055b86f8d7e911b295e09cf27a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 00:31:15 +0100 Subject: Spanish comment of node-tool.cpp (bzr r11950.1.225) --- src/ui/tools/node-tool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index b3acb79ad..168ec995a 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,6 +14,7 @@ #include #include #include "ui/tools/tool-base.h" +//spanish: lo necesitamos para llamarlo desde el Live Effect #include "selection.h" namespace Inkscape { -- cgit v1.2.3 From 14a50ad8c16b1d840e7a68ba8a75e2cec174a0a5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 01:02:40 +0100 Subject: Spanish comment of pencil-tool.cpp/.h (bzr r11950.1.226) --- src/ui/tools/pen-tool.cpp | 150 ++++++++++++++++------------------------------ src/ui/tools/pen-tool.h | 2 +- 2 files changed, 54 insertions(+), 98 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index f8d8d4c90..9b5acb6cc 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//Incluimos los archivos necesarios para las BSpline y Spiro +//spanish: incluimos los archivos necesarios para las BSpline y Spiro #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" @@ -76,29 +76,29 @@ namespace UI { namespace Tools { static void spdc_pen_set_initial_point(PenTool *pc, Geom::Point const p); -//Añade los modos spiro y bspline +//spanish: añade los modos spiro y bspline static void sp_pen_context_set_mode(PenTool *const pc, guint mode); -//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void bspline_spiro_color(PenTool *const pc); -//Crea un nodo en modo bspline o spiro +//spanish: crea un nodo en modo bspline o spiro static void bspline_spiro(PenTool *const pc,bool shift); -//Crea un nodo de modo spiro o bspline +//spanish: crea un nodo de modo spiro o bspline static void bspline_spiro_on(PenTool *const pc); -//Crea un nodo de tipo CUSP +//spanish: crea un nodo de tipo CUSP static void bspline_spiro_off(PenTool *const pc); -//Continua una curva existente en modo bspline o spiro +//spanish: continua una curva existente en modo bspline o spiro static void bspline_spiro_start_anchor(PenTool *const pc,bool shift); -//Continua una curva exsitente con el nodo de union en modo bspline o spiro +//spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro static void bspline_spiro_start_anchor_on(PenTool *const pc); -//Continua una curva existente con el nodo de union en modo CUSP +//spanish: continua una curva existente con el nodo de union en modo CUSP static void bspline_spiro_start_anchor_off(PenTool *const pc); -//Modifica la "red_curve" cuando se detecta movimiento +//spanish: modifica la "red_curve" cuando se detecta movimiento static void bspline_spiro_motion(PenTool *const pc,bool shift); -//Cierra la curva con el último nodo en modo bspline o spiro +//spanish: cierra la curva con el último nodo en modo bspline o spiro static void bspline_spiro_end_anchor_on(PenTool *const pc); -//Cierra la curva con el último nodo en modo CUSP +//spanish: cierra la curva con el último nodo en modo CUSP static void bspline_spiro_end_anchor_off(PenTool *const pc); -//Unimos todas las curvas en juego y llamamos a la función doEffect. +//spanish: unimos todas las curvas en juego y llamamos a la función doEffect. static void bspline_spiro_build(PenTool *const pc); //function bspline cloned from lpe-bspline.cpp static void bspline_doEffect(SPCurve * curve); @@ -195,6 +195,7 @@ PenTool::~PenTool() { void sp_pen_context_set_polyline_mode(PenTool *const pc) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); + //spanish: cambiamos los modos para dar cabida al modo bspline pc->polylines_only = (mode == 3 || mode == 4); pc->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -206,6 +207,7 @@ void sp_pen_context_set_polyline_mode(PenTool *const pc) { *.Set the mode of draw spiro, and bsplines */ void sp_pen_context_set_mode(PenTool *const pc, guint mode) { + //spanish: definimos los modos pc->spiro = (mode == 1); pc->bspline = (mode == 2); } @@ -474,7 +476,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev // Set start anchor pc->sa = anchor; - //Continuamos una curva existente + //spanish: continuamos una curva existente if(anchor){ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); } @@ -529,7 +531,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev } } - //Evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar + //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar pc->state = (pc->spiro || pc->bspline || pc->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -597,9 +599,8 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me //we take out the function the const "tolerance" because we need it later Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gint const tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); - //"spiro_color" lo ejecutamos siempre sea o no spiro if (pen_within_tolerance) { - if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance) { + if ( Geom::LInfty( event_w - pen_drag_origin_w ) < tolerance ) { return FALSE; // Do not drag if we're within tolerance from origin. } } @@ -610,8 +611,10 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me // Find desktop coordinates Geom::Point p = dt->w2d(event_w); + // Test, whether we hit any anchor SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); + switch (pc->mode) { case PenTool::MODE_CLICK: switch (pc->state) { @@ -691,7 +694,9 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me case PenTool::CONTROL: case PenTool::CLOSE: // Placing controls is last operation in CLOSE state + // snap the handle + spdc_endpoint_snap_handle(pc, p, mevent.state); if (!pc->polylines_only) { spdc_pen_set_ctrl(pc, p, mevent.state); @@ -718,7 +723,7 @@ static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &me default: break; } - //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. + //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(pc->bspline){ bspline_spiro_color(pc); bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); @@ -759,7 +764,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); //with this we avoid creating a new point over the existing one if(pc->spiro || pc->bspline){ - //Si intentamos crear un nodo en el mismo sitio que el origen, paramos. + //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. if(pc->npoints > 0 && pc->p[0] == pc->p[3]){ return FALSE; } @@ -775,7 +780,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r p = anchor->dp; } pc->sa = anchor; - //continuamos una curva existente + //spanish: continuamos una curva existente if (anchor) { if(pc->bspline || pc->spiro){ bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK)); @@ -805,7 +810,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r spdc_endpoint_snap(pc, p, revent.state); } spdc_pen_finish_segment(pc, p, revent.state); - //Ocultamos la guia del penultimo nodo al cerrar la curva + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } @@ -832,7 +837,7 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r case PenTool::CLOSE: spdc_endpoint_snap(pc, p, revent.state); spdc_pen_finish_segment(pc, p, revent.state); - //Ocultamos la guia del penultimo nodo al cerrar la curva + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(pc->spiro){ sp_canvas_item_hide(pc->c1); } @@ -925,7 +930,7 @@ static void pen_redraw_all (PenTool *const pc) sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); // handles - //Ocultamos los tiradores en modo BSpline y spiro + //spanish: ocultamos los tiradores en modo bspline y spiro if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) { SP_CTRL(pc->c1)->moveto(pc->p[1]); pc->cl1->setCoords(pc->p[0], pc->p[1]); @@ -939,7 +944,7 @@ static void pen_redraw_all (PenTool *const pc) Geom::Curve const * last_seg = pc->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //Ocultamos los tiradores en modo BSpline y spiro + //spanish: ocultamos los tiradores en modo bspline y spiro if ( cubic && (*cubic)[2] != pc->p[0] && !pc->spiro && !pc->bspline ) { @@ -954,9 +959,8 @@ static void pen_redraw_all (PenTool *const pc) } } - //Simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. - //como es un redibujo simplemente no llamamos a la función global - //sino al final de esta + //spanish: simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. + //como es un redibujo simplemente no llamamos a la función global sino al final de esta //Lanzamos solamente el redibujado bspline_spiro_build(pc); } @@ -989,12 +993,12 @@ static void pen_lastpoint_move_screen (PenTool *const pc, gdouble x, gdouble y) static void pen_lastpoint_tocurve (PenTool *const pc) { - //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->spiro && !pc->bspline) return; Geom::CubicBezier const * cubic; pc->p[1] = pc->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(pc->red_curve->last_segment()->finalPoint() - pc->red_curve->last_segment()->initialPoint()); - //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(pc->spiro||pc->bspline){ if(!pc->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1032,7 +1036,7 @@ static void pen_lastpoint_tocurve (PenTool *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } - //Si el último nodo es una union con otra curva + //spanish: si el último nodo es una union con otra curva if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ bspline_spiro_start_anchor(pc, false); } @@ -1043,11 +1047,11 @@ static void pen_lastpoint_tocurve (PenTool *const pc) static void pen_lastpoint_toline (PenTool *const pc) { - //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (pc->npoints != 5 && !pc->bspline) return; - //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(pc->spiro || pc->bspline){ if(!pc->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1079,7 +1083,7 @@ static void pen_lastpoint_toline (PenTool *const pc) pc->green_curve->append_continuous(previous, 0.0625); } } - //Si el último nodo es una union con otra curva + //spanish: si el último nodo es una union con otra curva if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){ bspline_spiro_start_anchor(pc, true); } @@ -1268,7 +1272,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) } else { pc->p[1] = pc->p[0]; } - //Asignamos el valor a un tercio de distancia del último segmento. + //spanish: asignamos el valor a un tercio de distancia del último segmento. if(pc->bspline){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); } @@ -1278,7 +1282,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) : pc->p[3])); pc->npoints = 2; - //Eliminamos el último segmento de la curva verde + //spanish: eliminamos el último segmento de la curva verde if( pc->green_curve->get_segment_count() == 1){ pc->npoints = 5; if (pc->green_bpaths) { @@ -1290,7 +1294,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) }else{ pc->green_curve->backspace(); } - //Asignamos el valor de pc->p[1] a el opuesto de el ultimo segmento de la línea verde + //spanish: asignamos el valor de pc->p[1] a el opuesto de el ultimo segmento de la línea verde if(pc->spiro){ cubic = dynamic_cast(pc->green_curve->last_segment()); if ( cubic ) { @@ -1305,7 +1309,7 @@ static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event) pc->state = PenTool::POINT; spdc_pen_set_subsequent_point(pc, pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //Redibujamos + //spanish: redibujamos bspline_spiro_build(pc); ret = TRUE; } @@ -1381,7 +1385,7 @@ static void spdc_pen_set_angle_distance_status_message(PenTool *const pc, Geom:: } -//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro static void bspline_spiro_color(PenTool *const pc) { bool remake_green_bpaths = false; @@ -1719,7 +1723,7 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) } -//preparates the curves for its trasformation into BSline curves. +//spanish: preparates the curves for its trasformation into BSline curves. static void bspline_spiro_build(PenTool *const pc) { if(!pc->spiro && !pc->bspline) @@ -1748,7 +1752,7 @@ static void bspline_spiro_build(PenTool *const pc) } if(!curve->is_empty()){ - //cerramos la curva si estan cerca los puntos finales de la curva spiro + //spanish: cerramos la curva si estan cerca los puntos finales de la curva spiro if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1787,26 +1791,19 @@ static void bspline_spiro_build(PenTool *const pc) static void bspline_doEffect(SPCurve * curve) { + //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; - // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); curve->reset(); - //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... if (path_it->empty()) continue; - //Itreadores - + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing 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 - //dichos manejadores SPCurve *nCurve = new SPCurve(); Geom::Point previousNode(0,0); Geom::Point node(0,0); @@ -1820,23 +1817,13 @@ static void bspline_doEffect(SPCurve * curve) Geom::D2< Geom::SBasis > SBasisHelper; Geom::CubicBezier const *cubic = NULL; if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! curve_endit = path_it->end_open(); } } - //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 - - //Recorremos todos los segmentos menos el último while ( curve_it2 != curve_endit ) { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida SPCurve * in = new SPCurve(); in->moveto(curve_it1->initialPoint()); in->lineto(curve_it1->finalPoint()); @@ -1851,8 +1838,6 @@ static void bspline_doEffect(SPCurve * curve) } in->reset(); delete in; - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); SPCurve * out = new SPCurve(); out->moveto(curve_it2->initialPoint()); out->lineto(curve_it2->finalPoint()); @@ -1869,37 +1854,25 @@ static void bspline_doEffect(SPCurve * curve) } out->reset(); delete out; - //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 SPCurve *lineHelper = new SPCurve(); lineHelper->moveto(pointAt2); lineHelper->lineto(nextPointAt1); SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); delete lineHelper; - //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); SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(previousNode); curveHelper->curveto(pointAt1, pointAt2, node); - //añadimos la curva generada a la curva pricipal nCurve->append_continuous(curveHelper, 0.0625); curveHelper->reset(); delete curveHelper; - //aumentamos los valores para el siguiente paso en el bucle ++curve_it1; ++curve_it2; } - //Aberiguamos la ultima parte de la curva correspondiente al último segmento SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(node); - //Si está cerrada la curva, la cerramos sobre el valor guardado previamente - //Si no finalizamos en el punto final Geom::Point startNode(0,0); if (path_it->closed()) { SPCurve * start = new SPCurve(); @@ -1920,7 +1893,6 @@ static void bspline_doEffect(SPCurve * curve) end->moveto(curve_it1->initialPoint()); end->lineto(curve_it1->finalPoint()); Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis(); - //Geom::BezierCurve const *bezier = dynamic_cast(&*curve_endit); cubic = dynamic_cast(&*curve_it1); if(cubic){ lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment()))); @@ -1932,7 +1904,6 @@ static void bspline_doEffect(SPCurve * curve) SBasisHelper = lineHelper->first_segment()->toSBasis(); lineHelper->reset(); delete lineHelper; - //Guardamos el principio de la curva startNode = SBasisHelper.valueAt(0.5); curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); nCurve->append_continuous(curveHelper, 0.0625); @@ -1950,7 +1921,6 @@ static void bspline_doEffect(SPCurve * curve) } curveHelper->reset(); delete curveHelper; - //y cerramos la curva if (path_it->closed()) { nCurve->closepath_current(); } @@ -1961,12 +1931,12 @@ static void bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp +//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp static void spiro_doEffect(SPCurve * curve) { using Geom::X; using Geom::Y; - // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); guint len = curve->get_segment_count() + 2; @@ -1978,41 +1948,31 @@ static void spiro_doEffect(SPCurve * curve) if (path_it->empty()) continue; - // start of path { Geom::Point p = path_it->front().pointAt(0); path[ip].x = p[X]; path[ip].y = p[Y]; - path[ip].ty = '{' ; // for closed paths, this is overwritten + path[ip].ty = '{' ; ip++; } - // midpoints - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); - Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + Geom::Path::const_iterator curve_endit = path_it->end_default(); if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. + const Geom::Curve &closingline = path_it->back_closed(); if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! curve_endit = path_it->end_open(); } } while ( curve_it2 != curve_endit ) { - /* This deals with the node between curve_it1 and curve_it2. - * Loop to end_default (so without last segment), loop ends when curve_it2 hits the end - * and then curve_it1 points to end or closing segment */ Geom::Point p = curve_it1->finalPoint(); path[ip].x = p[X]; path[ip].y = p[Y]; - // Determine type of spiro node this is, determined by the tangents (angles) of the curves - // TODO: see if this can be simplified by using /helpers/geom-nodetype.cpp:get_nodetype bool this_is_line = is_straight_curve(*curve_it1); bool next_is_line = is_straight_curve(*curve_it2); @@ -2036,15 +1996,13 @@ static void spiro_doEffect(SPCurve * curve) ip++; } - // add last point to the spiropath Geom::Point p = curve_it1->finalPoint(); path[ip].x = p[X]; path[ip].y = p[Y]; if (path_it->closed()) { - // curve_it1 points to the (visually) closing segment. determine the match between first and this last segment (the closing node) Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front()); switch (nodetype) { - case Geom::NODE_NONE: // can't happen! but if it does, it means the path isn't closed :-) + case Geom::NODE_NONE: path[ip].ty = '}'; ip++; break; @@ -2057,12 +2015,10 @@ static void spiro_doEffect(SPCurve * curve) break; } } else { - // set type to path closer path[ip].ty = '}'; ip++; } - // run subpath through spiro int sp_len = ip; Spiro::spiro_run(path, sp_len, *curve); ip = 0; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index b0b56feb4..4f87429f4 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -48,7 +48,7 @@ public: bool polylines_only; bool polylines_paraxial; - //Propiedad que guarda si el modo Spiro está activo o no + //spanish: propiedad que guarda si el modo Spiro está activo o no bool spiro; bool bspline; int num_clicks; -- cgit v1.2.3 From d8a7188e7a73050e329103b79e769b8fa498ede5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 01:04:31 +0100 Subject: Spanish comment of pencil-tool.cpp (bzr r11950.1.227) --- src/ui/tools/pencil-tool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 2027f0981..883b3fa36 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -728,7 +728,7 @@ interpolate(PencilTool *pc) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -880,7 +880,7 @@ fit_and_split(PencilTool *pc) pc->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From b28d4dbc9e7ad573973f557afcec89dd005c9d96 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 01:06:03 +0100 Subject: refactor, fixing some diff diferences (bzr r11950.1.228) --- src/widgets/toolbox.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 901276620..02da805bf 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -115,6 +115,7 @@ enum BarId { BAR_COMMANDS, BAR_SNAP, }; + #define BAR_ID_KEY "BarIdValue" #define HANDLE_POS_MARK "x-inkscape-pos" -- cgit v1.2.3 From 3e2698fd64dbf8c63b1efc758be5b3a1c30fe1fc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 31 Dec 2013 01:42:32 +0100 Subject: fix a bug whith degenerate handles (bzr r11950.1.229) --- src/ui/tool/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 9eab1d7dc..a932e5b7b 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -764,7 +764,7 @@ void Node::showHandles(bool v) //Cada vez que actuemos sobre dichos tiradores en un trazado //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; - if(_pm().isBSpline) + if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())) this->bsplineWeight = 0.3334; } -- cgit v1.2.3 From c08c28e9a22f0fe5f06e9dc34430c3acb16f3c13 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 2 Jan 2014 16:15:27 +0100 Subject: Fixed a boring bug sometimes curves be converted to lines, increasing a bit the distance from the handle to the line (bzr r11950.1.230) --- src/ui/tool/node.cpp | 21 ++++++++++++++++++--- src/ui/tool/path-manipulator.cpp | 6 ++---- src/ui/tools/pen-tool.cpp | 29 +++++++++++++++++------------ 3 files changed, 37 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index a932e5b7b..39b21ae6d 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1388,6 +1388,12 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { + //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion + bool isBSpline = false; + if( this->bsplineWeight != 0.0000) + isBSpline = true; if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { @@ -1417,15 +1423,24 @@ Glib::ustring Node::_getTip(unsigned state) const // No modifiers: assemble tip from node type char const *nodetype = node_type_to_localized_string(_type); if (_selection.transformHandlesEnabled() && selected()) { - if (_selection.size() == 1) { + if (_selection.size() == 1 && !isBSpline) { return format_tip(C_("Path node tip", "%s: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype); + }else if(_selection.size() == 1){ + return format_tip(C_("Path node tip", + "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),this->bsplineWeight); } return format_tip(C_("Path node tip", "%s: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype); } - return format_tip(C_("Path node tip", - "%s: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"), nodetype); + if (!isBSpline) { + return format_tip(C_("Path node tip", + "%s: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)"), nodetype); + }else{ + return format_tip(C_("Path node tip", + "BSpline node: drag to shape the path, click to select only this node (more: Shift, Ctrl, Alt)")); + + } } Glib::ustring Node::_getDragTip(GdkEventMotion */*event*/) const diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index e70717728..cda8374c5 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1219,13 +1219,11 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ Node *n = h->parent(); Node * nextNode = NULL; nextNode = n->nodeToward(h); - Geom::Point positionH = h->position(); - positionH = Geom::Point(positionH[X] + 0.0001,positionH[Y] + 0.0001); if(nextNode && n->position() != h->position()){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(positionH,*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } return pos; } @@ -1252,7 +1250,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); n->bsplineWeight = pos; ret = SBasisInsideNodes.valueAt(pos); - ret = Geom::Point(ret[X] + 0.0001,ret[Y] + 0.0001); + ret = Geom::Point(ret[X] + 0.005,ret[Y] + 0.005); }else{ if(pos == 0.0000){ n->bsplineWeight = 0.0000; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 9b5acb6cc..a48f8911a 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -959,7 +959,7 @@ static void pen_redraw_all (PenTool *const pc) } } - //spanish: simplemente redibujamos la spiro teniendo en cuenta si el nodo es cusp o symm. + //spanish: simplemente redibujamos la spiro. //como es un redibujo simplemente no llamamos a la función global sino al final de esta //Lanzamos solamente el redibujado bspline_spiro_build(pc); @@ -1451,7 +1451,7 @@ static void bspline_spiro_on(PenTool *const pc) pc->p[0] = pc->red_curve->first_segment()->initialPoint(); pc->p[3] = pc->red_curve->first_segment()->finalPoint(); pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X] + 0.0001,pc->p[2][Y] + 0.0001); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.005,pc->p[2][Y] + 0.005); } } @@ -1492,7 +1492,7 @@ static void bspline_spiro_start_anchor_on(PenTool *const pc) Geom::Point A = tmpCurve->last_segment()->initialPoint(); Geom::Point D = tmpCurve->last_segment()->finalPoint(); Geom::Point C = D + (1./3)*(A - D); - C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); if(cubic){ lastSeg->moveto(A); lastSeg->curveto((*cubic)[1],C,D); @@ -1549,19 +1549,23 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ using Geom::X; using Geom::Y; + if(pc->red_curve->is_empty()) return; + pc->npoints = 5; SPCurve *tmpCurve = new SPCurve(); pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.005,pc->p[2][Y] + 0.005); if(pc->green_curve->is_empty() && !pc->sa){ pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.005,pc->p[1][Y] + 0.005); }else if(!pc->green_curve->is_empty()){ tmpCurve = pc->green_curve->copy(); }else{ tmpCurve = pc->sa->curve->copy(); if(pc->sa->start) tmpCurve = tmpCurve->create_reverse(); - } - if(!tmpCurve->is_empty() && !pc->red_curve->is_empty()){ + + if(!tmpCurve->is_empty()){ Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(cubic){ if(pc->bspline){ @@ -1577,16 +1581,17 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ WPower->reset(); pc->p[1] = SBasisWPower.valueAt(WP); if(!Geom::are_near(pc->p[1],pc->p[0])) - pc->p[1] = Geom::Point(pc->p[1][X] + 0.0001,pc->p[1][Y] + 0.0001); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.005,pc->p[1][Y] + 0.005); if(shift) - pc->p[2]=pc->p[3]; - else - pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); + pc->p[2] = pc->p[3]; }else{ pc->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] ); + pc->p[1] = Geom::Point(pc->p[1][X] + 0.005,pc->p[1][Y] + 0.005); } }else{ pc->p[1] = pc->p[0]; + if(shift) + pc->p[2] = pc->p[3]; } } @@ -1606,7 +1611,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) using Geom::X; using Geom::Y; pc->p[2] = pc->p[3] + (1./3)*(pc->p[0] - pc->p[3]); - pc->p[2] = Geom::Point(pc->p[2][X] + 0.0001,pc->p[2][Y] + 0.0001); + pc->p[2] = Geom::Point(pc->p[2][X] + 0.005,pc->p[2][Y] + 0.005); SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); @@ -1616,7 +1621,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); }else{ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] ); } @@ -1645,7 +1650,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.0001,C[Y] + 0.0001); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); }else{ C = pc->p[3] + (Geom::Point)(pc->p[3] - pc->p[2] ); } -- cgit v1.2.3 From 0b15b05d641661e6b1d5cb73520c7cdead1cfc89 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 9 Jan 2014 17:46:40 +0100 Subject: Fix a bug whith oposite handles on node move,and a little cleanup (bzr r11950.1.232) --- src/ui/tool/node.cpp | 18 ++++++++++-------- src/ui/tool/path-manipulator.cpp | 7 +------ 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 39b21ae6d..63556e499 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -170,7 +170,6 @@ void Handle::move(Geom::Point const &new_pos) //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } return; @@ -188,7 +187,6 @@ void Handle::move(Geom::Point const &new_pos) //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -215,7 +213,6 @@ void Handle::move(Geom::Point const &new_pos) //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this)); - _parent->bsplineWeight = _pm().BSplineHandlePosition(this); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -310,7 +307,6 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven void Handle::handle_2button_press(){ if(_pm().isBSpline){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); - _parent->bsplineWeight = 0.3334; this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); _pm().update(); } @@ -764,8 +760,14 @@ void Node::showHandles(bool v) //Cada vez que actuemos sobre dichos tiradores en un trazado //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; - if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())) - this->bsplineWeight = 0.3334; + if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())){ + if (!_front.isDegenerate()) { + _pm().BSplineHandlePosition(&_front); + } + if (!_back.isDegenerate()) { + _pm().BSplineHandlePosition(&_back); + } + } } void Node::updateHandles() @@ -1125,9 +1127,9 @@ void Node::_setState(State state) //spanish: esto muestra los tiradores al seleccionar los nodos if(_pm().isBSpline){ if(!this->back()->isDegenerate()){ - this->bsplineWeight = _pm().BSplineHandlePosition(this->back()); + _pm().BSplineHandlePosition(this->back()); }else if (!this->front()->isDegenerate()){ - this->bsplineWeight = _pm().BSplineHandlePosition(this->front()); + _pm().BSplineHandlePosition(this->front()); }else{ this->bsplineWeight = 0.0000; } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index cda8374c5..8a0568fbd 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1225,6 +1225,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } + n->bsplineWeight = pos; return pos; } @@ -1265,17 +1266,11 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); if(prevNode){ - n->back()->setPosition(BSplineHandleReposition(n->back(),n->bsplineWeight)); - if(prevNode->front()->position() == prevNode->position()) - prevNode->bsplineWeight = 0.000; if(!prevNode->isEndNode()) prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); } if(nextNode){ - n->front()->setPosition(BSplineHandleReposition(n->front(),n->bsplineWeight)); - if(nextNode->front()->position() == nextNode->position()) - nextNode->bsplineWeight = 0.000; if(!nextNode->isEndNode()) nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); -- cgit v1.2.3 From 7af8d4e83411f23c762da6bfbd2130e76923df7f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 19:34:23 +0100 Subject: show outline like normal paths, by good su_v suggestion (bzr r11950.1.239) --- src/ui/tool/path-manipulator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 7bbe39f8d..654e1fa5d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -911,8 +911,8 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - if(isBSpline) show = true; - if (show == _show_outline) return; + //if(isBSpline) show = true; + //if (show == _show_outline) return; _show_outline = show; _updateOutline(); } -- cgit v1.2.3 From 2563a8cae7411cfee682cbd306f43d5721908c42 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 19:45:02 +0100 Subject: show outline by default in bspline, tnx to su_v suggestion (bzr r11950.1.241) --- src/ui/tool/path-manipulator.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 654e1fa5d..da364926a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -148,6 +148,9 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); + if(isBSpline){ + _show_outline(true); + } } PathManipulator::~PathManipulator() -- cgit v1.2.3 From e582ac68a9ebeca19cc10c47fb6b57a514937278 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 19:52:10 +0100 Subject: fix bug compiling (bzr r11950.1.242) --- src/ui/tool/path-manipulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index da364926a..83af89732 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -149,7 +149,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); if(isBSpline){ - _show_outline(true); + _show_outline = true; } } -- cgit v1.2.3 From 2cb207295847d68e22aab2e8adb967819ff8feaa Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 22:16:10 +0100 Subject: Hack to can show/hide bspline lines (bzr r11950.1.243) --- src/ui/tool/path-manipulator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 83af89732..9cda94097 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -150,6 +150,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, BSpline(); if(isBSpline){ _show_outline = true; + _updateOutline(); + _show_outline = false; } } @@ -914,8 +916,7 @@ void PathManipulator::showHandles(bool show) /** Set the visibility of outline. */ void PathManipulator::showOutline(bool show) { - //if(isBSpline) show = true; - //if (show == _show_outline) return; + if (show == _show_outline) return; _show_outline = show; _updateOutline(); } -- cgit v1.2.3 From 210d60046203fad93e65f049c5c6a7516d967f07 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 30 Jan 2014 23:40:40 +0100 Subject: add comment to bspline red outline hack (bzr r11950.1.244) --- src/ui/tool/path-manipulator.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 9cda94097..4092cd22b 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -148,6 +148,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); + //Small Hack to default show red path in bspline on select, independent of the state of toogle button + //it become some inconsistent behaviour in the show_path toogle button if(isBSpline){ _show_outline = true; _updateOutline(); -- cgit v1.2.3 From 1e8014478b4185861ec348250a88d8476140b35f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 1 Feb 2014 12:33:03 +0100 Subject: Add correct preview for coninuing paths whith pencil and draw modes (bzr r11950.1.245) --- src/ui/tools/pen-tool.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index a48f8911a..8c13a0584 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -43,6 +43,10 @@ #include "tools-switch.h" #include "ui/control-manager.h" //spanish: incluimos los archivos necesarios para las BSpline y Spiro +#include "live_effects/effect.h" +#include "live_effects/lpeobject.h" +#include "live_effects/lpeobject-reference.h" +#include "live_effects/parameter/path.h" #define INKSCAPE_LPE_SPIRO_C #include "live_effects/lpe-spiro.h" @@ -68,6 +72,8 @@ #include "tool-factory.h" +#include "live_effects/effect.h" + using Inkscape::ControlManager; @@ -1467,6 +1473,32 @@ static void bspline_spiro_off(PenTool *const pc) static void bspline_spiro_start_anchor(PenTool *const pc, bool shift) { + LivePathEffect::LPEBSpline *lpe_bsp = NULL; + + if (SP_IS_LPE_ITEM(pc->white_item) && SP_LPE_ITEM(pc->white_item)->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(pc->white_item)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + if(thisEffect){ + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } + if(lpe_bsp){ + pc->bspline = true; + }else{ + pc->bspline = false; + } + LivePathEffect::LPESpiro *lpe_spi = NULL; + + if (SP_IS_LPE_ITEM(pc->white_item) && SP_LPE_ITEM(pc->white_item)->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(pc->white_item)->getPathEffectOfType(Inkscape::LivePathEffect::SPIRO); + if(thisEffect){ + lpe_spi = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + } + } + if(lpe_spi){ + pc->spiro = true; + }else{ + pc->spiro = false; + } if(!pc->spiro && !pc->bspline) return; -- cgit v1.2.3 From b9f1c85c61ce91fedca5486ef371bf6301e76128 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Feb 2014 17:31:55 +0100 Subject: fixing su_v advertising memory bug (bzr r11950.1.247) --- src/ui/tools/freehand-base.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 5825a149c..6561a0c2f 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -531,22 +531,33 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Step C - test start if (dc->sa) { - SPCurve *s = dc->sa->curve; - dc->white_curves = g_slist_remove(dc->white_curves, s); - if (dc->sa->start) { - s = reverse_then_unref(s); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ + dc->sa->curve->unref() + }else{ + SPCurve *s = dc->sa->curve; + dc->white_curves = g_slist_remove(dc->white_curves, s); + if (dc->sa->start) { + s = reverse_then_unref(s); + } + s->append_continuous(c, 0.0625); + c->unref(); + c = s; } - s->append_continuous(c, 0.0625); - c->unref(); - c = s; } else /* Step D - test end */ if (dc->ea) { - SPCurve *e = dc->ea->curve; - dc->white_curves = g_slist_remove(dc->white_curves, e); - if (!dc->ea->start) { - e = reverse_then_unref(e); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ + dc->ea->curve->unref() + SPCurve *e = dc->ea->curve; + dc->white_curves = g_slist_remove(dc->white_curves, e); + if (!dc->ea->start) { + e = reverse_then_unref(e); + } + c->append_continuous(e, 0.0625); + e->unref(); } - c->append_continuous(e, 0.0625); - e->unref(); } -- cgit v1.2.3 From 46c24197ff9e17b30d97cab8893d5017b9b99dc3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Feb 2014 20:10:00 +0100 Subject: update to trunk (bzr r11950.1.249) --- src/ui/tools/freehand-base.cpp | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 6561a0c2f..5825a149c 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -531,33 +531,22 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Step C - test start if (dc->sa) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ - dc->sa->curve->unref() - }else{ - SPCurve *s = dc->sa->curve; - dc->white_curves = g_slist_remove(dc->white_curves, s); - if (dc->sa->start) { - s = reverse_then_unref(s); - } - s->append_continuous(c, 0.0625); - c->unref(); - c = s; + SPCurve *s = dc->sa->curve; + dc->white_curves = g_slist_remove(dc->white_curves, s); + if (dc->sa->start) { + s = reverse_then_unref(s); } + s->append_continuous(c, 0.0625); + c->unref(); + c = s; } else /* Step D - test end */ if (dc->ea) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 1 && - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) != 2){ - dc->ea->curve->unref() - SPCurve *e = dc->ea->curve; - dc->white_curves = g_slist_remove(dc->white_curves, e); - if (!dc->ea->start) { - e = reverse_then_unref(e); - } - c->append_continuous(e, 0.0625); - e->unref(); + SPCurve *e = dc->ea->curve; + dc->white_curves = g_slist_remove(dc->white_curves, e); + if (!dc->ea->start) { + e = reverse_then_unref(e); } + c->append_continuous(e, 0.0625); + e->unref(); } -- cgit v1.2.3 From 215e1988378008820be9bfb7d948d8b6e33eb0a1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 8 Feb 2014 22:16:43 +0100 Subject: Removing hack for force show red lines in bspline mode (bzr r11950.1.251) --- src/ui/tool/path-manipulator.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 4092cd22b..bad07daee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -148,13 +148,6 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _createControlPointsFromGeometry(); BSpline(); - //Small Hack to default show red path in bspline on select, independent of the state of toogle button - //it become some inconsistent behaviour in the show_path toogle button - if(isBSpline){ - _show_outline = true; - _updateOutline(); - _show_outline = false; - } } PathManipulator::~PathManipulator() -- cgit v1.2.3 From be22cb94d23816986838e9636ce44ee8537a8570 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 26 Feb 2014 22:29:31 +0100 Subject: Fixed some/all bugs related to continuing bspline/spiro curves advertaising by suv (bzr r11950.1.257) --- src/ui/tools/freehand-base.cpp | 37 +++++++++++++++++++++---------- src/ui/tools/pen-tool.cpp | 50 +++++++++++++++++++++++------------------- 2 files changed, 52 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 5e406a0d4..d8a8e901a 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -469,7 +469,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // Concat RBG SPCurve *c = dc->green_curve; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // Green dc->green_curve = new SPCurve(); while (dc->green_bpaths) { @@ -490,12 +490,16 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); if (c->is_empty()) { + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + SPDesktop *desktop = dc->desktop; + spdc_selection_modified(sp_desktop_selection(desktop), 0, dc); + } c->unref(); return; } // Step A - test, whether we ended on green anchor - if ( forceclosed || ( dc->green_anchor && dc->green_anchor->active ) ) { + if ( forceclosed || (dc->green_anchor && dc->green_anchor->active) ) { // We hit green anchor, closing Green-Blue-Red dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed.")); c->closepath_current(); @@ -513,21 +517,33 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { - c = reverse_then_unref(c); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { + dc->sa->curve = reverse_then_unref(dc->sa->curve); + } + dc->sa->curve->append_continuous(c, 0.0625); + c->unref(); + if(Geom::are_near(dc->sa->curve->first_path()->initialPoint(), dc->ea->dp)){ + dc->sa->curve->closepath_current(); + } + }else{ + if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { + c = reverse_then_unref(c); + } + dc->sa->curve->append_continuous(c, 0.0625); + c->unref(); + dc->sa->curve->closepath_current(); } - dc->sa->curve->append_continuous(c, 0.0625); - c->unref(); - dc->sa->curve->closepath_current(); //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white //pasándole la curva de inicio necesaria - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); spdc_flush_white(dc, dc->sa->curve); - }else + }else{ spdc_flush_white(dc, NULL); + } return; } @@ -550,10 +566,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->append_continuous(e, 0.0625); e->unref(); } - - spdc_flush_white(dc, c); - c->unref(); } diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 8c13a0584..a344dc7a6 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -414,11 +414,18 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev ToolBase *event_context = SP_EVENT_CONTEXT(pc); //Test whether we hit any anchor. SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); + //with this we avoid creating a new point over the existing one - if(!bevent.button == 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ + if(bevent.button != 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ + pc->state = PenTool::STOP; + if( anchor && anchor == pc->sa && pc->green_curve->is_empty()){ + //spanish Borrar siguiente linea para evitar un nodo encima de otro + spdc_pen_finish_segment(pc, event_dt, bevent.state); + spdc_pen_finish(pc, FALSE); + return TRUE; + } return FALSE; } - gint ret = FALSE; if (bevent.button == 1 && !event_context->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) @@ -486,7 +493,7 @@ static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bev if(anchor){ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); } - if (anchor && !sp_pen_context_has_waiting_LPE(pc)) { + if (anchor && (!sp_pen_context_has_waiting_LPE(pc) || pc->bspline || pc->spiro)) { // Adjust point to anchor if needed; if we have a waiting LPE, we need // a fresh path to be created so don't continue an existing one p = anchor->dp; @@ -755,7 +762,6 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r } gint ret = FALSE; - ToolBase *event_context = SP_EVENT_CONTEXT(pc); if ( revent.button == 1 && !event_context->space_panning) { @@ -769,11 +775,10 @@ static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &r // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); //with this we avoid creating a new point over the existing one - if(pc->spiro || pc->bspline){ - //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. - if(pc->npoints > 0 && pc->p[0] == pc->p[3]){ - return FALSE; - } + //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. + + if((!anchor || anchor == pc->sa) && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){ + return TRUE; } switch (pc->mode) { @@ -1442,9 +1447,7 @@ static void bspline_spiro(PenTool *const pc, bool shift) if(!pc->spiro && !pc->bspline) return; - if(!pc->anchor_statusbar) - shift?bspline_spiro_off(pc):bspline_spiro_on(pc); - + shift?bspline_spiro_off(pc):bspline_spiro_on(pc); bspline_spiro_build(pc); } @@ -1628,10 +1631,11 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ } if(pc->anchor_statusbar && !pc->red_curve->is_empty()){ - if(shift) + if(shift){ bspline_spiro_end_anchor_off(pc); - else + }else{ bspline_spiro_end_anchor_on(pc); + } } bspline_spiro_build(pc); @@ -1675,10 +1679,9 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) tmpCurve = tmpCurve->create_reverse(); pc->green_curve->reset(); pc->green_curve = tmpCurve; - }else{ + }else { tmpCurve = pc->sa->curve->copy(); - if(!pc->sa->start) - tmpCurve = tmpCurve->create_reverse(); + if(!pc->sa->start) tmpCurve = tmpCurve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(pc->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); @@ -1712,10 +1715,11 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) static void bspline_spiro_end_anchor_off(PenTool *const pc) { - pc->p[2] = pc->p[3]; SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); + pc->p[2] = pc->p[3]; if(!pc->sa || pc->sa->curve->is_empty()){ + tmpCurve = pc->green_curve->create_reverse(); if(pc->green_curve->get_segment_count()==0)return; Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); @@ -1734,10 +1738,9 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) pc->green_curve->reset(); pc->green_curve = tmpCurve; } - }else{ + }else { tmpCurve = pc->sa->curve->copy(); - if(!pc->sa->start) - tmpCurve = tmpCurve->create_reverse(); + if(!pc->sa->start) tmpCurve = tmpCurve->create_reverse(); Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(cubic){ lastSeg->moveto((*cubic)[0]); @@ -1789,7 +1792,7 @@ static void bspline_spiro_build(PenTool *const pc) } if(!curve->is_empty()){ - //spanish: cerramos la curva si estan cerca los puntos finales de la curva spiro + //spanish: cerramos la curva si estan cerca los puntos finales de la curva if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -2194,7 +2197,8 @@ static void spdc_pen_finish(PenTool *const pc, gboolean const closed) SPDesktop *const desktop = pc->desktop; pc->message_context->clear(); desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - + if(pc->spiro || pc->bspline) pc->blue_curve->reset(); + //spanish para cancelar linea sin un segmento creado pc->red_curve->reset(); spdc_concat_colors_and_flush(pc, closed); pc->sa = NULL; -- cgit v1.2.3 From 1f76e96f90e3badb3b9693d477e6e75fbaaa1bd1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 28 Feb 2014 20:12:44 +0100 Subject: adding some comments (bzr r11950.1.260) --- src/ui/tool/node.cpp | 3 +-- src/ui/tools/freehand-base.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 63556e499..69f4a8e82 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -322,7 +322,6 @@ bool Handle::grabbed(GdkEventMotion *) void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) { - Geom::Point parent_pos = _parent->position(); Geom::Point origin = _last_drag_origin(); SnapManager &sm = _desktop->namedview->snap_manager; @@ -479,7 +478,7 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //spanish: un truco para, si el nodo tiene fuerza, nos marca que es //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index c65d8133b..861ea0503 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -483,6 +483,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); + //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente + //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada + //porque la modificamos al continuar por un anchor if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -493,7 +496,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) } // Step A - test, whether we ended on green anchor - if ( forceclosed || (dc->green_anchor && dc->green_anchor->active) ) { + if ( forceclosed || ( dc->green_anchor && dc->green_anchor->active ) ) { // We hit green anchor, closing Green-Blue-Red dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed.")); c->closepath_current(); @@ -511,6 +514,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); + //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor + //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { -- cgit v1.2.3 From 616ae6e54d98f03dc1ff3ce7d3c528521fd7e233 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 1 Mar 2014 16:28:13 +0100 Subject: Substitute isBSpline property by a cached function isBSpline(bool) (bzr r11950.1.261) --- src/ui/tool/curve-drag-point.cpp | 4 ++-- src/ui/tool/node.cpp | 30 +++++++++++++++--------------- src/ui/tool/path-manipulator.cpp | 19 +++++++++++-------- src/ui/tool/path-manipulator.h | 3 +-- 4 files changed, 29 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index 0ee848f15..e5412fdc2 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -54,7 +54,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; //spanish: solo actualizamos los nodos si no es bspline - if(!_pm.isBSpline){ + if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); } @@ -90,7 +90,7 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT - if(!_pm.isBSpline){ + if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); }else if(weight>=0.8 && !second->isEndNode() && held_shift(*event))second->back()->move(new_pos); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 69f4a8e82..78d8fe833 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -168,7 +168,7 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //spanish: mueve el tirador y su opuesto la misma proporción - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -185,7 +185,7 @@ void Handle::move(Geom::Point const &new_pos) setRelativePos(new_delta); //spanish: mueve el tirador y su opuesto la misma proporción - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -211,7 +211,7 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //spanish: mueve el tirador y su opuesto la misma proporción - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); } @@ -305,7 +305,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven //spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 void Handle::handle_2button_press(){ - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); _pm().update(); @@ -361,7 +361,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) new_pos = result; //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el //parametro "steps whith control" del efecto en vivo BSpline - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; @@ -371,7 +371,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) std::vector unselected; //spanish: si está activado el ajuste (snap) y no es bspline - if (snap && !_pm().isBSpline) { + if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -413,7 +413,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } //spanish: si es bspline pero no está presionado SHIFT o CONTROL //lo fija en la posición original - if(_pm().isBSpline && !held_shift(*event) && !held_control(*event)){ + if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } move(new_pos); // needed for correct update, even though it's redundant @@ -433,7 +433,7 @@ void Handle::ungrabbed(GdkEventButton *event) if (dist.length() <= drag_tolerance) { move(_parent->position()); //spanish: marca la fuerza del bspline como 0.0000 - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } } @@ -626,7 +626,7 @@ void Node::move(Geom::Point const &new_pos) //de nuevo una vez sea movido el nodo double oldPos = 0.0000; Node *n = this; - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ oldPos = n->bsplineWeight; } @@ -640,7 +640,7 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión //y despues los de los nodos colindantes - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); _pm().BSplineNodeHandlesReposition(this); @@ -652,7 +652,7 @@ void Node::transform(Geom::Affine const &m) //spanish: guardamos la fuerza anterior del nodo para reaplicarsela //de nuevo una vez sea movido el nodo double oldPos = 0.0000; - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; } Geom::Point old_pos = position(); @@ -665,7 +665,7 @@ void Node::transform(Geom::Affine const &m) _fixNeighbors(old_pos, position()); //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión //y despues los de los nodos colindantes - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); _pm().BSplineNodeHandlesReposition(this); @@ -759,7 +759,7 @@ void Node::showHandles(bool v) //Cada vez que actuemos sobre dichos tiradores en un trazado //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; - if(_pm().isBSpline && (!_front.isDegenerate() || !_back.isDegenerate())){ + if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { _pm().BSplineHandlePosition(&_front); } @@ -871,7 +871,7 @@ void Node::setType(NodeType type, bool update_handles) //spanish: en los cambios de tipo de nodo, sobre trazados bspline, //o bien los mantenemos con potencia 0.0000 en modo esquina //o les damos la potencia por defecto en modo de curva - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); @@ -1124,7 +1124,7 @@ void Node::_setState(State state) mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); //spanish: esto muestra los tiradores al seleccionar los nodos - if(_pm().isBSpline){ + if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); }else if (!this->front()->isDegenerate()){ diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index bad07daee..a6689d93d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -103,11 +103,9 @@ private: }; void build_segment(Geom::PathBuilder &, Node *, Node *); -//spanish: una propiedad isBSpline, por defecto falsa y una función al final de la función (BSpline()) que la define realmente PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) - , isBSpline(false) , _subpaths(*this) , _multi_path_manipulator(mpm) , _path(path) @@ -147,7 +145,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - BSpline(); + isBSpline(true); } PathManipulator::~PathManipulator() @@ -666,7 +664,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite start = next; } //spanish: si se borra, reajustamos los tiradores - if(isBSpline){ + if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ pos = BSplineHandlePosition(start.prev()->back()); @@ -1203,11 +1201,16 @@ int PathManipulator::BSplineGetSteps(){ } //spanish: determina si el trazado tiene efecto bspline -void PathManipulator::BSpline(){ - isBSpline = false; - if(this->BSplineGetSteps()>0){ +bool PathManipulator::isBSpline(bool recalculate){ + static int BSplineSteps = this->BSplineGetSteps(); + if(recalculate){ + BSplineSteps = this->BSplineGetSteps(); + } + bool isBSpline = false; + if(BSplineSteps>0){ isBSpline = true; } + return isBSpline; } //spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador @@ -1283,7 +1286,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; - BSpline(); + isBSpline(true); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 5f075834e..5186bfc95 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -96,7 +96,6 @@ public: NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - bool isBSpline; int BSplineGetSteps(); // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -107,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - void BSpline(); + bool isBSpline(bool recalculate); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); -- cgit v1.2.3 From 9f066846c116c7a963bfaa805282b9b8d4c014e4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 2 Mar 2014 03:07:44 +0100 Subject: =?UTF-8?q?Fixed=20update=20to=20trunk,=20lot=20of=20changes=20vin?= =?UTF-8?q?=C3=ADcius?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.265) --- src/ui/tools/pen-tool.cpp | 122 +++++++++++++++------------------------------- src/ui/tools/pen-tool.h | 29 ++++++++++- 2 files changed, 66 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index c6d87e2d8..65823b642 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -81,52 +81,6 @@ namespace Inkscape { namespace UI { namespace Tools { -static void spdc_pen_set_initial_point(PenTool *pc, Geom::Point const p); -//spanish: añade los modos spiro y bspline -static void sp_pen_context_set_mode(PenTool *const pc, guint mode); -//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro -static void bspline_spiro_color(PenTool *const pc); -//spanish: crea un nodo en modo bspline o spiro -static void bspline_spiro(PenTool *const pc,bool shift); -//spanish: crea un nodo de modo spiro o bspline -static void bspline_spiro_on(PenTool *const pc); -//spanish: crea un nodo de tipo CUSP -static void bspline_spiro_off(PenTool *const pc); -//spanish: continua una curva existente en modo bspline o spiro -static void bspline_spiro_start_anchor(PenTool *const pc,bool shift); -//spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro -static void bspline_spiro_start_anchor_on(PenTool *const pc); -//spanish: continua una curva existente con el nodo de union en modo CUSP -static void bspline_spiro_start_anchor_off(PenTool *const pc); -//spanish: modifica la "red_curve" cuando se detecta movimiento -static void bspline_spiro_motion(PenTool *const pc,bool shift); -//spanish: cierra la curva con el último nodo en modo bspline o spiro -static void bspline_spiro_end_anchor_on(PenTool *const pc); -//spanish: cierra la curva con el último nodo en modo CUSP -static void bspline_spiro_end_anchor_off(PenTool *const pc); -//spanish: unimos todas las curvas en juego y llamamos a la función doEffect. -static void bspline_spiro_build(PenTool *const pc); -//function bspline cloned from lpe-bspline.cpp -static void bspline_doEffect(SPCurve * curve); -//function spiro cloned from lpe-spiro.cpp -static void spiro_doEffect(SPCurve * curve); - -static void spdc_pen_set_subsequent_point(PenTool *const pc, Geom::Point const p, bool statusbar, guint status = 0); -static void spdc_pen_set_ctrl(PenTool *pc, Geom::Point const p, guint state); -static void spdc_pen_finish_segment(PenTool *pc, Geom::Point p, guint state); - -static void spdc_pen_finish(PenTool *pc, gboolean closed); - -static gint pen_handle_button_press(PenTool *const pc, GdkEventButton const &bevent); -static gint pen_handle_motion_notify(PenTool *const pc, GdkEventMotion const &mevent); -static gint pen_handle_button_release(PenTool *const pc, GdkEventButton const &revent); -static gint pen_handle_2button_press(PenTool *const pc, GdkEventButton const &bevent); -static gint pen_handle_key_press(PenTool *const pc, GdkEvent *event); -static void spdc_reset_colors(PenTool *pc); - -static void pen_disable_events(PenTool *const pc); -static void pen_enable_events(PenTool *const pc); - static Geom::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical @@ -217,13 +171,13 @@ void PenTool::setPolylineMode() { this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline //todo: merge to one function only - sp_pen_context_set_mode(this, mode); + this->_pen_context_set_mode(mode); } /* *.Set the mode of draw spiro, and bsplines */ -void sp_pen_context_set_mode(PenTool *const pc, guint mode) { +void PenTool::_pen_context_set_mode(guint mode) { //spanish: definimos los modos this->spiro = (mode == 1); this->bspline = (mode == 2); @@ -425,7 +379,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { Geom::Point const event_w(bevent.x, bevent.y); Geom::Point event_dt(desktop->w2d(event_w)); //Test whether we hit any anchor. - SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); + SPDrawAnchor * const anchor = spdc_test_inside(this, event_w); ToolBase *event_context = SP_EVENT_CONTEXT(this); //with this we avoid creating a new point over the existing one @@ -433,8 +387,8 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ //spanish Borrar siguiente linea para evitar un nodo encima de otro - spdc_pen_finish_segment(pc, event_dt, bevent.state); - spdc_pen_finish(pc, FALSE); + _finishSegment(event_dt, bevent.state); + _finish( FALSE); return TRUE; } return FALSE; @@ -505,7 +459,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { this->sa = anchor; if(anchor){ - bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_start_anchor(bevent.state & GDK_SHIFT_MASK); } if (anchor && (!this->hasWaitingLPE()|| this->bspline || this->spiro)) { // Adjust point to anchor if needed; if we have a waiting LPE, we need @@ -753,12 +707,12 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { } //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(this->bspline){ - bspline_spiro_color(pc); - bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_color(); + this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); }else{ if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { - bspline_spiro_color(pc); - bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_color(); + this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); pen_drag_origin_w = event_w; } } @@ -809,7 +763,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { //spanish: continuamos una curva existente if (anchor) { if(this->bspline || this->spiro){ - bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK)); + this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; } } this->_setInitialPoint(p); @@ -986,7 +940,7 @@ void PenTool::_redrawAll() { //spanish: simplemente redibujamos la spiro. //como es un redibujo simplemente no llamamos a la función global sino al final de esta //Lanzamos solamente el redibujado - bspline_spiro_build(pc); + this->_bspline_spiro_build(); } void PenTool::_lastpointMove(gdouble x, gdouble y) { @@ -1060,7 +1014,7 @@ void PenTool::_lastpointToCurve() { } //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ - bspline_spiro_start_anchor(pc, false); + this->_bspline_spiro_start_anchor(false); } } @@ -1107,7 +1061,7 @@ void PenTool::_lastpointToLine() { } //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ - bspline_spiro_start_anchor(pc, true); + this->_bspline_spiro_start_anchor(true); } } @@ -1332,7 +1286,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; //spanish: redibujamos - bspline_spiro_build(pc); + this->_bspline_spiro_build(); ret = TRUE; } break; @@ -1406,7 +1360,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro -static void bspline_spiro_color(PenTool *const pc) +void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; if(this->spiro){ @@ -1451,16 +1405,16 @@ static void bspline_spiro_color(PenTool *const pc) } -static void bspline_spiro(PenTool *const pc, bool shift) +void PenTool::_bspline_spiro(bool shift) { if(!this->spiro && !this->bspline) return; - shift?bspline_spiro_off(pc):bspline_spiro_on(pc); - bspline_spiro_build(pc); + shift?this->_bspline_spiro_off():this->_bspline_spiro_on(); + this->_bspline_spiro_build(); } -static void bspline_spiro_on(PenTool *const pc) +void PenTool::_bspline_spiro_on() { if(!this->red_curve->is_empty()){ using Geom::X; @@ -1473,7 +1427,7 @@ static void bspline_spiro_on(PenTool *const pc) } } -static void bspline_spiro_off(PenTool *const pc) +void PenTool::_bspline_spiro_off() { if(!this->red_curve->is_empty()){ this->npoints = 5; @@ -1483,7 +1437,7 @@ static void bspline_spiro_off(PenTool *const pc) } } -static void bspline_spiro_start_anchor(PenTool *const pc, bool shift) +void PenTool::_bspline_spiro_start_anchor(bool shift) { LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1518,12 +1472,12 @@ static void bspline_spiro_start_anchor(PenTool *const pc, bool shift) return; if(shift) - bspline_spiro_start_anchor_off(pc); + this->_bspline_spiro_start_anchor_off(); else - bspline_spiro_start_anchor_on(pc); + this->_bspline_spiro_start_anchor_on(); } -static void bspline_spiro_start_anchor_on(PenTool *const pc) +void PenTool::_bspline_spiro_start_anchor_on() { using Geom::X; using Geom::Y; @@ -1559,7 +1513,7 @@ static void bspline_spiro_start_anchor_on(PenTool *const pc) this->sa->curve = tmpCurve; } -static void bspline_spiro_start_anchor_off(PenTool *const pc) +void PenTool::_bspline_spiro_start_anchor_off() { SPCurve *tmpCurve = new SPCurve(); tmpCurve = this->sa->curve->copy(); @@ -1587,7 +1541,7 @@ static void bspline_spiro_start_anchor_off(PenTool *const pc) } -static void bspline_spiro_motion(PenTool *const pc, bool shift){ +void PenTool::_bspline_spiro_motion(bool shift){ if(!this->spiro && !this->bspline) return; @@ -1641,16 +1595,16 @@ static void bspline_spiro_motion(PenTool *const pc, bool shift){ if(this->anchor_statusbar && !this->red_curve->is_empty()){ if(shift){ - bspline_spiro_end_anchor_off(pc); + this->_bspline_spiro_end_anchor_off(); }else{ - bspline_spiro_end_anchor_on(pc); + this->_bspline_spiro_end_anchor_on(); } } - bspline_spiro_build(pc); + this->_bspline_spiro_build(); } -static void bspline_spiro_end_anchor_on(PenTool *const pc) +void PenTool::_bspline_spiro_end_anchor_on() { using Geom::X; @@ -1721,7 +1675,7 @@ static void bspline_spiro_end_anchor_on(PenTool *const pc) } } -static void bspline_spiro_end_anchor_off(PenTool *const pc) +void PenTool::_bspline_spiro_end_anchor_off() { SPCurve *tmpCurve = new SPCurve(); @@ -1773,7 +1727,7 @@ static void bspline_spiro_end_anchor_off(PenTool *const pc) //spanish: preparates the curves for its trasformation into BSline curves. -static void bspline_spiro_build(PenTool *const pc) +void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) return; @@ -1812,9 +1766,9 @@ static void bspline_spiro_build(PenTool *const pc) //Effect *spr = static_cast ( new LPEbspline(lpeobj) ); //spr->doEffect(curve); if(this->bspline){ - bspline_doEffect(curve); + this->_bspline_doEffect(curve); }else{ - spiro_doEffect(curve); + this->_spiro_doEffect(curve); } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); @@ -1838,7 +1792,7 @@ static void bspline_spiro_build(PenTool *const pc) } } -static void bspline_doEffect(SPCurve * curve) +void PenTool::_bspline_doEffect(SPCurve * curve) { //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) @@ -1981,7 +1935,7 @@ static void bspline_doEffect(SPCurve * curve) //Spiro function cloned from lpe-spiro.cpp //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp -static void spiro_doEffect(SPCurve * curve) +void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; using Geom::Y; @@ -2178,7 +2132,7 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { if (!this->red_curve->is_empty()) { - bspline_spiro(pc,(state & GDK_SHIFT_MASK)); + this->_bspline_spiro(state & GDK_SHIFT_MASK); this->green_curve->append_continuous(this->red_curve, 0.0625); SPCurve *curve = this->red_curve->copy(); diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 07fc037be..88e528b22 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -88,7 +88,34 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - + //spanish: añade los modos spiro y bspline + void _pen_context_set_mode(guint mode); + //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro + void _bspline_spiro_color(); + //spanish: crea un nodo en modo bspline o spiro + void _bspline_spiro(bool shift); + //spanish: crea un nodo de modo spiro o bspline + void _bspline_spiro_on(); + //spanish: crea un nodo de tipo CUSP + void _bspline_spiro_off(); + //spanish: continua una curva existente en modo bspline o spiro + void _bspline_spiro_start_anchor(bool shift); + //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro + void _bspline_spiro_start_anchor_on(); + //spanish: continua una curva existente con el nodo de union en modo CUSP + void _bspline_spiro_start_anchor_off(); + //spanish: modifica la "red_curve" cuando se detecta movimiento + void _bspline_spiro_motion(bool shift); + //spanish: cierra la curva con el último nodo en modo bspline o spiro + void _bspline_spiro_end_anchor_on(); + //spanish: cierra la curva con el último nodo en modo CUSP + void _bspline_spiro_end_anchor_off(); + //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. + void _bspline_spiro_build(); + //function bspline cloned from lpe-bspline.cpp + void _bspline_doEffect(SPCurve * curve); + //function spiro cloned from lpe-spiro.cpp + void _spiro_doEffect(SPCurve * curve); void _setInitialPoint(Geom::Point const p); void _setSubsequentPoint(Geom::Point const p, bool statusbar, guint status = 0); void _setCtrl(Geom::Point const p, guint state); -- cgit v1.2.3 From 1d854ff519b9c0867bfa4ecaf2f6329ca256f06a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 10:29:06 -0500 Subject: Experimental merge of Ponyscape features into trunk (will not compile) (bzr r13090.1.1) --- src/live_effects/CMakeLists.txt | 13 + src/live_effects/Makefile_insert | 14 +- src/live_effects/effect-enum.h | 6 + src/live_effects/effect.cpp | 39 +- src/live_effects/lpe-attach-path.cpp | 203 ++ src/live_effects/lpe-attach-path.h | 54 + src/live_effects/lpe-bounding-box.cpp | 67 + src/live_effects/lpe-bounding-box.h | 37 + src/live_effects/lpe-ellipse_5pts.cpp | 214 ++ src/live_effects/lpe-ellipse_5pts.h | 50 + src/live_effects/lpe-fill-between-many.cpp | 77 + src/live_effects/lpe-fill-between-many.h | 36 + src/live_effects/lpe-fill-between-strokes.cpp | 116 ++ src/live_effects/lpe-fill-between-strokes.h | 38 + src/live_effects/lpe-jointype.cpp | 203 ++ src/live_effects/lpe-jointype.h | 43 + src/live_effects/lpe-powerstroke-interpolators.h | 42 +- src/live_effects/lpe-powerstroke.cpp | 97 +- src/live_effects/lpe-powerstroke.h | 2 + src/live_effects/parameter/Makefile_insert | 4 + src/live_effects/parameter/originalpatharray.cpp | 486 +++++ src/live_effects/parameter/originalpatharray.h | 123 ++ .../parameter/powerstrokepointarray.cpp | 39 +- src/live_effects/parameter/powerstrokepointarray.h | 23 +- src/live_effects/parameter/transformedpoint.cpp | 182 ++ src/live_effects/parameter/transformedpoint.h | 87 + src/live_effects/pathoutlineprovider.h | 766 ++++++++ src/sp-item.cpp | 20 + src/sp-item.h | 10 + src/sp-object.h | 1 + src/ui/dialog/Makefile_insert | 4 + src/ui/dialog/lpe-powerstroke-properties.cpp | 203 ++ src/ui/dialog/lpe-powerstroke-properties.h | 99 + src/ui/dialog/objects.cpp | 2048 ++++++++++++++++++++ src/ui/dialog/objects.h | 255 +++ src/ui/dialog/tags.cpp | 1182 +++++++++++ src/ui/dialog/tags.h | 181 ++ src/ui/widget/clipmaskicon.cpp | 177 ++ src/ui/widget/clipmaskicon.h | 102 + src/ui/widget/highlight-picker.cpp | 176 ++ src/ui/widget/highlight-picker.h | 90 + src/ui/widget/insertordericon.cpp | 166 ++ src/ui/widget/insertordericon.h | 100 + src/ui/widget/layertypeicon.cpp | 167 ++ src/ui/widget/layertypeicon.h | 108 ++ 45 files changed, 8126 insertions(+), 24 deletions(-) create mode 100644 src/live_effects/lpe-attach-path.cpp create mode 100644 src/live_effects/lpe-attach-path.h create mode 100644 src/live_effects/lpe-bounding-box.cpp create mode 100644 src/live_effects/lpe-bounding-box.h create mode 100644 src/live_effects/lpe-ellipse_5pts.cpp create mode 100644 src/live_effects/lpe-ellipse_5pts.h create mode 100644 src/live_effects/lpe-fill-between-many.cpp create mode 100644 src/live_effects/lpe-fill-between-many.h create mode 100644 src/live_effects/lpe-fill-between-strokes.cpp create mode 100644 src/live_effects/lpe-fill-between-strokes.h create mode 100644 src/live_effects/lpe-jointype.cpp create mode 100755 src/live_effects/lpe-jointype.h create mode 100644 src/live_effects/parameter/originalpatharray.cpp create mode 100644 src/live_effects/parameter/originalpatharray.h create mode 100644 src/live_effects/parameter/transformedpoint.cpp create mode 100644 src/live_effects/parameter/transformedpoint.h create mode 100755 src/live_effects/pathoutlineprovider.h create mode 100644 src/ui/dialog/lpe-powerstroke-properties.cpp create mode 100644 src/ui/dialog/lpe-powerstroke-properties.h create mode 100644 src/ui/dialog/objects.cpp create mode 100644 src/ui/dialog/objects.h create mode 100644 src/ui/dialog/tags.cpp create mode 100644 src/ui/dialog/tags.h create mode 100644 src/ui/widget/clipmaskicon.cpp create mode 100644 src/ui/widget/clipmaskicon.h create mode 100644 src/ui/widget/highlight-picker.cpp create mode 100644 src/ui/widget/highlight-picker.h create mode 100644 src/ui/widget/insertordericon.cpp create mode 100644 src/ui/widget/insertordericon.h create mode 100644 src/ui/widget/layertypeicon.cpp create mode 100644 src/ui/widget/layertypeicon.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index a5f50a69d..8ad1ccf9b 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -2,8 +2,10 @@ set(live_effects_SRC effect.cpp lpe-angle_bisector.cpp + lpe-attach-path.cpp lpe-bendpath.cpp lpe-boolops.cpp + lpe-bounding-box.cpp lpe-circle_3pts.cpp lpe-circle_with_radius.cpp lpe-clone-original.cpp @@ -11,8 +13,11 @@ set(live_effects_SRC lpe-copy_rotate.cpp lpe-curvestitch.cpp lpe-dynastroke.cpp + lpe-ellipse-5pts.cpp lpe-envelope.cpp lpe-extrude.cpp + lpe-fill-between-many.cpp + lpe-fill-between-strokes.cpp lpe-gears.cpp lpe-interpolate.cpp lpe-knot.cpp @@ -47,11 +52,13 @@ set(live_effects_SRC parameter/parameter.cpp parameter/path.cpp parameter/originalpath.cpp + parameter/originalpatharray.cpp parameter/path-reference.cpp parameter/point.cpp parameter/powerstrokepointarray.cpp parameter/random.cpp parameter/text.cpp + paramter/transformedpoint.cpp parameter/unit.cpp parameter/vector.cpp @@ -61,8 +68,10 @@ set(live_effects_SRC effect-enum.h effect.h lpe-angle_bisector.h + lpe-attach-path.h lpe-bendpath.h lpe-boolops.h + lpe-bounding-box.h lpe-circle_3pts.h lpe-circle_with_radius.h lpe-clone-original.h @@ -70,8 +79,11 @@ set(live_effects_SRC lpe-copy_rotate.h lpe-curvestitch.h lpe-dynastroke.h + lpe-ellipse-5pts.h lpe-envelope.h lpe-extrude.h + lpe-fill-between-many.h + lpe-fill-between-strokes.h lpe-gears.h lpe-interpolate.h lpe-knot.h @@ -109,6 +121,7 @@ set(live_effects_SRC parameter/path-reference.h parameter/path.h parameter/originalpath.h + parameter/originalpatharray.h parameter/point.h parameter/powerstrokepointarray.h parameter/random.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 9c3c171f2..76d7b418f 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -82,4 +82,16 @@ ink_common_sources += \ live_effects/lpe-path_length.cpp \ live_effects/lpe-path_length.h \ live_effects/lpe-line_segment.cpp \ - live_effects/lpe-line_segment.h + live_effects/lpe-line_segment.h \ + live_effects/lpe-bounding-box.cpp \ + live_effects/lpe-bounding-box.h \ + live_effects/lpe-attach-path.cpp \ + live_effects/lpe-attach-path.h \ + live_effects/lpe-fill-between-strokes.cpp \ + live_effects/lpe-fill-between-stroke.h \ + live_effects/lpe-fill-between-many.cpp \ + live_effects/lpe-fill-between-many.h \ + live_effects/lpe-ellipse_5pts.cpp \ + live_effects/lpe-ellipse_5pts.h \ + live_effects/lpe-jointype.cpp \ + live_effects/lpe-jointype.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 43af33b53..46bc56a81 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -50,6 +50,12 @@ enum EffectType { EXTRUDE, POWERSTROKE, CLONE_ORIGINAL, + ATTACH_PATH, + FILL_BETWEEN_STROKES, + FILL_BETWEEN_MANY, + ELLIPSE_5PTS, + BOUNDING_BOX, + JOIN_TYPE, INVALID_LPE // This must be last (I made it such that it is not needed anymore I think..., Don't trust on it being last. - johan) }; diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 12990ee24..17b229352 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,7 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -//#define LPE_ENABLE_TEST_EFFECTS +#define LPE_ENABLE_TEST_EFFECTS #ifdef HAVE_CONFIG_H # include "config.h" @@ -47,6 +47,12 @@ #include "live_effects/lpe-extrude.h" #include "live_effects/lpe-powerstroke.h" #include "live_effects/lpe-clone-original.h" +#include "live_effects/lpe-attach-path.h" +#include "live_effects/lpe-fill-between-strokes.h" +#include "live_effects/lpe-fill-between-many.h" +#include "live_effects/lpe-ellipse_5pts.h" +#include "live_effects/lpe-bounding-box.h" +#include "live_effects/lpe-jointype.h" #include "xml/node-event-vector.h" #include "sp-object.h" @@ -103,9 +109,10 @@ const Util::EnumData LPETypeData[] = { {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, {TEXT_LABEL, N_("Text label"), "text_label"}, + {JOIN_TYPE, N_("Join type"), "join_type"}, #endif /* 0.46 */ - {BEND_PATH, N_("Bend"), "bend_path"}, + {BEND_PATH, N_("Bend"), "bend_path"}, {GEARS, N_("Gears"), "gears"}, {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"}, @@ -120,8 +127,14 @@ const Util::EnumData LPETypeData[] = { {SKETCH, N_("Sketch"), "sketch"}, {RULER, N_("Ruler"), "ruler"}, /* 0.49 */ - {POWERSTROKE, N_("Power stroke"), "powerstroke"}, - {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, + {POWERSTROKE, N_("Power stroke"), "powerstroke"}, + {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, +/* Ponyscape */ + {ATTACH_PATH, N_("Attach path"), "attach_path"}, + {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, + {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, + {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, + {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -245,6 +258,24 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case CLONE_ORIGINAL: neweffect = static_cast ( new LPECloneOriginal(lpeobj) ); break; + case ATTACH_PATH: + neweffect = static_cast ( new LPEAttachPath(lpeobj) ); + break; + case FILL_BETWEEN_STROKES: + neweffect = static_cast ( new LPEFillBetweenStrokes(lpeobj) ); + break; + case FILL_BETWEEN_MANY: + neweffect = static_cast ( new LPEFillBetweenMany(lpeobj) ); + break; + case ELLIPSE_5PTS: + neweffect = static_cast ( new LPEEllipse5Pts(lpeobj) ); + break; + case BOUNDING_BOX: + neweffect = static_cast ( new LPEBoundingBox(lpeobj) ); + break; + case JOIN_TYPE: + neweffect = static_cast ( new LPEJoinType(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-attach-path.cpp b/src/live_effects/lpe-attach-path.cpp new file mode 100644 index 000000000..b3d5ed9b7 --- /dev/null +++ b/src/live_effects/lpe-attach-path.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (C) Johan Engelen 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include "live_effects/lpe-attach-path.h" + +#include "display/curve.h" +#include "sp-item.h" +#include "2geom/path.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "2geom/bezier-curve.h" +#include "2geom/path-sink.h" +#include "parameter/parameter.h" +#include "live_effects/parameter/point.h" +#include "parameter/originalpath.h" +#include "2geom/affine.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEAttachPath::LPEAttachPath(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + start_path(_("Start path:"), _("Path to attach to the start of this path"), "startpath", &wr, this), + start_path_position(_("Start path position:"), _("Position to attach path start to"), "startposition", &wr, this, 0.0), + start_path_curve_start(_("Start path curve start:"), _("Starting curve"), "startcurvestart", &wr, this, Geom::Point(20,0)/*, true*/), + start_path_curve_end(_("Start path curve end:"), _("Ending curve"), "startcurveend", &wr, this, Geom::Point(20,0)/*, true*/), + end_path(_("End path:"), _("Path to attach to the end of this path"), "endpath", &wr, this), + end_path_position(_("End path position:"), _("Position to attach path end to"), "endposition", &wr, this, 0.0), + end_path_curve_start(_("End path curve start:"), _("Starting curve"), "endcurvestart", &wr, this, Geom::Point(20,0)/*, true*/), + end_path_curve_end(_("End path curve end:"), _("Ending curve"), "endcurveend", &wr, this, Geom::Point(20,0)/*, true*/) +{ + registerParameter( dynamic_cast(&start_path) ); + registerParameter( dynamic_cast(&start_path_position) ); + registerParameter( dynamic_cast(&start_path_curve_start) ); + registerParameter( dynamic_cast(&start_path_curve_end) ); + + registerParameter( dynamic_cast(&end_path) ); + registerParameter( dynamic_cast(&end_path_position) ); + registerParameter( dynamic_cast(&end_path_curve_start) ); + registerParameter( dynamic_cast(&end_path_curve_end) ); + + //perceived_path = true; + show_orig_path = true; + curve_start_previous_origin = start_path_curve_end.getOrigin(); + curve_end_previous_origin = end_path_curve_end.getOrigin(); +} + +LPEAttachPath::~LPEAttachPath() +{ + +} + +void LPEAttachPath::resetDefaults(SPItem const * item) +{ + curve_start_previous_origin = start_path_curve_end.getOrigin(); + curve_end_previous_origin = end_path_curve_end.getOrigin(); +} + +void LPEAttachPath::doBeforeEffect(const SPLPEItem *lpeitem) +{ + lpe_effect = lpeitem; +} + +void LPEAttachPath::doEffect (SPCurve * curve) +{ + std::vector this_pathv = curve->get_pathvector(); + if (lpe_effect && !this_pathv.empty()) { + Geom::Path p = Geom::Path(this_pathv.front().initialPoint()); + + bool set_start_end = start_path_curve_end.getOrigin() != curve_start_previous_origin; + bool set_end_end = end_path_curve_end.getOrigin() != curve_end_previous_origin; + + if (start_path.linksToPath()) { + + std::vector linked_pathv = start_path.get_pathvector(); + Geom::Affine linkedtransform = start_path.getObject()->getRelativeTransform(lpe_effect); + + if ( !linked_pathv.empty() ) + { + Geom::Path transformedpath = linked_pathv.front() * linkedtransform; + start_path_curve_start.setOrigin(this_pathv.front().initialPoint()); + + std::vector derivs = this_pathv.front().front().pointAndDerivatives(0, 3); + + for (unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) { + Geom::Coord length = derivs[deriv_n].length(); + if ( ! Geom::are_near(length, 0) ) { + if (set_start_end) { + start_path_position.param_set_value(transformedpath.nearestPoint(start_path_curve_end.getOrigin())); + } + + if (start_path_position > transformedpath.size()) { + start_path_position.param_set_value(transformedpath.size()); + } else if (start_path_position < 0) { + start_path_position.param_set_value(0); + } + const Geom::Curve *c = start_path_position >= transformedpath.size() ? &transformedpath.back() : &transformedpath.at_index((int)start_path_position); + + std::vector derivs_2 = c->pointAndDerivatives(start_path_position >= transformedpath.size() ? 1 : (start_path_position - (int)start_path_position), 3); + for (unsigned deriv_n_2 = 1; deriv_n_2 < derivs_2.size(); deriv_n_2++) { + Geom::Coord length_2 = derivs[deriv_n_2].length(); + if ( ! Geom::are_near(length_2, 0) ) { + start_path_curve_end.setOrigin(derivs_2[0]); + curve_start_previous_origin = start_path_curve_end.getOrigin(); + + double startangle = atan2(start_path_curve_start.getVector().y(), start_path_curve_start.getVector().x()); + double endangle = atan2(start_path_curve_end.getVector().y(), start_path_curve_end.getVector().x()); + double startderiv = atan2(derivs[deriv_n].y(), derivs[deriv_n].x()); + double endderiv = atan2(derivs_2[deriv_n_2].y(), derivs_2[deriv_n_2].x()); + Geom::Point pt1 = Geom::Point(start_path_curve_start.getVector().length() * cos(startangle + startderiv), start_path_curve_start.getVector().length() * sin(startangle + startderiv)); + Geom::Point pt2 = Geom::Point(start_path_curve_end.getVector().length() * cos(endangle + endderiv), start_path_curve_end.getVector().length() * sin(endangle + endderiv)); + p = Geom::Path(derivs_2[0]); + p.appendNew(-pt2 + derivs_2[0], -pt1 + this_pathv.front().initialPoint(), this_pathv.front().initialPoint()); + break; + + } + } + break; + } + } + } + } + + p.append(this_pathv.front()); + + if (end_path.linksToPath()) { + + std::vector linked_pathv = end_path.get_pathvector(); + Geom::Affine linkedtransform = end_path.getObject()->getRelativeTransform(lpe_effect); + + if ( !linked_pathv.empty() ) + { + Geom::Path transformedpath = linked_pathv.front() * linkedtransform; + Geom::Curve * last_seg_reverse = this_pathv.front().back().reverse(); + + end_path_curve_start.setOrigin(last_seg_reverse->initialPoint()); + + std::vector derivs = last_seg_reverse->pointAndDerivatives(0, 3); + for (unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) { + Geom::Coord length = derivs[deriv_n].length(); + if ( ! Geom::are_near(length, 0) ) { + if (set_end_end) { + end_path_position.param_set_value(transformedpath.nearestPoint(end_path_curve_end.getOrigin())); + } + + if (end_path_position > transformedpath.size()) { + end_path_position.param_set_value(transformedpath.size()); + } else if (end_path_position < 0) { + end_path_position.param_set_value(0); + } + const Geom::Curve *c = end_path_position >= transformedpath.size() ? &transformedpath.back() : &transformedpath.at_index((int)end_path_position); + + std::vector derivs_2 = c->pointAndDerivatives(end_path_position >= transformedpath.size() ? 1 : (end_path_position - (int)end_path_position), 3); + for (unsigned deriv_n_2 = 1; deriv_n_2 < derivs_2.size(); deriv_n_2++) { + Geom::Coord length_2 = derivs[deriv_n_2].length(); + if ( ! Geom::are_near(length_2, 0) ) { + + end_path_curve_end.setOrigin(derivs_2[0]); + curve_end_previous_origin = end_path_curve_end.getOrigin(); + + double startangle = atan2(end_path_curve_start.getVector().y(), end_path_curve_start.getVector().x()); + double endangle = atan2(end_path_curve_end.getVector().y(), end_path_curve_end.getVector().x()); + double startderiv = atan2(derivs[deriv_n].y(), derivs[deriv_n].x()); + double endderiv = atan2(derivs_2[deriv_n_2].y(), derivs_2[deriv_n_2].x()); + Geom::Point pt1 = Geom::Point(end_path_curve_start.getVector().length() * cos(startangle + startderiv), end_path_curve_start.getVector().length() * sin(startangle + startderiv)); + Geom::Point pt2 = Geom::Point(end_path_curve_end.getVector().length() * cos(endangle + endderiv), end_path_curve_end.getVector().length() * sin(endangle + endderiv)); + p.appendNew(-pt1 + this_pathv.front().finalPoint(), -pt2 + derivs_2[0], derivs_2[0]); + + break; + + } + } + break; + } + } + delete last_seg_reverse; + } + } + Geom::PathVector outvector; + outvector.push_back(p); + curve->set_pathvector(outvector); + } +} + +} // namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-attach-path.h b/src/live_effects/lpe-attach-path.h new file mode 100644 index 000000000..3dda189d6 --- /dev/null +++ b/src/live_effects/lpe-attach-path.h @@ -0,0 +1,54 @@ +#ifndef INKSCAPE_LPE_ATTACH_PATH_H +#define INKSCAPE_LPE_ATTACH_PATH_H + +/* + * Inkscape::LPEAttachPath + * + * Copyright (C) Ted Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/point.h" +#include "live_effects/parameter/originalpath.h" +#include "live_effects/parameter/vector.h" +#include "live_effects/parameter/bool.h" +#include "live_effects/parameter/transformedpoint.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEAttachPath : public Effect { +public: + LPEAttachPath(LivePathEffectObject *lpeobject); + virtual ~LPEAttachPath(); + + virtual void doBeforeEffect(const SPLPEItem *lpeitem); + virtual void doEffect (SPCurve * curve); + virtual void resetDefaults(SPItem const * item); + +private: + LPEAttachPath(const LPEAttachPath&); + LPEAttachPath& operator=(const LPEAttachPath&); + + Geom::Point curve_start_previous_origin; + Geom::Point curve_end_previous_origin; + + OriginalPathParam start_path; + ScalarParam start_path_position; + TransformedPointParam start_path_curve_start; + VectorParam start_path_curve_end; + + OriginalPathParam end_path; + ScalarParam end_path_position; + TransformedPointParam end_path_curve_start; + VectorParam end_path_curve_end; + const SPLPEItem * lpe_effect; +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape + +#endif diff --git a/src/live_effects/lpe-bounding-box.cpp b/src/live_effects/lpe-bounding-box.cpp new file mode 100644 index 000000000..bafd5e70e --- /dev/null +++ b/src/live_effects/lpe-bounding-box.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "live_effects/lpe-bounding-box.h" + +#include "display/curve.h" +#include "sp-item.h" +#include "2geom/path.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "2geom/bezier-curve.h" +#include "lpe-bounding-box.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEBoundingBox::LPEBoundingBox(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this), + visual_bounds(_("Visual Bounds"), _("Uses the visual bounding box"), "visualbounds", &wr, this) +{ + registerParameter( dynamic_cast(&linked_path) ); + registerParameter( dynamic_cast(&visual_bounds) ); + //perceived_path = true; +} + +LPEBoundingBox::~LPEBoundingBox() +{ + +} + +void LPEBoundingBox::doEffect (SPCurve * curve) +{ + if (curve) { + if ( linked_path.linksToPath() && linked_path.getObject() ) { + SPItem * item = linked_path.getObject(); + Geom::OptRect bbox = visual_bounds.get_value() ? item->visualBounds() : item->geometricBounds(); + Geom::Path p(Geom::Point(bbox->left(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->top())); + p.appendNew(Geom::Point(bbox->right(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->bottom())); + p.appendNew(Geom::Point(bbox->left(), bbox->top())); + std::vector out; + out.push_back(p); + curve->set_pathvector(out); + } + } +} + +} // namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-bounding-box.h b/src/live_effects/lpe-bounding-box.h new file mode 100644 index 000000000..d028a20ac --- /dev/null +++ b/src/live_effects/lpe-bounding-box.h @@ -0,0 +1,37 @@ +#ifndef INKSCAPE_LPE_BOUNDING_BOX_H +#define INKSCAPE_LPE_BOUNDING_BOX_H + +/* + * Inkscape::LPEFillBetweenStrokes + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/originalpath.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEBoundingBox : public Effect { +public: + LPEBoundingBox(LivePathEffectObject *lpeobject); + virtual ~LPEBoundingBox(); + + virtual void doEffect (SPCurve * curve); + +private: + OriginalPathParam linked_path; + BoolParam visual_bounds; + +private: + LPEBoundingBox(const LPEBoundingBox&); + LPEBoundingBox& operator=(const LPEBoundingBox&); +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape + +#endif diff --git a/src/live_effects/lpe-ellipse_5pts.cpp b/src/live_effects/lpe-ellipse_5pts.cpp new file mode 100644 index 000000000..b0a5919fe --- /dev/null +++ b/src/live_effects/lpe-ellipse_5pts.cpp @@ -0,0 +1,214 @@ +/** \file + * LPE "Ellipse through 5 points" implementation + */ + +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-ellipse_5pts.h" + +// You might need to include other 2geom files. You can add them here: +#include +#include <2geom/path.h> +#include <2geom/circle.h> +#include <2geom/ellipse.h> +#include <2geom/path-sink.h> +#include "inkscape.h" +#include "desktop.h" +#include "message-stack.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEEllipse5Pts::LPEEllipse5Pts(LivePathEffectObject *lpeobject) : + Effect(lpeobject) +{ + //perceived_path = true; +} + +LPEEllipse5Pts::~LPEEllipse5Pts() +{ +} + +static double _det3(double (*mat)[3]) +{ + for (int i = 0; i < 2; i++) + { + for (int j = i + 1; j < 3; j++) + { + for (int k = i + 1; k < 3; k++) + { + mat[j][k] = (mat[j][k] * mat[i][i] - mat[j][i] * mat[i][k]); + if (i) mat[j][k] /= mat[i-1][i-1]; + } + } + } + return mat[2][2]; +} +static double _det5(double (*mat)[5]) +{ + for (int i = 0; i < 4; i++) + { + for (int j = i + 1; j < 5; j++) + { + for (int k = i + 1; k < 5; k++) + { + mat[j][k] = (mat[j][k] * mat[i][i] - mat[j][i] * mat[i][k]); + if (i) mat[j][k] /= mat[i-1][i-1]; + } + } + } + return mat[4][4]; +} + +std::vector +LPEEllipse5Pts::doEffect_path (std::vector const & path_in) +{ + std::vector path_out = std::vector(); + + if (path_in[0].size() < 4) { + + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Five points required for constructing an ellipse")); + return path_in; + } + // we assume that the path has >= 3 nodes + Geom::Point A = path_in[0].initialPoint(); + Geom::Point B = path_in[0].pointAt(1); + Geom::Point C = path_in[0].pointAt(2); + Geom::Point D = path_in[0].pointAt(3); + Geom::Point E = path_in[0].pointAt(4); + + using namespace Geom; + + double rowmajor_matrix[5][6] = + { + {A.x()*A.x(), A.x()*A.y(), A.y()*A.y(), A.x(), A.y(), 1}, + {B.x()*B.x(), B.x()*B.y(), B.y()*B.y(), B.x(), B.y(), 1}, + {C.x()*C.x(), C.x()*C.y(), C.y()*C.y(), C.x(), C.y(), 1}, + {D.x()*D.x(), D.x()*D.y(), D.y()*D.y(), D.x(), D.y(), 1}, + {E.x()*E.x(), E.x()*E.y(), E.y()*E.y(), E.x(), E.y(), 1} + }; + + double mat_a[5][5] = + { + {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, + {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, + {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, + {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, + {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} + }; + double mat_b[5][5] = + { + {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, + {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, + {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, + {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, + {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} + }; + double mat_c[5][5] = + { + {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, + {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, + {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, + {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, + {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} + }; + double mat_d[5][5] = + { + {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, + {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, + {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, + {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]}, + {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} + }; + double mat_e[5][5] = + { + {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, + {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, + {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, + {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, + {rowmajor_matrix[0][5], rowmajor_matrix[1][5], rowmajor_matrix[2][5], rowmajor_matrix[3][5], rowmajor_matrix[4][5]} + }; + double mat_f[5][5] = + { + {rowmajor_matrix[0][0], rowmajor_matrix[1][0], rowmajor_matrix[2][0], rowmajor_matrix[3][0], rowmajor_matrix[4][0]}, + {rowmajor_matrix[0][1], rowmajor_matrix[1][1], rowmajor_matrix[2][1], rowmajor_matrix[3][1], rowmajor_matrix[4][1]}, + {rowmajor_matrix[0][2], rowmajor_matrix[1][2], rowmajor_matrix[2][2], rowmajor_matrix[3][2], rowmajor_matrix[4][2]}, + {rowmajor_matrix[0][3], rowmajor_matrix[1][3], rowmajor_matrix[2][3], rowmajor_matrix[3][3], rowmajor_matrix[4][3]}, + {rowmajor_matrix[0][4], rowmajor_matrix[1][4], rowmajor_matrix[2][4], rowmajor_matrix[3][4], rowmajor_matrix[4][4]} + }; + + double a1 = _det5(mat_a); + double b1 = -_det5(mat_b); + double c1 = _det5(mat_c); + double d1 = -_det5(mat_d); + double e1 = _det5(mat_e); + double f1 = -_det5(mat_f); + + double mat_check[][3] = + { + {a1, b1/2, d1/2}, + {b1/2, c1, e1/2}, + {d1/2, e1/2, f1} + }; + + if (_det3(mat_check) == 0 || a1*c1 - b1*b1/4 <= 0) { + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No ellipse found for specified points")); + return path_in; + } + + Geom::Ellipse el(a1, b1, c1, d1, e1, f1); + + double s, e; + double x0, y0, x1, y1, x2, y2, x3, y3; + double len; + + // figure out if we have a slice, guarding against rounding errors + + Path p(Geom::Point(cos(0), sin(0))); + + double end = 2 * M_PI; + for (s = 0; s < end; s += M_PI_2) { + e = s + M_PI_2; + if (e > end) + e = end; + len = 4*tan((e - s)/4)/3; + x0 = cos(s); + y0 = sin(s); + x1 = x0 + len * cos(s + M_PI_2); + y1 = y0 + len * sin(s + M_PI_2); + x3 = cos(e); + y3 = sin(e); + x2 = x3 + len * cos(e - M_PI_2); + y2 = y3 + len * sin(e - M_PI_2); + p.appendNew(Geom::Point(x1,y1), Geom::Point(x2,y2), Geom::Point(x3,y3)); + } + + Geom::Affine aff = Geom::Scale(el.ray(Geom::X), el.ray(Geom::Y)) * Geom::Rotate(el.rot_angle()) * Geom::Translate(el.center()); + + path_out.push_back(p * aff); + + return path_out; +} + +/* ######################## */ + +} //namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-ellipse_5pts.h b/src/live_effects/lpe-ellipse_5pts.h new file mode 100644 index 000000000..d3b1fccfa --- /dev/null +++ b/src/live_effects/lpe-ellipse_5pts.h @@ -0,0 +1,50 @@ +#ifndef INKSCAPE_LPE_ELLIPSE_5PTS_H +#define INKSCAPE_LPE_ELLIPSE_5PTS_H + +/** \file + * LPE "Ellipse through 5 points" implementation + */ + +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/point.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEEllipse5Pts : public Effect { +public: + LPEEllipse5Pts(LivePathEffectObject *lpeobject); + virtual ~LPEEllipse5Pts(); + + virtual std::vector doEffect_path (std::vector const & path_in); + +private: + LPEEllipse5Pts(const LPEEllipse5Pts&); + LPEEllipse5Pts& operator=(const LPEEllipse5Pts&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp new file mode 100644 index 000000000..00cc1fed5 --- /dev/null +++ b/src/live_effects/lpe-fill-between-many.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include "live_effects/lpe-fill-between-many.h" + +#include "display/curve.h" +#include "sp-item.h" +#include "2geom/path.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "2geom/bezier-curve.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEFillBetweenMany::LPEFillBetweenMany(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + linked_paths(_("Linked path:"), _("Paths from which to take the original path data"), "linkedpaths", &wr, this) +{ + registerParameter( dynamic_cast(&linked_paths) ); + //perceived_path = true; +} + +LPEFillBetweenMany::~LPEFillBetweenMany() +{ + +} + +void LPEFillBetweenMany::doEffect (SPCurve * curve) +{ + std::vector res_pathv; + SPItem * firstObj = NULL; + for (std::vector::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); iter++) { + SPObject *obj; + if ((*iter)->ref.isAttached() && (obj = (*iter)->ref.getObject()) && SP_IS_ITEM(obj) && !(*iter)->_pathvector.empty()) { + Geom::Path linked_path; + if ((*iter)->reversed) { + linked_path = (*iter)->_pathvector.front().reverse(); + } else { + linked_path = (*iter)->_pathvector.front(); + } + + if (!res_pathv.empty()) { + linked_path = linked_path * SP_ITEM(obj)->getRelativeTransform(firstObj); + res_pathv.front().appendNew(linked_path.initialPoint()); + res_pathv.front().append(linked_path); + } else { + firstObj = SP_ITEM(obj); + res_pathv.push_back(linked_path); + } + } + } + if (!res_pathv.empty()) { + res_pathv.front().close(); + } + curve->set_pathvector(res_pathv); +} + +} // namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-fill-between-many.h b/src/live_effects/lpe-fill-between-many.h new file mode 100644 index 000000000..99ee8b15f --- /dev/null +++ b/src/live_effects/lpe-fill-between-many.h @@ -0,0 +1,36 @@ +#ifndef INKSCAPE_LPE_FILL_BETWEEN_MANY_H +#define INKSCAPE_LPE_FILL_BETWEEN_MANY_H + +/* + * Inkscape::LPEFillBetweenStrokes + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/originalpatharray.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEFillBetweenMany : public Effect { +public: + LPEFillBetweenMany(LivePathEffectObject *lpeobject); + virtual ~LPEFillBetweenMany(); + + virtual void doEffect (SPCurve * curve); + +private: + OriginalPathArrayParam linked_paths; + +private: + LPEFillBetweenMany(const LPEFillBetweenMany&); + LPEFillBetweenMany& operator=(const LPEFillBetweenMany&); +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape + +#endif diff --git a/src/live_effects/lpe-fill-between-strokes.cpp b/src/live_effects/lpe-fill-between-strokes.cpp new file mode 100644 index 000000000..e72979ed0 --- /dev/null +++ b/src/live_effects/lpe-fill-between-strokes.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "live_effects/lpe-fill-between-strokes.h" + +#include "display/curve.h" +#include "sp-item.h" +#include "2geom/path.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "2geom/bezier-curve.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEFillBetweenStrokes::LPEFillBetweenStrokes(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + linked_path(_("Linked path:"), _("Path from which to take the original path data"), "linkedpath", &wr, this), + second_path(_("Second path:"), _("Second path from which to take the original path data"), "secondpath", &wr, this), + reverse_second(_("Reverse Second"), _("Reverses the second path order"), "reversesecond", &wr, this) +{ + registerParameter( dynamic_cast(&linked_path) ); + registerParameter( dynamic_cast(&second_path) ); + registerParameter( dynamic_cast(&reverse_second) ); + //perceived_path = true; +} + +LPEFillBetweenStrokes::~LPEFillBetweenStrokes() +{ + +} + +void LPEFillBetweenStrokes::doEffect (SPCurve * curve) +{ + if (curve) { + if ( linked_path.linksToPath() && second_path.linksToPath() && linked_path.getObject() && second_path.getObject() ) { + std::vector linked_pathv = linked_path.get_pathvector(); + std::vector second_pathv = second_path.get_pathvector(); + std::vector result_linked_pathv; + std::vector result_second_pathv; + Geom::Affine second_transform = second_path.getObject()->getRelativeTransform(linked_path.getObject()); + + for (std::vector::iterator iter = linked_pathv.begin(); iter != linked_pathv.end(); ++iter) + { + result_linked_pathv.push_back((*iter)); + } + for (std::vector::iterator iter = second_pathv.begin(); iter != second_pathv.end(); ++iter) + { + result_second_pathv.push_back((*iter) * second_transform); + } + + if ( !result_linked_pathv.empty() && !result_second_pathv.empty() && !result_linked_pathv.front().closed() ) { + if (reverse_second.get_value()) + { + result_linked_pathv.front().appendNew(result_second_pathv.front().finalPoint()); + result_linked_pathv.front().append(result_second_pathv.front().reverse()); + } + else + { + result_linked_pathv.front().appendNew(result_second_pathv.front().initialPoint()); + result_linked_pathv.front().append(result_second_pathv.front()); + } + curve->set_pathvector(result_linked_pathv); + } + else if ( !result_linked_pathv.empty() ) { + curve->set_pathvector(result_linked_pathv); + } + else if ( !result_second_pathv.empty() ) { + curve->set_pathvector(result_second_pathv); + } + } + else if ( linked_path.linksToPath() && linked_path.getObject() ) { + std::vector linked_pathv = linked_path.get_pathvector(); + std::vector result_pathv; + + for (std::vector::iterator iter = linked_pathv.begin(); iter != linked_pathv.end(); ++iter) + { + result_pathv.push_back((*iter)); + } + if ( !result_pathv.empty() ) { + curve->set_pathvector(result_pathv); + } + } + else if ( second_path.linksToPath() && second_path.getObject() ) { + std::vector second_pathv = second_path.get_pathvector(); + std::vector result_pathv; + + for (std::vector::iterator iter = second_pathv.begin(); iter != second_pathv.end(); ++iter) + { + result_pathv.push_back((*iter)); + } + if ( !result_pathv.empty() ) { + curve->set_pathvector(result_pathv); + } + } + } +} + +} // namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-fill-between-strokes.h b/src/live_effects/lpe-fill-between-strokes.h new file mode 100644 index 000000000..ec57b1852 --- /dev/null +++ b/src/live_effects/lpe-fill-between-strokes.h @@ -0,0 +1,38 @@ +#ifndef INKSCAPE_LPE_FILL_BETWEEN_STROKES_H +#define INKSCAPE_LPE_FILL_BETWEEN_STROKES_H + +/* + * Inkscape::LPEFillBetweenStrokes + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/originalpath.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEFillBetweenStrokes : public Effect { +public: + LPEFillBetweenStrokes(LivePathEffectObject *lpeobject); + virtual ~LPEFillBetweenStrokes(); + + virtual void doEffect (SPCurve * curve); + +private: + OriginalPathParam linked_path; + OriginalPathParam second_path; + BoolParam reverse_second; + +private: + LPEFillBetweenStrokes(const LPEFillBetweenStrokes&); + LPEFillBetweenStrokes& operator=(const LPEFillBetweenStrokes&); +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape + +#endif diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp new file mode 100644 index 000000000..97c0a1b8a --- /dev/null +++ b/src/live_effects/lpe-jointype.cpp @@ -0,0 +1,203 @@ +/** \file + * LPE "Join Type" implementation + */ + /* Authors: + * + * Liam P White + * + * Copyright (C) 2014 Authors + * + * Released under GNU GPL v2, read the file 'COPYING' for more information + */ + +#include + +#include "sp-shape.h" +#include "style.h" +#include "xml/repr.h" +#include "sp-paint-server.h" +#include "svg/svg-color.h" +#include "desktop-style.h" +#include "svg/css-ostringstream.h" +#include "display/curve.h" +#include "live_effects/parameter/enum.h" + +#include <2geom/path.h> +#include <2geom/svg-elliptical-arc.h> +#include "live_effects/pathoutlineprovider.h" + +#include "lpe-jointype.h" + +namespace Inkscape { +namespace LivePathEffect { + +static const Util::EnumData JoinTypeData[] = { + {LINEJOIN_STRAIGHT, N_("Beveled"), "bevel"}, + {LINEJOIN_ROUND, N_("Rounded"), "round"}, + {LINEJOIN_POINTY, N_("Miter"), "miter"}, + {LINEJOIN_REFLECTED, N_("Reflected"), "extrapolated"}, + {LINEJOIN_EXTRAPOLATED, N_("Extrapolated arc"), "extrp_arc"} +}; + +static const Util::EnumData CapTypeData[] = { + {butt_straight, N_("Butt"), "butt"}, + {butt_round, N_("Rounded"), "round"}, + {butt_square, N_("Square"), "square"}, + {butt_pointy, N_("Peak"), "peak"} +}; + +static const Util::EnumDataConverter CapTypeConverter(CapTypeData, sizeof(CapTypeData)/sizeof(*CapTypeData)); +static const Util::EnumDataConverter JoinTypeConverter(JoinTypeData, sizeof(JoinTypeData)/sizeof(*JoinTypeData)); + +LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + line_width(_("Line width"), _("Thickness of the stroke"), "line_width", &wr, this, 10.), + linecap_type(_("Line cap"), _("The end shape of the stroke"), "linecap_type", CapTypeConverter, &wr, this, butt_straight), + linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", JoinTypeConverter, &wr, this, join_pointy), + miter_limit(_("Miter limit:"), _("Maximum length of the miter join (in units of stroke width)"), "miter_limit", &wr, this, 100.), + attempt_force_join(_("Force miter"), _("Overrides the miter limit and forces a join."), "attempt_force_join", &wr, this, true) +{ + show_orig_path = true; + registerParameter( dynamic_cast(&linecap_type) ); + registerParameter( dynamic_cast(&line_width) ); + registerParameter( dynamic_cast(&linejoin_type) ); + registerParameter( dynamic_cast(&miter_limit) ); + registerParameter( dynamic_cast(&attempt_force_join) ); + was_initialized = false; +} + +LPEJoinType::~LPEJoinType() +{ +} + +//from LPEPowerStroke -- sets fill if stroke color because we will +//be converting to a fill to make the new join. + +void LPEJoinType::doOnApply(SPLPEItem const* lpeitem) +{ + if (SP_IS_SHAPE(lpeitem)) { + SPLPEItem* item = const_cast(lpeitem); + double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed : 1.; + + SPCSSAttr *css = sp_repr_css_attr_new (); + if (lpeitem->style->stroke.isSet()) { + if (lpeitem->style->stroke.isPaintserver()) { + SPPaintServer * server = lpeitem->style->getStrokePaintServer(); + if (server) { + Glib::ustring str; + str += "url(#"; + str += server->getId(); + str += ")"; + sp_repr_css_set_property (css, "fill", str.c_str()); + } + } else if (lpeitem->style->stroke.isColor()) { + gchar c[64]; + sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value))); + sp_repr_css_set_property (css, "fill", c); + } else { + sp_repr_css_set_property (css, "fill", "none"); + } + } else { + sp_repr_css_unset_property (css, "fill"); + } + + sp_repr_css_set_property(css, "stroke", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); + if (!was_initialized) + { + was_initialized = true; + line_width.param_set_value(width); + } + } else { + g_warning("LPE Join Type can only be applied to paths (not groups)."); + } +} + +//from LPEPowerStroke -- sets stroke color from existing fill color + +void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem) +{ + + if (SP_IS_SHAPE(lpeitem)) { + SPLPEItem *item = const_cast(lpeitem); + + SPCSSAttr *css = sp_repr_css_attr_new (); + if (lpeitem->style->fill.isSet()) { + if (lpeitem->style->fill.isPaintserver()) { + SPPaintServer * server = lpeitem->style->getFillPaintServer(); + if (server) { + Glib::ustring str; + str += "url(#"; + str += server->getId(); + str += ")"; + sp_repr_css_set_property (css, "stroke", str.c_str()); + } + } else if (lpeitem->style->fill.isColor()) { + gchar c[64]; + sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value))); + sp_repr_css_set_property (css, "stroke", c); + } else { + sp_repr_css_set_property (css, "stroke", "none"); + } + } else { + sp_repr_css_unset_property (css, "stroke"); + } + + Inkscape::CSSOStringStream os; + os << fabs(line_width); + sp_repr_css_set_property (css, "stroke-width", os.str().c_str()); + + sp_repr_css_set_property(css, "fill", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); + item->updateRepr(); + } +} + + +std::vector LPEJoinType::doEffect_path(std::vector const & path_in) +{ + std::vector path_out = std::vector(); + if (path_in.empty()) + { + return path_out; + } + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + #define miter_lim ( (attempt_force_join) ? std::numeric_limits::max() : fabs(line_width * miter_limit)) + + //magic! + if (linejoin_type.get_value() <= 2) + { + p.Outline(&outlinepath, line_width / 2, static_cast( linejoin_type.get_value() ), + static_cast( linecap_type.get_value() ), miter_lim); + //fix memory leak + std::vector *pv_p = outlinepath.MakePathVector(); + path_out = *pv_p; + delete pv_p; + + } else if (linejoin_type.get_value() == 3) { + //reflected arc join + path_out = Outline::outlinePath(path_in, line_width, static_cast( linejoin_type.get_value() ), + static_cast( linecap_type.get_value() ), miter_lim); + + } else if (linejoin_type.get_value() == 4) { + //extrapolated arc join + path_out = Outline::outlinePath_extr(path_in, line_width, LINEJOIN_STRAIGHT, static_cast(linecap_type.get_value()), miter_lim); + + } + + #undef miter_lim + return path_out; +} + +} //namespace LivePathEffect +} //namespace Inkscape diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h new file mode 100755 index 000000000..db113c66a --- /dev/null +++ b/src/live_effects/lpe-jointype.h @@ -0,0 +1,43 @@ +/* Authors: + * Liam P White + * + * Copyright (C) 2014 Authors + * + * Released under GNU GPL v2, read the file COPYING for more information + */ +#ifndef INKSCAPE_LPE_JOINTYPE_H +#define INKSCAPE_LPE_JOINTYPE_H + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/point.h" +#include "live_effects/parameter/enum.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEJoinType : public Effect { +public: + LPEJoinType(LivePathEffectObject *lpeobject); + virtual ~LPEJoinType(); + + virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void doOnRemove(SPLPEItem const* lpeitem); + virtual std::vector doEffect_path (std::vector const & path_in); + +private: + LPEJoinType(const LPEJoinType&); + LPEJoinType& operator=(const LPEJoinType&); + + ScalarParam line_width; + EnumParam linecap_type; + EnumParam linejoin_type; + ScalarParam miter_limit; + BoolParam attempt_force_join; + bool was_initialized; +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h index 6f5b75af8..f080b06e6 100644 --- a/src/live_effects/lpe-powerstroke-interpolators.h +++ b/src/live_effects/lpe-powerstroke-interpolators.h @@ -27,7 +27,8 @@ enum InterpolatorType { INTERP_LINEAR, INTERP_CUBICBEZIER, INTERP_CUBICBEZIER_JOHAN, - INTERP_SPIRO + INTERP_SPIRO, + INTERP_CUBICBEZIER_SMOOTH }; class Interpolator { @@ -133,6 +134,43 @@ private: CubicBezierJohan& operator=(const CubicBezierJohan&); }; +/// @todo invent name for this class +class CubicBezierSmooth : public Interpolator { +public: + CubicBezierSmooth(double beta = 0.2) { + _beta = beta; + }; + virtual ~CubicBezierSmooth() {}; + + virtual Path interpolateToPath(std::vector const &points) const { + Path fit; + fit.start(points.at(0)); + unsigned int num_points = points.size(); + for (unsigned int i = 1; i < num_points; ++i) { + Point p0 = points.at(i-1); + Point p1 = points.at(i); + Point dx = Point(p1[X] - p0[X], 0); + if (i == 1) { + fit.appendNew(p0, p1-0.75*dx, p1); + } else if (i == points.size() - 1) { + fit.appendNew(p0+0.75*dx, p1, p1); + } else { + fit.appendNew(p0+_beta*dx, p1-_beta*dx, p1); + } + } + return fit; + }; + + void setBeta(double beta) { + _beta = beta; + } + + double _beta; + +private: + CubicBezierSmooth(const CubicBezierSmooth&); + CubicBezierSmooth& operator=(const CubicBezierSmooth&); +}; class SpiroInterpolator : public Interpolator { public: @@ -179,6 +217,8 @@ Interpolator::create(InterpolatorType type) { return new Geom::Interpolate::CubicBezierJohan(); case INTERP_SPIRO: return new Geom::Interpolate::SpiroInterpolator(); + case INTERP_CUBICBEZIER_SMOOTH: + return new Geom::Interpolate::CubicBezierSmooth(); default: return new Geom::Interpolate::Linear(); } diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index acf8ab6a5..f6bc1de65 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -15,6 +15,11 @@ #include "sp-shape.h" #include "style.h" +#include "xml/repr.h" +#include "sp-paint-server.h" +#include "svg/svg-color.h" +#include "desktop-style.h" +#include "svg/css-ostringstream.h" #include "display/curve.h" #include <2geom/path.h> @@ -185,6 +190,7 @@ namespace Inkscape { namespace LivePathEffect { static const Util::EnumData InterpolatorTypeData[] = { + {Geom::Interpolate::INTERP_CUBICBEZIER_SMOOTH, N_("CubicBezierSmooth"), "CubicBezierSmooth"}, {Geom::Interpolate::INTERP_LINEAR , N_("Linear"), "Linear"}, {Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"}, {Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"}, @@ -222,9 +228,7 @@ static const Util::EnumData LineJoinTypeData[] = { {LINEJOIN_EXTRP_MITER, N_("Extrapolated"), "extrapolated"}, {LINEJOIN_MITER, N_("Miter"), "miter"}, {LINEJOIN_SPIRO, N_("Spiro"), "spiro"}, -#ifdef LPE_ENABLE_TEST_EFFECTS {LINEJOIN_EXTRP_MITER_ARC, N_("Extrapolated arc"), "extrp_arc"}, -#endif }; static const Util::EnumDataConverter LineJoinTypeConverter(LineJoinTypeData, sizeof(LineJoinTypeData)/sizeof(*LineJoinTypeData)); @@ -232,12 +236,12 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), offset_points(_("Offset points"), _("Offset points"), "offset_points", &wr, this), sort_points(_("Sort points"), _("Sort offset points according to their time value along the curve"), "sort_points", &wr, this, true), - interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN), + interpolator_type(_("Interpolator type:"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CUBICBEZIER), interpolator_beta(_("Smoothness:"), _("Sets the smoothness for the CubicBezierJohan interpolator; 0 = linear interpolation, 1 = smooth"), "interpolator_beta", &wr, this, 0.2), - start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ROUND), - linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_ROUND), + start_linecap_type(_("Start cap:"), _("Determines the shape of the path's start"), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT), + linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_EXTRP_MITER_ARC), miter_limit(_("Miter limit:"), _("Maximum length of the miter (in units of stroke width)"), "miter_limit", &wr, this, 4.), - end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ROUND) + end_linecap_type(_("End cap:"), _("Determines the shape of the path's end"), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_BUTT) { show_orig_path = true; @@ -266,20 +270,52 @@ void LPEPowerStroke::doOnApply(SPLPEItem const* lpeitem) { if (SP_IS_SHAPE(lpeitem)) { + SPLPEItem* item = const_cast(lpeitem); std::vector points; Geom::PathVector const &pathv = SP_SHAPE(lpeitem)->_curve->get_pathvector(); - double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed : 1.; + double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed / 2 : 1.; + + SPCSSAttr *css = sp_repr_css_attr_new (); + if (lpeitem->style->stroke.isSet()) { + if (lpeitem->style->stroke.isPaintserver()) { + SPPaintServer * server = lpeitem->style->getStrokePaintServer(); + if (server) { + Glib::ustring str; + str += "url(#"; + str += server->getId(); + str += ")"; + sp_repr_css_set_property (css, "fill", str.c_str()); + } + } else if (lpeitem->style->stroke.isColor()) { + gchar c[64]; + sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value))); + sp_repr_css_set_property (css, "fill", c); + } else { + sp_repr_css_set_property (css, "fill", "none"); + } + } else { + sp_repr_css_unset_property (css, "fill"); + } + + sp_repr_css_set_property(css, "stroke", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); + + item->updateRepr(); if (pathv.empty()) { - points.push_back( Geom::Point(0.,width) ); + points.push_back( Geom::Point(0.2,width) ); points.push_back( Geom::Point(0.5,width) ); - points.push_back( Geom::Point(1.,width) ); + points.push_back( Geom::Point(0.8,width) ); } else { Geom::Path const &path = pathv.front(); Geom::Path::size_type const size = path.size_default(); - points.push_back( Geom::Point(0.,width) ); + if (!path.closed()) { + points.push_back( Geom::Point(0.2,width) ); + } points.push_back( Geom::Point(0.5*size,width) ); if (!path.closed()) { - points.push_back( Geom::Point(size,width) ); + points.push_back( Geom::Point(size - 0.2,width) ); } } offset_points.param_set_and_write_new_value(points); @@ -288,6 +324,45 @@ LPEPowerStroke::doOnApply(SPLPEItem const* lpeitem) } } +void LPEPowerStroke::doOnRemove(SPLPEItem const* lpeitem) +{ + if (SP_IS_SHAPE(lpeitem)) { + SPLPEItem *item = const_cast(lpeitem); + SPCSSAttr *css = sp_repr_css_attr_new (); + if (lpeitem->style->fill.isSet()) { + if (lpeitem->style->fill.isPaintserver()) { + SPPaintServer * server = lpeitem->style->getFillPaintServer(); + if (server) { + Glib::ustring str; + str += "url(#"; + str += server->getId(); + str += ")"; + sp_repr_css_set_property (css, "stroke", str.c_str()); + } + } else if (lpeitem->style->fill.isColor()) { + gchar c[64]; + sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value))); + sp_repr_css_set_property (css, "stroke", c); + } else { + sp_repr_css_set_property (css, "stroke", "none"); + } + } else { + sp_repr_css_unset_property (css, "stroke"); + } + + Inkscape::CSSOStringStream os; + os << offset_points.median_width() * 2; + sp_repr_css_set_property (css, "stroke-width", os.str().c_str()); + + sp_repr_css_set_property(css, "fill", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); + + item->updateRepr(); + } +} + void LPEPowerStroke::adjustForNewPath(std::vector const & path_in) { diff --git a/src/live_effects/lpe-powerstroke.h b/src/live_effects/lpe-powerstroke.h index 7bc736820..a773434aa 100644 --- a/src/live_effects/lpe-powerstroke.h +++ b/src/live_effects/lpe-powerstroke.h @@ -25,9 +25,11 @@ public: LPEPowerStroke(LivePathEffectObject *lpeobject); virtual ~LPEPowerStroke(); + virtual std::vector doEffect_path (std::vector const & path_in); virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void doOnRemove(SPLPEItem const* lpeitem); // methods called by path-manipulator upon edits void adjustForNewPath(std::vector const & path_in); diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index efdda686a..37cc3dc62 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -18,10 +18,14 @@ ink_common_sources += \ live_effects/parameter/path.h \ live_effects/parameter/originalpath.cpp \ live_effects/parameter/originalpath.h \ + live_effects/parameter/originalpatharray.cpp \ + live_effects/parameter/originalpatharray.h \ live_effects/parameter/powerstrokepointarray.cpp \ live_effects/parameter/powerstrokepointarray.h \ live_effects/parameter/text.cpp \ live_effects/parameter/text.h \ + live_effects/parameter/transformedpoint.cpp \ + live_effects/parameter/transformedpoint.h \ live_effects/parameter/unit.cpp \ live_effects/parameter/unit.h \ live_effects/parameter/vector.cpp \ diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp new file mode 100644 index 000000000..29e4c409c --- /dev/null +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -0,0 +1,486 @@ +/* + * Copyright (C) Johan Engelen 2008 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/originalpatharray.h" + +#include +#include +#include +#include + +#include + +#include "inkscape.h" +#include "icon-size.h" +#include "widgets/icon.h" +#include "ui/clipboard.h" +#include "svg/svg.h" +#include "svg/stringstream.h" +#include "originalpath.h" +#include "uri.h" +#include "display/curve.h" + +#include +#include <2geom/coord.h> +#include <2geom/point.h> +#include "sp-shape.h" +#include "sp-text.h" +#include "live_effects/effect.h" + +#include "verbs.h" +#include "document-undo.h" +#include "document.h" + +namespace Inkscape { + +namespace LivePathEffect { + +class OriginalPathArrayParam::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colObject); + add(_colLabel); + add(_colReverse); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colReverse; +}; + +OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect ) +: Parameter(label, tip, key, wr, effect), + _vector(), + _tree(), + _text_renderer(), + _toggle_renderer(), + _scroller() +{ + _model = new ModelColumns(); + _store = Gtk::TreeStore::create(*_model); + _tree.set_model(_store); + + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column(_("Name"), *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + _tree.set_search_column(_model->_colLabel); + + Gtk::CellRendererToggle * _toggle_renderer = manage(new Gtk::CellRendererToggle()); + int toggleColNum = _tree.append_column(_("Reverse"), *_toggle_renderer) - 1; + Gtk::TreeViewColumn* col = _tree.get_column(toggleColNum); + _toggle_renderer->set_activatable(true); + _toggle_renderer->signal_toggled().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_reverse_toggled)); + col->add_attribute(_toggle_renderer->property_active(), _model->_colReverse); + + _scroller.add(_tree); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + + oncanvas_editable = true; + +} + +OriginalPathArrayParam::~OriginalPathArrayParam() +{ + while (!_vector.empty()) { + PathAndDirection *w = _vector.back(); + _vector.pop_back(); + unlink(w); + delete w; + } + delete _model; +} + +void OriginalPathArrayParam::on_reverse_toggled(const Glib::ustring& path) +{ + Gtk::TreeModel::iterator iter = _store->get_iter(path); + Gtk::TreeModel::Row row = *iter; + PathAndDirection *w = row[_model->_colObject]; + row[_model->_colReverse] = !row[_model->_colReverse]; + w->reversed = row[_model->_colReverse]; + + gchar * full = param_getSVGValue(); + param_write_to_repr(full); + g_free(full); + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Link path parameter to path")); +} + +void OriginalPathArrayParam::param_set_default() +{ + +} + +Gtk::Widget* OriginalPathArrayParam::param_newWidget() +{ + Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox()); + Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox()); + + vbox->pack_start(_scroller, Gtk::PACK_EXPAND_WIDGET); + + + { // Paste path to link button + Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_PASTE, Inkscape::ICON_SIZE_BUTTON) ); + Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_link_button_click)); + hbox->pack_start(*pButton, Gtk::PACK_SHRINK); + pButton->set_tooltip_text(_("Link to path")); + } + + { // Remove linked path + Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_REMOVE, Inkscape::ICON_SIZE_BUTTON) ); + Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_remove_button_click)); + hbox->pack_start(*pButton, Gtk::PACK_SHRINK); + pButton->set_tooltip_text(_("Remove Path")); + } + + { // Move Down + Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_GO_DOWN, Inkscape::ICON_SIZE_BUTTON) ); + Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_down_button_click)); + hbox->pack_end(*pButton, Gtk::PACK_SHRINK); + pButton->set_tooltip_text(_("Move Down")); + } + + { // Move Down + Gtk::Widget *pIcon = Gtk::manage( sp_icon_get_icon( GTK_STOCK_GO_UP, Inkscape::ICON_SIZE_BUTTON) ); + Gtk::Button *pButton = Gtk::manage(new Gtk::Button()); + pButton->set_relief(Gtk::RELIEF_NONE); + pIcon->show(); + pButton->add(*pIcon); + pButton->show(); + pButton->signal_clicked().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_up_button_click)); + hbox->pack_end(*pButton, Gtk::PACK_SHRINK); + pButton->set_tooltip_text(_("Move Up")); + } + + vbox->pack_end(*hbox, Gtk::PACK_SHRINK); + + vbox->show_all_children(true); + + return vbox; +} + +bool OriginalPathArrayParam::_selectIndex(const Gtk::TreeIter& iter, int* i) +{ + if ((*i)-- <= 0) { + _tree.get_selection()->select(iter); + return true; + } + return false; +} + +void OriginalPathArrayParam::on_up_button_click() +{ + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + + int i = -1; + std::vector::iterator piter = _vector.begin(); + for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, iter++) { + if (*iter == row[_model->_colObject]) { + _vector.erase(iter); + _vector.insert(piter, row[_model->_colObject]); + break; + } + } + + gchar * full = param_getSVGValue(); + param_write_to_repr(full); + g_free(full); + + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Move path up")); + + _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_selectIndex), &i)); + } +} + +void OriginalPathArrayParam::on_down_button_click() +{ + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + + int i = 0; + for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); i++, iter++) { + if (*iter == row[_model->_colObject]) { + std::vector::iterator niter = _vector.erase(iter); + if (niter != _vector.end()) { + niter++; + i++; + } + _vector.insert(niter, row[_model->_colObject]); + break; + } + } + + gchar * full = param_getSVGValue(); + param_write_to_repr(full); + g_free(full); + + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Move path down")); + + _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_selectIndex), &i)); + } +} + +void OriginalPathArrayParam::on_remove_button_click() +{ + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + remove_link(row[_model->_colObject]); + + gchar * full = param_getSVGValue(); + param_write_to_repr(full); + g_free(full); + + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Remove path")); + } + +} + +void +OriginalPathArrayParam::on_link_button_click() +{ + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + Glib::ustring pathid = cm->getShapeOrTextObjectId(SP_ACTIVE_DESKTOP); + + if (pathid == "") { + return; + } + // add '#' at start to make it an uri. + pathid.insert(pathid.begin(), '#'); + + Inkscape::SVGOStringStream os; + bool foundOne = false; + for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + if (foundOne) { + os << "|"; + } else { + foundOne = true; + } + os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0"); + } + + if (foundOne) { + os << "|"; + } + + os << pathid.c_str() << ",0"; + + param_write_to_repr(os.str().c_str()); + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Link path parameter to path")); +} + +void OriginalPathArrayParam::unlink(PathAndDirection* to) +{ + to->linked_modified_connection.disconnect(); + to->linked_delete_connection.disconnect(); + to->ref.detach(); + to->_pathvector = Geom::PathVector(); + if (to->href) { + g_free(to->href); + to->href = NULL; + } +} + +void OriginalPathArrayParam::remove_link(PathAndDirection* to) +{ + unlink(to); + for (std::vector::iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + if (*iter == to) { + PathAndDirection *w = *iter; + _vector.erase(iter); + delete w; + return; + } + } +} + +void OriginalPathArrayParam::linked_delete(SPObject */*deleted*/, PathAndDirection* to) +{ + //remove_link(to); + + gchar * full = param_getSVGValue(); + param_write_to_repr(full); + g_free(full); +} + +bool OriginalPathArrayParam::_updateLink(const Gtk::TreeIter& iter, PathAndDirection* pd) +{ + Gtk::TreeModel::Row row = *iter; + if (row[_model->_colObject] == pd) { + SPObject *obj = pd->ref.getObject(); + row[_model->_colLabel] = obj && obj->getId() ? ( obj->label() ? obj->label() : obj->getId() ) : pd->href; + return true; + } + return false; +} + +void OriginalPathArrayParam::linked_changed(SPObject */*old_obj*/, SPObject *new_obj, PathAndDirection* to) +{ + to->linked_delete_connection.disconnect(); + to->linked_modified_connection.disconnect(); + to->linked_transformed_connection.disconnect(); + + if (new_obj && SP_IS_ITEM(new_obj)) { + to->linked_delete_connection = new_obj->connectDelete(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_delete), to)); + to->linked_modified_connection = new_obj->connectModified(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_modified), to)); + to->linked_transformed_connection = SP_ITEM(new_obj)->connectTransformed(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_transformed), to)); + + linked_modified(new_obj, SP_OBJECT_MODIFIED_FLAG, to); + } else { + to->_pathvector = Geom::PathVector(); + SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); + _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); + } +} + +void OriginalPathArrayParam::linked_transformed(Geom::Affine const *mp, SPItem* original, PathAndDirection* to) +{ + +} + +void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint flags, PathAndDirection* to) +{ + if (!to) { + return; + } + SPCurve *curve = NULL; + if (SP_IS_SHAPE(linked_obj)) { + curve = SP_SHAPE(linked_obj)->getCurveBeforeLPE(); + } + if (SP_IS_TEXT(linked_obj)) { + curve = SP_TEXT(linked_obj)->getNormalizedBpath(); + } + + if (curve == NULL) { + // curve invalid, set empty pathvector + to->_pathvector = Geom::PathVector(); + } else { + to->_pathvector = curve->get_pathvector(); + curve->unref(); + } +} + +void OriginalPathArrayParam::linked_modified(SPObject *linked_obj, guint flags, PathAndDirection* to) +{ + if (!to) { + return; + } + setPathVector(linked_obj, flags, to); + SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); + _store->foreach_iter(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); +} + +//void PathParam::linked_transformed(Geom::Affine const *rel_transf, SPItem *moved_item) +//{ +// linked_transformed_callback(rel_transf, moved_item); +//} + +bool OriginalPathArrayParam::param_readSVGValue(const gchar* strvalue) +{ + if (strvalue) { + while (!_vector.empty()) { + PathAndDirection *w = _vector.back(); + unlink(w); + _vector.pop_back(); + delete w; + } + _store->clear(); + + gchar ** strarray = g_strsplit(strvalue, "|", 0); + for (gchar ** iter = strarray; *iter != NULL; iter++) { + if ((*iter)[0] == '#') { + gchar ** substrarray = g_strsplit(*iter, ",", 0); + PathAndDirection* w = new PathAndDirection((SPObject *)param_effect->getLPEObj()); + w->href = g_strdup(*substrarray); + w->reversed = *(substrarray+1) != NULL && (*(substrarray+1))[0] == '1'; + + w->linked_changed_connection = w->ref.changedSignal().connect(sigc::bind(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_changed), w)); + w->ref.attach(URI(w->href)); + + _vector.push_back(w); + + Gtk::TreeModel::iterator iter = _store->append(); + Gtk::TreeModel::Row row = *iter; + SPObject *obj = w->ref.getObject(); + + row[_model->_colObject] = w; + row[_model->_colLabel] = obj ? ( obj->label() ? obj->label() : obj->getId() ) : w->href; + row[_model->_colReverse] = w->reversed; + g_strfreev (substrarray); + } + } + g_strfreev (strarray); + return true; + } + return false; +} + +gchar * OriginalPathArrayParam::param_getSVGValue() const +{ + Inkscape::SVGOStringStream os; + bool foundOne = false; + for (std::vector::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + if (foundOne) { + os << "|"; + } else { + foundOne = true; + } + os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0"); + } + gchar * str = g_strdup(os.str().c_str()); + return str; +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/originalpatharray.h b/src/live_effects/parameter/originalpatharray.h new file mode 100644 index 000000000..865a3f8e5 --- /dev/null +++ b/src/live_effects/parameter/originalpatharray.h @@ -0,0 +1,123 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINALPATHARRAY_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_ORIGINALPATHARRAY_H + +/* + * Inkscape::LivePathEffectParameters + * +* Copyright (C) Johan Engelen 2008 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include +#include +#include +#include + +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/path-reference.h" + +#include "svg/svg.h" +#include "svg/stringstream.h" +#include "path-reference.h" +#include "sp-object.h" + +namespace Inkscape { + +namespace LivePathEffect { + +class PathAndDirection { +public: + PathAndDirection(SPObject *owner) + : href(NULL), + ref(owner), + _pathvector(Geom::PathVector()), + reversed(false) + { + + } + gchar *href; + URIReference ref; + //SPItem *obj; + std::vector _pathvector; + bool reversed; + + sigc::connection linked_changed_connection; + sigc::connection linked_delete_connection; + sigc::connection linked_modified_connection; + sigc::connection linked_transformed_connection; +}; + +class OriginalPathArrayParam : public Parameter { +public: + class ModelColumns; + + OriginalPathArrayParam( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect); + + virtual ~OriginalPathArrayParam(); + + virtual Gtk::Widget * param_newWidget(); + virtual bool param_readSVGValue(const gchar * strvalue); + virtual gchar * param_getSVGValue() const; + virtual void param_set_default(); + + /** Disable the canvas indicators of parent class by overriding this method */ + virtual void param_editOncanvas(SPItem * /*item*/, SPDesktop * /*dt*/) {}; + /** Disable the canvas indicators of parent class by overriding this method */ + virtual void addCanvasIndicators(SPLPEItem const* /*lpeitem*/, std::vector & /*hp_vec*/) {}; + + std::vector _vector; + +protected: + bool _updateLink(const Gtk::TreeIter& iter, PathAndDirection* pd); + bool _selectIndex(const Gtk::TreeIter& iter, int* i); + void unlink(PathAndDirection* to); + void remove_link(PathAndDirection* to); + void setPathVector(SPObject *linked_obj, guint flags, PathAndDirection* to); + + void linked_changed(SPObject *old_obj, SPObject *new_obj, PathAndDirection* to); + void linked_modified(SPObject *linked_obj, guint flags, PathAndDirection* to); + void linked_transformed(Geom::Affine const *mp, SPItem *original, PathAndDirection* to); + void linked_delete(SPObject *deleted, PathAndDirection* to); + + ModelColumns *_model; + Glib::RefPtr _store; + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::CellRendererToggle *_toggle_renderer; + Gtk::TreeView::Column *_name_column; + Gtk::ScrolledWindow _scroller; + + void on_link_button_click(); + void on_remove_button_click(); + void on_up_button_click(); + void on_down_button_click(); + void on_reverse_toggled(const Glib::ustring& path); + +private: + OriginalPathArrayParam(const OriginalPathArrayParam&); + OriginalPathArrayParam& operator=(const OriginalPathArrayParam&); +}; + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/powerstrokepointarray.cpp b/src/live_effects/parameter/powerstrokepointarray.cpp index fecdfeda8..ac0000b1a 100644 --- a/src/live_effects/parameter/powerstrokepointarray.cpp +++ b/src/live_effects/parameter/powerstrokepointarray.cpp @@ -6,6 +6,7 @@ #include +#include "ui/dialog/lpe-powerstroke-properties.h" #include "live_effects/parameter/powerstrokepointarray.h" #include "live_effects/effect.h" @@ -102,6 +103,23 @@ PowerStrokePointArrayParam::recalculate_controlpoints_for_new_pwd2(Geom::Piecewi } } +float PowerStrokePointArrayParam::median_width() +{ + size_t size = _vector.size(); + if (size > 0) + { + if (size % 2 == 0) + { + return (_vector[size / 2 - 1].y() + _vector[size / 2].y()) / 2; + } + else + { + return _vector[size / 2].y(); + } + } + return 1; +} + void PowerStrokePointArrayParam::set_pwd2(Geom::Piecewise > const & pwd2_in, Geom::Piecewise > const & pwd2_normal_in) { @@ -117,7 +135,7 @@ PowerStrokePointArrayParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotMode knot_mode = mode; knot_color = color; } - +/* class PowerStrokePointArrayParamKnotHolderEntity : public KnotHolderEntity { public: PowerStrokePointArrayParamKnotHolderEntity(PowerStrokePointArrayParam *p, unsigned int index); @@ -127,7 +145,7 @@ public: virtual Geom::Point knot_get() const; virtual void knot_click(guint state); - /** Checks whether the index falls within the size of the parameter's vector */ + /** Checks whether the index falls within the size of the parameter's vector / bool valid_index(unsigned int index) const { return (_pparam->_vector.size() > index); }; @@ -135,7 +153,7 @@ public: private: PowerStrokePointArrayParam *_pparam; unsigned int _index; -}; +};*/ PowerStrokePointArrayParamKnotHolderEntity::PowerStrokePointArrayParamKnotHolderEntity(PowerStrokePointArrayParam *p, unsigned int index) : _pparam(p), @@ -181,6 +199,12 @@ PowerStrokePointArrayParamKnotHolderEntity::knot_get() const return canvas_point; } +void PowerStrokePointArrayParamKnotHolderEntity::knot_set_offset(Geom::Point offset) +{ + _pparam->_vector.at(_index) = Geom::Point(offset.x(), offset.y() / 2); + this->parent_holder->knot_ungrabbed_handler(this->knot); +} + void PowerStrokePointArrayParamKnotHolderEntity::knot_click(guint state) { @@ -223,10 +247,15 @@ PowerStrokePointArrayParamKnotHolderEntity::knot_click(guint state) // add knot to knotholder PowerStrokePointArrayParamKnotHolderEntity *e = new PowerStrokePointArrayParamKnotHolderEntity(_pparam, _index+1); e->create( this->desktop, this->item, parent_holder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Stroke width control point: drag to alter the stroke width. Ctrl+click adds a control point, Ctrl+Alt+click deletes it."), + _("Stroke width control point: drag to alter the stroke width. Ctrl+click adds a control point, Ctrl+Alt+click deletes it, Shift+click launches width dialog."), _pparam->knot_shape, _pparam->knot_mode, _pparam->knot_color); parent_holder->add(e); } + } + else if ((state & GDK_MOD1_MASK) || (state & GDK_SHIFT_MASK)) + { + Geom::Point offset = Geom::Point(_pparam->_vector.at(_index).x(), _pparam->_vector.at(_index).y() * 2); + Inkscape::UI::Dialogs::PowerstrokePropertiesDialog::showDialog(this->desktop, offset, this); } } @@ -235,7 +264,7 @@ void PowerStrokePointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, S for (unsigned int i = 0; i < _vector.size(); ++i) { PowerStrokePointArrayParamKnotHolderEntity *e = new PowerStrokePointArrayParamKnotHolderEntity(this, i); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Stroke width control point: drag to alter the stroke width. Ctrl+click adds a control point, Ctrl+Alt+click deletes it."), + _("Stroke width control point: drag to alter the stroke width. Ctrl+click adds a control point, Ctrl+Alt+click deletes it, Shift+click launches width dialog."), knot_shape, knot_mode, knot_color); knotholder->add(e); } diff --git a/src/live_effects/parameter/powerstrokepointarray.h b/src/live_effects/parameter/powerstrokepointarray.h index e1fa440f2..911bbc82d 100644 --- a/src/live_effects/parameter/powerstrokepointarray.h +++ b/src/live_effects/parameter/powerstrokepointarray.h @@ -20,8 +20,6 @@ namespace Inkscape { namespace LivePathEffect { -class PowerStrokePointArrayParamKnotHolderEntity; - class PowerStrokePointArrayParam : public ArrayParam { public: PowerStrokePointArrayParam( const Glib::ustring& label, @@ -37,6 +35,8 @@ public: void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + float median_width(); + virtual bool providesKnotHolderEntities() const { return true; } virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); @@ -60,6 +60,25 @@ private: Geom::Piecewise > last_pwd2_normal; }; +class PowerStrokePointArrayParamKnotHolderEntity : public KnotHolderEntity { +public: + PowerStrokePointArrayParamKnotHolderEntity(PowerStrokePointArrayParam *p, unsigned int index); + virtual ~PowerStrokePointArrayParamKnotHolderEntity() {} + + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + virtual void knot_set_offset(Geom::Point offset); + virtual void knot_click(guint state); + + /** Checks whether the index falls within the size of the parameter's vector */ + bool valid_index(unsigned int index) const { + return (_pparam->_vector.size() > index); + }; + +private: + PowerStrokePointArrayParam *_pparam; + unsigned int _index; +}; } //namespace LivePathEffect diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp new file mode 100644 index 000000000..f5b01e267 --- /dev/null +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -0,0 +1,182 @@ +/* + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "ui/widget/registered-widget.h" +#include "live_effects/parameter/transformedpoint.h" +#include "sp-lpe-item.h" +#include "knotholder.h" +#include "svg/svg.h" +#include "svg/stringstream.h" + +#include "live_effects/effect.h" +#include "desktop.h" +#include "verbs.h" + +namespace Inkscape { + +namespace LivePathEffect { + +TransformedPointParam::TransformedPointParam( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, + Effect* effect, Geom::Point default_vector, + bool dontTransform) + : Parameter(label, tip, key, wr, effect), + defvalue(default_vector), + origin(0.,0.), + vector(default_vector), + noTransform(dontTransform) +{ + vec_knot_shape = SP_KNOT_SHAPE_DIAMOND; + vec_knot_mode = SP_KNOT_MODE_XOR; + vec_knot_color = 0xffffb500; +} + +TransformedPointParam::~TransformedPointParam() +{ + +} + +void +TransformedPointParam::param_set_default() +{ + setOrigin(Geom::Point(0.,0.)); + setVector(defvalue); +} + +bool +TransformedPointParam::param_readSVGValue(const gchar * strvalue) +{ + gchar ** strarray = g_strsplit(strvalue, ",", 4); + if (!strarray) { + return false; + } + double val[4]; + unsigned int i = 0; + while (i < 4 && strarray[i]) { + if (sp_svg_number_read_d(strarray[i], &val[i]) != 0) { + i++; + } else { + break; + } + } + g_strfreev (strarray); + if (i == 4) { + setOrigin( Geom::Point(val[0], val[1]) ); + setVector( Geom::Point(val[2], val[3]) ); + return true; + } + return false; +} + +gchar * +TransformedPointParam::param_getSVGValue() const +{ + Inkscape::SVGOStringStream os; + os << origin << " , " << vector; + gchar * str = g_strdup(os.str().c_str()); + return str; +} + +Gtk::Widget * +TransformedPointParam::param_newWidget() +{ + Inkscape::UI::Widget::RegisteredVector * pointwdg = Gtk::manage( + new Inkscape::UI::Widget::RegisteredVector( param_label, + param_tooltip, + param_key, + *param_wr, + param_effect->getRepr(), + param_effect->getSPDoc() ) ); + pointwdg->setPolarCoords(); + pointwdg->setValue( vector, origin ); + pointwdg->clearProgrammatically(); + pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change vector parameter")); + + Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); + static_cast(hbox)->pack_start(*pointwdg, true, true); + static_cast(hbox)->show_all_children(); + + return dynamic_cast (hbox); +} + +void +TransformedPointParam::set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector) +{ + setValues(new_origin, new_vector); + gchar * str = param_getSVGValue(); + param_write_to_repr(str); + g_free(str); +} + +void +TransformedPointParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) +{ + if (!noTransform) { + set_and_write_new_values( origin * postmul, vector * postmul.withoutTranslation() ); + } +} + + +void +TransformedPointParam::set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) +{ + vec_knot_shape = shape; + vec_knot_mode = mode; + vec_knot_color = color; +} + +void +TransformedPointParam::set_oncanvas_color(guint32 color) +{ + vec_knot_color = color; +} + +class TransformedPointParamKnotHolderEntity_Vector : public KnotHolderEntity { +public: + TransformedPointParamKnotHolderEntity_Vector(TransformedPointParam *p) : param(p) { } + virtual ~TransformedPointParamKnotHolderEntity_Vector() {} + + virtual void knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) { + Geom::Point const s = p - param->origin; + /// @todo implement angle snapping when holding CTRL + param->setVector(s); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + }; + virtual Geom::Point knot_get() const{ + return param->origin + param->vector; + }; + virtual void knot_click(guint /*state*/){ + g_print ("This is the vector handle associated to parameter '%s'\n", param->param_key.c_str()); + }; + +private: + TransformedPointParam *param; +}; + +void +TransformedPointParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + TransformedPointParamKnotHolderEntity_Vector *vector_e = new TransformedPointParamKnotHolderEntity_Vector(this); + vector_e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, handleTip(), vec_knot_shape, vec_knot_mode, vec_knot_color); + knotholder->add(vector_e); +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/transformedpoint.h b/src/live_effects/parameter/transformedpoint.h new file mode 100644 index 000000000..37af8b98f --- /dev/null +++ b/src/live_effects/parameter/transformedpoint.h @@ -0,0 +1,87 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_TRANSFORMED_POINT_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_TRANSFORMED_POINT_H + +/* + * Inkscape::LivePathEffectParameters + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include <2geom/point.h> + +#include "live_effects/parameter/parameter.h" + +#include "knot-holder-entity.h" + +namespace Inkscape { + +namespace LivePathEffect { + + +class TransformedPointParam : public Parameter { +public: + TransformedPointParam( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + Geom::Point default_vector = Geom::Point(1,0), + bool dontTransform = false); + virtual ~TransformedPointParam(); + + virtual Gtk::Widget * param_newWidget(); + inline const gchar *handleTip() const { return param_tooltip.c_str(); } + + virtual bool param_readSVGValue(const gchar * strvalue); + virtual gchar * param_getSVGValue() const; + + Geom::Point getVector() const { return vector; }; + Geom::Point getOrigin() const { return origin; }; + void setValues(Geom::Point const &new_origin, Geom::Point const &new_vector) { setVector(new_vector); setOrigin(new_origin); }; + void setVector(Geom::Point const &new_vector) { vector = new_vector; }; + void setOrigin(Geom::Point const &new_origin) { origin = new_origin; }; + virtual void param_set_default(); + + void set_and_write_new_values(Geom::Point const &new_origin, Geom::Point const &new_vector); + + virtual void param_transform_multiply(Geom::Affine const &postmul, bool set); + + void set_vector_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + //void set_origin_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + void set_oncanvas_color(guint32 color); + + virtual bool providesKnotHolderEntities() const { return true; } + virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); + +private: + TransformedPointParam(const TransformedPointParam&); + TransformedPointParam& operator=(const TransformedPointParam&); + + Geom::Point defvalue; + + Geom::Point origin; + Geom::Point vector; + + bool noTransform; + + /// The looks of the vector and origin knots oncanvas + SPKnotShapeType vec_knot_shape; + SPKnotModeType vec_knot_mode; + guint32 vec_knot_color; +// SPKnotShapeType ori_knot_shape; +// SPKnotModeType ori_knot_mode; +// guint32 ori_knot_color; + +// friend class VectorParamKnotHolderEntity_Origin; + friend class TransformedPointParamKnotHolderEntity_Vector; +}; + + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h new file mode 100755 index 000000000..8aa2e38ad --- /dev/null +++ b/src/live_effects/pathoutlineprovider.h @@ -0,0 +1,766 @@ +#pragma once + +#include <2geom/path.h> +#include <2geom/circle.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/shape.h> +#include <2geom/transforms.h> +#include <2geom/path-sink.h> + +#include +#include + +enum LineJoinType { + LINEJOIN_STRAIGHT, + LINEJOIN_ROUND, + LINEJOIN_POINTY, + LINEJOIN_REFLECTED, + LINEJOIN_EXTRAPOLATED +}; + +namespace Geom +{ + /** + * Refer to: Weisstein, Eric W. "Circle-Circle Intersection." + From MathWorld--A Wolfram Web Resource. + http://mathworld.wolfram.com/Circle-CircleIntersection.html + * + * @return 0 if no intersection + * @return 1 if one circle is contained in the other + * @return 2 if intersections are found (they are written to p0 and p1) + */ + static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, + Point & p0, Point & p1) + { + Point X0 = circle0.center(); + double r0 = circle0.ray(); + Point X1 = circle1.center(); + double r1 = circle1.ray(); + + /* dx and dy are the vertical and horizontal distances between + * the circle centers. + */ + Point D = X1 - X0; + + /* Determine the straight-line distance between the centers. */ + double d = L2(D); + + /* Check for solvability. */ + if (d > (r0 + r1)) + { + /* no solution. circles do not intersect. */ + return 0; + } + if (d <= fabs(r0 - r1)) + { + /* no solution. one circle is contained in the other */ + return 1; + } + + /* 'point 2' is the point where the line through the circle + * intersection points crosses the line between the circle + * centers. + */ + + /* Determine the distance from point 0 to point 2. */ + double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; + + /* Determine the coordinates of point 2. */ + Point p2 = X0 + D * (a/d); + + /* Determine the distance from point 2 to either of the + * intersection points. + */ + double h = std::sqrt((r0*r0) - (a*a)); + + /* Now determine the offsets of the intersection points from + * point 2. + */ + Point r = (h/d)*rot90(D); + + /* Determine the absolute intersection points. */ + p0 = p2 + r; + p1 = p2 - r; + + return 2; + } + /** + * Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t. + * Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt). + */ + static Circle touching_circle( D2 const &curve, double t, double tol=0.01 ) + { + D2 dM=derivative(curve); + if ( are_near(L2sq(dM(t)),0.) ) { + dM=derivative(dM); + } + if ( are_near(L2sq(dM(t)),0.) ) { // try second time + dM=derivative(dM); + } + Piecewise > unitv = unitVector(dM,tol); + Piecewise dMlength = dot(Piecewise >(dM),unitv); + Piecewise k = cross(derivative(unitv),unitv); + k = divide(k,dMlength,tol,3); + double curv = k(t); // note that this value is signed + + Geom::Point normal = unitTangentAt(curve, t).cw(); + double radius = 1/curv; + Geom::Point center = curve(t) + radius*normal; + return Geom::Circle(center, fabs(radius)); + } + + static std::vector split_at_cusps(const Geom::Path& in) + { + Geom::PathVector out = Geom::PathVector(); + Geom::Path temp = Geom::Path(); + + for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) + { + temp = Geom::Path(); + temp.append(in[path_descr]); + out.push_back(temp); + } + + return out; + } + + static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) + { + std::vector temp; + sbasis_to_bezier(temp, sbasis_in, 4); + return Geom::CubicBezier( temp ); + } + + static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, + Geom::Point const & origin_b, Geom::Point const & vector_b) + { + Geom::Coord denom = cross(vector_b, vector_a); + if (!Geom::are_near(denom,0.)){ + Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom; + return origin_a + t * vector_a; + } + return boost::none; + } +} + +namespace Outline +{ + + typedef Geom::D2 D2SB; + typedef Geom::Piecewise PWD2; + + static void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve*cbc2, Geom::Point endPt, double miter_limit) +{ + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + if (cross.empty()) + { + Geom::Path pth; + pth.append(*cbc1); + + Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); + + pth = Geom::Path(); + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + + Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.); + Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0); + + Geom::Point points[2]; + int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]); + if (solutions == 2) + { + Geom::Point sol(0,0); + if ( dot(tang2,points[0]-endPt) > 0 ) + { + // points[0] is bad, choose points[1] + sol = points[1]; + } + else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1] + // points[1] is bad, choose points[0] + sol = points[0]; + } + else + { + // both points are good, choose nearest + sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? + points[0] : points[1]; + } + Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true); + Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true); + + if (arc0) + { + path_builder.append (arc0->toSBasis()); + delete arc0; + arc0 = NULL; + } + + if (arc1) + { + path_builder.append (arc1->toSBasis()); + delete arc1; + arc1 = NULL; + } + } + else + { + path_builder.appendNew (endPt); + } + } + else + { + path_builder.appendNew (endPt); + } +} + static Geom::Path half_outline_extrp(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) + { + Geom::PathVector pv = split_at_cusps(path_in); + unsigned m; + Path path_outline = Path(); + Path path_tangent = Path(); + + Geom::Point initialPoint; + Geom::Point endPoint; + + Geom::Path path_builder = Geom::Path(); + Geom::PathVector * pathvec; + + //load the first portion in before the loop starts + { + path_outline = Path(); + path_outline.LoadPath(pv[0], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + //now half of first cusp has been loaded + + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + //instead of array accessing twice, dereferencing used for clarity + initialPoint = (*pathvec)[0].initialPoint(); + + path_builder.start(initialPoint); + path_builder.append( (*pathvec)[0] ); + + path_outline = Path(); + path_outline.LoadPath(pv[1], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + + path_builder.append( (*pathvec)[0] ); + + //always set pointers null after deleting + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + for (m = 2; m < pv.size(); m++) + { + path_outline = Path(); + path_outline.LoadPath(pv[m], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + path_builder.append( (*pathvec)[0] ); + + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + return path_builder; + } + + //Create a reflected outline join. + //Note: it is generally recommended to let half_outline do this for you! + //path_builder: the path to append the curves to + //cbc1: the curve before the join + //cbc2: the curve after the join + //endPt: the point to end at + //miter_limit: the miter parameter + static void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit) + { + //the most important work for the reflected join is done here + + //determine where we are in the path. If we're on the inside, ignore + //and just lineTo. On the outside, we'll do a little reflection magic :) + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + if (cross.empty()) + { + //probably on the outside of the corner + Geom::Path pth; + pth.append(*cbc1); + + Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); + + //reflect curves along the bevel + D2SB newcurve1 = pth.toPwSb()[0] * + Geom::reflection ( -Geom::rot90(tang1) , + cbc1->finalPoint() ); + + Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1)); + + pth = Geom::Path(); + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + D2SB newcurve2 = pth.toPwSb()[0] * + Geom::reflection ( -Geom::rot90(tang2) , + cbc2->initialPoint() ); + Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2)); + + cross = Geom::crossings(bzr1, bzr2); + if ( cross.empty() ) + { + //std::cout << "Oops, no crossings!" << std::endl; + //curves didn't cross; default to miter + /*boost::optional p = intersection_point (cbc1->finalPoint(), tang1, + cbc2->initialPoint(), tang2); + if (p) + { + path_builder.appendNew (*p); + }*/ + //bevel + path_builder.appendNew( endPt ); + } + else + { + //join + std::pair sub1 = bzr1.subdivide(cross[0].ta); + std::pair sub2 = bzr2.subdivide(cross[0].tb); + + //@TODO joins have a strange tendency to cross themselves twice. Check this. + + //sections commented out are for general stability + path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); + path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); + } + } + else // cross.empty() + { + //probably on the inside of the corner + path_builder.appendNew ( endPt ); + } + } + + /** @brief Converts a path to one half of an outline. + * path_in: The input path to use. (To create the other side use path_in.reverse() ) + * line_width: the line width to use (usually you want to divide this by 2) + * linecap_type: (not used here) the cap to apply. Passed to libvarot. + * miter_limit: the miter parameter + */ + static Geom::Path half_outline(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) + { + Geom::PathVector pv = split_at_cusps(path_in); + unsigned m; + Path path_outline = Path(); + Path path_tangent = Path(); + //needed for closing the path + Geom::Point initialPoint; + Geom::Point endPoint; + + //some issues prevented me from using a PathBuilder here + //it seems like PathBuilder::peek() gave me a null reference exception + //and I was unable to get a stack trace on Windows, so had to switch to Linux + //to see what the hell was wrong. :( + //I wasted five hours opening it in IDAPro, VS2012, and GDB Windows + + /*Program received signal SIGSEGV, Segmentation fault. + 0x00000000006539ac in get_curves (this=0x0) + at /usr/include/c++/4.6/bits/locale_facets.h:1077 + 1077 { return __c; } + */ + + Geom::Path path_builder = Geom::Path(); + Geom::PathVector * pathvec; + + //load the first portion in before the loop starts + { + path_outline = Path(); + path_outline.LoadPath(pv[0], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + //now half of first cusp has been loaded + + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + //instead of array accessing twice, dereferencing used for clarity + initialPoint = (*pathvec)[0].initialPoint(); + + path_builder.start(initialPoint); + path_builder.append( (*pathvec)[0] ); + + path_outline = Path(); + path_outline.LoadPath(pv[1], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + + path_builder.append( (*pathvec)[0] ); + + //always set pointers null after deleting + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + for (m = 2; m < pv.size(); m++) + { + path_outline = Path(); + path_outline.LoadPath(pv[m], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + path_builder.append( (*pathvec)[0] ); + + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + return path_builder; + } + + static Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim) + { + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + Geom::PathVector path_out; + for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) + { + if (path_in[lmnop].size() > 1) + { + Geom::Path p_init; + Geom::Path p_rev; + Geom::PathBuilder pb = Geom::PathBuilder(); + + if ( !path_in[lmnop].closed() ) + { + p_init = Outline::half_outline( path_in[lmnop], -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline( path_in[lmnop].reverse(), -line_width, butt, + miter_lim ); + + pb.moveTo(p_init.initialPoint() ); + pb.append(p_init); + + //cap + if (butt == butt_straight) { + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } + + pb.append(p_rev); + + if (butt == butt_straight) { + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); + //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); + + pb.lineTo(p_init.initialPoint() ); + } + } + else + { + //final join + //refer to half_outline for documentation + Geom::Path p_almost = path_in[lmnop]; + p_almost.appendNew ( path_in[lmnop].initialPoint() ); + p_init = Outline::half_outline( p_almost, -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline( p_almost.reverse(), -line_width, butt, + miter_lim ); + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + + //this is a kludge, because I can't find how to make this work properly + bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), + path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == + (path_in[lmnop] [path_in[lmnop].size()].length())); + + p_almost = p_init; + if (lastIsLinear) + { + p_almost.erase_last(); p_almost.erase_last(); + } + + //outside test + Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); + Geom::Curve* cbc2 = p_almost[0].duplicate(); + + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //this is the outside path + + //reuse the old one + p_init = p_almost; + Outline::reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside, carry on :-) + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + + p_almost = p_rev; + if (lastIsLinear) + { + p_almost.erase(p_almost.begin() ); + p_almost.erase(p_almost.begin() ); + } + + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + + cbc1 = p_almost[p_almost.size() - 1].duplicate(); + cbc2 = p_almost[0].duplicate(); + + cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //outside path + + p_init = p_almost; + reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + //pb.closePath(); + pb.flush(); + Geom::PathVector pv_np = pb.peek(); + //hack + for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) + { + path_out.push_back( pv_np[abcd] ); + } + } + else + { + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + p.Outline(&outlinepath, line_width / 2, join, butt, miter_lim); + std::vector *pv_p = outlinepath.MakePathVector(); + //hack + path_out.push_back( (*pv_p)[0].reverse() ); + delete pv_p; + } + } + return path_out; + } + static Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim) + { + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + Geom::PathVector path_out; + for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) + { + if (path_in[lmnop].size() > 1) + { + Geom::Path p_init; + Geom::Path p_rev; + Geom::PathBuilder pb = Geom::PathBuilder(); + + if ( !path_in[lmnop].closed() ) + { + p_init = Outline::half_outline_extrp( path_in[lmnop], -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline_extrp( path_in[lmnop].reverse(), -line_width, butt, + miter_lim ); + + pb.moveTo(p_init.initialPoint() ); + pb.append(p_init); + + //cap + if (butt == butt_straight) { + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } + + pb.append(p_rev); + + if (butt == butt_straight) { + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); + //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); + + pb.lineTo(p_init.initialPoint() ); + } + } + else + { + //final join + //refer to half_outline for documentation + Geom::Path p_almost = path_in[lmnop]; + p_almost.appendNew ( path_in[lmnop].initialPoint() ); + p_init = Outline::half_outline_extrp( p_almost, -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline_extrp( p_almost.reverse(), -line_width, butt, + miter_lim ); + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + + //this is a kludge, because I can't find how to make this work properly + bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), + path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == + (path_in[lmnop] [path_in[lmnop].size()].length())); + + p_almost = p_init; + if (lastIsLinear) + { + p_almost.erase_last(); p_almost.erase_last(); + } + + //outside test + Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); + Geom::Curve* cbc2 = p_almost[0].duplicate(); + + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //this is the outside path + + //reuse the old one + p_init = p_almost; + Outline::extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside, carry on :-) + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + + p_almost = p_rev; + if (lastIsLinear) + { + p_almost.erase(p_almost.begin() ); + p_almost.erase(p_almost.begin() ); + } + + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + + cbc1 = p_almost[p_almost.size() - 1].duplicate(); + cbc2 = p_almost[0].duplicate(); + + cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //outside path + + p_init = p_almost; + extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + //pb.closePath(); + pb.flush(); + Geom::PathVector pv_np = pb.peek(); + //hack + for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) + { + path_out.push_back( pv_np[abcd] ); + } + } + else + { + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + p.Outline(&outlinepath, line_width / 2, join_pointy, butt, miter_lim); + std::vector *pv_p = outlinepath.MakePathVector(); + //hack + path_out.push_back( (*pv_p)[0].reverse() ); + delete pv_p; + } + } + return path_out; + } + + +} // namespace Outline + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 5e126f486..aec749929 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -183,6 +183,26 @@ bool SPItem::isHidden(unsigned display_key) const { return true; } +bool SPItem::isHighlightSet() const { + return _highlightColor != NULL; +} + +guint32 SPItem::highlight_color() const { + if (_highlightColor) + { + return atoi(_highlightColor) | 0x000000ff; + } + else if (parent && parent != this && SP_IS_ITEM(parent)) + { + return SP_ITEM(parent)->highlight_color(); + } + else + { + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + return prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff) | 0x000000ff; + } +} + void SPItem::setEvaluated(bool evaluated) { _is_evaluated = evaluated; _evaluated_status = StatusSet; diff --git a/src/sp-item.h b/src/sp-item.h index d605c99b9..dc0c54a80 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -145,6 +145,15 @@ public: bool isHidden() const; void setHidden(bool hidden); + /* Objects dialogue */ + bool isHighlightSet() const; + guint32 highlight_color() const; + + void setHighlightColor(guint32 color); + + void unsetHighlightColor(); + /********************/ + bool isEvaluated() const; void setEvaluated(bool visible); void resetEvaluated(); @@ -215,6 +224,7 @@ public: void set_i2d_affine(Geom::Affine const &transform); Geom::Affine dt2i_affine() const; + gchar *_highlightColor; private: enum EvaluatedStatus { diff --git a/src/sp-object.h b/src/sp-object.h index 3faadb404..4f7ef3f4c 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -45,6 +45,7 @@ class SPObject; #define SP_OBJECT_WRITE_BUILD (1 << 0) #define SP_OBJECT_WRITE_EXT (1 << 1) #define SP_OBJECT_WRITE_ALL (1 << 2) +#define SP_OBJECT_WRITE_NO_CHILDREN (1 << 3) #include #include diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index c37767a08..1cf667f2a 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -109,4 +109,8 @@ ink_common_sources += \ ui/dialog/undo-history.h \ ui/dialog/xml-tree.cpp \ ui/dialog/xml-tree.h \ + ui/dialog/lpe-powerstroke-properties.cpp \ + ui/dialog/lpe-powerstroke-properties.h \ + ui/dialog/objects.cpp \ + ui/dialog/objects.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp new file mode 100644 index 000000000..cef6f494e --- /dev/null +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -0,0 +1,203 @@ +/** + * @file + * Dialog for renaming layers. + */ +/* Author: + * Bryce W. Harrington + * Andrius R. + * Abhishek Sharma + * + * Copyright (C) 2004 Bryce Harrington + * Copyright (C) 2006 Andrius R. + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#include "lpe-powerstroke-properties.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "sp-object.h" +#include "sp-item.h" +#include "verbs.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +//#include "event-context.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +PowerstrokePropertiesDialog::PowerstrokePropertiesDialog() +: _desktop(NULL), _knotpoint(NULL), _position_visible(false) +{ + Gtk::Box *mainVBox = get_vbox(); + + _layout_table.set_spacings(4); + _layout_table.resize (2, 2); + + // Layer name widgets + _powerstroke_position_entry.set_activates_default(true); + _powerstroke_position_label.set_label(_("Position:")); + _powerstroke_position_label.set_alignment(1.0, 0.5); + + _powerstroke_width_entry.set_activates_default(true); + _powerstroke_width_label.set_label(_("Width:")); + _powerstroke_width_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_powerstroke_position_label, + 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_powerstroke_position_entry, + 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + _layout_table.attach(_powerstroke_width_label, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL); + _layout_table.attach(_powerstroke_width_entry, 1, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + + mainVBox->pack_start(_layout_table, true, true, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_can_default(); + + _apply_button.set_use_underline(true); + _apply_button.set_can_default(); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_apply)); + + signal_delete_event().connect( + sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &PowerstrokePropertiesDialog::_close)), + true + ) + ); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); + + set_focus(_powerstroke_width_entry); +} + +PowerstrokePropertiesDialog::~PowerstrokePropertiesDialog() { + + _setDesktop(NULL); +} + +void PowerstrokePropertiesDialog::showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt) +{ + PowerstrokePropertiesDialog *dialog = new PowerstrokePropertiesDialog(); + + dialog->_setDesktop(desktop); + dialog->_setKnotPoint(knotpoint); + dialog->_setPt(pt); + + dialog->set_title(_("Modify Node Position")); + dialog->_apply_button.set_label(_("_Move")); + + dialog->set_modal(true); + desktop->setWindowTransient (dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void +PowerstrokePropertiesDialog::_apply() +{ + std::istringstream i_pos(_powerstroke_position_entry.get_text()); + std::istringstream i_width(_powerstroke_width_entry.get_text()); + double d_pos, d_width; + if ((i_pos >> d_pos) && i_width >> d_width) { + _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); + } + _close(); +} + +void +PowerstrokePropertiesDialog::_close() +{ + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +bool PowerstrokePropertiesDialog::_handleKeyEvent(GdkEventKey *event) +{ + + /*switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: { + _apply(); + return true; + } + break; + }*/ + return false; +} + +void PowerstrokePropertiesDialog::_handleButtonEvent(GdkEventButton* event) +{ + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + _apply(); + } +} + +void PowerstrokePropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +{ + _powerstroke_position_entry.set_text(boost::lexical_cast(knotpoint.x())); + _powerstroke_width_entry.set_text(boost::lexical_cast(knotpoint.y())); +} + +void PowerstrokePropertiesDialog::_setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt) +{ + _knotpoint = const_cast(pt); +} + +void PowerstrokePropertiesDialog::_setDesktop(SPDesktop *desktop) { + if (desktop) { + Inkscape::GC::anchor (desktop); + } + if (_desktop) { + Inkscape::GC::release (_desktop); + } + _desktop = desktop; +} + +} // namespace +} // namespace +} // namespace + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/lpe-powerstroke-properties.h b/src/ui/dialog/lpe-powerstroke-properties.h new file mode 100644 index 000000000..c53eac0d9 --- /dev/null +++ b/src/ui/dialog/lpe-powerstroke-properties.h @@ -0,0 +1,99 @@ +/** @file + * @brief Dialog for renaming layers + */ +/* Author: + * Bryce W. Harrington + * + * Copyright (C) 2004 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H +#define INKSCAPE_DIALOG_POWERSTROKE_PROPERTIES_H + +#include <2geom/point.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "live_effects/parameter/powerstrokepointarray.h" + +class SPDesktop; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +class PowerstrokePropertiesDialog : public Gtk::Dialog { + public: + PowerstrokePropertiesDialog(); + virtual ~PowerstrokePropertiesDialog(); + + Glib::ustring getName() const { return "LayerPropertiesDialog"; } + + static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt); + +protected: + + SPDesktop *_desktop; + Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *_knotpoint; + + Gtk::Label _powerstroke_position_label; + Gtk::Entry _powerstroke_position_entry; + Gtk::Label _powerstroke_width_label; + Gtk::Entry _powerstroke_width_entry; + Gtk::Table _layout_table; + bool _position_visible; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + + sigc::connection _destroy_connection; + + static PowerstrokePropertiesDialog &_instance() { + static PowerstrokePropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setPt(const Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity *pt); + + void _apply(); + void _close(); + + void _setKnotPoint(Geom::Point knotpoint); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton* event); + + friend class Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity; + +private: + PowerstrokePropertiesDialog(PowerstrokePropertiesDialog const &); // no copy + PowerstrokePropertiesDialog &operator=(PowerstrokePropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp new file mode 100644 index 000000000..31e73db29 --- /dev/null +++ b/src/ui/dialog/objects.cpp @@ -0,0 +1,2048 @@ +/* + * A simple panel for objects + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "objects.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/insertordericon.h" +#include "ui/widget/clipmaskicon.h" +#include "ui/widget/highlight-picker.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +//#include "event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "layer-manager.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +/** + * Gets an instance of the Objects panel + */ +ObjectsPanel& ObjectsPanel::getInstance() +{ + return *new ObjectsPanel(); +} + +/** + * Column enumeration + */ +enum { + COL_VISIBLE = 1, + COL_LOCKED, + COL_TYPE, + COL_INSERTORDER, + COL_CLIPMASK, + COL_HIGHLIGHT +}; + +/** + * Button enumeration + */ +enum { + BUTTON_NEW = 0, + BUTTON_RENAME, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DUPLICATE, + BUTTON_DELETE, + BUTTON_SOLO, + BUTTON_SHOW_ALL, + BUTTON_HIDE_ALL, + BUTTON_LOCK_OTHERS, + BUTTON_LOCK_ALL, + BUTTON_UNLOCK_ALL, + BUTTON_SETCLIP, + BUTTON_CLIPGROUP, + BUTTON_SETINVCLIP, + BUTTON_UNSETCLIP, + BUTTON_SETMASK, + BUTTON_UNSETMASK, + BUTTON_GROUP, + BUTTON_UNGROUP, + BUTTON_COLLAPSE_ALL, + DRAGNDROP +}; + +/** + * Xml node observer for observing objects in the document + */ +class ObjectsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + /** + * Creates a new object watcher + * @param pnl The panel to which the object watcher belongs + * @param obj The object to watch + */ + ObjectWatcher(ObjectsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _highlightAttr(g_quark_from_string("inkscape:highlight-color")), + _lockedAttr(g_quark_from_string("sodipodi:insensitive")), + _labelAttr(g_quark_from_string("inkscape:label")), + _groupAttr(g_quark_from_string("inkscape:groupmode")), + _styleAttr(g_quark_from_string("style")), + _clipAttr(g_quark_from_string("clip-path")), + _maskAttr(g_quark_from_string("mask")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _lockedAttr || name == _labelAttr || name == _highlightAttr || name == _groupAttr || name == _styleAttr || name == _clipAttr || name == _maskAttr ) { + _pnl->_updateObject(_obj, name == _highlightAttr); + if ( name == _styleAttr ) { + _pnl->_updateComposite(); + } + } + } + } + + /** + * Objects panel to which this watcher belongs + */ + ObjectsPanel* _pnl; + + /** + * The object that is being observed + */ + SPObject* _obj; + + /** + * The xml representation of the object that is being observed + */ + Inkscape::XML::Node* _repr; + + /* These are quarks which define the attributes that we are observing */ + GQuark _highlightAttr; + GQuark _lockedAttr; + GQuark _labelAttr; + GQuark _groupAttr; + GQuark _styleAttr; + GQuark _clipAttr; + GQuark _maskAttr; +}; + +class ObjectsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +class ObjectsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colObject); + add(_colVisible); + add(_colLocked); + add(_colLabel); + add(_colType); + add(_colHighlight); + add(_colClipMask); + add(_colInsertOrder); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colVisible; + Gtk::TreeModelColumn _colLocked; + Gtk::TreeModelColumn _colType; + Gtk::TreeModelColumn _colHighlight; + Gtk::TreeModelColumn _colClipMask; + Gtk::TreeModelColumn _colInsertOrder; +}; + +/** + * Stylizes a button using the given icon name and tooltip + */ +void ObjectsPanel::_styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ) +{ + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *Gtk::manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + + btn.set_tooltip_text (tooltip); + +} + +/** + * Adds an item to the pop-up (right-click) menu + * @param desktop The active destktop + * @param code Action code + * @param iconName Icon name + * @param fallback Fallback text + * @param id Button id for callback function + * @return The generated menu item + */ +Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = Gtk::manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +/** + * Callback function for when an object changes. Essentially refreshes the entire tree + * @param obj Object which was changed (currently not used as the entire tree is recreated) + */ +void ObjectsPanel::_objectsChanged(SPObject */*obj*/) +{ + //First, unattach the watchers + while (!_objectWatchers.empty()) + { + ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + //Get the current document's root and use that to enumerate the tree + SPDocument* document = _desktop->doc(); + SPRoot* root = document->getRoot(); + if ( root ) { + _selectedConnection.block(); + //Clear the tree store + _store->clear(); + //Add all items recursively + _addObject( root, 0 ); + _selectedConnection.unblock(); + //Set the tree selection + _objectsSelected(_desktop->selection); + //Handle button sensitivity + _checkTreeSelection(); + } + } +} + +/** + * Recursively adds the children of the given item to the tree + * @param obj Root object to add to the tree + * @param parentRow Parent tree row (or NULL if adding to tree root) + */ +void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + + if (SP_IS_ITEM(child)) + { + SPItem * item = SP_ITEM(child); + SPGroup * group = SP_IS_GROUP(child) ? SP_GROUP(child) : 0; + + //Add the item to the tree and set the column information + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = item; + row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + row[_model->_colVisible] = !item->isHidden(); + row[_model->_colLocked] = !item->isSensitive(); + row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; + row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; + row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); + row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + + //If our parent object is a group and it's expanded, expand the tree + if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) + { + _tree.expand_to_path( _store->get_path(iter) ); + } + + //Add an object watcher to the item + ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + + //If the item is a group, recursively add its children + if (group) + { + _addObject( child, &row ); + } + } + } + } +} + +/** + * Updates an item in the tree and optionally recursively updates the item's children + * @param obj The item to update in the tree + * @param recurse Whether to recurse through the item's children + */ +void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { + //Find the object in the tree store and update it + _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); + if (recurse) + { + for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) + { + _updateObject(iter, recurse); + } + } +} + +/** + * Checks items in the tree store and updates the given item + * @param iter Current item being looked at in the tree + * @param obj Object to update + * @return + */ +bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + //We found our item in the tree!! Update it! + SPItem * item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + SPGroup * group = SP_IS_GROUP(obj) ? SP_GROUP(obj) : 0; + + row[_model->_colLabel] = obj->label() ? obj->label() : obj->getId(); + row[_model->_colVisible] = item ? !item->isHidden() : false; + row[_model->_colLocked] = item ? !item->isSensitive() : false; + row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; + row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; + row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? (item->clip_ref->getObject()->inverse ? 3 : 1) : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; + row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + + return true; + } + + return false; +} + +/** + * Updates the composite controls for the selected item + */ +void ObjectsPanel::_updateComposite() { + if (!_blockCompositeUpdate) + { + //Set the default values + bool setValues = true; + + //Get/set the values + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_compositingChanged), &setValues)); + } +} + +/** + * Sets the compositing values for the first selected item in the tree + * @param iter Current tree item + * @param setValues Whether to set the compositing values + * @param blur Blur value to use + */ +void ObjectsPanel::_compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (*setValues) + { + _setCompositingValues(item); + *setValues = false; + } + } +} + +/** + * Occurs when the current desktop selection changes + * @param sel The current selection + */ +void ObjectsPanel::_objectsSelected( Selection *sel ) { + + bool setOpacity = true; + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + SPItem *item = NULL; + for (const GSList * iter = sel->itemList(); iter != NULL; iter = iter->next) + { + item = reinterpret_cast(iter->data); + if (setOpacity) + { + _setCompositingValues(item); + setOpacity = false; + } + _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, iter->next == NULL)); + } + if (!item) { + if (_desktop->currentLayer() && SP_IS_ITEM(_desktop->currentLayer())) { + item = SP_ITEM(_desktop->currentLayer()); + _setCompositingValues(item); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_checkForSelected), item, true)); + } + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +/** + * Helper function for setting the compositing values + * @param item Item to use for setting the compositing values + */ +void ObjectsPanel::_setCompositingValues(SPItem *item) +{ + //Block the connections to avoid interference + _opacityConnection.block(); + _blendConnection.block(); + _blurConnection.block(); + + //Set the opacity + _opacity_adjustment.set_value((item->style->opacity.set ? SP_SCALE24_TO_FLOAT(item->style->opacity.value) : 1) * _opacity_adjustment.get_upper()); + SPFeBlend *spblend = NULL; + SPGaussianBlur *spblur = NULL; + if (item->style->getFilter()) + { + for(SPObject *primitive_obj = item->style->getFilter()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { + if(SP_IS_FEBLEND(primitive_obj) && !spblend) { + //Get the blend mode + spblend = SP_FEBLEND(primitive_obj); + } + + if(SP_IS_GAUSSIANBLUR(primitive_obj) && !spblur) { + //Get the blur value + spblur = SP_GAUSSIANBLUR(primitive_obj); + } + } + } + + //Set the blend mode + _fe_cb.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL); + + //Set the blur value + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + if (bbox && spblur) { + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? + _fe_blur.set_blur_value(spblur->stdDeviation.getNumber() * 400 / perimeter); + } else { + _fe_blur.set_blur_value(0); + } + + //Unblock connections + _blurConnection.unblock(); + _blendConnection.unblock(); + _opacityConnection.unblock(); +} + +/** + * Checks the tree and selects the specified item, optionally scrolling to the item + * @param path Current tree path + * @param iter Current tree item + * @param item Item to select in the tree + * @param scrollto Whether to scroll to the item + * @return Whether to continue searching the tree + */ +bool ObjectsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto) +{ + bool stopGoing = false; + + Gtk::TreeModel::Row row = *iter; + if ( item == row[_model->_colObject] ) + { + //We found the item! Expand to the path and select it in the tree. + _tree.expand_to_path( path ); + + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + if (scrollto) { + //Scroll to the item in the tree + _tree.scroll_to_row(path); + } + + stopGoing = true; + } + + return stopGoing; +} + +/** + * Pushes the current tree selection to the canvas + */ +void ObjectsPanel::_pushTreeSelectionToCurrent() +{ + if ( _desktop && _desktop->currentRoot() ) { + //block connections for selection and compositing values to prevent interference + _selectionChangedConnection.block(); + + //Clear the selection and then iterate over the tree selection, pushing each item to the desktop + _desktop->selection->clear(); + bool setOpacity = true; + _tree.get_selection()->selected_foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_selected_row_callback), &setOpacity)); + //unblock connections + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); + } +} + +/** + * Helper function for pushing the current tree selection to the current desktop + * @param iter Current tree item + * @param setCompositingValues Whether to set the compositing values + * @param blur + */ +void ObjectsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setCompositingValues ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) + { + //If the item is not a layer, then select it and set the current layer to its parent (if it's the first item) + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + else + { + //If the item is a layer, set the current layer + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); + } + if (*setCompositingValues) + { + //Only set the compositing values for the first item + _setCompositingValues(item); + *setCompositingValues = false; + } + } +} + +/** + * Handles button sensitivity + */ +void ObjectsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + //TODO: top/bottom sensitivity + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +/** + * Sets visibility of items in the tree + * @param iter Current item in the tree + * @param visible Whether the item should be visible or not + */ +void ObjectsPanel::_setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->setHidden( !visible ); + row[_model->_colVisible] = visible; + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Sets sensitivity of items in the tree + * @param iter Current item in the tree + * @param locked Whether the item should be locked + */ +void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->setLocked( locked ); + row[_model->_colLocked] = locked; + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Handles keyboard events + * @param event Keyboard event passed in from GDK + * @return Whether the event should be eaten (om nom nom) + */ +bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: + { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + //Rename item + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + break; + case GDK_Home: + { + //Move item(s) to top of containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT ); + } + return true; + } + case GDK_End: + { + //Move item(s) to bottom of containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK ); + } + return true; + } + case GDK_KEY_Page_Up: + { + //Move item(s) up in containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + if (event->state & GDK_SHIFT_MASK) { + _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); + } else { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + return true; + } + case GDK_KEY_Page_Down: + { + //Move item(s) down in containing group/layer + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + if (event->state & GDK_SHIFT_MASK) { + _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); + } else { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + return true; + } + //TODO: Handle Ctrl-A, etc. + } + return false; +} + +/** + * Handles mouse events + * @param event Mouse event from GDK + * @return whether to eat the event (om nom nom) + */ +bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + static bool overVisible = false; + + //Right mouse button was clicked, launch the pop-up menu + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + //Left mouse button was pressed! In order to handle multiple item drag & drop, + //we need to defer selection by setting the select function so that the tree doesn't + //automatically select anything. In order to handle multiple item icon clicking, + //we need to eat the event. There might be a better way to do both of these... + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + overVisible = false; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (col == _tree.get_column(COL_VISIBLE-1)) { + //Click on visible column, eat this event to keep row selection + overVisible = true; + return true; + } else if (col == _tree.get_column(COL_LOCKED-1) || + col == _tree.get_column(COL_TYPE-1) || + col == _tree.get_column(COL_INSERTORDER - 1) || + col == _tree.get_column(COL_HIGHLIGHT-1)) { + //Click on an icon column, eat this event to keep row selection + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + //Click on a selected item with no modifiers, defer selection to the mouse-up by + //setting the select function to _noSelection + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_noSelection)); + _defer_target = path; + } + } + } + + //Restore the selection function to allow tree selection on mouse button release + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction)); + } + + //CellRenderers do not have good support for dealing with multiple items, so + //we handle all events on them here + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + //We had deferred a selection target, select it here (assuming no drag & drop) + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } + else { + if (event->state & GDK_SHIFT_MASK) { + // Shift left click on the visible/lock columns toggles "solo" mode + if (col == _tree.get_column(COL_VISIBLE - 1)) { + _takeAction(BUTTON_SOLO); + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + _takeAction(BUTTON_LOCK_OTHERS); + } + } else if (event->state & GDK_MOD1_MASK) { + // Alt+left click on the visible/lock columns toggles "solo" mode and preserves selection + Gtk::TreeModel::iterator iter = _store->get_iter(path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPItem *item = row[_model->_colObject]; + if (col == _tree.get_column(COL_VISIBLE - 1)) { + _desktop->toggleLayerSolo( item ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:solo", SP_VERB_LAYER_SOLO, _("Toggle layer solo")); + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + _desktop->toggleLockOtherLayers( item ); + DocumentUndo::maybeDone(_desktop->doc(), "layer:lockothers", SP_VERB_LAYER_LOCK_OTHERS, _("Lock other layers")); + } + } + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPItem* item = row[_model->_colObject]; + + if (col == _tree.get_column(COL_VISIBLE - 1)) { + if (overVisible) { + //Toggle visibility + bool newValue = !row[_model->_colVisible]; + if (_tree.get_selection()->is_selected(path)) + { + //If the current row is selected, toggle the visibility + //for all selected items + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setVisibleIter), newValue)); + } + else + { + //If the current row is not selected, toggle just its visibility + row[_model->_colVisible] = newValue; + item->setHidden(!newValue); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Unhide objects") : _("Hide objects")); + overVisible = false; + } + } else if (col == _tree.get_column(COL_LOCKED - 1)) { + //Toggle locking + bool newValue = !row[_model->_colLocked]; + if (_tree.get_selection()->is_selected(path)) + { + //If the current row is selected, toggle the sensitivity for + //all selected items + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setLockedIter), newValue)); + } + else + { + //If the current row is not selected, toggle just its sensitivity + row[_model->_colLocked] = newValue; + item->setLocked( newValue ); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Lock objects") : _("Unlock objects")); + + } else if (col == _tree.get_column(COL_TYPE - 1)) { + if (SP_IS_GROUP(item)) + { + //Toggle the current item between a group and a layer + SPGroup * g = SP_GROUP(item); + bool newValue = g->layerMode() == SPGroup::LAYER; + row[_model->_colType] = newValue ? 1: 2; + g->setLayerMode(newValue ? SPGroup::GROUP : SPGroup::LAYER); + g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Layer to group") : _("Group to layer")); + } + } else if (col == _tree.get_column(COL_INSERTORDER - 1)) { + if (SP_IS_GROUP(item)) + { + //Toggle the current item's insert order + SPGroup * g = SP_GROUP(item); + bool newValue = !g->insertBottom(); + row[_model->_colInsertOrder] = newValue ? 2: 1; + g->setInsertBottom(newValue); + g->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, + newValue? _("Set insert mode bottom") : _("Set insert mode top")); + } + } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { + //Clear the highlight targets + _highlight_target.clear(); + if (_tree.get_selection()->is_selected(path)) + { + //If the current item is selected, store all selected items + //in the highlight source + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeHighlightTarget)); + } else { + //If the current item is not selected, store only it in the highlight source + _storeHighlightTarget(iter); + } + if (_colorSelector) + { + //Set up the color selector + SPColor color; + color.set( row[_model->_colHighlight] ); + _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight])); + } + //Show the color selector dialog + _colorSelectorDialog.show(); + } + } + } + } + } + + //Second mouse button press, set double click status for when the mouse is released + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + //Double click on mouse button release, if we're over the label column, edit + //the item name + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + + return false; +} + +/** + * Stores items in the highlight target vector to manipulate with the color selector + * @param iter Current tree item to store + */ +void ObjectsPanel::_storeHighlightTarget(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + _highlight_target.push_back(item); + } +} + +/* + * Drap and drop within the tree + */ +bool ObjectsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + //Set up our defaults and clear the source vector + _dnd_into = false; + _dnd_target = NULL; + _dnd_source.clear(); + + //Add all selected items to the source vector + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_storeDragSource)); + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/4) && cell_y <= (int)(cell_height * 3/4)); + if (cell_y > (int)(cell_height * 3/4)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = NULL; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + //Set the drop target. If we're not dropping into a group, we cannot + //drop into it, so set _dnd_into false. + _dnd_target = row[_model->_colObject]; + if (!(SP_IS_GROUP(_dnd_target))) _dnd_into = false; + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/** + * Stores all selected items as the drag source + * @param iter Current tree item + */ +void ObjectsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Move a layer in response to a drag & drop action + */ +void ObjectsPanel::_doTreeMove( ) +{ + g_assert(_desktop != NULL); + g_assert(_document != NULL); + + std::vector idvector; + + //Clear the desktop selection + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPItem *obj = _dnd_source.back(); + _dnd_source.pop_back(); + + if (obj != _dnd_target) { + //Store the object id (for selection later) and move the object + idvector.push_back(g_strdup(obj->getId())); + obj->moveTo(_dnd_target, _dnd_into); + } + } + + //Select items + while (!idvector.empty()) { + //Grab the id from the vector, get the item in the document and select it + gchar * id = idvector.back(); + idvector.pop_back(); + SPObject *obj = _document->getObjectById(id); + g_free(id); + if (obj && SP_IS_ITEM(obj)) { + SPItem *item = SP_ITEM(obj); + if (!SP_IS_GROUP(item) || SP_GROUP(item)->layerMode() != SPGroup::LAYER) + { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + else + { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item); + } + } + } + + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Moved objects")); +} + +/** + * Fires the action verb + */ +void ObjectsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +/** + * Executes the given button action during the idle time + */ +void ObjectsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &ObjectsPanel::_executeAction), 0 ); + } +} + +/** + * Executes the pending button action + */ +bool ObjectsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _document && _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_LAYER_NEW ); + } + break; + case BUTTON_RENAME: + { + _fireAction( SP_VERB_LAYER_RENAME ); + } + break; + case BUTTON_TOP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT); + } + } + break; + case BUTTON_BOTTOM: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK); + } + } + break; + case BUTTON_UP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + break; + case BUTTON_DOWN: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + break; + case BUTTON_DUPLICATE: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_DUPLICATE ); + } + else + { + _fireAction( SP_VERB_EDIT_DUPLICATE ); + } + } + break; + case BUTTON_DELETE: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_DELETE ); + } + else + { + _fireAction( SP_VERB_EDIT_DELETE ); + } + } + break; + case BUTTON_SOLO: + { + _fireAction( SP_VERB_LAYER_SOLO ); + } + break; + case BUTTON_SHOW_ALL: + { + _fireAction( SP_VERB_LAYER_SHOW_ALL ); + } + break; + case BUTTON_HIDE_ALL: + { + _fireAction( SP_VERB_LAYER_HIDE_ALL ); + } + break; + case BUTTON_LOCK_OTHERS: + { + _fireAction( SP_VERB_LAYER_LOCK_OTHERS ); + } + break; + case BUTTON_LOCK_ALL: + { + _fireAction( SP_VERB_LAYER_LOCK_ALL ); + } + break; + case BUTTON_UNLOCK_ALL: + { + _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); + } + break; + case BUTTON_SETCLIP: + { + _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); + } + break; + case BUTTON_UNSETCLIP: + { + _fireAction( SP_VERB_OBJECT_UNSET_CLIPPATH ); + } + break; + case BUTTON_SETMASK: + { + _fireAction( SP_VERB_OBJECT_SET_MASK ); + } + break; + case BUTTON_UNSETMASK: + { + _fireAction( SP_VERB_OBJECT_UNSET_MASK ); + } + break; + case BUTTON_GROUP: + { + _fireAction( SP_VERB_SELECTION_GROUP ); + } + break; + case BUTTON_UNGROUP: + { + _fireAction( SP_VERB_SELECTION_UNGROUP ); + } + break; + case BUTTON_COLLAPSE_ALL: + { + for (SPObject* obj = _document->getRoot()->firstChild(); obj != NULL; obj = obj->next) { + if (SP_IS_GROUP(obj)) { + _setCollapsed(SP_GROUP(obj)); + } + } + _objectsChanged(_document->getRoot()); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + +/** + * Handles an unsuccessful item label edit (escape pressed, etc.) + */ +void ObjectsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +/** + * Handle a successful item label edit + * @param path Tree path of the item currently being edited + * @param new_text New label text + */ +void ObjectsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +/** + * Renames an item in the tree + * @param row Tree row + * @param name New label to give to the item + */ +void ObjectsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPItem* item = row[_model->_colObject]; + if ( item ) { + gchar const* oldLabel = item->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + item->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } +} + +/** + * A row selection function used by the tree that doesn't allow any new items to be selected. + * Currently, this is used to allow multi-item drag & drop. + */ +bool ObjectsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool /*currentlySelected*/ ) +{ + return false; +} + +/** + * Default row selection function taken from the layers dialog + */ +bool ObjectsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +/** + * Sets a group to be collapsed and recursively collapses its children + * @param group The group to collapse + */ +void ObjectsPanel::_setCollapsed(SPGroup * group) +{ + group->setExpanded(false); + group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + for (SPObject *iter = group->children; iter != NULL; iter = iter->next) + { + if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + } +} + +/** + * Sets a group to be expanded or collapsed + * @param iter Current tree item + * @param isexpanded Whether to expand or collapse + */ +void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPItem* item = row[_model->_colObject]; + if (item && SP_IS_GROUP(item)) + { + if (isexpanded) + { + //If we're expanding, simply perform the expansion + SP_GROUP(item)->setExpanded(isexpanded); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + else + { + //If we're collapsing, we need to recursively collapse, so call our helper function + _setCollapsed(SP_GROUP(item)); + } + } +} + +/** + * Callback for when the highlight color is changed + * @param csel Color selector + * @param cp Objects panel + */ +void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) +{ + SPColor color; + float alpha = 0; + csel->base->getColorAlpha(color, alpha); + guint32 rgba = color.toRGBA32( alpha ); + + ObjectsPanel *ptr = reinterpret_cast(cp); + + //Set the highlight color for all items in the _highlight_target (all selected items) + for (std::vector::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) + { + SPItem * target = *iter; + target->setHighlightColor(rgba); + target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); +} + +/** + * Callback for when the opacity value is changed + */ +void ObjectsPanel::_opacityValueChanged() +{ + _blockCompositeUpdate = true; + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &ObjectsPanel::_opacityChangedIter)); + DocumentUndo::maybeDone(_document, "opacity", SP_VERB_DIALOG_OBJECTS, _("Set object opacity")); + _blockCompositeUpdate = false; +} + +/** + * Change the opacity of the selected items in the tree + * @param iter Current tree item + */ +void ObjectsPanel::_opacityChangedIter(const Gtk::TreeIter& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + item->style->opacity.set = TRUE; + item->style->opacity.value = SP_SCALE24_FROM_FLOAT(_opacity_adjustment.get_value() / _opacity_adjustment.get_upper()); + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Callback for when the blend mode is changed + */ +void ObjectsPanel::_blendValueChanged() +{ + _blockCompositeUpdate = true; + const Glib::ustring blendmode = _fe_cb.get_blend_mode(); + + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blendChangedIter), blendmode)); + DocumentUndo::done(_document, SP_VERB_DIALOG_OBJECTS, _("Set object blend mode")); + _blockCompositeUpdate = false; +} + +/** + * Sets the blend mode of the selected tree items + * @param iter Current tree item + * @param blendmode Blend mode to set + */ +void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + //Since blur and blend are both filters, we need to set both at the same time + SPStyle *style = item->style; + g_assert(style != NULL); + + if (blendmode != "normal") { + gdouble radius = 0; + if (item->style->getFilter()) { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_GAUSSIANBLUR(primitive)) { + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + if (bbox) { + radius = SP_GAUSSIANBLUR(primitive)->stdDeviation.getNumber(); + } + } + } + } + SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius); + sp_style_set_property_url(item, "filter", filter, false); + } else { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_FEBLEND(primitive)) { + primitive->deleteObject(); + break; + } + } + if (!item->style->getFilter()->children) { + remove_filter(item, false); + } + } + + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Callback for when the blur value has changed + */ +void ObjectsPanel::_blurValueChanged() +{ + _blockCompositeUpdate = true; + _tree.get_selection()->selected_foreach_iter(sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_blurChangedIter), _fe_blur.get_blur_value())); + DocumentUndo::maybeDone(_document, "blur", SP_VERB_DIALOG_OBJECTS, _("Set object blur")); + _blockCompositeUpdate = false; +} + +/** + * Sets the blur value for the selected items in the tree + * @param iter Current tree item + * @param blur Blur value to set + */ +void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur) +{ + Gtk::TreeModel::Row row = *iter; + SPItem* item = row[_model->_colObject]; + if (item) + { + //Since blur and blend are both filters, we need to set both at the same time + SPStyle *style = item->style; + if (style) { + Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); + double radius; + if (bbox) { + double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; // fixme: this is only half the perimeter, is that correct? + radius = blur * perimeter / 400; + } else { + radius = 0; + } + + if (radius != 0) { + SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius); + sp_style_set_property_url(item, "filter", filter, false); + } else if (item->style->filter.set && item->style->getFilter()) { + for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { + if (SP_IS_GAUSSIANBLUR(primitive)) { + primitive->deleteObject(); + break; + } + } + if (!item->style->getFilter()->children) { + remove_filter(item, false); + } + } + item->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + } +} + +/** + * Constructor + */ +ObjectsPanel::ObjectsPanel() : + UI::Widget::Panel("", "/dialogs/objects", SP_VERB_DIALOG_OBJECTS), + _rootWatcher(0), + _deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + _composite_vbox(false, 0), + _opacity_vbox(false, 0), + _opacity_label(_("Opacity:")), + _opacity_label_unit(_("%")), +#if WITH_GTKMM_3_0 + _opacity_adjustment(Gtk::Adjustment::create(100.0, 0.0, 100.0, 1.0, 1.0, 0.0)), +#else + _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0), +#endif + _opacity_hscale(_opacity_adjustment), + _opacity_spin_button(_opacity_adjustment, 0.01, 1), + _fe_cb(UI::Widget::SimpleFilterModifier::BLEND), + _fe_vbox(false, 0), + _fe_alignment(1, 1, 1, 1), + _fe_blur(UI::Widget::SimpleFilterModifier::BLUR), + _blur_vbox(false, 0), + _blur_alignment(1, 1, 1, 1), + _colorSelectorDialog("dialogs.colorpickerwindow") +{ + //Create the tree model and store + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + //Set up the tree + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + //Create the column CellRenderers + //Visible + Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); + int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; + eyeRenderer->property_activatable() = true; + Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); + if ( col ) { + col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); + } + + //Locked + Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); + int lockedColNum = _tree.append_column("lock", *renderer) - 1; + renderer->property_activatable() = true; + col = _tree.get_column(lockedColNum); + if ( col ) { + col->add_attribute( renderer->property_active(), _model->_colLocked ); + } + + //Type + Inkscape::UI::Widget::LayerTypeIcon * typeRenderer = Gtk::manage( new Inkscape::UI::Widget::LayerTypeIcon()); + int typeColNum = _tree.append_column("type", *typeRenderer) - 1; + typeRenderer->property_activatable() = true; + col = _tree.get_column(typeColNum); + if ( col ) { + col->add_attribute( typeRenderer->property_active(), _model->_colType ); + } + + //Insert order + Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); + int insertColNum = _tree.append_column("type", *insertRenderer) - 1; + col = _tree.get_column(insertColNum); + if ( col ) { + col->add_attribute( insertRenderer->property_active(), _model->_colInsertOrder ); + } + + //Clip/mask + Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); + int clipColNum = _tree.append_column("clipmask", *clipRenderer) - 1; + col = _tree.get_column(clipColNum); + if ( col ) { + col->add_attribute( clipRenderer->property_active(), _model->_colClipMask ); + } + + //Highlight + Inkscape::UI::Widget::HighlightPicker * highlightRenderer = Gtk::manage( new Inkscape::UI::Widget::HighlightPicker()); + int highlightColNum = _tree.append_column("highlight", *highlightRenderer) - 1; + col = _tree.get_column(highlightColNum); + if ( col ) { + col->add_attribute( highlightRenderer->property_active(), _model->_colHighlight ); + } + + //Label + _text_renderer = Gtk::manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + //Set the expander and search columns + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + _tree.set_search_column(_model->_colLabel); + + //Set up the tree selection + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &ObjectsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &ObjectsPanel::_rowSelectFunction) ); + + //Set up tree signals + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleKeyEvent), false ); + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleDragDrop), false); + _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), false)); + _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_setExpanded), true)); + + //Set up the label editing signals + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &ObjectsPanel::_handleEditingCancelled) ); + + //Set up the scroller window and pack the page + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _page.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + //Set up the compositing items + //Blend mode filter effect + _composite_vbox.pack_start(_fe_vbox, false, false, 2); + _fe_alignment.set_padding(0, 0, 4, 0); + _fe_alignment.add(_fe_cb); + _fe_vbox.pack_start(_fe_alignment, false, false, 0); + _blendConnection = _fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blendValueChanged)); + + //Blur filter effect + _composite_vbox.pack_start(_blur_vbox, false, false, 2); + _blur_alignment.set_padding(0, 0, 4, 0); + _blur_alignment.add(_fe_blur); + _blur_vbox.pack_start(_blur_alignment, false, false, 0); + _blurConnection = _fe_blur.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_blurValueChanged)); + + //Opacity + _composite_vbox.pack_start(_opacity_vbox, false, false, 2); + _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER); + _opacity_hbox.pack_start(_opacity_label, false, false, 3); + _opacity_vbox.pack_start(_opacity_hbox, false, false, 0); + _opacity_hbox.pack_start(_opacity_hscale, true, true, 0); + _opacity_hbox.pack_start(_opacity_spin_button, false, false, 0); + _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3); + _opacity_hscale.set_draw_value(false); +#if WITH_GTKMM_3_0 + _opacityConnection = _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); + _opacity_label.set_mnemonic_widget(_opacity_hscale); +#else + _opacityConnection = _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectsPanel::_opacityValueChanged)); + _opacity_label.set_mnemonic_widget(_opacity_hscale); +#endif + + //Keep the labels aligned + GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget(labels, GTK_WIDGET(_opacity_label.gobj())); + gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_cb.get_blur_label()->gobj())); + gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_blur.get_blur_label()->gobj())); + + //Pack the compositing functions and the button row + _page.pack_end(_composite_vbox, Gtk::PACK_SHRINK); + _page.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + //Pack into the panel contents + _getContents()->pack_start(_page, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + //Set up the button row + Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); + _watchingNonTop.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + btn = Gtk::manage( new Gtk::Button() ); + _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); + _watchingNonBottom.push_back( btn ); + _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + _watching.push_back(&_composite_vbox); + + //Set up the pop-up menu + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_EDIT_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SOLO, 0, "Solo", (int)BUTTON_SOLO ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SHOW_ALL, 0, "Show All", (int)BUTTON_SHOW_ALL ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_HIDE_ALL, 0, "Hide All", (int)BUTTON_HIDE_ALL ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_OTHERS, 0, "Lock Others", (int)BUTTON_LOCK_OTHERS ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_ALL, 0, "Lock All", (int)BUTTON_LOCK_ALL ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_UNLOCK_ALL, 0, "Unlock All", (int)BUTTON_UNLOCK_ALL ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_RAISE, GTK_STOCK_GO_UP, "Up", (int)BUTTON_UP ) ); + _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_LOWER, GTK_STOCK_GO_DOWN, "Down", (int)BUTTON_DOWN ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_GROUP, 0, "Group", (int)BUTTON_GROUP ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_SELECTION_UNGROUP, 0, "Ungroup", (int)BUTTON_UNGROUP ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); + //not implemented + //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); + + //will never be implemented + //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_INVERSE_CLIPPATH, 0, "Set Inverse Clip", (int)BUTTON_SETINVCLIP ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_CLIPPATH, 0, "Unset Clip", (int)BUTTON_UNSETCLIP ) ); + + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_MASK, 0, "Set Mask", (int)BUTTON_SETMASK ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_UNSET_MASK, 0, "Unset Mask", (int)BUTTON_UNSETMASK ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + //Set initial sensitivity of buttons + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + //Set up the color selection dialog + GtkWidget *dlg = GTK_WIDGET(_colorSelectorDialog.gobj()); + sp_transientize(dlg); + + _colorSelectorDialog.hide(); + _colorSelectorDialog.set_title (_("Select Highlight Color")); + _colorSelectorDialog.set_border_width (4); + _colorSelectorDialog.property_modal() = true; + _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); + _colorSelectorDialog.get_vbox()->pack_start ( + *Glib::wrap(&_colorSelector->vbox), true, true, 0); + + g_signal_connect(G_OBJECT(_colorSelector), "dragged", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + g_signal_connect(G_OBJECT(_colorSelector), "released", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + g_signal_connect(G_OBJECT(_colorSelector), "changed", + G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + + gtk_widget_show(GTK_WIDGET(_colorSelector)); + + setDesktop( targetDesktop ); + + show_all_children(); + + //Connect the desktop changed connection + desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectsPanel::setDesktop) ); + _deskTrack.connect(GTK_WIDGET(gobj())); +} + +/** + * Destructor + */ +ObjectsPanel::~ObjectsPanel() +{ + //Close the highlight selection dialog + _colorSelectorDialog.hide(); + _colorSelector = NULL; + + //Set the desktop to null, which will disconnect all object watchers + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + _deskTrack.disconnect(); +} + +/** + * Sets the current document + */ +void ObjectsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + //Clear all object watchers + while (!_objectWatchers.empty()) + { + ObjectsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + //Delete the root watcher + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getRoot() && document->getRoot()->getRepr()) + { + //Create a new root watcher for the document and then call _objectsChanged to fill the tree + _rootWatcher = new ObjectsPanel::ObjectWatcher(this, document->getRoot()); + document->getRoot()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getRoot()); + } +} + +/** + * Set the current panel desktop + */ +void ObjectsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //Connect desktop signals + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &ObjectsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &ObjectsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } else { + setDocument(NULL, NULL); + } + } + _deskTrack.setBase(desktop); +} +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h new file mode 100644 index 000000000..7b07afd63 --- /dev/null +++ b/src/ui/dialog/objects.h @@ -0,0 +1,255 @@ +/* + * A simple dialog for objects UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_OBJECTS_PANEL_H +#define SEEN_OBJECTS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPGroup; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays objects. + */ +class ObjectsPanel : public UI::Widget::Panel +{ +public: + ObjectsPanel(); + virtual ~ObjectsPanel(); + + static ObjectsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +private: + //Internal Classes: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + //Connections, Watchers, Trackers: + + //Document root watcher + ObjectsPanel::ObjectWatcher* _rootWatcher; + + //All object watchers + std::vector _objectWatchers; + + //Connection for when the desktop changes + sigc::connection desktopChangeConn; + + //Connection for when the document changes + sigc::connection _documentChangedConnection; + + //Connection for when the active selection in the document changes + sigc::connection _selectionChangedConnection; + + //Connection for when the selection in the dialog changes + sigc::connection _selectedConnection; + + //Connections for when the opacity/blend/blur of the active selection in the document changes + sigc::connection _opacityConnection; + sigc::connection _blendConnection; + sigc::connection _blurConnection; + + //Desktop tracker for grabbing the desktop changed connection + DesktopTracker _deskTrack; + + //Members: + + //The current desktop + SPDesktop* _desktop; + + //The current document + SPDocument* _document; + + //Tree data model + ModelColumns* _model; + + //Prevents the composite controls from updating + bool _blockCompositeUpdate; + + // + InternalUIBounce* _pending; + + //Whether the drag & drop was dragged into an item + gboolean _dnd_into; + + //List of drag & drop source items + std::vector _dnd_source; + + //Drag & drop target item + SPItem* _dnd_target; + + //List of items to change the highlight on + std::vector _highlight_target; + + //GUI Members: + + GdkEvent* _toggleEvent; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _page; + + /* Composite Settings */ + Gtk::VBox _composite_vbox; + Gtk::VBox _opacity_vbox; + Gtk::HBox _opacity_hbox; + Gtk::Label _opacity_label; + Gtk::Label _opacity_label_unit; +#if WITH_GTKMM_3_0 + Glib::RefPtr _opacity_adjustment; +#else + Gtk::Adjustment _opacity_adjustment; +#endif + Gtk::HScale _opacity_hscale; + Inkscape::UI::Widget::SpinButton _opacity_spin_button; + + Inkscape::UI::Widget::SimpleFilterModifier _fe_cb; + Gtk::VBox _fe_vbox; + Gtk::Alignment _fe_alignment; + Inkscape::UI::Widget::SimpleFilterModifier _fe_blur; + Gtk::VBox _blur_vbox; + Gtk::Alignment _blur_alignment; + + Gtk::Dialog _colorSelectorDialog; + SPColorSelector *_colorSelector; + + + //Methods: + + ObjectsPanel(ObjectsPanel const &); // no copy + ObjectsPanel &operator=(ObjectsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + void _setVisibleIter( const Gtk::TreeModel::iterator& iter, const bool visible ); + void _setLockedIter( const Gtk::TreeModel::iterator& iter, const bool locked ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeHighlightTarget(const Gtk::TreeModel::iterator& iter); + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter, bool *setOpacity ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + void _setCollapsed(SPGroup * group); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _compositingChanged( const Gtk::TreeModel::iterator& iter, bool *setValues ); + void _updateComposite(); + void _setCompositingValues(SPItem *item); + + void _updateObject(SPObject *obj, bool recurse); + bool _checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPItem* item, bool scrollto); + + void _objectsChanged(SPObject *obj); + void _addObject( SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _opacityChangedIter(const Gtk::TreeIter& iter); + void _opacityValueChanged(); + + void _blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring blendmode); + void _blendValueChanged(); + + void _blurChangedIter(const Gtk::TreeIter& iter, double blur); + void _blurValueChanged(); + + + void setupDialog(const Glib::ustring &title); + + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp new file mode 100644 index 000000000..f994b571f --- /dev/null +++ b/src/ui/dialog/tags.cpp @@ -0,0 +1,1182 @@ +/* + * A simple panel for tags + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "tags.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "layer-fns.h" +#include "layer-manager.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/addtoicon.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +#include "event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-tag.h" +#include "sp-defs.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +TagsPanel& TagsPanel::getInstance() +{ + return *new TagsPanel(); +} + +enum { + COL_ADD = 1 +}; + +enum { + BUTTON_NEW = 0, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DELETE, + DRAGNDROP +}; + +class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : + _pnl(pnl), + _obj(obj), + _repr(repr), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + ObjectWatcher(TagsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _labelAttr ) { + _pnl->_updateObject( _obj); + } + } + } + + TagsPanel* _pnl; + SPObject* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; +}; + +class TagsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) +{ + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } + } + } + + btn.set_tooltip_text (tooltip); +} + + +Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +void TagsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +void TagsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); + } +} + +bool TagsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_TAG_NEW ); + } + break; + case BUTTON_TOP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_TOP ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_FRONT); + } + } + break; + case BUTTON_BOTTOM: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_TO_BOTTOM ); + } + else + { + _fireAction( SP_VERB_SELECTION_TO_BACK); + } + } + break; + case BUTTON_UP: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_RAISE ); + } + else + { + _fireAction( SP_VERB_SELECTION_RAISE ); + } + } + break; + case BUTTON_DOWN: + { + if (_desktop->selection->isEmpty()) + { + _fireAction( SP_VERB_LAYER_LOWER ); + } + else + { + _fireAction( SP_VERB_SELECTION_LOWER ); + } + } + break; + case BUTTON_DELETE: + { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + + +class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colParentObject); + add(_colObject); + add(_colLabel); + add(_colAddRemove); + add(_colAllowAddRemove); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colParentObject; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colAddRemove; + Gtk::TreeModelColumn _colAllowAddRemove; +}; + +void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) +{ + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && obj->parent) { + todelete->push_back(obj); + } +} + +void TagsPanel::_updateObject( SPObject *obj ) { + _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); +} + +bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + /* + * We get notified of layer update here (from layer->setLabel()) before layer->label() is set + * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which + * has the correct value (bug #168351) + */ + //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); + gchar const *label; + SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; + if (use && use->ref->isAttached()) { + label = use->ref->getObject()->getAttribute("inkscape:label"); + } else { + label = obj->getAttribute("inkscape:label"); + } + row[_model->_colLabel] = label ? label : obj->getId(); + row[_model->_colAddRemove] = SP_IS_TAG(obj); + } + + return false; +} + +void TagsPanel::_objectsSelected( Selection *sel ) { + + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) + { + SPObject *obj = reinterpret_cast(iter->data); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + SPObject * it = row[_model->_colObject]; + if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) + { + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + } + return false; +} + +void TagsPanel::_objectsChanged(SPObject* root) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + SPDocument* document = _desktop->doc(); + SPDefs* root = document->getDefs(); + if ( root ) { + _selectedConnection.block(); + _store->clear(); + _addObject( document, root, 0 ); + _selectedConnection.unblock(); + _objectsSelected(_desktop->selection); + _checkTreeSelection(); + } + } +} + +void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG(child)) + { + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colAddRemove] = true; + row[_model->_colAllowAddRemove] = true; + + _tree.expand_to_path( _store->get_path(iter) ); + + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + _addObject( doc, child, &row ); + } + } + if (SP_IS_TAG(obj) && obj->children) + { + Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row rowitems = *iteritems; + rowitems[_model->_colObject] = NULL; + rowitems[_model->_colParentObject] = obj; + rowitems[_model->_colLabel] = _("Items"); + rowitems[_model->_colAddRemove] = false; + rowitems[_model->_colAllowAddRemove] = false; + + _tree.expand_to_path( _store->get_path(iteritems) ); + + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child)) + { + SPItem *item = SP_TAG_USE(child)->ref->getObject(); + Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; + row[_model->_colAddRemove] = false; + row[_model->_colAllowAddRemove] = true; + + if (SP_TAG(obj)->expanded()) { + _tree.expand_to_path( _store->get_path(iter) ); + } + + if (item) { + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); + item->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + } + } + } + } + } +} + +void TagsPanel::_select_tag( SPTag * tag ) +{ + for (SPObject * child = tag->children; child != NULL; child = child->next) + { + if (SP_IS_TAG(child)) { + _select_tag(SP_TAG(child)); + } else if (SP_IS_TAG_USE(child)) { + SPObject * obj = SP_TAG_USE(child)->ref->getObject(); + if (obj) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); + _desktop->selection->add(obj); + } + } + } +} + +void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _select_tag(SP_TAG(obj)); + } else if (SP_IS_TAG_USE(obj)) { + SPObject * item = SP_TAG_USE(obj)->ref->getObject(); + if (item) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + } + } + } +} + +void TagsPanel::_pushTreeSelectionToCurrent() +{ + _selectionChangedConnection.block(); + // TODO hunt down the possible API abuse in getting NULL + if ( _desktop && _desktop->currentRoot() ) { + _desktop->selection->clear(); + _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); + } + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); +} + +void TagsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; +// if ( _tree.get_selection()->count_selected_rows() > 0 ) { +// sensitive = true; +// +// SPObject* inTree = _selectedLayer(); +// if ( inTree ) { +// +// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); +// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); +// +// } +// } + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +bool TagsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && SP_IS_TAG(obj)) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + } + case GDK_KEY_Delete: { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + return true; + } + break; + } + return false; +} + +bool TagsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + // Alt left click on the visible/lock columns - eat this event to keep row selection + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (col == _tree.get_column(COL_ADD-1)) { + down_at_add = true; + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); + _defer_target = path; + } else { + down_at_add = false; + } + } else { + down_at_add = false; + } + } + + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); + } + + // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here. + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + + if (obj) { + if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { + if (SP_IS_TAG(obj)) { + bool wasadded = false; + for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) + { + SPObject *newobj = reinterpret_cast(iter->data); + bool addchild = true; + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { + addchild = false; + } + } + if (addchild) { + Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); + obj->appendChild(clone); + wasadded = true; + } + } + if (wasadded) { + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to tag")); + } + } else { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * tobj = *iter; + if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { + tobj->parent->getRepr()->removeChild(tobj->getRepr()); + } + } + } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); + } + } + } + } + } + } + + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + } + + return false; +} + +void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + _dnd_into = true; + _dnd_target = _document->getDefs(); + _dnd_source.clear(); + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); + + if (_dnd_source.empty()) { + return true; + } + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y > (int)(cell_height * 2/3)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = _document->getDefs(); + _dnd_into = true; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + SPObject *pobj = row[_model->_colParentObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _dnd_target = SP_TAG(obj); + } else if (SP_IS_TAG(obj->parent)) { + _dnd_target = SP_TAG(obj->parent); + _dnd_into = true; + } + } else if (pobj && SP_IS_TAG(pobj)) { + _dnd_target = SP_TAG(pobj); + _dnd_into = true; + } else { + return true; + } + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/* + * Move a layer in response to a drag & drop action + */ +void TagsPanel::_doTreeMove( ) +{ + if (_dnd_target) { + for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) + { + SPTag *src = *iter; + if (src != _dnd_target) { + src->moveTo(_dnd_target, _dnd_into); + } + } + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPTag *src = _dnd_source.back(); + _select_tag(src); + _dnd_source.pop_back(); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, + _("Moved tags")); + } +} + + +void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +void TagsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + if (SP_IS_TAG(obj)) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } + } +} + +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + return false; +} + +bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colParentObject]; + if (obj && SP_IS_TAG(obj)) + { + SP_TAG(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Constructor + */ +TagsPanel::TagsPanel() : + UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), + _rootWatcher(0), + deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + desktopChangeConn() +{ + //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); + int addColNum = _tree.append_column("type", *addRenderer) - 1; + Gtk::TreeViewColumn *col = _tree.get_column(addColNum); + if ( col ) { + col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); + col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); + } + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); + + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); + _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); + _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); + + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); + + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); + + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new tag") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + +// btn = manage( new Gtk::Button("Dup") ); +// btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); +// _buttonsRow.add( *btn ); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Tag") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + setDesktop( targetDesktop ); + + show_all_children(); + + // restorePanelPrefs(); + + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); +} + +TagsPanel::~TagsPanel() +{ + + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + deskTrack.disconnect(); +} + +void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getDefs() && document->getDefs()->getRepr()) + { + _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); + document->getDefs()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getDefs()); + } +} + +void TagsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //setLabel( _desktop->doc()->name ); + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } + } +/* + GSList const *layers = _desktop->doc()->getResourceList( "layer" ); + g_message( "layers list starts at %p", layers ); + for ( GSList const *iter=layers ; iter ; iter = iter->next ) { + SPObject *layer=static_cast(iter->data); + g_message(" {%s} [%s]", layer->id, layer->label() ); + } +*/ + deskTrack.setBase(desktop); +} + + + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h new file mode 100644 index 000000000..d35dfba01 --- /dev/null +++ b/src/ui/dialog/tags.h @@ -0,0 +1,181 @@ +/* + * A simple dialog for tags UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TAGS_PANEL_H +#define SEEN_TAGS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPTag; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays layers. + */ +class TagsPanel : public UI::Widget::Panel +{ +public: + TagsPanel(); + virtual ~TagsPanel(); + + //virtual void setOrientation( Gtk::AnchorType how ); + + static TagsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +protected: + //virtual void _handleAction( int setId, int itemId ); + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); +private: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + TagsPanel(TagsPanel const &); // no copy + TagsPanel &operator=(TagsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); + void _select_tag( SPTag * tag ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _updateObject(SPObject *obj); + bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); + + void _objectsChanged(SPObject *root); + void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); + +// std::vector groupConnections; + TagsPanel::ObjectWatcher* _rootWatcher; + std::vector _objectWatchers; + + // Hooked to the layer manager: + sigc::connection _documentChangedConnection; + sigc::connection _selectionChangedConnection; + + sigc::connection _changedConnection; + sigc::connection _addedConnection; + sigc::connection _removedConnection; + + // Internal + sigc::connection _selectedConnection; + sigc::connection _expandedConnection; + sigc::connection _collapsedConnection; + + DesktopTracker deskTrack; + SPDesktop* _desktop; + SPDocument* _document; + ModelColumns* _model; + InternalUIBounce* _pending; + gboolean _dnd_into; + std::vector _dnd_source; + SPObject* _dnd_target; + + GdkEvent* _toggleEvent; + bool down_at_add; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _layersPage; + + sigc::connection desktopChangeConn; + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/clipmaskicon.cpp b/src/ui/widget/clipmaskicon.cpp new file mode 100644 index 000000000..de7638bfe --- /dev/null +++ b/src/ui/widget/clipmaskicon.cpp @@ -0,0 +1,177 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/clipmaskicon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +ClipMaskIcon::ClipMaskIcon() : + Glib::ObjectBase(typeid(ClipMaskIcon)), + Gtk::CellRendererPixbuf(), + _pixClipName(INKSCAPE_ICON("path-intersection")), + _pixInverseName(INKSCAPE_ICON("path-difference")), + _pixMaskName(INKSCAPE_ICON("mask-intersection")), + _property_active(*this, "active", 0), + _property_pixbuf_clip(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_inverse(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_mask(*this, "pixbuf_off", Glib::RefPtr(0)) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); + Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); + + if (!icon_theme->has_icon(_pixClipName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixClipName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixInverseName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixInverseName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixMaskName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixMaskName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + + if (icon_theme->has_icon(_pixClipName)) { + _property_pixbuf_clip = icon_theme->load_icon(_pixClipName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixInverseName)) { + _property_pixbuf_inverse = icon_theme->load_icon(_pixInverseName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixMaskName)) { + _property_pixbuf_mask = icon_theme->load_icon(_pixMaskName, phys, (Gtk::IconLookupFlags)0); + } + + property_pixbuf() = Glib::RefPtr(0); +} + + +#if WITH_GTKMM_3_0 +void ClipMaskIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void ClipMaskIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void ClipMaskIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = phys;//+= (*width) >> 1; + } + if ( height ) { + *height =phys;//+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void ClipMaskIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void ClipMaskIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + switch (_property_active.get_value()) + { + case 1: + property_pixbuf() = _property_pixbuf_clip; + break; + case 2: + property_pixbuf() = _property_pixbuf_mask; + break; + case 3: + property_pixbuf() = _property_pixbuf_inverse; + break; + default: + property_pixbuf() = Glib::RefPtr(0); + break; + } +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +ClipMaskIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/clipmaskicon.h b/src/ui/widget/clipmaskicon.h new file mode 100644 index 000000000..f1c1e7628 --- /dev/null +++ b/src/ui/widget/clipmaskicon.h @@ -0,0 +1,102 @@ +#ifndef __UI_DIALOG_CLIPMASKICON_H__ +#define __UI_DIALOG_CLIPMASKICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class ClipMaskIcon : public Gtk::CellRendererPixbuf { +public: + ClipMaskIcon(); + virtual ~ClipMaskIcon() {}; + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + int phys; + + Glib::ustring _pixClipName; + Glib::ustring _pixInverseName; + Glib::ustring _pixMaskName; + + Glib::Property _property_active; + Glib::Property< Glib::RefPtr > _property_pixbuf_clip; + Glib::Property< Glib::RefPtr > _property_pixbuf_inverse; + Glib::Property< Glib::RefPtr > _property_pixbuf_mask; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp new file mode 100644 index 000000000..b799b5e29 --- /dev/null +++ b/src/ui/widget/highlight-picker.cpp @@ -0,0 +1,176 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "display/cairo-utils.h" + +#include + +#include "highlight-picker.h" +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +HighlightPicker::HighlightPicker() : + Glib::ObjectBase(typeid(HighlightPicker)), + Gtk::CellRendererPixbuf(), + _property_active(*this, "active", 0) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; +} + +HighlightPicker::~HighlightPicker() +{ +} + + +#if WITH_GTKMM_3_0 +void HighlightPicker::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void HighlightPicker::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void HighlightPicker::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = 10;//+= (*width) >> 1; + } + if ( height ) { + *height = 20; //cell_area ? cell_area->get_height() / 2 : 50; //+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void HighlightPicker::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void HighlightPicker::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + GdkRectangle carea; + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 20); + cairo_t *ct = cairo_create(s); + + /* Transparent area */ + carea.x = 0; + carea.y = 0; + carea.width = 10; + carea.height = 20; + + cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard(); + + cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height / 2); + cairo_set_source(ct, checkers); + cairo_fill_preserve(ct); + ink_cairo_set_source_rgba32(ct, _property_active.get_value()); + cairo_fill(ct); + + cairo_pattern_destroy(checkers); + + cairo_rectangle(ct, carea.x, carea.y + carea.height / 2, carea.width, carea.height / 2); + ink_cairo_set_source_rgba32(ct, _property_active.get_value() | 0x000000ff); + cairo_fill(ct); + + cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height); + ink_cairo_set_source_rgba32(ct, 0x333333ff); + cairo_set_line_width(ct, 2); + cairo_stroke(ct); + + cairo_destroy(ct); + cairo_surface_flush(s); + + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s), + GDK_COLORSPACE_RGB, TRUE, 8, + 10, 20, cairo_image_surface_get_stride(s), + ink_cairo_pixbuf_cleanup, s); + convert_pixbuf_argb32_to_normal(pixbuf); + + property_pixbuf() = Glib::wrap(pixbuf); +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +HighlightPicker::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/highlight-picker.h b/src/ui/widget/highlight-picker.h new file mode 100644 index 000000000..2d7dbc14e --- /dev/null +++ b/src/ui/widget/highlight-picker.h @@ -0,0 +1,90 @@ +#ifndef __UI_DIALOG_HIGHLIGHT_PICKER_H__ +#define __UI_DIALOG_HIGHLIGHT_PICKER_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class HighlightPicker : public Gtk::CellRendererPixbuf { +public: + HighlightPicker(); + virtual ~HighlightPicker(); + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + +private: + + Glib::Property _property_active; +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp new file mode 100644 index 000000000..9002a99c2 --- /dev/null +++ b/src/ui/widget/insertordericon.cpp @@ -0,0 +1,166 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/insertordericon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +InsertOrderIcon::InsertOrderIcon() : + Glib::ObjectBase(typeid(InsertOrderIcon)), + Gtk::CellRendererPixbuf(), + _pixTopName(INKSCAPE_ICON("insert-top")), + _pixBottomName(INKSCAPE_ICON("insert-bottom")), + _property_active(*this, "active", 0), + _property_pixbuf_top(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_bottom(*this, "pixbuf_on", Glib::RefPtr(0)) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); + Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); + + if (!icon_theme->has_icon(_pixTopName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixTopName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixBottomName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixBottomName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + + if (icon_theme->has_icon(_pixTopName)) { + _property_pixbuf_top = icon_theme->load_icon(_pixTopName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixBottomName)) { + _property_pixbuf_bottom = icon_theme->load_icon(_pixBottomName, phys, (Gtk::IconLookupFlags)0); + } + + property_pixbuf() = Glib::RefPtr(0); +} + + +#if WITH_GTKMM_3_0 +void InsertOrderIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void InsertOrderIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void InsertOrderIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = phys;//+= (*width) >> 1; + } + if ( height ) { + *height =phys;//+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void InsertOrderIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void InsertOrderIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + switch (_property_active.get_value()) + { + case 1: + property_pixbuf() = _property_pixbuf_top; + break; + case 2: + property_pixbuf() = _property_pixbuf_bottom; + break; + default: + property_pixbuf() = Glib::RefPtr(0); + break; + } +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +InsertOrderIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/insertordericon.h b/src/ui/widget/insertordericon.h new file mode 100644 index 000000000..4b4b51de2 --- /dev/null +++ b/src/ui/widget/insertordericon.h @@ -0,0 +1,100 @@ +#ifndef __UI_DIALOG_INSERTORDERICON_H__ +#define __UI_DIALOG_INSERTORDERICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class InsertOrderIcon : public Gtk::CellRendererPixbuf { +public: + InsertOrderIcon(); + virtual ~InsertOrderIcon() {}; + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + int phys; + + Glib::ustring _pixTopName; + Glib::ustring _pixBottomName; + + Glib::Property _property_active; + Glib::Property< Glib::RefPtr > _property_pixbuf_top; + Glib::Property< Glib::RefPtr > _property_pixbuf_bottom; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/layertypeicon.cpp b/src/ui/widget/layertypeicon.cpp new file mode 100644 index 000000000..bfe855b28 --- /dev/null +++ b/src/ui/widget/layertypeicon.cpp @@ -0,0 +1,167 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/layertypeicon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +LayerTypeIcon::LayerTypeIcon() : + Glib::ObjectBase(typeid(LayerTypeIcon)), + Gtk::CellRendererPixbuf(), + _pixLayerName(INKSCAPE_ICON("dialog-layers")), + _pixGroupName(INKSCAPE_ICON("layer-duplicate")), + _pixPathName(INKSCAPE_ICON("layer-rename")), + _property_active(*this, "active", false), + _property_activatable(*this, "activatable", true), + _property_pixbuf_layer(*this, "pixbuf_on", Glib::RefPtr(0)), + _property_pixbuf_group(*this, "pixbuf_off", Glib::RefPtr(0)), + _property_pixbuf_path(*this, "pixbuf_off", Glib::RefPtr(0)) +{ + + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + int phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_DECORATION); + Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); + + if (!icon_theme->has_icon(_pixLayerName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixLayerName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixGroupName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixGroupName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + if (!icon_theme->has_icon(_pixPathName)) { + Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixPathName.data()), Inkscape::ICON_SIZE_DECORATION ); + } + + if (icon_theme->has_icon(_pixLayerName)) { + _property_pixbuf_layer = icon_theme->load_icon(_pixLayerName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixGroupName)) { + _property_pixbuf_group = icon_theme->load_icon(_pixGroupName, phys, (Gtk::IconLookupFlags)0); + } + if (icon_theme->has_icon(_pixPathName)) { + _property_pixbuf_path = icon_theme->load_icon(_pixPathName, phys, (Gtk::IconLookupFlags)0); + } + + property_pixbuf() = _property_pixbuf_path.get_value(); +} + + +#if WITH_GTKMM_3_0 +void LayerTypeIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void LayerTypeIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void LayerTypeIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width += (*width) >> 1; + } + if ( height ) { + *height += (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void LayerTypeIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void LayerTypeIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + property_pixbuf() = _property_active.get_value() == 1 ? _property_pixbuf_group : (_property_active.get_value() == 2 ? _property_pixbuf_layer : _property_pixbuf_path); +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +LayerTypeIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + _signal_pre_toggle.emit(event); + _signal_toggled.emit(path); + + return false; +} + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/layertypeicon.h b/src/ui/widget/layertypeicon.h new file mode 100644 index 000000000..4ad3f16fb --- /dev/null +++ b/src/ui/widget/layertypeicon.h @@ -0,0 +1,108 @@ +#ifndef __UI_DIALOG_LAYERTYPEICON_H__ +#define __UI_DIALOG_LAYERTYPEICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class LayerTypeIcon : public Gtk::CellRendererPixbuf { +public: + LayerTypeIcon(); + virtual ~LayerTypeIcon() {}; + + sigc::signal signal_toggled() { return _signal_toggled;} + sigc::signal signal_pre_toggle() { return _signal_pre_toggle; } + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy property_activatable() { return _property_activatable.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + Glib::ustring _pixLayerName; + Glib::ustring _pixGroupName; + Glib::ustring _pixPathName; + + Glib::Property _property_active; + Glib::Property _property_activatable; + Glib::Property< Glib::RefPtr > _property_pixbuf_layer; + Glib::Property< Glib::RefPtr > _property_pixbuf_group; + Glib::Property< Glib::RefPtr > _property_pixbuf_path; + + sigc::signal _signal_toggled; + sigc::signal _signal_pre_toggle; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 9bfba5c24a89f0d2ae75fc78a0aa21743a29e978 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 11:56:51 -0500 Subject: Experimental merge of Ponyscape features into trunk (will not compile) (bzr r13090.1.2) --- src/sp-item-group.cpp | 12 ++++++++++++ src/sp-item-group.h | 8 ++++++++ src/ui/dialog/objects.cpp | 12 +++++++++++- src/verbs.h | 2 ++ 4 files changed, 33 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 2cfe97db8..fbd9a6538 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -616,6 +616,18 @@ SPGroup::LayerMode SPGroup::layerDisplayMode(unsigned int dkey) const { } } +void SPGroup::setExpanded(bool isexpanded) { + if ( _expanded != isexpanded ){ + _expanded = isexpanded; + } +} + +void SPGroup::setInsertBottom(bool insertbottom) { + if ( _insertBottom != insertbottom) { + _insertBottom = insertbottom; + } +} + void SPGroup::setLayerDisplayMode(unsigned int dkey, SPGroup::LayerMode mode) { if ( layerDisplayMode(dkey) != mode ) { _display_modes[dkey] = mode; diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 2004a72b8..68bbd083a 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -35,12 +35,20 @@ public: enum LayerMode { GROUP, LAYER, MASK_HELPER }; + bool _expanded; + bool _insertBottom; LayerMode _layer_mode; std::map _display_modes; LayerMode layerMode() const { return _layer_mode; } void setLayerMode(LayerMode mode); + bool expanded() const { return _expanded; } + void setExpanded(bool isexpanded); + + bool insertBottom() const { return _insertBottom; } + void setInsertBottom(bool insertbottom); + LayerMode effectiveLayerMode(unsigned int display_key) const { if ( _layer_mode == LAYER ) { return LAYER; diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 31e73db29..5023a8813 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -57,6 +57,8 @@ //#define DUMP_LAYERS 1 +guint get_group0_keyval(GdkEventKey *event); + namespace Inkscape { namespace UI { namespace Dialog { @@ -414,7 +416,7 @@ bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) row[_model->_colLocked] = item ? !item->isSensitive() : false; row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; - row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? (item->clip_ref->getObject()->inverse ? 3 : 1) : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; + row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; return true; @@ -2035,6 +2037,14 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) } //namespace UI } //namespace Inkscape +guint get_group0_keyval(GdkEventKey *event) { + guint keyval = 0; + gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( + gdk_display_get_default()), event->hardware_keycode, + (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, + NULL, NULL, NULL); + return keyval; +} /* Local Variables: diff --git a/src/verbs.h b/src/verbs.h index 0f764eb29..b8a0b1fd5 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -289,6 +289,8 @@ enum { SP_VERB_DIALOG_INPUT, SP_VERB_DIALOG_EXTENSIONEDITOR, SP_VERB_DIALOG_LAYERS, + SP_VERB_DIALOG_OBJECTS, + SP_VERB_DIALOG_TAGS, SP_VERB_DIALOG_LIVE_PATH_EFFECT, SP_VERB_DIALOG_FILTER_EFFECTS, SP_VERB_DIALOG_SVG_FONTS, -- cgit v1.2.3 From 05f60fa645caeda752fe6bffb33993f6485cadb6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 12:48:51 -0500 Subject: Experimental merge of Ponyscape to Inkscape trunk (does not compile) (bzr r13090.1.3) --- src/ui/widget/filter-effect-chooser.cpp | 2 ++ src/ui/widget/filter-effect-chooser.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 65706a9dc..3932bdfd4 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -23,6 +23,8 @@ namespace Widget { SimpleFilterModifier::SimpleFilterModifier(int flags) : _lb_blend(_("Blend mode:")), + _lb_blur(_("_Blur:")), + _lb_blur_unit(_("%")), _blend(BlendModeConverter, SP_ATTR_INVALID, false), _blur(_("Blur (%)"), 0, 0, 100, 1, 0.01, 1) { diff --git a/src/ui/widget/filter-effect-chooser.h b/src/ui/widget/filter-effect-chooser.h index 6f0c2f26e..a467adcb1 100644 --- a/src/ui/widget/filter-effect-chooser.h +++ b/src/ui/widget/filter-effect-chooser.h @@ -54,11 +54,13 @@ public: double get_blur_value() const; void set_blur_value(const double); void set_blur_sensitive(const bool); + Gtk::Label *get_blur_label() { return &_lb_blur; }; private: int _flags; Gtk::HBox _hb_blend; - Gtk::Label _lb_blend; + Gtk::HBox _hb_blur; + Gtk::Label _lb_blend, _lb_blur, _lb_blur_unit; ComboBoxEnum _blend; SpinScale _blur; -- cgit v1.2.3 From ac167afb76ab4c730ac9dc945dc5dcd8efb8f5cf Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 12:59:13 -0500 Subject: Experimental Ponyscape to Inkscape merge (does not compile) (bzr r13090.1.4) --- src/display/cairo-utils.cpp | 4 +--- src/display/cairo-utils.h | 2 ++ src/ui/widget/Makefile_insert | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 5b358ade7..c0a17bcdd 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -30,8 +30,6 @@ #include "helper/geom-curves.h" #include "display/cairo-templates.h" -static void ink_cairo_pixbuf_cleanup(guchar *, void *); - /** * Key for cairo_surface_t to keep track of current color interpolation value * Only the address of the structure is used, it is never initialized. See: @@ -1119,7 +1117,7 @@ GdkPixbuf *ink_pixbuf_create_from_cairo_surface(cairo_surface_t *s) * to gdk_pixbuf_new_from_data when creating a GdkPixbuf backed by * a Cairo surface. */ -static void ink_cairo_pixbuf_cleanup(guchar * /*pixels*/, void *data) +void ink_cairo_pixbuf_cleanup(guchar * /*pixels*/, void *data) { cairo_surface_t *surface = static_cast(data); cairo_surface_destroy(surface); diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 505e2ca77..fa0ee8853 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -21,6 +21,8 @@ #include "style.h" struct SPColor; +void ink_cairo_pixbuf_cleanup(guchar *, void *); +void convert_pixbuf_argb32_to_normal(GdkPixbuf *pb); namespace Inkscape { diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index 710b95c2b..e388b27f5 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -81,5 +81,10 @@ ink_common_sources += \ ui/widget/unit-menu.cpp \ ui/widget/unit-menu.h \ ui/widget/unit-tracker.h \ - ui/widget/unit-tracker.cpp - + ui/widget/unit-tracker.cpp \ + ui/widget/clipmaskicon.cpp \ + ui/widget/clipmaskicon.h \ + ui/widget/highlight-picker.cpp \ + ui/widget/highlight-picker.h \ + ui/widget/layertypeicon.cpp \ + ui/widget/layertypeicon.h -- cgit v1.2.3 From 1f7732ba927a31166d834a206bdfc7d20128d483 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 14:15:38 -0500 Subject: Attempt at merging certaing features of Ponyscape to trunk (will not link) (bzr r13090.1.5) --- src/sp-item.cpp | 1 + src/sp-item.h | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index aec749929..279606481 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -416,6 +416,7 @@ void SPItem::build(SPDocument *document, Inkscape::XML::Node *repr) { object->readAttr( "inkscape:transform-center-y" ); object->readAttr( "inkscape:connector-avoid" ); object->readAttr( "inkscape:connection-points" ); + object->readAttr( "inkscape:highlight-color" ); SPObject::build(document, repr); } diff --git a/src/sp-item.h b/src/sp-item.h index dc0c54a80..0c0edae2a 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -146,6 +146,10 @@ public: void setHidden(bool hidden); /* Objects dialogue */ + bool isSensitive() const { + return sensitive; + }; + bool isHighlightSet() const; guint32 highlight_color() const; -- cgit v1.2.3 From 8830d1ad5ab0693313d760cc99e2df0f35c9f6d9 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 16:29:52 -0500 Subject: Updated to include (non-functional) Objects dialogue (bzr r13090.1.6) --- src/menus-skeleton.h | 1 + src/ui/dialog/objects.cpp | 41 ++++++++++++++++++++++++++++++++++++++ src/ui/widget/Makefile_insert | 4 +++- src/ui/widget/highlight-picker.cpp | 32 ++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 3fcb77207..855b7774b 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -179,6 +179,7 @@ static char const menus_skeleton[] = " \n" " \n" " \n" +" \n" " \n" " \n" " \n" diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 5023a8813..ebfa16f02 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -37,6 +37,7 @@ #include "ui/widget/insertordericon.h" #include "ui/widget/clipmaskicon.h" #include "ui/widget/highlight-picker.h" +#include "ui/tools/node-tool.h" #include "verbs.h" #include "widgets/icon.h" #include "xml/node.h" @@ -54,6 +55,7 @@ #include "sp-clippath.h" #include "sp-mask.h" #include "layer-manager.h" +#include "tools-switch.h" //#define DUMP_LAYERS 1 @@ -2037,6 +2039,9 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) } //namespace UI } //namespace Inkscape +//should be okay to put these here because they are never referenced anywhere else +using namespace Inkscape::UI::Tools; + guint get_group0_keyval(GdkEventKey *event) { guint keyval = 0; gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( @@ -2046,6 +2051,42 @@ guint get_group0_keyval(GdkEventKey *event) { return keyval; } +void SPItem::setHighlightColor(guint32 const color) +{ + g_free(_highlightColor); + if (color & 0x000000ff) + { + _highlightColor = g_strdup_printf("%u", color); + } + else + { + _highlightColor = NULL; + } + + NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(tool->desktop, TOOLS_NODES); + } + } +} + +void SPItem::unsetHighlightColor() +{ + g_free(_highlightColor); + _highlightColor = NULL; + NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(tool->desktop, TOOLS_NODES); + } + } +} + /* Local Variables: mode:c++ diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index e388b27f5..2c543c5cc 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -87,4 +87,6 @@ ink_common_sources += \ ui/widget/highlight-picker.cpp \ ui/widget/highlight-picker.h \ ui/widget/layertypeicon.cpp \ - ui/widget/layertypeicon.h + ui/widget/layertypeicon.h \ + ui/widget/insertordericon.cpp \ + ui/widget/insertordericon.h diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index b799b5e29..bf93fa960 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -157,11 +157,41 @@ HighlightPicker::activate_vfunc(GdkEvent* event, return false; } - } // namespace Widget } // namespace UI } // namespace Inkscape +//should be okay to put this here +/** + * Converts GdkPixbuf's data to premultiplied ARGB. + * This function will convert a GdkPixbuf in place into Cairo's native pixel format. + * Note that this is a hack intended to save memory. When the pixbuf is in Cairo's format, + * using it with GTK will result in corrupted drawings. + */ +void +convert_pixbuf_normal_to_argb32(GdkPixbuf *pb) +{ + convert_pixels_pixbuf_to_argb32( + gdk_pixbuf_get_pixels(pb), + gdk_pixbuf_get_width(pb), + gdk_pixbuf_get_height(pb), + gdk_pixbuf_get_rowstride(pb)); +} + +/** + * Converts GdkPixbuf's data back to its native format. + * Once this is done, the pixbuf can be used with GTK again. + */ +void +convert_pixbuf_argb32_to_normal(GdkPixbuf *pb) +{ + convert_pixels_argb32_to_pixbuf( + gdk_pixbuf_get_pixels(pb), + gdk_pixbuf_get_width(pb), + gdk_pixbuf_get_height(pb), + gdk_pixbuf_get_rowstride(pb)); +} + /* Local Variables: mode:c++ -- cgit v1.2.3 From 169c4551d14f4403f01724b93740c23e841f5fb0 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 17:00:28 -0500 Subject: Fix verbs.cpp (bzr r13090.1.7) --- src/verbs.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index 653d5f892..4ac5fdc41 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2040,6 +2040,9 @@ void DialogVerb::perform(SPAction *action, void *data) case SP_VERB_DIALOG_LAYERS: dt->_dlg_mgr->showDialog("LayersPanel"); break; + case SP_VERB_DIALOG_OBJECTS: + dt->_dlg_mgr->showDialog("ObjectsPanel"); + break; case SP_VERB_DIALOG_LIVE_PATH_EFFECT: dt->_dlg_mgr->showDialog("LivePathEffect"); break; -- cgit v1.2.3 From b8fb6e46b8e96c90a2182061d3a6c4fab1e7f784 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 17:23:47 -0500 Subject: Attempt 2 at getting objects dialogue (bzr r13090.1.8) --- src/verbs.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index 4ac5fdc41..b5c5abe13 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2861,6 +2861,8 @@ Verb *Verb::_base_verbs[] = { N_("Query information about extensions"), NULL), new DialogVerb(SP_VERB_DIALOG_LAYERS, "DialogLayers", N_("Layer_s..."), N_("View Layers"), INKSCAPE_ICON("dialog-layers")), + new DialogVerb(SP_VERB_DIALOG_OBJECTS, "DialogObjects", N_("Object_s..."), + N_("View Objects"), INKSCAPE_ICON("dialog-layers")), new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), N_("Manage, edit, and apply path effects"), NULL), new DialogVerb(SP_VERB_DIALOG_FILTER_EFFECTS, "DialogFilterEffects", N_("Filter _Editor..."), -- cgit v1.2.3 From fc643d9de8b5b3faf6d43559a43308fbce56e592 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 17:39:47 -0500 Subject: Fix objects dialogue (bzr r13090.1.9) --- src/ui/dialog/dialog-manager.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 6d32e3aa8..bbb55ceee 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -54,6 +54,7 @@ #include "ui/dialog/xml-tree.h" #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" +#include "ui/dialog/objects.h" namespace Inkscape { namespace UI { @@ -108,6 +109,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); + registerFactory("ObjectsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -142,6 +144,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); + registerFactory("ObjectsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); -- cgit v1.2.3 From fef7175272bbed79c874496c71092d3ba6e38d98 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 2 Mar 2014 23:50:04 +0100 Subject: Add new curve structure to show temporay item while draw on bspline and spiro, maybe the previous usage of the blue_curve give the strange errors in mac noticed by suv (bzr r11950.1.266) --- src/ui/tools/freehand-base.cpp | 22 ++++++++++++++++++++++ src/ui/tools/freehand-base.h | 4 ++++ src/ui/tools/pen-tool.cpp | 28 +++++++++++++++++++--------- 3 files changed, 45 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 31d2f6191..cb6111bd5 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -82,6 +82,8 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , red_curve(NULL) , blue_bpath(NULL) , blue_curve(NULL) + , blue2_bpath(NULL) + , blue2_curve(NULL) , green_bpaths(NULL) , green_curve(NULL) , green_anchor(NULL) @@ -137,6 +139,13 @@ void FreehandBase::setup() { // Create blue curve this->blue_curve = new SPCurve(); + // Create blue2 bpath + this->blue2_bpath = sp_canvas_bpath_new(sp_desktop_sketch(this->desktop), NULL); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue2_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + + // Create blue2 curve + this->blue2_curve = new SPCurve(); + // Create green curve this->green_curve = new SPCurve(); @@ -483,6 +492,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); + // Blue2 + dc->blue2_curve->reset(); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); + //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada //porque la modificamos al continuar por un anchor @@ -718,6 +731,15 @@ static void spdc_free_colors(FreehandBase *dc) dc->blue_curve = dc->blue_curve->unref(); } + // Blue2 + if (dc->blue2_bpath) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->blue2_bpath)); + dc->blue2_bpath = NULL; + } + if (dc->blue2_curve) { + dc->blue2_curve = dc->blue2_curve->unref(); + } + // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index c8da9faed..d5c2fc9ba 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -57,6 +57,10 @@ public: SPCanvasItem *blue_bpath; SPCurve *blue_curve; + // Blue2 + SPCanvasItem *blue2_bpath; + SPCurve *blue2_curve; + // Green GSList *green_bpaths; SPCurve *green_curve; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 65823b642..5846c3cec 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1303,6 +1303,9 @@ void PenTool::_resetColors() { // Blue this->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), NULL); + // Blue2 + this->blue2_curve->reset(); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue2_bpath), NULL); // Green while (this->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); @@ -1373,6 +1376,16 @@ void PenTool::_bspline_spiro_color() this->green_color = 0x00ff000; remake_green_bpaths = true; } + }else if(this->bspline){ + //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent + if(this->green_color != 0xff00007f){ + //since we are not im spiro mode, we assign the original colours + //to the red and the green curve, removing their transparency + this->red_color = 0xff00007f; + //Damos color rojo a la linea verde + this->green_color = 0xff00007f; + remake_green_bpaths = true; + } }else{ //If we come from working with the spiro curve and change the mode the "green_curve" colour is transparent if(this->green_color != 0x00ff007f){ @@ -1383,9 +1396,7 @@ void PenTool::_bspline_spiro_color() remake_green_bpaths = true; } //we hide the spiro/bspline rests - if(!this->bspline){ - sp_canvas_item_hide(this->blue_bpath); - } + sp_canvas_item_hide(this->blue2_bpath); } //We erase all the "green_bpaths" to recreate them after with the colour //transparency recently modified @@ -1771,11 +1782,11 @@ void PenTool::_bspline_spiro_build() this->_spiro_doEffect(curve); } - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_item_show(this->blue_bpath); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue2_bpath), curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(this->blue2_bpath), this->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_item_show(this->blue2_bpath); curve->unref(); - this->blue_curve->reset(); + this->blue2_curve->reset(); //We hide the holders that doesn't contribute anything if(this->spiro){ sp_canvas_item_show(this->c1); @@ -1787,7 +1798,7 @@ void PenTool::_bspline_spiro_build() sp_canvas_item_hide(this->cl0); }else{ //if the curve is empty - sp_canvas_item_hide(this->blue_bpath); + sp_canvas_item_hide(this->blue2_bpath); } } @@ -2167,7 +2178,6 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - if(this->spiro || this->bspline) this->blue_curve->reset(); //spanish para cancelar linea sin un segmento creado this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); -- cgit v1.2.3 From 93e2eef0d931bc2250b0328ddc24dac76c7c3e03 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 18:18:32 -0500 Subject: Modified Objects dialogue to stop crashing on change of highlight color (bzr r13090.1.10) --- src/sp-item.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 279606481..79d8cc37d 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -99,6 +99,8 @@ SPItem::SPItem() : SPObject() { sensitive = TRUE; bbox_valid = FALSE; + _highlightColor = NULL; + transform_center_x = 0; transform_center_y = 0; -- cgit v1.2.3 From 4eed716131afa00f3590b7d60600ef0c476c78e3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 2 Mar 2014 20:24:50 -0500 Subject: Fixed path color when changed by Objects Dialog (bzr r13090.1.11) --- src/attributes.cpp | 1 + src/attributes.h | 1 + src/sp-item.cpp | 17 +++++++++++++++++ src/ui/tool/multi-path-manipulator.cpp | 6 +++--- src/ui/tool/multi-path-manipulator.h | 2 +- src/ui/tools/node-tool.cpp | 3 ++- 6 files changed, 25 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index ee2a80fd3..4e39b648e 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -41,6 +41,7 @@ static SPStyleProp const props[] = { {SP_ATTR_TRANSFORM_CENTER_X, "inkscape:transform-center-x"}, {SP_ATTR_TRANSFORM_CENTER_Y, "inkscape:transform-center-y"}, {SP_ATTR_INKSCAPE_PATH_EFFECT, "inkscape:path-effect"}, + {SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, "inkscape:highlight-color"}, /* SPAnchor */ {SP_ATTR_XLINK_HREF, "xlink:href"}, {SP_ATTR_XLINK_TYPE, "xlink:type"}, diff --git a/src/attributes.h b/src/attributes.h index b8843fcb7..d1c93b819 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -40,6 +40,7 @@ enum SPAttributeEnum { SP_ATTR_TRANSFORM_CENTER_X, SP_ATTR_TRANSFORM_CENTER_Y, SP_ATTR_INKSCAPE_PATH_EFFECT, + SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR, /* SPAnchor */ SP_ATTR_XLINK_HREF, SP_ATTR_XLINK_TYPE, diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 79d8cc37d..ff3e3a31c 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -493,11 +493,23 @@ void SPItem::set(unsigned int key, gchar const* value) { break; } case SP_ATTR_SODIPODI_INSENSITIVE: + { item->sensitive = !value; for (SPItemView *v = item->display; v != NULL; v = v->next) { v->arenaitem->setSensitive(item->sensitive); } break; + } + case SP_ATTR_INKSCAPE_HIGHLIGHT_COLOR: + { + g_free(item->_highlightColor); + if (value) { + item->_highlightColor = g_strdup(value); + } else { + item->_highlightColor = NULL; + } + break; + } case SP_ATTR_CONNECTOR_AVOID: item->avoidRef->setAvoid(value); break; @@ -706,6 +718,11 @@ Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::X g_free ((void *) uri); } } + if (item->_highlightColor){ + repr->setAttribute("inkscape:highlight-color", item->_highlightColor); + } else { + repr->setAttribute("inkscape:highlight-color", NULL); + } SPObject::write(xml_doc, repr, flags); diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 65987ad52..b54b5ad07 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -182,7 +182,7 @@ void MultiPathManipulator::setItems(std::set const &s) ShapeRecord const &r = *i; if (!SP_IS_PATH(r.item) && !IS_LIVEPATHEFFECT(r.item)) continue; boost::shared_ptr newpm(new PathManipulator(*this, (SPPath*) r.item, - r.edit_transform, _getOutlineColor(r.role), r.lpe_key)); + r.edit_transform, _getOutlineColor(r.role, r.item), r.lpe_key)); newpm->showHandles(_show_handles); // always show outlines for clips and masks newpm->showOutline(_show_outline || r.role != SHAPE_ROLE_NORMAL); @@ -833,7 +833,7 @@ void MultiPathManipulator::_doneWithCleanup(gchar const *reason, bool alert_LPE) } /** Get an outline color based on the shape's role (normal, mask, LPE parameter, etc.). */ -guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role) +guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role, SPItem *item) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); switch(role) { @@ -845,7 +845,7 @@ guint32 MultiPathManipulator::_getOutlineColor(ShapeRole role) return prefs->getColor("/tools/nodes/lpe_param_color", 0x009000ff); case SHAPE_ROLE_NORMAL: default: - return prefs->getColor("/tools/nodes/outline_color", 0xff0000ff); + return item->highlight_color(); } } diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index 1328372c6..d3746b878 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -106,7 +106,7 @@ private: void _commit(CommitEvent cps); void _done(gchar const *reason, bool alert_LPE = false); void _doneWithCleanup(gchar const *reason, bool alert_LPE = false); - guint32 _getOutlineColor(ShapeRole role); + guint32 _getOutlineColor(ShapeRole role, SPItem *item); MapType _mmap; public: diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index b1e11bd66..719b67108 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -473,7 +473,8 @@ bool NodeTool::root_handler(GdkEvent* event) { SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), - prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, + //prefs->getInt("/tools/nodes/highlight_color", 0xff0000ff), 1.0, + over_item->highlight_color(), 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(flash), 0, SP_WIND_RULE_NONZERO); -- cgit v1.2.3 From 224de42669ff754155838d37c48a56fa70c9bc94 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 4 Mar 2014 12:38:20 +0100 Subject: Reduce a half the spiro distance to redraw (bzr r11950.1.273) --- src/ui/tools/pen-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 5846c3cec..0c97bd445 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -710,7 +710,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); }else{ - if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) { + if ( Geom::LInfty( event_w - pen_drag_origin_w ) > (tolerance/2) || mevent.time == 0) { this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); pen_drag_origin_w = event_w; -- cgit v1.2.3 From 3d7f15d8b4adc83c04a2ba5c654529beeeec0c3b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 4 Mar 2014 20:23:58 +0100 Subject: Change tooltip to one more explicit to make cusp nodes (bzr r11950.1.275) --- src/ui/tools/pen-tool.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 0c97bd445..ad77fcb53 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -642,7 +642,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { if(!this->spiro && !this->bspline){ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path.")); }else{ - this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path. Shift to cusp node")); + this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path. Shift+Click make a cusp node")); } this->anchor_statusbar = true; } else if (!anchor && this->anchor_statusbar) { @@ -656,7 +656,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { if(!this->spiro && !this->bspline){ this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point.")); }else{ - this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point. Shift to cusp node")); + this->message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point. Shift+Click make a cusp node")); } this->anchor_statusbar = true; } else if (!anchor && this->anchor_statusbar) { @@ -2084,8 +2084,8 @@ void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint sta _("Line segment: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"); if(this->spiro || this->bspline){ message = is_curve ? - _("Curve segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path" ): - _("Line segment: angle %3.2f°, distance %s; with Shift to cusp node, Enter to finish the path"); + _("Curve segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter to finish the path" ): + _("Line segment: angle %3.2f°, distance %s; with Shift+Click make a cusp node, Enter to finish the path"); } this->_setAngleDistanceStatusMessage(p, 0, message); } -- cgit v1.2.3 From dc1f7ce719d703d8dd4d7747d1967a3e8a1bfb18 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 16:53:56 -0500 Subject: Remove tag dialog temporarily (bzr r13090.1.13) --- src/ui/dialog/Makefile_insert | 2 -- src/ui/dialog/dialog-manager.cpp | 6 +++--- src/ui/dialog/swatches.cpp | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index bdb1abcda..1cf667f2a 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -113,6 +113,4 @@ ink_common_sources += \ ui/dialog/lpe-powerstroke-properties.h \ ui/dialog/objects.cpp \ ui/dialog/objects.h \ - ui/dialog/tags.cpp \ - ui/dialog/tags.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index bbfea8cf0..1fddbf007 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -55,7 +55,7 @@ #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" #include "ui/dialog/objects.h" -#include "ui/dialog/tags.h" +//#include "ui/dialog/tags.h" namespace Inkscape { namespace UI { @@ -111,7 +111,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - registerFactory("TagsPanel", &create); + //registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -147,7 +147,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - registerFactory("TagsPanel", &create); + //registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 5e77a28ab..711bcfe2d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -20,6 +20,7 @@ #include "swatches.h" #include +#include #include #include @@ -57,6 +58,22 @@ #include "gradient-chemistry.h" #include "helper/action.h" #include "helper/action-context.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-pattern.h" +#include "icon-size.h" +#include "widgets/icon.h" +#include "filedialog.h" +#include "sp-stop.h" +#include "svg/svg-color.h" +#include "sp-radial-gradient.h" +#include "color-rgba.h" +#include "event-context.h" +#include +//sorry! +#ifdef WIN32 +#include +#endif namespace Inkscape { namespace UI { @@ -64,6 +81,7 @@ namespace Dialogs { #define VBLOCK 16 #define PREVIEW_PIXBUF_WIDTH 128 +#define SWATCHES_FILE_NAME "swatches.svg" void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); -- cgit v1.2.3 From 12971e975dae83c23e89cdbff99e990d3916b6ff Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 18:05:52 -0500 Subject: Added some basic swatch stuff (does not compile) (bzr r13090.1.14) --- src/ui/dialog/swatches.cpp | 2940 ++++++++++++++++++++++++++++++-------------- src/ui/dialog/swatches.h | 155 ++- 2 files changed, 2157 insertions(+), 938 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 711bcfe2d..a0c79b8ac 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -43,10 +43,10 @@ #include "path-prefix.h" #include "preferences.h" #include "sp-item.h" +#include "sp-gradient-fns.h" #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" -#include "ui/previewholder.h" #include "widgets/desktop-widget.h" #include "widgets/gradient-vector.h" #include "widgets/eek-preview.h" @@ -57,7 +57,6 @@ #include "verbs.h" #include "gradient-chemistry.h" #include "helper/action.h" -#include "helper/action-context.h" #include "xml/node-observer.h" #include "xml/repr.h" #include "sp-pattern.h" @@ -68,1172 +67,2255 @@ #include "svg/svg-color.h" #include "sp-radial-gradient.h" #include "color-rgba.h" -#include "event-context.h" +#include "svg/css-ostringstream.h" +//#include "event-context.h" //no longer exists #include -//sorry! #ifdef WIN32 #include #endif +guint get_group0_keyval(GdkEventKey *event); +void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); + namespace Inkscape { namespace UI { namespace Dialogs { -#define VBLOCK 16 -#define PREVIEW_PIXBUF_WIDTH 128 #define SWATCHES_FILE_NAME "swatches.svg" -void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); - -std::list userSwatchPages; -std::list systemSwatchPages; -static std::map docPalettes; -static std::vector docTrackings; -static std::map docPerPanel; - - -class SwatchesPanelHook : public SwatchesPanel -{ -public: - static void convertGradient( GtkMenuItem *menuitem, gpointer userData ); - static void deleteGradient( GtkMenuItem *menuitem, gpointer userData ); -}; +static char* trim( char* str ) { + char* ret = str; + while ( *str && (*str == ' ' || *str == '\t') ) { + str++; + } + ret = str; + while ( *str ) { + str++; + } + str--; + while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { + *str-- = 0; + } + return ret; +} -static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(false); +static void skipWhitespace( char*& str ) { + while ( *str == ' ' || *str == '\t' ) { + str++; } } -static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(true); +static bool parseNum( char*& str, int& val ) { + val = 0; + while ( '0' <= *str && *str <= '9' ) { + val = val * 10 + (*str - '0'); + str++; } + bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); + return retval; } -static GtkWidget* popupMenu = 0; -static GtkWidget *popupSubHolder = 0; -static GtkWidget *popupSub = 0; -static std::vector popupItems; -static std::vector popupExtras; -static ColorItem* bounceTarget = 0; -static SwatchesPanel* bouncePanel = 0; +static char * SwatchFile; +static SPDocument * SwatchDocument; +static unsigned int page_suffix; -static void redirClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) +static void loadPalletFile() { - if ( bounceTarget ) { - handleClick( GTK_WIDGET(menuitem), bounceTarget ); + if (!SwatchDocument) { + SwatchFile=g_build_filename(INKSCAPE_PALETTESDIR, _("swatches.svg"), NULL); + SwatchDocument=SPDocument::createNewDoc (SwatchFile, TRUE); + if (!SwatchDocument) { + SwatchDocument = SPDocument::createNewDoc(NULL, TRUE, true); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } } } -static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) +static void addStop( Inkscape::XML::Node *parent, Glib::ustring const &color, gfloat opacity, gchar const *offset ) { - if ( bounceTarget ) { - handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget ); +#ifdef SP_GR_VERBOSE + g_message("addStop(%p, %s, %d, %s)", parent, color.c_str(), opacity, offset); +#endif + Inkscape::XML::Node *stop = parent->document()->createElement("svg:stop"); + { + gchar *tmp = g_strdup_printf( "stop-color:%s;stop-opacity:%f;", color.c_str(), opacity < 0.0 ? 0.0 : (opacity > 1.0 ? 1.0 : opacity) ); + stop->setAttribute( "style", tmp ); + g_free(tmp); } + + stop->setAttribute( "offset", offset ); + + parent->appendChild(stop); + Inkscape::GC::release(stop); } -static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) +static SPGroup* importGPL(SPDocument* doc, const gchar* full) { - if ( gr ) { - bool shown = false; - if ( desktop && desktop->doc() ) { - Inkscape::Selection *selection = sp_desktop_selection( desktop ); - GSList const *items = selection->itemList(); - if (items) { - SPStyle *query = sp_style_new( desktop->doc() ); - int result = objects_query_fillstroke(const_cast(items), query, true); - if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { - // could be pertinent - if (query->fill.isPaintserver()) { - SPPaintServer* server = query->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* grad = SP_GRADIENT(server); - if ( grad->isSwatch() && grad->getId() == gr->getId()) { - desktop->_dlg_mgr->showDialog("FillAndStroke"); - shown = true; + SPGroup* ret = NULL; + if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { + + /*Load the pallet file here*/ + char block[1024]; + FILE *f = Inkscape::IO::fopen_utf8name( full, "r" ); + if ( f ) { + char* result = fgets( block, sizeof(block), f ); + if ( result ) { + if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { + bool inHeader = true; + bool hasErr = false; + + Inkscape::XML::Node * page = doc->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (doc->getObjectById(id)); + + page->setAttribute("id", id); + + do { + result = fgets( block, sizeof(block), f ); + block[sizeof(block) - 1] = 0; + if ( result ) { + if ( block[0] == '#' ) { + // ignore comment + } else { + char *ptr = block; + // very simple check for header versus entry + while ( *ptr == ' ' || *ptr == '\t' ) { + ptr++; + } + if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { + // blank line. skip it. + } else if ( '0' <= *ptr && *ptr <= '9' ) { + // should be an entry link + inHeader = false; + ptr = block; + Glib::ustring name(""); + skipWhitespace(ptr); + if ( *ptr ) { + int r = 0; + int g = 0; + int b = 0; + hasErr = parseNum(ptr, r); + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, g); + } + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, b); + } + if ( !hasErr && *ptr ) { + char* n = trim(ptr); + if (n != NULL) { + name = g_dpgettext2(NULL, "Palette", n); + } + } + if ( !hasErr ) { + // Add the entry now + + Inkscape::XML::Node *grad = doc->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute("inkscape:label", name.c_str()); + grad->setAttribute( "osb:paint", "solid", 0 ); + SPColor color((float)r / 255, (float)g / 255, (float)b / 255); + addStop(grad, color.toString(), 1, "0"); + page->appendChild(grad); + Inkscape::GC::release(grad); + } + } else { + hasErr = true; + } + } else { + if ( !inHeader ) { + // Hmmm... probably bad. Not quite the format we want? + hasErr = true; + } else { + char* sep = strchr(result, ':'); + if ( sep ) { + *sep = 0; + char* val = trim(sep + 1); + char* name = trim(result); + if ( *name ) { + if ( strcmp( "Name", name ) == 0 ) + { + page->setAttribute("inkscape:label", val); + } + } else { + // error + hasErr = true; + } + } else { + // error + hasErr = true; + } + } + } } } + } while ( result && !hasErr ); + if ( !hasErr ) { + doc->getDefs()->appendChild(page); + Inkscape::GC::release(page); + SPObject* obj = doc->getObjectByRepr(page); + if (SP_IS_GROUP(obj)) { + ret = SP_GROUP(obj); + } + #if ENABLE_MAGIC_COLORS + ColorItem::_wireMagicColors( onceMore ); + #endif // ENABLE_MAGIC_COLORS + } else { + delete page; } } - sp_style_unref(query); } - } - if (!shown) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (prefs->getBool("/dialogs/gradienteditor/showlegacy", false)) { - // Legacy gradient dialog - GtkWidget *dialog = sp_gradient_vector_editor_new( gr ); - gtk_widget_show( dialog ); - } else { - // Invoke the gradient tool - Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); - if ( verb ) { - SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); - if ( action ) { - sp_action_perform( action, NULL ); - } - } - } + fclose(f); } + /* end loading the pallet file*/ } + return ret; } -static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ ) +SwatchesPanel& SwatchesPanel::getInstance() { - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - SPDocument *doc = desktop ? desktop->doc() : 0; - if (doc) { - std::string targetName(bounceTarget->def.descr); - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( targetName == grad->getId() ) { - editGradientImpl( desktop, grad ); - break; + return *new SwatchesPanel(); +} + +class SwatchesPanel::StopWatcher : public Inkscape::XML::NodeObserver { +public: + StopWatcher(SwatchesPanel* pnl, SPStop* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()) + { + _repr->addObserver(*this); + } + + ~StopWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ){} + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj) { + _pnl->_defsChanged( ); + } + } + + SwatchesPanel* _pnl; + SPStop* _obj; + Inkscape::XML::Node* _repr; +}; + +class SwatchesPanel::GradientWatcher : public Inkscape::XML::NodeObserver { +public: + GradientWatcher(SwatchesPanel* pnl, SPGradient* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")), + _swatchAttr(g_quark_from_string("osb:paint")) + { + _repr->addObserver(*this); + } + + ~GradientWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch()) { + _pnl->_defsChanged( ); + } + } + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch() ) { + _pnl->_defsChanged( ); + } + } + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) + { + if ( _pnl && _obj && _obj->isSwatch() ) { + _pnl->_defsChanged( ); + } + } + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj && ((_obj->isSwatch() && name == _labelAttr) || name == _swatchAttr)) { + _pnl->_defsChanged( ); + } + } + + SwatchesPanel* _pnl; + SPGradient* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; + GQuark _swatchAttr; +}; + +class SwatchesPanel::SwatchWatcher : public Inkscape::XML::NodeObserver { +public: + SwatchWatcher(SwatchesPanel* pnl, SPObject* obj, bool builtIn) : + _pnl(pnl), + _obj(obj), + _builtIn(builtIn), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")), + _swatchAttr(g_quark_from_string("osb:paint")) + { + _repr->addObserver(*this); + } + + ~SwatchWatcher() { + _repr->removeObserver(*this); + } + + virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj) { + SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); + if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); } } } } -} - -void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData ) -{ - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - SPDocument *doc = desktop ? desktop->doc() : 0; - gint index = GPOINTER_TO_INT(userData); - if ( doc && (index >= 0) && (static_cast(index) < popupItems.size()) ) { - Glib::ustring targetName = popupItems[index]; - - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( targetName == grad->getId() ) { - grad->setSwatch(); - DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, - _("Add gradient stop")); - break; + virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) + { + if ( _pnl && _obj) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); + } + } + } + virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) + { + if ( _pnl && _obj) { + SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); + if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); } } } } -} + virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if (_pnl && _obj && name == _labelAttr) { + if (_builtIn) { + _pnl->_swatchesChanged( ); + } else { + _pnl->_defsChanged( ); + } + } + } -void SwatchesPanelHook::deleteGradient( GtkMenuItem */*menuitem*/, gpointer /*userData*/ ) + SwatchesPanel* _pnl; + SPObject* _obj; + bool _builtIn; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; + GQuark _swatchAttr; +}; + +class SwatchesPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord { - if ( bounceTarget ) { - SwatchesPanel* swp = bouncePanel; - SPDesktop* desktop = swp ? swp->getDesktop() : 0; - sp_gradient_unset_swatch(desktop, bounceTarget->def.descr); +public: + + ModelColumns() + { + add(_colObject); + add(_colLabel); } -} + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; +}; -static SwatchesPanel* findContainingPanel( GtkWidget *widget ) +class SwatchesPanel::ModelColumnsDoc : public Gtk::TreeModel::ColumnRecord { - SwatchesPanel *swp = 0; +public: - std::map rawObjects; - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - rawObjects[GTK_WIDGET(it->first->gobj())] = it->first; + ModelColumnsDoc() + { + add(_colObject); + add(_colLabel); + add(_colPixbuf); } + virtual ~ModelColumnsDoc() {} - for (GtkWidget* curr = widget; curr && !swp; curr = gtk_widget_get_parent(curr)) { - if (rawObjects.find(curr) != rawObjects.end()) { - swp = rawObjects[curr]; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn > _colPixbuf; +}; + +static void StripChildGroups(Inkscape::XML::Node * node, SPObject* addTo) +{ + for (Inkscape::XML::Node * it = node->firstChild(); it != NULL;) { + if (!strcmp(it->name(), "svg:g")) { + Inkscape::XML::Node * todel = it; + it = it->next(); + node->removeChild(todel); + } else { + it = it->next(); } } - - return swp; + addTo->appendChildRepr(node); } -static void removeit( GtkWidget *widget, gpointer data ) +static void BubbleChildGroups(Inkscape::XML::Node * node, SPObject* addTo) { - gtk_container_remove( GTK_CONTAINER(data), widget ); + std::queue groups; + for (Inkscape::XML::Node * it = node->firstChild(); it != NULL; ) { + if (!strcmp(it->name(), "svg:g")) { + groups.push(it->duplicate(addTo->document->getReprDoc())); + Inkscape::XML::Node * todel = it; + it = it->next(); + node->removeChild(todel); + } else { + it = it->next(); + } + } + addTo->appendChildRepr(node); + while (!groups.empty()) { + Inkscape::XML::Node * it = groups.front(); + groups.pop(); + BubbleChildGroups(it, addTo); + Inkscape::GC::release(it); + } } -/* extern'ed from colot-item.cpp */ -gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ); +void SwatchesPanel::_addSwatchButtonClicked(SPGroup* swatch, bool recurse) +{ + if (_currentDocument) { + if (swatch && SP_IS_GROUP(swatch) ) { + Inkscape::XML::Node * copy = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); + if (recurse) { + BubbleChildGroups(copy, _currentDocument->getDefs()); + } else { + StripChildGroups(copy, _currentDocument->getDefs()); + } + Inkscape::GC::release(copy); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); + } + } +} -gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ) +void SwatchesPanel::_importButtonClicked(bool addToDoc, bool addToBI) { - gboolean handled = FALSE; - - if ( event && (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) { - SwatchesPanel* swp = findContainingPanel( widget ); - - if ( !popupMenu ) { - popupMenu = gtk_menu_new(); - GtkWidget* child = 0; - - //TRANSLATORS: An item in context menu on a colour in the swatches - child = gtk_menu_item_new_with_label(_("Set fill")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(redirClick), - user_data); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - - //TRANSLATORS: An item in context menu on a colour in the swatches - child = gtk_menu_item_new_with_label(_("Set stroke")); - - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(redirSecondaryClick), - user_data); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - - child = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_menu_item_new_with_label(_("Delete")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(SwatchesPanelHook::deleteGradient), - user_data ); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - gtk_widget_set_sensitive( child, FALSE ); - - child = gtk_menu_item_new_with_label(_("Edit...")); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(editGradient), - user_data ); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_separator_menu_item_new(); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - popupExtras.push_back(child); - - child = gtk_menu_item_new_with_label(_("Convert")); - gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); - //popupExtras.push_back(child); - //gtk_widget_set_sensitive( child, FALSE ); + if (addToDoc || addToBI) { + //# Get the current directory for finding files + static Glib::ustring open_path; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + if(open_path.empty()) + { + Glib::ustring attr = prefs->getString("/dialogs/open/path"); + if (!attr.empty()) open_path = attr; + } + + //# Test if the open_path directory exists + if (!Inkscape::IO::file_test(open_path.c_str(), + (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) + open_path = ""; + + #ifdef WIN32 + //# If no open path, default to our win32 documents folder + if (open_path.empty()) + { + // The path to the My Documents folder is read from the + // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal" + HKEY key = NULL; + if(RegOpenKeyExA(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { - popupSubHolder = child; - popupSub = gtk_menu_new(); - gtk_menu_item_set_submenu( GTK_MENU_ITEM(child), popupSub ); + WCHAR utf16path[_MAX_PATH]; + DWORD value_type; + DWORD data_size = sizeof(utf16path); + if(RegQueryValueExW(key, L"Personal", NULL, &value_type, + (BYTE*)utf16path, &data_size) == ERROR_SUCCESS) + { + g_assert(value_type == REG_SZ); + gchar *utf8path = g_utf16_to_utf8( + (const gunichar2*)utf16path, -1, NULL, NULL, NULL); + if(utf8path) + { + open_path = Glib::ustring(utf8path); + g_free(utf8path); + } + } } + } + #endif - gtk_widget_show_all(popupMenu); + //# If no open path, default to our home directory + if (open_path.empty()) + { + open_path = g_get_home_dir(); + open_path.append(G_DIR_SEPARATOR_S); } - if ( user_data ) { - ColorItem* item = reinterpret_cast(user_data); - bool show = swp && (swp->getSelectedIndex() == 0); - for ( std::vector::iterator it = popupExtras.begin(); it != popupExtras.end(); ++ it) { - gtk_widget_set_sensitive(*it, show); - } + Gtk::Window * parent = SP_ACTIVE_DESKTOP->getToplevel(); + //# Create a dialog + Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = + Inkscape::UI::Dialog::FileOpenDialog::create( + *parent, open_path, + Inkscape::UI::Dialog::SWATCH_TYPES, + _("Select file to open")); - bounceTarget = item; - bouncePanel = swp; - popupItems.clear(); - if ( popupMenu ) { - gtk_container_foreach(GTK_CONTAINER(popupSub), removeit, popupSub); - bool processed = false; - GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); - if ( wdgt ) { - SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); - if ( dtw && dtw->desktop ) { - // Pick up all gradients with vectors - const GSList *gradients = (dtw->desktop->doc())->getResourceList("gradient"); - gint index = 0; - for (const GSList *curr = gradients; curr; curr = curr->next) { - SPGradient* grad = SP_GRADIENT(curr->data); - if ( grad->hasStops() && !grad->isSwatch() ) { - //gl = g_slist_prepend(gl, curr->data); - processed = true; - GtkWidget *child = gtk_menu_item_new_with_label(grad->getId()); - gtk_menu_shell_append(GTK_MENU_SHELL(popupSub), child); - - popupItems.push_back(grad->getId()); - g_signal_connect( G_OBJECT(child), - "activate", - G_CALLBACK(SwatchesPanelHook::convertGradient), - GINT_TO_POINTER(index) ); - index++; - } - } + //# Show the dialog + bool const success = openDialogInstance->show(); - gtk_widget_show_all(popupSub); - } - } - gtk_widget_set_sensitive( popupSubHolder, processed ); + //# Save the folder the user selected for later + open_path = openDialogInstance->getCurrentDirectory(); - gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time); - handled = TRUE; - } + if (!success) + { + delete openDialogInstance; + return; } - } - return handled; -} + //# User selected something. Get name and type + Glib::ustring fileName = openDialogInstance->getFilename(); + //# We no longer need the file dialog object - delete it + delete openDialogInstance; + openDialogInstance = NULL; -static char* trim( char* str ) { - char* ret = str; - while ( *str && (*str == ' ' || *str == '\t') ) { - str++; - } - ret = str; - while ( *str ) { - str++; - } - str--; - while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { - *str-- = 0; - } - return ret; -} -static void skipWhitespace( char*& str ) { - while ( *str == ' ' || *str == '\t' ) { - str++; + if (!fileName.empty()) + { + Glib::ustring newFileName = Glib::filename_to_utf8(fileName); + + if ( newFileName.size() > 0) + fileName = newFileName; + else + g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); + + open_path = Glib::path_get_dirname (fileName); + open_path.append(G_DIR_SEPARATOR_S); + prefs->setString("/dialogs/open/path", open_path); + + SPDocument* importdoc = SPDocument::createNewDoc(fileName.c_str(), true); + Inkscape::XML::Node * page = NULL; + if (importdoc && importdoc->getDefs()) { + if (addToBI) { + page = SwatchDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (SwatchDocument->getObjectById(id)); + + page->setAttribute("id", id); + gchar* name = g_path_get_basename(importdoc->getName()); + page->setAttribute("inkscape:label", name); + g_free(name); + } + + for (SPObject* it = importdoc->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GROUP(it)) { + if (page) { + Inkscape::XML::Node * copy = it->getRepr()->duplicate(SwatchDocument->getReprDoc()); + page->appendChild(copy); + } + if (addToDoc) { + _addSwatchButtonClicked(SP_GROUP(it), false); + } + } + } + if (page) { + SwatchDocument->getDefs()->appendChildRepr(page); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } + + importdoc->doUnref(); + } else { + SPGroup* g = importGPL(addToBI ? SwatchDocument : _currentDocument, fileName.c_str()); + if (addToBI) { + if (addToDoc) { + _addSwatchButtonClicked(g, false); + } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } else { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); + } + } + } } } -static bool parseNum( char*& str, int& val ) { - val = 0; - while ( '0' <= *str && *str <= '9' ) { - val = val * 10 + (*str - '0'); - str++; +void SwatchesPanel::SetSelectedFill(SPGradient* swatch) +{ + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->fill.isSet()) { + if (it->style->fill.isPaintserver()) { + SPPaintServer * server = it->style->getFillPaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = swatch->getRepr(); + if (repr != drepr && grad != swatch) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { + Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); + swatch->appendChildRepr(clone); + Inkscape::GC::release(clone); + } + swatch->setSwatch(); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); + } + } + } else if (it->style->fill.isColor()) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + addStop(swatch->getRepr(), it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); + swatch->setSwatch(); + if (!_noLink.get_active()) { + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + } + } + } } - bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); - return retval; } - -void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) +void SwatchesPanel::SetSelectedStroke(SPGradient* swatch) { - char block[1024]; - FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); - if ( f ) { - char* result = fgets( block, sizeof(block), f ); - if ( result ) { - if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { - bool inHeader = true; - bool hasErr = false; - - SwatchPage *onceMore = new SwatchPage(); - - do { - result = fgets( block, sizeof(block), f ); - block[sizeof(block) - 1] = 0; - if ( result ) { - if ( block[0] == '#' ) { - // ignore comment - } else { - char *ptr = block; - // very simple check for header versus entry - while ( *ptr == ' ' || *ptr == '\t' ) { - ptr++; + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->stroke.isSet()) { + if (it->style->stroke.isPaintserver()) { + SPPaintServer * server = it->style->getStrokePaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = swatch->getRepr(); + if (repr != drepr && grad != swatch) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); } - if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { - // blank line. skip it. - } else if ( '0' <= *ptr && *ptr <= '9' ) { - // should be an entry link - inHeader = false; - ptr = block; - Glib::ustring name(""); - skipWhitespace(ptr); - if ( *ptr ) { - int r = 0; - int g = 0; - int b = 0; - hasErr = parseNum(ptr, r); - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, g); - } - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, b); - } - if ( !hasErr && *ptr ) { - char* n = trim(ptr); - if (n != NULL) { - name = g_dpgettext2(NULL, "Palette", n); - } - } - if ( !hasErr ) { - // Add the entry now - Glib::ustring nameStr(name); - ColorItem* item = new ColorItem( r, g, b, nameStr ); - onceMore->_colors.push_back(item); - } - } else { - hasErr = true; - } - } else { - if ( !inHeader ) { - // Hmmm... probably bad. Not quite the format we want? - hasErr = true; - } else { - char* sep = strchr(result, ':'); - if ( sep ) { - *sep = 0; - char* val = trim(sep + 1); - char* name = trim(result); - if ( *name ) { - if ( strcmp( "Name", name ) == 0 ) - { - onceMore->_name = val; - } - else if ( strcmp( "Columns", name ) == 0 ) - { - gchar* endPtr = 0; - guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 ); - if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { - // overflow - } else if ( (numVal == 0) && (endPtr == val) ) { - // failed conversion - } else { - onceMore->_prefWidth = numVal; - } - } - } else { - // error - hasErr = true; - } - } else { - // error - hasErr = true; - } - } + for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { + Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); + swatch->appendChildRepr(clone); + Inkscape::GC::release(clone); + } + swatch->setSwatch(); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); } } - } while ( result && !hasErr ); - if ( !hasErr ) { - if (user) - userSwatchPages.push_back(onceMore); - else - systemSwatchPages.push_back(onceMore); -#if ENABLE_MAGIC_COLORS - ColorItem::_wireMagicColors( onceMore ); -#endif // ENABLE_MAGIC_COLORS - } else { - delete onceMore; + } else if (it->style->stroke.isColor()) { + while (SPStop* olds = swatch->getFirstStop()) { + olds->deleteObject(); + } + addStop(swatch->getRepr(), it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); + swatch->setSwatch(); + if (!_noLink.get_active()) { + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); } } } + } +} - fclose(f); +void SwatchesPanel::MoveSwatchDown(SPGradient* swatch) +{ + if (_currentDocument && swatch) { + SPObject* next = swatch->next; + while (next && (!SP_IS_GRADIENT(next) || !(SP_GRADIENT(next)->isSwatch()))) { + next = next->next; + } + if (next) { + Inkscape::XML::Node* repr = swatch->getRepr(); + repr->parent()->changeOrder(repr, next->getRepr()); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Right")); + } } } -static bool -compare_swatch_names(SwatchPage const *a, SwatchPage const *b) { +void SwatchesPanel::MoveSwatchUp(SPGradient* swatch) +{ + if (_currentDocument && swatch) { + SPObject* g = NULL; + SPObject* next = swatch->parent->firstChild(); + while (next && next != swatch) { + if (SP_IS_GRADIENT(next) && SP_GRADIENT(next)->isSwatch()) { + g = next; + } + next = next->next; + } + if (g) { + g = g->getPrev(); + Inkscape::XML::Node* repr = swatch->getRepr(); + repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Left")); + } + } +} - return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0; +void SwatchesPanel::RemoveSwatch(SPGradient* swatch) +{ + if (_currentDocument) { + if (swatch->isReferenced()) { + Inkscape::XML::Node * repr = swatch->getRepr(); + repr->parent()->removeChild(repr); + _currentDocument->getDefs()->getRepr()->appendChild(repr); + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); + } else { + swatch->deleteObject(false); + } + } } -static void loadEmUp() +void SwatchesPanel::_setSelectionSwatch(SPGradient* swatch, bool isStroke) { - static bool beenHere = false; - gboolean userPalete = true; - if ( !beenHere ) { - beenHere = true; - - std::list sources; - sources.push_back( profile_path("palettes") ); - sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); - sources.push_back( g_strdup(CREATE_PALETTESDIR) ); - - // Use this loop to iterate through a list of possible document locations. - while (!sources.empty()) { - gchar *dirname = sources.front(); - if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS ) - && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) { - GError *err = 0; - GDir *directory = g_dir_open(dirname, 0, &err); - if (!directory) { - gchar *safeDir = Inkscape::IO::sanitizeString(dirname); - g_warning(_("Palettes directory (%s) is unavailable."), safeDir); - g_free(safeDir); + if (_currentDocument) { + if (swatch) { + if (_noLink.get_active()) { + if (swatch->isSolid()) { + ColorRGBA rgba(swatch->getFirstStop()->getEffectiveColor().toRGBA32(swatch->getFirstStop()->opacity)); + sp_desktop_set_color(_currentDesktop, rgba, false, !isStroke); } else { - gchar *filename = 0; - while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { - gchar* lower = g_ascii_strdown( filename, -1 ); -// if ( g_str_has_suffix(lower, ".gpl") ) { - if ( !g_str_has_suffix(lower, "~") ) { - gchar* full = g_build_filename(dirname, filename, NULL); - if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - _loadPaletteFile(full, userPalete); - } - g_free(full); - } -// } - g_free(lower); - } - g_dir_close(directory); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); + + Inkscape::XML::Node * clone = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); + _currentDocument->getDefs()->appendChildRepr(clone); + SPGradient* grad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + Inkscape::GC::release(clone); + grad->setSwatch(false); + SPGradient* normalized = sp_gradient_ensure_vector_normalized(grad); +// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { +// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); +// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); +// } + sp_desktop_set_style(_currentDesktop, css); + sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); + sp_repr_css_attr_unref (css); } + } else { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); + + SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); +// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { +// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); +// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); +// } + sp_desktop_set_style(_currentDesktop, css); + sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); + sp_repr_css_attr_unref (css); } - - // toss the dirname - g_free(dirname); - sources.pop_front(); - userPalete = false; + } else { + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, isStroke ? "stroke" : "fill", "none"); + sp_desktop_set_style(_currentDesktop, css); + } + if (isStroke) { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item stroke swatch")); + } else { + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item fill swatch")); } } +} - // Sort the list of swatches by name, grouped by user/system - userSwatchPages.sort(compare_swatch_names); - systemSwatchPages.sort(compare_swatch_names); +void SwatchesPanel::_swatchClicked(GdkEventButton* event, SPGradient* swatch) +{ + if (_currentDesktop) { + if (event->button == 3) { + Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi; + + Glib::ustring us = Glib::ustring::compose("%1", swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]")); + mi = Gtk::manage(new Gtk::MenuItem(swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]"))); + Gtk::Label* namelbl = dynamic_cast(mi->get_child()); + if (namelbl) { + namelbl->set_markup(us); + } + mi->show(); + mi->set_sensitive(false); + menu->append(*mi); + + Gtk::SeparatorMenuItem* sep; + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, false)); + mi->show(); + mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, true)); + mi->show(); + mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); + menu->append(*mi); + + if (swatch) { + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedFill), swatch)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedStroke), swatch)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Left"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchUp), swatch)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Right"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchDown), swatch)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::RemoveSwatch), swatch)); + mi->show(); + menu->append(*mi); + } + menu->popup(event->button, event->time); + } else if (!_currentDesktop->selection->isEmpty()) { + _setSelectionSwatch(swatch, event->state & GDK_SHIFT_MASK); + } + } } +void SwatchesPanel::MoveDown(SPGroup* page) +{ + if (_currentDocument && page) { + SPObject* next = page->next; + while (next && !SP_IS_GROUP(next)) { + next = next->next; + } + if (next) { + Inkscape::XML::Node* repr = page->getRepr(); + repr->parent()->changeOrder(repr, next->getRepr()); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Down")); + } + } +} - -SwatchesPanel& SwatchesPanel::getInstance() +void SwatchesPanel::MoveUp(SPGroup* page) { - return *new SwatchesPanel(); + if (_currentDocument && page) { + SPObject* g = NULL; + SPObject* next = page->parent->firstChild(); + while (next && next != page) { + if (SP_IS_GROUP(next)) { + g = next; + } + next = next->next; + } + if (g) { + g = g->getPrev(); + Inkscape::XML::Node* repr = page->getRepr(); + repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Up")); + } + } } +void SwatchesPanel::Remove(SPGroup* page) +{ + if (_currentDocument && page) { + std::vector toMove; + for(SPObject* obj = page->firstChild(); obj != NULL; obj = obj->next) { + if (SP_IS_GRADIENT(obj)) { + SPGradient* grad = SP_GRADIENT(obj); + if (grad->isReferenced()) { + toMove.push_back(grad->getRepr()); + } + } + } + while (!toMove.empty()) { + Inkscape::XML::Node * repr = toMove.back(); + toMove.pop_back(); + repr->parent()->removeChild(repr); + _currentDocument->getDefs()->getRepr()->appendChild(repr); + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); + } + page->deleteObject(false); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Remove Swatch Group")); + } +} -/** - * Constructor - */ -SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : - Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true), - _holder(0), - _clear(0), - _remove(0), - _currentIndex(0), - _currentDesktop(0), - _currentDocument(0) +void SwatchesPanel::AddSelectedFill(SPGroup* page) { - Gtk::RadioMenuItem* hotItem = 0; - _holder = new PreviewHolder(); - _clear = new ColorItem( ege::PaintDef::CLEAR ); - _remove = new ColorItem( ege::PaintDef::NONE ); - if (docPalettes.empty()) { - SwatchPage *docPalette = new SwatchPage(); - - docPalette->_name = "Auto"; - docPalettes[0] = docPalette; - } - - loadEmUp(); - if ( !systemSwatchPages.empty() ) { - SwatchPage* first = 0; - int index = 0; - Glib::ustring targetName; - if ( !_prefs_path.empty() ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - targetName = prefs->getString(_prefs_path + "/palette"); - if (!targetName.empty()) { - if (targetName == "Auto") { - first = docPalettes[0]; - } else { - //index++; - std::vector pages = _getSwatchSets(); - for ( std::vector::iterator iter = pages.begin(); iter != pages.end(); ++iter ) { - if ( (*iter)->_name == targetName ) { - first = *iter; - break; + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->fill.isSet()) { + if (it->style->fill.isPaintserver()) { + SPPaintServer * server = it->style->getFillPaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + if (_noLink.get_active()) { + Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + clone->setAttribute( "osb:paint", "gradient", 0 ); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else if (grad->isSwatch()) { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); + if (repr->parent() != drepr) { + repr->parent()->removeChild(repr); + drepr->appendChild(repr); + } + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); } - index++; } + } else if (it->style->fill.isColor()) { + Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute( "osb:paint", "solid", 0 ); + addStop(grad, it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); + if (page) { + page->appendChild(grad); + } else { + _currentDocument->getDefs()->appendChild(grad); + } + SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); + Inkscape::GC::release(grad); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); } } } + } +} - if ( !first ) { - first = docPalettes[0]; - _currentIndex = 0; - } else { - _currentIndex = index; - } - - _rebuild(); - - Gtk::RadioMenuItem::Group groupOne; - - int i = 0; - std::vector swatchSets = _getSwatchSets(); - for ( std::vector::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { - SwatchPage* curr = *it; - Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); - if ( curr == first ) { - hotItem = single; +void SwatchesPanel::AddSelectedStroke(SPGroup* page) +{ + if (_currentDesktop && _currentDocument) { + SPItem* it = _currentDesktop->selection->singleItem(); + if (it) { + if (it->style->stroke.isSet()) { + if (it->style->stroke.isPaintserver()) { + SPPaintServer * server = it->style->getStrokePaintServer(); + if (SP_IS_GRADIENT(server)) { + SPGradient *grad = SP_GRADIENT(server)->getVector(); + if (_noLink.get_active()) { + Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + clone->setAttribute( "osb:paint", "gradient", 0 ); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else if (grad->isSwatch()) { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); + if (page) { + page->appendChildRepr(clone); + } else { + _currentDocument->getDefs()->appendChildRepr(clone); + } + SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); + + sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + Inkscape::GC::release(clone); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } else { + Inkscape::XML::Node * repr = grad->getRepr(); + Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); + if (repr->parent() != drepr) { + repr->parent()->removeChild(repr); + drepr->appendChild(repr); + } + SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); + } + } + } else if (it->style->stroke.isColor()) { + Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); + grad->setAttribute( "osb:paint", "solid", 0 ); + addStop(grad, it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); + if (page) { + page->appendChild(grad); + } else { + _currentDocument->getDefs()->appendChild(grad); + } + SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); + Inkscape::GC::release(grad); + if (!_noLink.get_active()) { + sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); + } + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); + } } - _regItem( single, 3, i ); - - i++; } } +} - if (Glib::ustring(prefsPath) == "/dialogs/swatches") { - Gtk::Requisition sreq; -#if WITH_GTKMM_3_0 - Gtk::Requisition sreq_natural; - get_preferred_size(sreq_natural, sreq); -#else - sreq = size_request(); -#endif - int minHeight = 60; - if (sreq.height < minHeight) { - set_size_request(70, minHeight); - } +void SwatchesPanel::_addBIButtonClicked(GdkEventButton* event) +{ + if (popUpImportMenu) { + popUpImportMenu->popup(event->button, event->time); } +} - _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET); - _setTargetFillable(_holder); - - show_all_children(); - - restorePanelPrefs(); - if ( hotItem ) { - hotItem->set_active(); +void SwatchesPanel::NewGroupBI() +{ + if (_currentDocument) { + Inkscape::XML::Node * page = SwatchDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (SwatchDocument->getObjectById(id)); + + page->setAttribute("id", id); + + SwatchDocument->getDefs()->appendChild(page); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } -SwatchesPanel::~SwatchesPanel() +void SwatchesPanel::NewGroup() { - _trackDocument( this, 0 ); - - _documentConnection.disconnect(); - _selChanged.disconnect(); - - if ( _clear ) { - delete _clear; - } - if ( _remove ) { - delete _remove; - } - if ( _holder ) { - delete _holder; + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("New Swatch Group")); } } -void SwatchesPanel::setOrientation(SPAnchorType how) +void SwatchesPanel::SaveAs() { - // Must call the parent class or bad things might happen - Inkscape::UI::Widget::Panel::setOrientation( how ); - - if ( _holder ) - { - _holder->setOrientation(SP_ANCHOR_SOUTH); + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + + std::vector toMove; + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->isSwatch()) { + toMove.push_back(grad->getRepr()); + } + } + } + while (!toMove.empty()) { + Inkscape::XML::Node* repr = toMove.back(); + toMove.pop_back(); + repr->parent()->removeChild(repr); + page->appendChild(repr); + } + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Save Swatch Group")); } } -void SwatchesPanel::setDesktop( SPDesktop* desktop ) +void SwatchesPanel::Duplicate(SPGroup* oldpage) { - if ( desktop != _currentDesktop ) { - if ( _currentDesktop ) { - _documentConnection.disconnect(); - _selChanged.disconnect(); + if (_currentDocument) { + Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("page%d", page_suffix++); + } while (_currentDocument->getObjectById(id)); + + page->setAttribute("id", id); + if (oldpage->label()) page->setAttribute("inkscape:label", oldpage->label()); + + for (SPObject *it = oldpage->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->isSwatch()) { + Inkscape::XML::Node * copy = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); + page->appendChild(copy); + Inkscape::GC::release(copy); + } + } } + _currentDocument->getDefs()->appendChild(page); + DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Duplicate Swatch Group")); + } +} - _currentDesktop = desktop; +void SwatchesPanel::_lblClick(GdkEventButton* event, SPGroup* page) +{ + Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi; + Glib::ustring us = Glib::ustring::compose("%1", page ? (page->label() ? page->label() : page->getId()) : _("[Base]")); + mi = Gtk::manage(new Gtk::MenuItem(page ? (page->label() ? page->label() : page->getId()) : _("[Base]"))); + Gtk::Label* namelbl = dynamic_cast(mi->get_child()); + if (namelbl) { + namelbl->set_markup(us); + } + mi->show(); + mi->set_sensitive(false); + menu->append(*mi); + + Gtk::SeparatorMenuItem* sep; + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Fill"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedFill), page)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Stroke"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedStroke), page)); + mi->show(); + mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + if (page) { + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Up"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveUp), page)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Move Down"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveDown), page)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Duplicate"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Duplicate), page)); + mi->show(); + menu->append(*mi); + + sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + menu->append(*sep); + + mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Remove), page)); + mi->show(); + menu->append(*mi); + } else { + mi = Gtk::manage(new Gtk::MenuItem(_("Create New Group"))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); + mi->show(); + menu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Save As New Group"))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::SaveAs)); + mi->show(); + menu->append(*mi); + } + + menu->popup(event->button, event->time); +} - if ( desktop ) { - _currentDesktop->selection->connectChanged( - sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); +void SwatchesPanel::_defsChanged() +{ + if (_storeDoc) { + _storeDoc->clear(); + } + + while (!docWatchers.empty()) { + Inkscape::XML::NodeObserver* w = docWatchers.back(); + docWatchers.pop_back(); + delete w; + } + + std::vector tableChildren = _insideTable.get_children(); + for (std::vector::iterator c = tableChildren.begin(); c != tableChildren.end(); ++c) { + _insideTable.remove(**c); + } + + if (_currentDocument) { + Gtk::EventBox* eb; + Gtk::Label* lbl; + if (_showlabels) { + eb = Gtk::manage(new Gtk::EventBox()); + eb->add_events(Gdk::BUTTON_PRESS_MASK); + eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), NULL)); + + lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); + eb->add(*lbl); + _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + } + Glib::ustring str1 = Glib::ustring(_("[None]")); + ColorItem* item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str1)); + //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); + item->setName(_("[None]")); + _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + + unsigned int i = 1; + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GRADIENT(it)) { + SPGradient* grad = SP_GRADIENT(it); + if (grad->hasStops()) { + + GradientWatcher* w = new GradientWatcher(this, grad); + docWatchers.push_back(w); + + if (grad->isSwatch()) { + + for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { + StopWatcher* sw = new StopWatcher(this, s); + docWatchers.push_back(sw); + } - _currentDesktop->selection->connectModified( - sigc::hide(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection)))); + if (_storeDoc) { + Gtk::TreeModel::iterator iter = _storeDoc->append(); + Gtk::TreeModel::Row row = *iter; + row[_modelDoc->_colObject] = grad; + row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); + GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); + row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); + } + Glib::ustring str2 = Glib::ustring(it->label() ? it->label() : it->getId()); + item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str2)); + item->setGradient(grad); + //item->colorItemHandleButtonPress().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->setName(it->label() ? it->label() : it->getId()); + if (_showlabels) { + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } else { + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } - _currentDesktop->connectToolSubselectionChanged( - sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + i++; + } + } + } + } + + for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { + if (SP_IS_GROUP(it)) { + SwatchWatcher* w = new SwatchWatcher(this, it, false); + docWatchers.push_back(w); + + if (_showlabels) { + i += 20 - (i % 20); + eb = Gtk::manage(new Gtk::EventBox()); + eb->add_events(Gdk::BUTTON_PRESS_MASK); + eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); + lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); + eb->add(*lbl); + _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + } + + Gtk::TreeModel::iterator rowiter; + + if (_storeDoc) { + rowiter = _storeDoc->append(); + Gtk::TreeModel::Row row = *rowiter; + row[_modelDoc->_colObject] = it; + row[_modelDoc->_colLabel] = it->label() ? it->label() : it->getId(); + } + + for (SPObject *cit = it->firstChild(); cit != NULL; cit = cit->next) { + if (SP_IS_GRADIENT(cit)) { + SPGradient* grad = SP_GRADIENT(cit); + + if (grad->hasStops()) { + + GradientWatcher* w = new GradientWatcher(this, grad); + docWatchers.push_back(w); + + if (grad->isSwatch()) { + + for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { + StopWatcher* sw = new StopWatcher(this, s); + docWatchers.push_back(sw); + } - sigc::bound_mem_functor1 first = sigc::mem_fun(*this, &SwatchesPanel::_setDocument); - sigc::slot base2 = first; - sigc::slot slot2 = sigc::hide<0>( base2 ); - _documentConnection = desktop->connectDocumentReplaced( slot2 ); + if (_storeDoc && rowiter) { + Gtk::TreeModel::iterator iter = _storeDoc->append(rowiter->children()); + Gtk::TreeModel::Row row = *iter; + row[_modelDoc->_colObject] = grad; + row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); + GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); + row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - _setDocument( desktop->doc() ); - } else { - _setDocument(0); + _editDoc.expand_to_path(_storeDoc->get_path(iter)); + } + Glib::ustring str3= Glib::ustring(cit->label() ? cit->label() : cit->getId()); + item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str3)); + item->setGradient(grad); + //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->setName(cit->label() ? cit->label() : cit->getId()); + if (_showlabels) { + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } else { + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + } + i++; + } + } + } + } + } } } + + _scroller.show_all_children(); + _scroller.queue_draw(); } - -class DocTrack +Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) { -public: - DocTrack(SPDocument *doc, sigc::connection &docDestroy, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : - doc(doc), - updatePending(false), - lastGradientUpdate(0.0), - docDestroy(docDestroy), - gradientRsrcChanged(gradientRsrcChanged), - defsChanged(defsChanged), - defsModified(defsModified) - { - if ( !timer ) { - timer = new Glib::Timer(); - refreshTimer = Glib::signal_timeout().connect( sigc::ptr_fun(handleTimerCB), 33 ); + Gtk::MenuItem* mi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId(),1)); + Gtk::Menu* m = NULL; + + Gtk::TreeModel::Row* r; + if (_store) { + Gtk::TreeModel::iterator iter = parentRow ? _store->append(parentRow->children()) : _store->append(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = group; + row[_model->_colLabel] = group->label() ? group->label() : group->getId(); + + if (SP_IS_GROUP(group->parent) && SP_GROUP(group->parent)->expanded()) { + _editBI.expand_to_path(_store->get_path(iter)); } - timerRefCount++; + r = &row; + } else { + r = NULL; } - - ~DocTrack() + + bool hasswatches = false; + for (SPObject * obj = group->firstChild(); obj != NULL; obj = obj->next) { - timerRefCount--; - if ( timerRefCount <= 0 ) { - refreshTimer.disconnect(); - timerRefCount = 0; - if ( timer ) { - timer->stop(); - delete timer; - timer = 0; + if (SP_IS_GROUP(obj)) { + if (!m) { + m = manage(new Gtk::Menu()); + m->show_all(); + mi->set_submenu(*m); + + Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(_("[All]"))); + basemi->show(); + Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); + if (namelbl) { + namelbl->set_markup(_("[All]")); + } + basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, true)); + m->append(*basemi); + + Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + m->append(*sep); } + SwatchWatcher* w = new SwatchWatcher(this, obj, true); + rootWatchers.push_back(w); + m->append(*_addSwatchGroup(SP_GROUP(obj), r)); + } else if (SP_IS_GRADIENT(obj)) { + hasswatches = true; } - if (doc) { - docDestroy.disconnect(); - gradientRsrcChanged.disconnect(); - defsChanged.disconnect(); - defsModified.disconnect(); - doc = NULL; + } + if (!m) { + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); + } else if (hasswatches) { + Glib::ustring us = Glib::ustring::compose("%1", group->label() ? group->label() : group->getId()); + Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId())); + basemi->show(); + Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); + if (namelbl) { + namelbl->set_markup(us); } + basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); + m->prepend(*basemi); } + mi->show(); + return mi; +} - static bool handleTimerCB(); - - /** - * Checks if update should be queued or executed immediately. - * - * @return true if the update was queued and should not be immediately executed. - */ - static bool queueUpdateIfNeeded(SPDocument *doc); - - static Glib::Timer *timer; - static int timerRefCount; - static sigc::connection refreshTimer; - - SPDocument *doc; - bool updatePending; - double lastGradientUpdate; - sigc::connection docDestroy; - sigc::connection gradientRsrcChanged; - sigc::connection defsChanged; - sigc::connection defsModified; - -private: - DocTrack(DocTrack const &); // no copy - DocTrack &operator=(DocTrack const &); // no assign -}; - -Glib::Timer *DocTrack::timer = 0; -int DocTrack::timerRefCount = 0; -sigc::connection DocTrack::refreshTimer; +void SwatchesPanel::_swatchesChanged() +{ + while (!rootWatchers.empty()) { + Inkscape::XML::NodeObserver* w = rootWatchers.back(); + rootWatchers.pop_back(); + delete w; + } -static const double DOC_UPDATE_THREASHOLD = 0.090; + std::vector menuChildren = popUpMenu->get_children(); + for (std::vector::iterator c = menuChildren.begin(); c != menuChildren.end(); ++c) { + popUpMenu->remove(**c); + } + + if (_store) { + _store->clear(); + } + + Gtk::MenuItem* mi; + + for (SPObject * obj = SwatchDocument->getDefs()->firstChild(); obj != NULL; obj = obj->next) + { + if (SP_IS_GROUP(obj)) { + SwatchWatcher* w = new SwatchWatcher(this, obj, true); + rootWatchers.push_back(w); + popUpMenu->append(*_addSwatchGroup(SP_GROUP(obj), NULL)); + + } + } + Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + sep->show(); + popUpMenu->append(*sep); + + mi = manage(new Gtk::MenuItem(_("New Swatch Group..."),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); + mi->show(); + popUpMenu->append(*mi); + + mi = manage(new Gtk::MenuItem(_("Add Swatch File..."),1)); + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, false)); + mi->show(); + popUpMenu->append(*mi); + + mi = manage(new Gtk::MenuItem(_("Import Swatch File..."),1)); + mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, true)); + mi->show(); + popUpMenu->append(*mi); +} -bool DocTrack::handleTimerCB() +void SwatchesPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) { - double now = timer->elapsed(); + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } - std::vector needCallback; - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { - DocTrack *track = *it; - if ( track->updatePending && ( (now - track->lastGradientUpdate) >= DOC_UPDATE_THREASHOLD) ) { - needCallback.push_back(track); + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } } } + + btn.set_tooltip_text (fallback); + + if ( !set ) { + btn.set_label( fallback ); + } +} - for (std::vector::iterator it = needCallback.begin(); it != needCallback.end(); ++it) { - DocTrack *track = *it; - if ( std::find(docTrackings.begin(), docTrackings.end(), track) != docTrackings.end() ) { // Just in case one gets deleted while we are looping - // Note: calling handleDefsModified will call queueUpdateIfNeeded and thus update the time and flag. - SwatchesPanel::handleDefsModified(track->doc); +void SwatchesPanel::_addButtonClicked(GdkEventButton* event) { + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 1) ) { + if (popUpMenu) { + popUpMenu->popup(event->button, event->time); } } +} - return true; +void SwatchesPanel::NoLinkToggled() { + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring nolink = Glib::ustring::compose("%1/nolink", _prefs_path); + prefs->setBool(nolink, _noLink.get_active()); } -bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) +bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) { - bool deferProcessing = false; - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { - DocTrack *track = *it; - if ( track->doc == doc ) { - double now = timer->elapsed(); - double elapsed = now - track->lastGradientUpdate; - - if ( elapsed < DOC_UPDATE_THREASHOLD ) { - deferProcessing = true; - track->updatePending = true; - } else { - track->lastGradientUpdate = now; - track->updatePending = false; - } + static unsigned doubleclick = 0; + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } - break; + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _editBI.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnBI) { + // Double click on the Layer name, enable editing + _text_rendererBI->property_editable() = true; + _editBI.set_cursor (path, *_name_columnBI, true); + grab_focus(); } } - return deferProcessing; + + return false; } -void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) +bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) { - SPDocument *oldDoc = NULL; - if (docPerPanel.find(panel) != docPerPanel.end()) { - oldDoc = docPerPanel[panel]; - if (!oldDoc) { - docPerPanel.erase(panel); // Should not be needed, but clean up just in case. - } - } - if (oldDoc != document) { - if (oldDoc) { - docPerPanel[panel] = NULL; - bool found = false; - for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { - found = (it->second == document); - } - if (!found) { - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ - if ((*it)->doc == oldDoc) { - delete *it; - docTrackings.erase(it); - break; - } + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter && !_text_rendererBI->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_rendererBI->property_editable() = true; + _editBI.set_cursor(*path, *_name_columnBI, true); + grab_focus(); + return true; } } } - - if (document) { - bool found = false; - for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { - found = (it->second == document); - } - docPerPanel[panel] = document; - if (!found) { - sigc::connection conn0 = document->connectDestroy(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDocumentDestroy), document)); - sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) ); - sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) ); - sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) ); - - DocTrack *dt = new DocTrack(document, conn0, conn1, conn2, conn3); - docTrackings.push_back(dt); - - if (docPalettes.find(document) == docPalettes.end()) { - SwatchPage *docPalette = new SwatchPage(); - docPalette->_name = "Auto"; - docPalettes[document] = docPalette; + case GDK_KEY_Delete: { + + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj) { + obj->deleteObject(false); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } + return true; } + break; } + return false; } -void SwatchesPanel::_setDocument( SPDocument *document ) +void SwatchesPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) { - if ( document != _currentDocument ) { - _trackDocument(this, document); - _currentDocument = document; - handleGradientsChange( document ); - } + Gtk::TreeModel::iterator iter = _editBI.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_rendererBI->property_editable() = false; } -static void recalcSwatchContents(SPDocument* doc, - boost::ptr_vector &tmpColors, - std::map &previewMappings, - std::map &gradMappings) +void SwatchesPanel::_handleEditingCancelled() { - std::vector newList; - - if (doc) { - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( grad->isSwatch() ) { - newList.push_back(SP_GRADIENT(item->data)); + _text_rendererBI->property_editable() = false; +} + +void SwatchesPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && SwatchDocument) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } } } +} - if ( !newList.empty() ) { - std::reverse(newList.begin(), newList.end()); - for ( std::vector::iterator it = newList.begin(); it != newList.end(); ++it ) - { - SPGradient* grad = *it; - - cairo_surface_t *preview = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - PREVIEW_PIXBUF_WIDTH, VBLOCK); - cairo_t *ct = cairo_create(preview); - - Glib::ustring name( grad->getId() ); - ColorItem* item = new ColorItem( 0, 0, 0, name ); - - cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); - cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(grad, PREVIEW_PIXBUF_WIDTH); - cairo_set_source(ct, check); - cairo_paint(ct); - cairo_set_source(ct, gradient); - cairo_paint(ct); - - cairo_destroy(ct); - cairo_pattern_destroy(gradient); - cairo_pattern_destroy(check); - - cairo_pattern_t *prevpat = cairo_pattern_create_for_surface(preview); - cairo_surface_destroy(preview); +void SwatchesPanel::_setCollapsed(SPGroup * group) +{ + group->setExpanded(false); + group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + for (SPObject *iter = group->children; iter != NULL; iter = iter->next) + { + if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + } +} - previewMappings[item] = prevpat; +void SwatchesPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; - tmpColors.push_back(item); - gradMappings[item] = grad; + SPObject* obj = row[_model->_colObject]; + if (obj && SP_IS_GROUP(obj)) + { + if (isexpanded) + { + SP_GROUP(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } + else + { + _setCollapsed(SP_GROUP(obj)); } } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } -void SwatchesPanel::handleDocumentDestroy(SPDocument *document) +void SwatchesPanel::_deleteButtonClicked() { - if (document) { - for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ - if ((*it)->doc == document) { - delete *it; - docTrackings.erase(it); - break; - } + Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + if (obj) { + obj->deleteObject(false); + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } + } +} - if (docPalettes.find(document) != docPalettes.end()) { - docPalettes.erase(document); +bool SwatchesPanel::_handleButtonEventDoc(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _editDoc.get_path_at_pos( x, y, path ) ) { + Gtk::TreeModel::Children::iterator iter = _editDoc.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_modelDoc->_colObject]; + if (SP_IS_GRADIENT(obj)) { + _swatchClicked(event, SP_GRADIENT(obj)); + } else if (SP_IS_GROUP(obj)) { + _lblClick(event, SP_GROUP(obj)); + } else { + _lblClick(event, NULL); + } + } else { + _lblClick(event, NULL); } + } + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - if (it->second == document) { - SwatchesPanel* swp = it->first; - std::vector pages = swp->_getSwatchSets(); - if ((swp->_currentIndex >= static_cast(pages.size())) && (pages.size() > 0)) - { - swp->_setSelectedIndex(swp->_getSwatchSets().size() - 1); - } - swp->_rebuild(); - docPerPanel.erase(it); - break; - } + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _editDoc.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnDoc) { + // Double click on the Layer name, enable editing + _text_rendererDoc->property_editable() = true; + _editDoc.set_cursor (path, *_name_columnDoc, true); + grab_focus(); } } + + return false; } -void SwatchesPanel::handleGradientsChange(SPDocument *document) +void SwatchesPanel::_deleteButtonClickedDoc() { - SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; - if (docPalette) { - boost::ptr_vector tmpColors; - std::map tmpPrevs; - std::map tmpGrads; - recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - - for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { - it->first->setPattern(it->second); - cairo_pattern_destroy(it->second); + Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); + if (iter) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_modelDoc->_colObject]; + if (SP_IS_GRADIENT(obj)) { + RemoveSwatch(SP_GRADIENT(obj)); + } else if (SP_IS_GROUP(obj)) { + Remove(SP_GROUP(obj)); } + } +} - for (std::map::iterator it = tmpGrads.begin(); it != tmpGrads.end(); ++it) { - it->first->setGradient(it->second); - } - - docPalette->_colors.swap(tmpColors); - - // Figure out which SwatchesPanel instances are affected and update them. - - for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - if (it->second == document) { - SwatchesPanel* swp = it->first; - std::vector pages = swp->_getSwatchSets(); - SwatchPage* curr = pages[swp->_currentIndex]; - if (curr == docPalette) { - swp->_rebuild(); +bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) +{ + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); + if (iter && !_text_rendererDoc->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_modelDoc->_colObject]; + if (obj) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_rendererDoc->property_editable() = true; + _editDoc.set_cursor(*path, *_name_columnDoc, true); + grab_focus(); + return true; } } } + case GDK_KEY_Delete: { + + _deleteButtonClickedDoc(); + return true; + } + break; } + return false; } -void SwatchesPanel::handleDefsModified(SPDocument *document) +void SwatchesPanel::_renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name) { - SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; - if (docPalette && !DocTrack::queueUpdateIfNeeded(document) ) { - boost::ptr_vector tmpColors; - std::map tmpPrevs; - std::map tmpGrads; - recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - - if ( tmpColors.size() != docPalette->_colors.size() ) { - handleGradientsChange(document); - } else { - int cap = std::min(docPalette->_colors.size(), tmpColors.size()); - for (int i = 0; i < cap; i++) { - ColorItem *newColor = &tmpColors[i]; - ColorItem *oldColor = &docPalette->_colors[i]; - if ( (newColor->def.getType() != oldColor->def.getType()) || - (newColor->def.getR() != oldColor->def.getR()) || - (newColor->def.getG() != oldColor->def.getG()) || - (newColor->def.getB() != oldColor->def.getB()) ) { - oldColor->def.setRGB(newColor->def.getR(), newColor->def.getG(), newColor->def.getB()); - } - if (tmpGrads.find(newColor) != tmpGrads.end()) { - oldColor->setGradient(tmpGrads[newColor]); - } - if ( tmpPrevs.find(newColor) != tmpPrevs.end() ) { - oldColor->setPattern(tmpPrevs[newColor]); - } + if ( row && SwatchDocument) { + SPObject* obj = row[_modelDoc->_colObject]; + if ( obj ) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); } } - - for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { - cairo_pattern_destroy(it->second); - } } } +void SwatchesPanel::_handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _editDoc.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObjectDoc(row, new_text); + _text_rendererDoc->property_editable() = false; +} + +void SwatchesPanel::_handleEditingCancelledDoc() +{ + _text_rendererDoc->property_editable() = false; +} -std::vector SwatchesPanel::_getSwatchSets() const +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool SwatchesPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) { - std::vector tmp; - if (docPalettes.find(_currentDocument) != docPalettes.end()) { - tmp.push_back(docPalettes[_currentDocument]); + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + bool _dnd_top = false; + _dnd_into = false; + _dnd_target = SwatchDocument->getDefs()->lastChild(); + Gtk::TreeModel::iterator itersel = _editBI.get_selection()->get_selected(); + if (!itersel) { + return true; } + Gtk::TreeModel::Row rowsel = *itersel; + _dnd_source = rowsel[_model->_colObject]; - tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end()); - tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end()); + if (!_dnd_source) { + return true; + } + + if (_editBI.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _editBI.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y < (int)(cell_height * 1/3)) { + Gtk::TreeModel::Path next_path = target_path; + if (next_path.prev()) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + _dnd_top = true; + // Drop into the top level + _dnd_target = NULL; + } + } + } + if (!_dnd_top) { + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + _dnd_target = obj; + } + } + } + } + + if (_dnd_source != _dnd_target) { + + Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; + Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); + + if (target_ref != our_ref) { + if (!target_ref) { + target_ref = SwatchDocument->getDefs()->getRepr(); + if (target_ref != our_ref->parent()) { + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else { + our_ref->parent()->changeOrder(our_ref, NULL); + } + } else if (_dnd_into) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } + } + sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + } - return tmp; + return true; } -void SwatchesPanel::_updateFromSelection() +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time) { - SwatchPage *docPalette = (docPalettes.find(_currentDocument) != docPalettes.end()) ? docPalettes[_currentDocument] : 0; - if ( docPalette ) { - Glib::ustring fillId; - Glib::ustring strokeId; - - SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); - int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); - switch (result) { - case QUERY_STYLE_SINGLE: - case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: - { - if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { - SPPaintServer* server = tmpStyle->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* target = 0; - SPGradient* grad = SP_GRADIENT(server); - - if ( grad->isSwatch() ) { - target = grad; - } else if ( grad->ref ) { - SPGradient *tmp = grad->ref->getObject(); - if ( tmp && tmp->isSwatch() ) { - target = tmp; - } - } - if ( target ) { - //XML Tree being used directly here while it shouldn't be - gchar const* id = target->getRepr()->attribute("id"); - if ( id ) { - fillId = id; - } - } - } + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + bool _dnd_top = false; + _dnd_into = false; + _dnd_target = _currentDocument->getDefs()->lastChild(); + Gtk::TreeModel::iterator itersel = _editDoc.get_selection()->get_selected(); + if (!itersel) { + return true; + } + Gtk::TreeModel::Row rowsel = *itersel; + _dnd_source = rowsel[_modelDoc->_colObject]; + + if (!_dnd_source) { + return true; + } + + if (_editDoc.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _editDoc.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y < (int)(cell_height * 1/3)) { + Gtk::TreeModel::Path next_path = target_path; + if (next_path.prev()) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_storeDoc->iter_is_valid(_storeDoc->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + _dnd_top = true; + // Drop into the top level + _dnd_target = NULL; } - break; } } - - result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); - switch (result) { - case QUERY_STYLE_SINGLE: - case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: - { - if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { - SPPaintServer* server = tmpStyle->getStrokePaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient* target = 0; - SPGradient* grad = SP_GRADIENT(server); - if ( grad->isSwatch() ) { - target = grad; - } else if ( grad->ref ) { - SPGradient *tmp = grad->ref->getObject(); - if ( tmp && tmp->isSwatch() ) { - target = tmp; - } - } - if ( target ) { - //XML Tree being used directly here while it shouldn't be - gchar const* id = target->getRepr()->attribute("id"); - if ( id ) { - strokeId = id; - } + if (!_dnd_top) { + Gtk::TreeModel::iterator iter = _storeDoc->get_iter(target_path); + if (_storeDoc->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_modelDoc->_colObject]; + if (obj) { + _dnd_target = obj; + if (SP_IS_GRADIENT(obj)) { + _dnd_into = false; + if (SP_IS_GROUP(_dnd_source)) { + _dnd_target = obj->parent; } + } else if (SP_IS_GROUP(_dnd_source)) { + _dnd_into = false; } } - break; } } - sp_style_unref(tmpStyle); - - for ( boost::ptr_vector::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { - ColorItem* item = &*it; - bool isFill = (fillId == item->def.descr); - bool isStroke = (strokeId == item->def.descr); - item->setState( isFill, isStroke ); + } + + if (_dnd_source != _dnd_target) { + + Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; + Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); + + if (target_ref != our_ref) { + if (!target_ref) { + target_ref = _currentDocument->getDefs()->getRepr(); + if (target_ref != our_ref->parent()) { + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else { + our_ref->parent()->changeOrder(our_ref, NULL); + } + } else if (_dnd_into) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } } + DocumentUndo::done( _currentDocument , SP_VERB_DIALOG_SWATCHES, + _("Moved Swatches")); } + + return true; } -void SwatchesPanel::_handleAction( int setId, int itemId ) + +/** + * Constructor + */ +SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : + Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), + _scroller(), + _insideTable(1, 2), + _insideV(), + _insideH(), + _buttonsRow(), + _outsideV(), + _noLink(_("Don't Link")), + _showlabels(showLabels), + _store(0), + _scrollerBI(), + _editBI(), + _buttonsRowBI(), + _editBIV(), + _storeDoc(0), + _scrollerDoc(), + _editDoc(), + _buttonsRowDoc(), + _editDocV(), + _notebook(), + rootWatcher(0), + docWatcher(0), + _currentDesktop(0), + _currentDocument(0) { - switch( setId ) { - case 3: + _insideH.pack_start(_insideTable, Gtk::PACK_SHRINK); + if (_showlabels) { + _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); + _scroller.add(_insideV); + } else { + _scroller.property_height_request() = 45; + _scroller.add(_insideH); + } + + popUpMenu = manage( new Gtk::Menu() ); + popUpMenu->show_all_children(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Add Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked) ); + _buttonsRow.pack_start(*btn, Gtk::PACK_SHRINK); + +// btn = manage( new Gtk::Button() ); +// _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_DISCONNECT, C_("Unlink", "New") ); +// _buttonsRow.pack_end(*btn, Gtk::PACK_SHRINK); + + static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring nolink = Glib::ustring::compose("%1/nolink", prefsPath); + _noLink.set_tooltip_text(_("Don't link swatches")); + _noLink.set_active(prefs->getBool(nolink, false)); + _noLink.signal_toggled().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NoLinkToggled)); + _buttonsRow.pack_end(_noLink, Gtk::PACK_SHRINK); + + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_NONE); + + if (_showlabels) { + _outsideV.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + _outsideV.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); + + _notebook.append_page(_outsideV, "Use"); + + { + ModelColumnsDoc *zoop = new ModelColumnsDoc(); + _modelDoc = zoop; + + _storeDoc = Gtk::TreeStore::create( *zoop ); + + _editDoc.set_model( _storeDoc ); + _editDoc.set_headers_visible(false); + _editDoc.set_reorderable(true); + _editDoc.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked)); + _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClickedDoc))); + _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + + _pixbuf_rendererDoc = manage(new Gtk::CellRendererPixbuf()); + int pixbufColNum = _editDoc.append_column("Pixbuf", *_pixbuf_rendererDoc) - 1; + _pixbuf_columnDoc = _editDoc.get_column(pixbufColNum); + _pixbuf_columnDoc->add_attribute(_pixbuf_rendererDoc->property_pixbuf(), _modelDoc->_colPixbuf); + + _text_rendererDoc = manage(new Gtk::CellRendererText()); + int nameColNum = _editDoc.append_column("Name", *_text_rendererDoc) - 1; + _name_columnDoc = _editDoc.get_column(nameColNum); + _name_columnDoc->add_attribute(_text_rendererDoc->property_text(), _modelDoc->_colLabel); + + _text_rendererDoc->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditedDoc) ); + _text_rendererDoc->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelledDoc) ); + + _editDoc.set_expander_column( *_editDoc.get_column(nameColNum) ); + + _editDoc.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); + _editDoc.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); + _editDoc.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEventDoc), false ); + + _editDoc.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDropDoc), false); + + _scrollerDoc.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scrollerDoc.set_shadow_type(Gtk::SHADOW_IN); + _scrollerDoc.add(_editDoc); + + _editDocV.pack_start(_scrollerDoc, Gtk::PACK_EXPAND_WIDGET); + _editDocV.pack_end(_buttonsRowDoc, Gtk::PACK_SHRINK); + + _notebook.append_page(_editDocV, "Edit"); + } + { - _setSelectedIndex(itemId); + popUpImportMenu = Gtk::manage(new Gtk::Menu()); + + Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("New Swatch Group..."))); + mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroupBI)); + mi->show(); + popUpImportMenu->append(*mi); + + mi = Gtk::manage(new Gtk::MenuItem(_("Import Swatch File..."))); + mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), false, true)); + mi->show(); + popUpImportMenu->append(*mi); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _editBI.set_model( _store ); + _editBI.set_headers_visible(false); + _editBI.set_reorderable(true); + _editBI.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); + btn->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::_addBIButtonClicked)); + _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); + btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClicked))); + _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); + + _text_rendererBI = manage(new Gtk::CellRendererText()); + int nameColNum = _editBI.append_column("Name", *_text_rendererBI) - 1; + _name_columnBI = _editBI.get_column(nameColNum); + _name_columnBI->add_attribute(_text_rendererBI->property_text(), _model->_colLabel); + + _text_rendererBI->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEdited) ); + _text_rendererBI->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelled) ); + + _editBI.set_expander_column( *_editBI.get_column(nameColNum) ); + + _editBI.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); + _editBI.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); + _editBI.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEvent), false ); + + _editBI.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDrop), false); + _editBI.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), false)); + _editBI.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), true)); + + _scrollerBI.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scrollerBI.set_shadow_type(Gtk::SHADOW_IN); + _scrollerBI.add(_editBI); + + _editBIV.pack_start(_scrollerBI, Gtk::PACK_EXPAND_WIDGET); + _editBIV.pack_end(_buttonsRowBI, Gtk::PACK_SHRINK); + + _notebook.append_page(_editBIV, "Edit Built-In"); } - break; + + _getContents()->pack_end(_notebook, Gtk::PACK_EXPAND_WIDGET); + } else { + //_outsideV.pack_end(_scroller, Gtk::PACK_SHRINK); + _buttonsRow.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); + //_getContents()->pack_end(_outsideV, Gtk::PACK_SHRINK); + _getContents()->pack_end(_buttonsRow, Gtk::PACK_SHRINK); } + + loadPalletFile(); + + rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); + SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); + _swatchesChanged(); } -void SwatchesPanel::_setSelectedIndex( int index ) +SwatchesPanel::~SwatchesPanel() { - std::vector pages = _getSwatchSets(); - if ( index >= 0 && index < static_cast(pages.size()) ) { - _currentIndex = index; + if (rootWatcher) { + rootWatcher->_repr->removeObserver(*rootWatcher); + delete rootWatcher; + } + + if (docWatcher) { + docWatcher->_repr->removeObserver(*docWatcher); + delete docWatcher; + } + + _documentConnection.disconnect(); + _selChanged.disconnect(); +} - if ( !_prefs_path.empty() ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); +void SwatchesPanel::setDesktop( SPDesktop* desktop ) +{ + Inkscape::UI::Widget::Panel::setDesktop(desktop); + if ( desktop != _currentDesktop ) { + if ( _currentDesktop ) { + _documentConnection.disconnect(); + _selChanged.disconnect(); } - _rebuild(); + _currentDesktop = desktop; + + if ( desktop ) { + //_currentDesktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + _documentConnection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &SwatchesPanel::_setDocument)); + + _setDocument( desktop, desktop->doc() ); + } else { + _setDocument(0, 0); + } } } -void SwatchesPanel::_rebuild() +void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) { - std::vector pages = _getSwatchSets(); - if (_currentIndex < static_cast(pages.size())) { - SwatchPage* curr = pages[_currentIndex]; - _holder->clear(); - - if ( curr->_prefWidth > 0 ) { - _holder->setColumnPref( curr->_prefWidth ); + if ( document != _currentDocument ) { + if (docWatcher) { + docWatcher->_repr->removeObserver(*docWatcher); + delete docWatcher; + docWatcher = NULL; } - _holder->freezeUpdates(); - // TODO restore once 'clear' works _holder->addPreview(_clear); - _holder->addPreview(_remove); - for ( boost::ptr_vector::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { - _holder->addPreview(&*it); + _currentDocument = document; + + if (_currentDocument) { + docWatcher = new SwatchWatcher(this, _currentDocument->getDefs(), false); + _currentDocument->getDefs()->getRepr()->addObserver(*docWatcher); } - _holder->thawUpdates(); + _defsChanged(); } } @@ -1241,6 +2323,48 @@ void SwatchesPanel::_rebuild() } //namespace UI } //namespace Inkscape +//should be okay to add this here +guint get_group0_keyval(GdkEventKey *event) { + guint keyval = 0; + gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( + gdk_display_get_default()), event->hardware_keycode, + (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, + NULL, NULL, NULL); + return keyval; +} + +void +sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) +{ + + bool intercepted = false; + + if (gradient->isSolid()) { + ColorRGBA color(gradient->getFirstStop()->getEffectiveColor().toRGBA32(gradient->getFirstStop()->opacity)); + guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]); + gchar b[64]; + sp_svg_write_color(b, sizeof(b), rgba); + SPCSSAttr *css = sp_repr_css_attr_new(); + if (fill) { + sp_repr_css_set_property(css, "fill", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "fill-opacity", osalpha.str().c_str()); + } else { + sp_repr_css_set_property(css, "stroke", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "stroke-opacity", osalpha.str().c_str()); + } + intercepted = desktop->_set_style_signal.emit(css); + } + + if (!intercepted) { + for (const GSList *it = desktop->selection->itemList(); it != NULL; it = it->next) { + sp_item_set_gradient(SP_ITEM(it->data), gradient, SP_IS_RADIALGRADIENT(gradient) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, !fill ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); + } + } +} /* Local Variables: diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index 3abb81d98..cb8f87962 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -12,66 +12,161 @@ #include "ui/widget/panel.h" #include "enums.h" +#include "sp-object.h" +#include "sp-item-group.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sp-gradient.h" +#include "xml/node-observer.h" namespace Inkscape { namespace UI { -class PreviewHolder; - namespace Dialogs { -class ColorItem; -class SwatchPage; -class DocTrack; - /** * A panel that displays paint swatches. */ class SwatchesPanel : public Inkscape::UI::Widget::Panel { public: - SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches"); + SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches", bool showLabels = true); virtual ~SwatchesPanel(); - + static SwatchesPanel& getInstance(); - virtual void setOrientation(SPAnchorType how); - virtual void setDesktop( SPDesktop* desktop ); virtual SPDesktop* getDesktop() {return _currentDesktop;} - virtual int getSelectedIndex() {return _currentIndex;} // temporary - protected: - static void handleDocumentDestroy(SPDocument *document); - static void handleGradientsChange(SPDocument *document); - - virtual void _updateFromSelection(); - virtual void _handleAction( int setId, int itemId ); - virtual void _setDocument( SPDocument *document ); - virtual void _setSelectedIndex( int index ); - virtual void _rebuild(); - virtual std::vector _getSwatchSets() const; + virtual void _setDocument( SPDesktop* desktop, SPDocument *document ); private: + class ModelColumns; + class ModelColumnsDoc; + + class StopWatcher; + class GradientWatcher; + class SwatchWatcher; + SwatchesPanel(SwatchesPanel const &); // no copy SwatchesPanel &operator=(SwatchesPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ); + + void _setSelectionSwatch(SPGradient* swatchItem, bool isStroke); + + void NoLinkToggled(); + void NewGroup(); + void NewGroupBI(); + void _addBIButtonClicked(GdkEventButton* event); + void Duplicate(SPGroup* page); + void SaveAs(); + void AddSelectedFill(SPGroup* page); + void AddSelectedStroke(SPGroup* page); + void MoveUp(SPGroup* page); + void MoveDown(SPGroup* page); + void Remove(SPGroup* page); + + void SetSelectedFill(SPGradient* swatch); + void SetSelectedStroke(SPGradient* swatch); + void MoveSwatchUp(SPGradient* swatch); + void MoveSwatchDown(SPGradient* swatch); + void RemoveSwatch(SPGradient* swatch); + + void _lblClick(GdkEventButton* event, SPGroup* page); + void _addSwatchButtonClicked(SPGroup* swatch, bool recurse); + void _defsChanged(); + void _importButtonClicked(bool addToDoc, bool addToBI); + void _deleteButtonClicked(); + void _addButtonClicked(GdkEventButton* event); + void _swatchClicked(GdkEventButton* event, SPGradient* swatchItem); + + Gtk::MenuItem* _addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow); + void _swatchesChanged(); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _setCollapsed(SPGroup * group); + void _setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded); + + void _deleteButtonClickedDoc(); + bool _handleButtonEventDoc(GdkEventButton* event); + bool _handleKeyEventDoc(GdkEventKey *event); + + void _handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelledDoc(); + void _renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name); + + bool _handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + + Gtk::Menu *popUpMenu; + Gtk::Menu *popUpImportMenu; + + Gtk::ScrolledWindow _scroller; + Gtk::Table _insideTable; + Gtk::VBox _insideV; + Gtk::HBox _insideH; + Gtk::HBox _buttonsRow; + Gtk::VBox _outsideV; + Gtk::CheckButton _noLink; + bool _showlabels; + + SwatchesPanel::ModelColumns* _model; + Glib::RefPtr _store; + + Gtk::CellRendererText *_text_rendererBI; + Gtk::TreeView::Column *_name_columnBI; + Gtk::ScrolledWindow _scrollerBI; + Gtk::TreeView _editBI; + Gtk::HBox _buttonsRowBI; + Gtk::VBox _editBIV; + + SwatchesPanel::ModelColumnsDoc* _modelDoc; + Glib::RefPtr _storeDoc; + + Gtk::CellRendererText *_text_rendererDoc; + Gtk::CellRendererPixbuf *_pixbuf_rendererDoc; + Gtk::TreeView::Column *_name_columnDoc; + Gtk::TreeView::Column *_pixbuf_columnDoc; + Gtk::ScrolledWindow _scrollerDoc; + Gtk::TreeView _editDoc; + Gtk::HBox _buttonsRowDoc; + Gtk::VBox _editDocV; + + Gtk::Notebook _notebook; + + SwatchWatcher* rootWatcher; + std::vector rootWatchers; + + std::vector docWatchers; + SwatchWatcher* docWatcher; - static void _trackDocument( SwatchesPanel *panel, SPDocument *document ); - static void handleDefsModified(SPDocument *document); - - PreviewHolder* _holder; - ColorItem* _clear; - ColorItem* _remove; - int _currentIndex; SPDesktop* _currentDesktop; SPDocument* _currentDocument; + + bool _dnd_into; + SPObject* _dnd_source; + SPObject* _dnd_target; sigc::connection _documentConnection; sigc::connection _selChanged; - - friend class DocTrack; }; } //namespace Dialogs -- cgit v1.2.3 From 3093434e177d4bb7ccc57c1339fad00d47431c17 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 4 Mar 2014 21:24:03 -0500 Subject: Added a few swatch related functions (does not compile) (bzr r13090.1.15) --- src/sp-gradient-fns.h | 47 ++++++++ src/sp-tag-use-reference.cpp | 147 ++++++++++++++++++++++ src/sp-tag-use-reference.h | 77 ++++++++++++ src/sp-tag-use.cpp | 281 +++++++++++++++++++++++++++++++++++++++++++ src/sp-tag-use.h | 53 ++++++++ src/sp-tag.cpp | 240 ++++++++++++++++++++++++++++++++++++ src/sp-tag.h | 55 +++++++++ src/ui/dialog/swatches.cpp | 2 +- src/ui/widget/addtoicon.cpp | 149 +++++++++++++++++++++++ src/ui/widget/addtoicon.h | 98 +++++++++++++++ 10 files changed, 1148 insertions(+), 1 deletion(-) create mode 100644 src/sp-gradient-fns.h create mode 100644 src/sp-tag-use-reference.cpp create mode 100644 src/sp-tag-use-reference.h create mode 100644 src/sp-tag-use.cpp create mode 100644 src/sp-tag-use.h create mode 100644 src/sp-tag.cpp create mode 100644 src/sp-tag.h create mode 100644 src/ui/widget/addtoicon.cpp create mode 100644 src/ui/widget/addtoicon.h (limited to 'src') diff --git a/src/sp-gradient-fns.h b/src/sp-gradient-fns.h new file mode 100644 index 000000000..e57877256 --- /dev/null +++ b/src/sp-gradient-fns.h @@ -0,0 +1,47 @@ +#ifndef SEEN_SP_GRADIENT_FNS_H +#define SEEN_SP_GRADIENT_FNS_H + +/** \file + * Macros and fn declarations related to gradients. + */ + +#include +#include +#include <2geom/forward.h> +#include "sp-gradient-spread.h" +#include "sp-gradient-units.h" + +class SPGradient; +class SPMeshGradient; + +SPGradientSpread sp_gradient_get_spread (SPGradient *gradient); + +/* Gradient repr methods */ +void sp_gradient_repr_write_vector(SPGradient *gr); +void sp_gradient_repr_clear_vector(SPGradient *gr); + +void sp_meshgradient_repr_write(SPMeshGradient *mg); + +cairo_pattern_t *sp_gradient_create_preview_pattern(SPGradient *gradient, double width); + +/** Transforms to/from gradient position space in given environment */ +Geom::Affine sp_gradient_get_g2d_matrix(SPGradient const *gr, Geom::Affine const &ctm, + Geom::Rect const &bbox); +Geom::Affine sp_gradient_get_gs2d_matrix(SPGradient const *gr, Geom::Affine const &ctm, + Geom::Rect const &bbox); +void sp_gradient_set_gs2d_matrix(SPGradient *gr, Geom::Affine const &ctm, Geom::Rect const &bbox, + Geom::Affine const &gs2d); + + +#endif /* !SEEN_SP_GRADIENT_FNS_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-tag-use-reference.cpp b/src/sp-tag-use-reference.cpp new file mode 100644 index 000000000..8e48c0285 --- /dev/null +++ b/src/sp-tag-use-reference.cpp @@ -0,0 +1,147 @@ +/* + * The reference corresponding to href of element. + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include +#include +#include + +#include "enums.h" +#include "sp-tag-use-reference.h" + +#include "display/curve.h" +#include "livarot/Path.h" +#include "preferences.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "uri.h" + + + +bool SPTagUseReference::_acceptObject(SPObject * const obj) const +{ + if (SP_IS_ITEM(obj)) { + SPObject * const owner = getOwner(); + // Refuse references to us or to an ancestor. + for ( SPObject *iter = owner ; iter ; iter = iter->parent ) { + if ( iter == obj ) { + return false; + } + } + return true; + } else { + return false; + } +} + + +static void sp_usepath_href_changed(SPObject *old_ref, SPObject *ref, SPTagUsePath *offset); +static void sp_usepath_delete_self(SPObject *deleted, SPTagUsePath *offset); + +SPTagUsePath::SPTagUsePath(SPObject* i_owner):SPTagUseReference(i_owner) +{ + owner=i_owner; + originalPath = NULL; + sourceDirty=false; + sourceHref = NULL; + sourceRepr = NULL; + sourceObject = NULL; + _changed_connection = changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_usepath_href_changed), this)); // listening to myself, this should be virtual instead + + user_unlink = NULL; +} + +SPTagUsePath::~SPTagUsePath(void) +{ + delete originalPath; + originalPath = NULL; + + _changed_connection.disconnect(); // to do before unlinking + + quit_listening(); + unlink(); +} + +void +SPTagUsePath::link(char *to) +{ + if ( to == NULL ) { + quit_listening(); + unlink(); + } else { + if ( !sourceHref || ( strcmp(to, sourceHref) != 0 ) ) { + g_free(sourceHref); + sourceHref = g_strdup(to); + try { + attach(Inkscape::URI(to)); + } catch (Inkscape::BadURIException &e) { + /* TODO: Proper error handling as per + * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. + */ + g_warning("%s", e.what()); + detach(); + } + } + } +} + +void +SPTagUsePath::unlink(void) +{ + g_free(sourceHref); + sourceHref = NULL; + detach(); +} + +void +SPTagUsePath::start_listening(SPObject* to) +{ + if ( to == NULL ) { + return; + } + sourceObject = to; + sourceRepr = to->getRepr(); + _delete_connection = to->connectDelete(sigc::bind(sigc::ptr_fun(&sp_usepath_delete_self), this)); +} + +void +SPTagUsePath::quit_listening(void) +{ + if ( sourceObject == NULL ) { + return; + } + _delete_connection.disconnect(); + sourceRepr = NULL; + sourceObject = NULL; +} + +static void +sp_usepath_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPTagUsePath *offset) +{ + offset->quit_listening(); + SPItem *refobj = offset->getObject(); + if ( refobj ) { + offset->start_listening(refobj); + } +} + +static void +sp_usepath_delete_self(SPObject */*deleted*/, SPTagUsePath *offset) +{ + offset->owner->deleteObject(); +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use-reference.h b/src/sp-tag-use-reference.h new file mode 100644 index 000000000..039d2fd7d --- /dev/null +++ b/src/sp-tag-use-reference.h @@ -0,0 +1,77 @@ +#ifndef SEEN_SP_TAG_USE_REFERENCE_H +#define SEEN_SP_TAG_USE_REFERENCE_H + +/* + * The reference corresponding to href of element. + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include "sp-object.h" +#include "sp-item.h" +#include +#include +#include + +class Path; + +namespace Inkscape { +namespace XML { + struct Node; +} +} + + +class SPTagUseReference : public Inkscape::URIReference { +public: + SPTagUseReference(SPObject *owner) : URIReference(owner) {} + + SPItem *getObject() const { + return static_cast(URIReference::getObject()); + } + +protected: + virtual bool _acceptObject(SPObject * const obj) const; + +}; + + +class SPTagUsePath : public SPTagUseReference { +public: + Path *originalPath; + bool sourceDirty; + + SPObject *owner; + gchar *sourceHref; + Inkscape::XML::Node *sourceRepr; + SPObject *sourceObject; + + sigc::connection _delete_connection; + sigc::connection _changed_connection; + + SPTagUsePath(SPObject* i_owner); + ~SPTagUsePath(void); + + void link(char* to); + void unlink(void); + void start_listening(SPObject* to); + void quit_listening(void); + void refresh_source(void); + + void (*user_unlink) (SPObject *user); +}; + +#endif /* !SEEN_SP_USE_REFERENCE_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use.cpp b/src/sp-tag-use.cpp new file mode 100644 index 000000000..4c5171bbb --- /dev/null +++ b/src/sp-tag-use.cpp @@ -0,0 +1,281 @@ +/* + * SVG implementation + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include "display/drawing-group.h" +#include "attributes.h" +#include "document.h" +#include "sp-object-repr.h" +#include "uri.h" +#include "xml/repr.h" +#include "preferences.h" +#include "style.h" +#include "sp-symbol.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +/* fixme: */ + +static void sp_tag_use_class_init(SPTagUseClass *classname); +static void sp_tag_use_init(SPTagUse *use); +static void sp_tag_use_finalize(GObject *obj); + +static void sp_tag_use_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_tag_use_release(SPObject *object); +static void sp_tag_use_set(SPObject *object, unsigned key, gchar const *value); +static Inkscape::XML::Node *sp_tag_use_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); +static void sp_tag_use_update(SPObject *object, SPCtx *ctx, guint flags); + +static void sp_tag_use_href_changed(SPObject *old_ref, SPObject *ref, SPTagUse *use); + +static SPObjectClass *parent_class; + + +GType +sp_tag_use_get_type(void) +{ + static GType use_type = 0; + if (!use_type) { + GTypeInfo use_info = { + sizeof(SPTagUseClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_tag_use_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPTagUse), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_tag_use_init, + NULL, /* value_table */ + }; + use_type = g_type_register_static(SP_TYPE_OBJECT, "SPTagUse", &use_info, (GTypeFlags)0); + } + return use_type; +} + +static void +sp_tag_use_class_init(SPTagUseClass *classname) +{ + GObjectClass *gobject_class = (GObjectClass *) classname; + SPObjectClass *sp_object_class = (SPObjectClass *) classname; + + parent_class = (SPObjectClass*)g_type_class_peek_parent(classname); + + gobject_class->finalize = sp_tag_use_finalize; + + sp_object_class->build = sp_tag_use_build; + sp_object_class->release = sp_tag_use_release; + sp_object_class->set = sp_tag_use_set; + sp_object_class->write = sp_tag_use_write; + sp_object_class->update = sp_tag_use_update; +} + +static void +sp_tag_use_init(SPTagUse *use) +{ + use->href = NULL; + + new (&use->_changed_connection) sigc::connection(); + + use->ref = new SPTagUseReference(use); + + use->_changed_connection = use->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_tag_use_href_changed), use)); +} + +static void +sp_tag_use_finalize(GObject *obj) +{ + SPTagUse *use = reinterpret_cast(obj); + + if (use->child) { + use->detach(use->child); + use->child = NULL; + } + + use->ref->detach(); + delete use->ref; + use->ref = 0; + + use->_changed_connection.~connection(); + +} + +static void +sp_tag_use_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) parent_class)->build) { + (* ((SPObjectClass *) parent_class)->build)(object, document, repr); + } + + object->readAttr( "xlink:href" ); + + // We don't need to create child here: + // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, + // which will call sp_tag_use_href_changed, and that will take care of the child +} + +static void +sp_tag_use_release(SPObject *object) +{ + SPTagUse *use = SP_TAG_USE(object); + + if (use->child) { + object->detach(use->child); + use->child = NULL; + } + + use->_changed_connection.disconnect(); + + g_free(use->href); + use->href = NULL; + + use->ref->detach(); + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release(object); + } +} + +static void +sp_tag_use_set(SPObject *object, unsigned key, gchar const *value) +{ + SPTagUse *use = SP_TAG_USE(object); + + switch (key) { + case SP_ATTR_XLINK_HREF: { + if ( value && use->href && ( strcmp(value, use->href) == 0 ) ) { + /* No change, do nothing. */ + } else { + g_free(use->href); + use->href = NULL; + if (value) { + // First, set the href field, because sp_tag_use_href_changed will need it. + use->href = g_strdup(value); + + // Now do the attaching, which emits the changed signal. + try { + use->ref->attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + use->ref->detach(); + } + } else { + use->ref->detach(); + } + } + break; + } + + default: + if (((SPObjectClass *) parent_class)->set) { + ((SPObjectClass *) parent_class)->set(object, key, value); + } + break; + } +} + +static Inkscape::XML::Node * +sp_tag_use_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ + SPTagUse *use = SP_TAG_USE(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("inkscape:tagref"); + } + + if (((SPObjectClass *) (parent_class))->write) { + ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags); + } + + if (use->ref->getURI()) { + gchar *uri_string = use->ref->getURI()->toString(); + repr->setAttribute("xlink:href", uri_string); + g_free(uri_string); + } + + return repr; +} + +/** + * Returns the ultimate original of a SPTagUse (i.e. the first object in the chain of its originals + * which is not an SPTagUse). If no original is found, NULL is returned (it is the responsibility + * of the caller to make sure that this is handled correctly). + * + * Note that the returned is the clone object, i.e. the child of an SPTagUse (of the argument one for + * the trivial case) and not the "true original". + */ +SPItem * +sp_tag_use_root(SPTagUse *use) +{ + SPObject *orig = use->child; + while (orig && SP_IS_TAG_USE(orig)) { + orig = SP_TAG_USE(orig)->child; + } + if (!orig || !SP_IS_ITEM(orig)) + return NULL; + return SP_ITEM(orig); +} + +static void +sp_tag_use_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPTagUse *use) +{ + if (use->href) { + SPItem *refobj = use->ref->getObject(); + if (refobj) { + Inkscape::XML::Node *childrepr = refobj->getRepr(); + GType type = sp_repr_type_lookup(childrepr); + g_return_if_fail(type > G_TYPE_NONE); + if (g_type_is_a(type, SP_TYPE_ITEM)) { + use->child = (SPObject*) g_object_new(type, 0); + use->attach(use->child, use->lastChild()); + sp_object_unref(use->child, use); + (use->child)->invoke_build(use->document, childrepr, TRUE); + + } + } + } +} + +static void +sp_tag_use_update(SPObject *object, SPCtx *ctx, unsigned flags) +{ + if (((SPObjectClass *) (parent_class))->update) + ((SPObjectClass *) (parent_class))->update(object, ctx, flags); +} + +SPItem *sp_tag_use_get_original(SPTagUse *use) +{ + SPItem *ref = NULL; + if (use){ + if (use->ref){ + ref = use->ref->getObject(); + } + } + return ref; +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use.h b/src/sp-tag-use.h new file mode 100644 index 000000000..6e068fc21 --- /dev/null +++ b/src/sp-tag-use.h @@ -0,0 +1,53 @@ +#ifndef __SP_TAG_USE_H__ +#define __SP_TAG_USE_H__ + +/* + * SVG implementation + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "svg/svg-length.h" +#include "sp-object.h" + + +#define SP_TYPE_TAG_USE (sp_tag_use_get_type ()) +#define SP_TAG_USE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_TAG_USE, SPTagUse)) +#define SP_TAG_USE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_TAG_USE, SPTagUseClass)) +#define SP_IS_TAG_USE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_TAG_USE)) +#define SP_IS_TAG_USE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_TAG_USE)) + +class SPTagUse; +class SPTagUseClass; +class SPTagUseReference; + +struct SPTagUse : public SPObject { + // item built from the original's repr (the visible clone) + // relative to the SPUse itself, it is treated as a child, similar to a grouped item relative to its group + SPObject *child; + + gchar *href; + + // the reference to the original object + SPTagUseReference *ref; + sigc::connection _changed_connection; +}; + +struct SPTagUseClass { + SPObjectClass parent_class; +}; + +GType sp_tag_use_get_type (void); + +SPItem *sp_tag_use_unlink (SPTagUse *use); +SPItem *sp_tag_use_get_original (SPTagUse *use); + +SPItem *sp_tag_use_root(SPTagUse *use); +#endif diff --git a/src/sp-tag.cpp b/src/sp-tag.cpp new file mode 100644 index 000000000..eef55d628 --- /dev/null +++ b/src/sp-tag.cpp @@ -0,0 +1,240 @@ +/** \file + * SVG implementation + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "attributes.h" +#include "sp-tag.h" +#include "xml/repr.h" +#include + +#define DEBUG_TAG +#ifdef DEBUG_TAG +# define debug(f, a...) { g_print("%s(%d) %s:", \ + __FILE__,__LINE__,__FUNCTION__); \ + g_print(f, ## a); \ + g_print("\n"); \ + } +#else +# define debug(f, a...) /**/ +#endif + +/* Tag base class */ + +static void sp_tag_class_init(SPTagClass *klass); +static void sp_tag_init(SPTag *tag); + +static void sp_tag_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_tag_release(SPObject *object); +static void sp_tag_set(SPObject *object, unsigned int key, gchar const *value); +static void sp_tag_update(SPObject *object, SPCtx *ctx, guint flags); +static Inkscape::XML::Node *sp_tag_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); + +static SPObjectClass *tag_parent_class; + +GType +sp_tag_get_type() +{ + static GType tag_type = 0; + + if (!tag_type) { + GTypeInfo tag_info = { + sizeof(SPTagClass), + NULL, NULL, + (GClassInitFunc) sp_tag_class_init, + NULL, NULL, + sizeof(SPTag), + 16, + (GInstanceInitFunc) sp_tag_init, + NULL, /* value_table */ + }; + tag_type = g_type_register_static(SP_TYPE_OBJECT, "SPTag", &tag_info, (GTypeFlags)0); + } + return tag_type; +} + +static void +sp_tag_class_init(SPTagClass *klass) +{ + //GObjectClass *gobject_class = (GObjectClass *)klass; + SPObjectClass *sp_object_class = (SPObjectClass *)klass; + + tag_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass); + + sp_object_class->build = sp_tag_build; + sp_object_class->release = sp_tag_release; + sp_object_class->write = sp_tag_write; + sp_object_class->set = sp_tag_set; + sp_object_class->update = sp_tag_update; +} + +static void +sp_tag_init(SPTag *tag) +{ +} + +/* + * Move this SPItem into or after another SPItem in the doc + * \param target - the SPItem to move into or after + * \param intoafter - move to after the target (false), move inside (sublayer) of the target (true) + */ +void SPTag::moveTo(SPObject *target, gboolean intoafter) { + + Inkscape::XML::Node *target_ref = ( target ? target->getRepr() : NULL ); + Inkscape::XML::Node *our_ref = getRepr(); + gboolean first = FALSE; + + if (target_ref == our_ref) { + // Move to ourself ignore + return; + } + + if (!target_ref) { + // Assume move to the "first" in the top node, find the top node + target_ref = our_ref; + while (target_ref->parent() != target_ref->root()) { + target_ref = target_ref->parent(); + } + first = TRUE; + } + + if (intoafter) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else if (!first) { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } +} + +/** + * Reads the Inkscape::XML::Node, and initializes SPTag variables. For this to get called, + * our name must be associated with a repr via "sp_object_type_register". Best done through + * sp-object-repr.cpp's repr_name_entries array. + */ +static void +sp_tag_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + object->readAttr( "inkscape:expanded" ); + + if (((SPObjectClass *) tag_parent_class)->build) { + ((SPObjectClass *) tag_parent_class)->build(object, document, repr); + } +} + +/** + * Drops any allocated memory. + */ +static void +sp_tag_release(SPObject *object) +{ + /* deal with our children and our selves here */ + + if (((SPObjectClass *) tag_parent_class)->release) + ((SPObjectClass *) tag_parent_class)->release(object); +} + +/** + * Sets a specific value in the SPTag. + */ +static void +sp_tag_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPTag *tag = SP_TAG(object); + + switch (key) + { + case SP_ATTR_INKSCAPE_EXPANDED: + if ( value && !strcmp(value, "true") ) { + tag->setExpanded(true); + } + break; + default: + if (((SPObjectClass *) tag_parent_class)->set) { + ((SPObjectClass *) tag_parent_class)->set(object, key, value); + } + break; + } +} + +void SPTag::setExpanded(bool isexpanded) { + if ( _expanded != isexpanded ){ + _expanded = isexpanded; + } +} + +/** + * Receives update notifications. + */ +static void +sp_tag_update(SPObject *object, SPCtx *ctx, guint flags) +{ + //SPTag *tag = SP_TAG(object); + + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + + /* do something to trigger redisplay, updates? */ + + } + + if (((SPObjectClass *) tag_parent_class)->update) { + ((SPObjectClass *) tag_parent_class)->update(object, ctx, flags); + } +} + +/** + * Writes its settings to an incoming repr object, if any. + */ +static Inkscape::XML::Node * +sp_tag_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) +{ + SPTag *tag = SP_TAG(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = doc->createElement("inkscape:tag"); + } + + // Inkscape-only object, not copied during an "plain SVG" dump: + if (flags & SP_OBJECT_WRITE_EXT) { + + if (tag->_expanded) { + repr->setAttribute("inkscape:expanded", "true"); + } else { + repr->setAttribute("inkscape:expanded", NULL); + } + } + + if (((SPObjectClass *) tag_parent_class)->write) { + ((SPObjectClass *) tag_parent_class)->write(object, doc, repr, flags); + } + + return repr; +} + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-tag.h b/src/sp-tag.h new file mode 100644 index 000000000..c5eec785a --- /dev/null +++ b/src/sp-tag.h @@ -0,0 +1,55 @@ +#ifndef SP_TAG_H_SEEN +#define SP_TAG_H_SEEN + +/** \file + * SVG implementation + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" + +/* Skeleton base class */ + +#define SP_TYPE_TAG (sp_tag_get_type()) +#define SP_TAG(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_TAG, SPTag)) +#define SP_IS_TAG(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_TAG)) + +class SPTag; +class SPTagClass; + +class SPTag : public SPObject { +public: + bool _expanded; + + bool expanded() const { return _expanded; } + void setExpanded(bool isexpanded); + + void moveTo(SPObject *target, gboolean intoafter); + +}; + +struct SPTagClass { + SPObjectClass parent_class; +}; + +GType sp_tag_get_type(); + + +#endif /* !SP_SKELETON_H_SEEN */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index a0c79b8ac..2956c6d17 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -68,7 +68,7 @@ #include "sp-radial-gradient.h" #include "color-rgba.h" #include "svg/css-ostringstream.h" -//#include "event-context.h" //no longer exists +#include "ui/tools/tool-base.h" //event-context.h #include #ifdef WIN32 #include diff --git a/src/ui/widget/addtoicon.cpp b/src/ui/widget/addtoicon.cpp new file mode 100644 index 000000000..3d6091f70 --- /dev/null +++ b/src/ui/widget/addtoicon.cpp @@ -0,0 +1,149 @@ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "ui/widget/addtoicon.h" + +#include + +#include "widgets/icon.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "layertypeicon.h" +#include "addtoicon.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +AddToIcon::AddToIcon() : + Glib::ObjectBase(typeid(AddToIcon)), + Gtk::CellRendererPixbuf(), +// _pixAddName(INKSCAPE_ICON("layer-new")), + _property_active(*this, "active", false) +// _property_pixbuf_add(*this, "pixbuf_on", Glib::RefPtr(0)) +{ + property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; + phys = sp_icon_get_phys_size((int)Inkscape::ICON_SIZE_BUTTON); +// Glib::RefPtr icon_theme = Gtk::IconTheme::get_default(); +// +// if (!icon_theme->has_icon(_pixAddName)) { +// Inkscape::queueIconPrerender( INKSCAPE_ICON(_pixAddName.data()), Inkscape::ICON_SIZE_DECORATION ); +// } +// if (icon_theme->has_icon(_pixAddName)) { +// _property_pixbuf_add = icon_theme->load_icon(_pixAddName, phys, (Gtk::IconLookupFlags)0); +// } +// +// _property_pixbuf_add = Gtk::Widget:: + + property_stock_id() = GTK_STOCK_ADD; +} + + +#if WITH_GTKMM_3_0 +void AddToIcon::get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const +{ + Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h); + + if (min_h) { + min_h += (min_h) >> 1; + } + + if (nat_h) { + nat_h += (nat_h) >> 1; + } +} + +void AddToIcon::get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const +{ + Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w); + + if (min_w) { + min_w += (min_w) >> 1; + } + + if (nat_w) { + nat_w += (nat_w) >> 1; + } +} +#else +void AddToIcon::get_size_vfunc(Gtk::Widget& widget, + const Gdk::Rectangle* cell_area, + int* x_offset, + int* y_offset, + int* width, + int* height ) const +{ + Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height ); + + if ( width ) { + *width = phys;//+= (*width) >> 1; + } + if ( height ) { + *height =phys;//+= (*height) >> 1; + } +} +#endif + +#if WITH_GTKMM_3_0 +void AddToIcon::render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ) +#else +void AddToIcon::render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ) +#endif +{ + property_stock_id() = property_active().get_value() ? GTK_STOCK_ADD : GTK_STOCK_DELETE; + +#if WITH_GTKMM_3_0 + Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags ); +#else + Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags ); +#endif +} + +bool +AddToIcon::activate_vfunc(GdkEvent* event, + Gtk::Widget& /*widget*/, + const Glib::ustring& path, + const Gdk::Rectangle& /*background_area*/, + const Gdk::Rectangle& /*cell_area*/, + Gtk::CellRendererState /*flags*/) +{ + return false; +} + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + + diff --git a/src/ui/widget/addtoicon.h b/src/ui/widget/addtoicon.h new file mode 100644 index 000000000..aa8b4148e --- /dev/null +++ b/src/ui/widget/addtoicon.h @@ -0,0 +1,98 @@ +#ifndef __UI_DIALOG_ADDTOICON_H__ +#define __UI_DIALOG_ADDTOICON_H__ +/* + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +class AddToIcon : public Gtk::CellRendererPixbuf { +public: + AddToIcon(); + virtual ~AddToIcon() {}; + + Glib::PropertyProxy property_active() { return _property_active.get_proxy(); } + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_on(); + Glib::PropertyProxy< Glib::RefPtr > property_pixbuf_off(); + +protected: + +#if WITH_GTKMM_3_0 + virtual void render_vfunc( const Cairo::RefPtr& cr, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + Gtk::CellRendererState flags ); + + virtual void get_preferred_width_vfunc(Gtk::Widget& widget, + int& min_w, + int& nat_w) const; + + virtual void get_preferred_height_vfunc(Gtk::Widget& widget, + int& min_h, + int& nat_h) const; +#else + virtual void render_vfunc( const Glib::RefPtr& window, + Gtk::Widget& widget, + const Gdk::Rectangle& background_area, + const Gdk::Rectangle& cell_area, + const Gdk::Rectangle& expose_area, + Gtk::CellRendererState flags ); + + virtual void get_size_vfunc( Gtk::Widget &widget, + Gdk::Rectangle const *cell_area, + int *x_offset, int *y_offset, int *width, int *height ) const; +#endif + + virtual bool activate_vfunc(GdkEvent *event, + Gtk::Widget &widget, + const Glib::ustring &path, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + + +private: + int phys; + +// Glib::ustring _pixAddName; + + Glib::Property _property_active; +// Glib::Property< Glib::RefPtr > _property_pixbuf_add; + +}; + + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +#endif /* __UI_DIALOG_IMAGETOGGLER_H__ */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 9ae7e81723f4ea4e2640ed01d55d94e73874804f Mon Sep 17 00:00:00 2001 From: Guiu Rocafort Date: Wed, 5 Mar 2014 12:37:27 +0100 Subject: translations from spanish to english done, it might need a little review, but everything seems ok (bzr r11950.5.1) --- src/ui/tool/curve-drag-point.cpp | 5 ++- src/ui/tool/multi-path-manipulator.cpp | 5 ++- src/ui/tool/node.cpp | 64 ++++++++++++++++---------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 14 +++---- src/ui/tools/freehand-base.cpp | 23 ++++++------ src/ui/tools/node-tool.h | 3 +- src/ui/tools/pen-tool.cpp | 67 ++++++++++++++++------------------ src/ui/tools/pen-tool.h | 26 ++++++------- src/ui/tools/pencil-tool.cpp | 4 +- 10 files changed, 106 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index e5412fdc2..ad03cf75d 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,7 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - //spanish: solo actualizamos los nodos si no es bspline + // only update the nodes if the mode is bspline if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -89,7 +89,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT + + //modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index b7f3ac29b..68aaa77a5 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,9 +671,10 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: si es trazado bspline (mode 2) + + //if the trace is bspline ( mode 2) if(mode==2){ - //spanish: ¿correcto? + // is this correct ? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 78d8fe833..73460a313 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -184,7 +184,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -210,7 +210,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + // moves the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -292,7 +292,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo + // new double click event to set the handlers of a node to the default proportion, 0.3334% case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -303,7 +303,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 +//this function moves the handler and its oposite to the default proportion of 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -359,8 +359,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el - //parametro "steps whith control" del efecto en vivo BSpline + // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" + // by default in live BSpline if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -370,7 +370,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - //spanish: si está activado el ajuste (snap) y no es bspline + //if the snap adjustment is activated and it is not bspline if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -411,8 +411,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - //spanish: si es bspline pero no está presionado SHIFT o CONTROL - //lo fija en la posición original + //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -432,7 +431,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //spanish: marca la fuerza del bspline como 0.0000 + //sets the bspline strength to 0.0000 if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } @@ -478,9 +477,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - //spanish: un truco para, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + // a trick to mark as bspline if the node has no strength, we are going to use it later + // to show the appropiate messages. We cannot do it in any different way becasue the function is constant + bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -622,8 +621,8 @@ 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(); - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + + // save the previous node strength to apply it again once the node is moved double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline(false)){ @@ -638,8 +637,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the affected handlers. First the node ones, later the adjoining ones. if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -649,8 +648,7 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + // save the previous node strength to apply it again later when the node is moved double oldPos = 0.0000; if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; @@ -663,8 +661,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the involved handlers, first the node ones, later the adjoining ones if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -755,9 +753,11 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. - //Cada vez que actuemos sobre dichos tiradores en un trazado - //bspline esta fuerza se tiene que actualizar + + // define the node strength, depending on being or not bspline traced. + // every time we operate over these handlers in a trace bspline + // that strength needs to be updated. + this->bsplineWeight = 0.0000; if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { @@ -868,9 +868,8 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - //spanish: en los cambios de tipo de nodo, sobre trazados bspline, - //o bien los mantenemos con potencia 0.0000 en modo esquina - //o les damos la potencia por defecto en modo de curva + /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, + or we give them the default power in curve mode */ if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1123,7 +1122,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //spanish: esto muestra los tiradores al seleccionar los nodos + //this shows the handlers when selecting the nodes if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); @@ -1389,9 +1388,10 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - //spanish: un truco par, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + + /* if the node doesnt have strength, it marks it as bspline, we'll use it later + to show the appropiate messages. We cannot do it in any other way, because the + function is constant */ bool isBSpline = false; if( this->bsplineWeight != 0.0000) isBSpline = true; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index b7d6951d0..4393446d9 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,7 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //spanish: creamos valor de potencia bspline asociado a cada nodo + //strength value for each node double bsplineWeight; /** diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index a6689d93d..1cc075603 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -663,7 +663,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - //spanish: si se borra, reajustamos los tiradores + // if we are removing, we readjust the handlers if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ @@ -1182,7 +1182,7 @@ void PathManipulator::_createControlPointsFromGeometry() } } -//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza +//determines if the trace has a bspline effect and the number of steps that it takes int PathManipulator::BSplineGetSteps(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1200,7 +1200,7 @@ int PathManipulator::BSplineGetSteps(){ return steps; } -//spanish: determina si el trazado tiene efecto bspline +// determines if the trace has bspline effect bool PathManipulator::isBSpline(bool recalculate){ static int BSplineSteps = this->BSplineGetSteps(); if(recalculate){ @@ -1213,7 +1213,7 @@ bool PathManipulator::isBSpline(bool recalculate){ return isBSpline; } -//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador +// returns the corresponding strength to the position of a handler double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1231,13 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } -//spanish: mueve el tirador a la posición que le corresponda +// moves the handler to the corresponding position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } -//spanish: mueve el tirador a una posición específica +// moves the handler to the specified position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1263,7 +1263,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } -//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos +//moves the node handlers and its oposite handlers to the strength of its nodes void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index cb6111bd5..40a257de9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -252,7 +252,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //spanish: añadimos el modo bspline a los efectos en espera + //add the bspline node in the waiting effects if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -496,9 +496,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente - //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada - //porque la modificamos al continuar por un anchor + /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. + if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because + we modify it when continuing through an anchor. */ if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -527,8 +527,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor - //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes + + /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. + this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and + close incorrectly one of the parts */ if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { @@ -547,8 +549,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->unref(); dc->sa->curve->closepath_current(); } - //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white - //pasándole la curva de inicio necesaria + + //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); @@ -679,9 +681,8 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. - //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en - //la que cerramos el trazado. + /* modify the anchoring curve so it is equal to the starting curve. + this curve is modified when it's modified and we need them to be equal to the closing curve */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 168ec995a..42f89cd1c 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,7 +14,8 @@ #include #include #include "ui/tools/tool-base.h" -//spanish: lo necesitamos para llamarlo desde el Live Effect + +// we need it to call it from Live Effect #include "selection.h" namespace Inkscape { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 5846c3cec..bb1a03b7c 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//spanish: incluimos los archivos necesarios para las BSpline y Spiro +// we include the necessary files for BSpline & Spiro #include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" @@ -166,7 +166,7 @@ PenTool::~PenTool() { void PenTool::setPolylineMode() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: cambiamos los modos para dar cabida al modo bspline + // change the nodes to make space for bspline mode this->polylines_only = (mode == 3 || mode == 4); this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -178,7 +178,7 @@ void PenTool::setPolylineMode() { *.Set the mode of draw spiro, and bsplines */ void PenTool::_pen_context_set_mode(guint mode) { - //spanish: definimos los modos + // define the nodes this->spiro = (mode == 1); this->bspline = (mode == 2); } @@ -386,7 +386,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ - //spanish Borrar siguiente linea para evitar un nodo encima de otro + //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); _finish( FALSE); return TRUE; @@ -512,7 +512,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { } } - //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar + // avoid the creation of a control point so a node is created in the release event this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -705,7 +705,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { default: break; } - //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. + // calls the function "bspline_spiro_motion" when the mouse starts or stops moving if(this->bspline){ this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); @@ -743,9 +743,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(this, event_w); - //with this we avoid creating a new point over the existing one - //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. - + // if we try to create a node in the same place as another node, we skip if((!anchor || anchor == this->sa) && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ return TRUE; } @@ -760,7 +758,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { p = anchor->dp; } this->sa = anchor; - //spanish: continuamos una curva existente + // continue the existing curve if (anchor) { if(this->bspline || this->spiro){ this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; @@ -790,7 +788,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { this->_endpointSnap(p, revent.state); } this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hude the guide of the penultimate node when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -817,7 +815,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::CLOSE: this->_endpointSnap(p, revent.state); this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hide the penultimate node guide when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -908,7 +906,7 @@ void PenTool::_redrawAll() { sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); // handles - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if (this->p[0] != this->p[1] && !this->spiro && !this->bspline) { SP_CTRL(this->c1)->moveto(this->p[1]); this->cl1->setCoords(this->p[0], this->p[1]); @@ -922,7 +920,7 @@ void PenTool::_redrawAll() { Geom::Curve const * last_seg = this->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if ( cubic && (*cubic)[2] != this->p[0] && !this->spiro && !this->bspline ) { @@ -937,9 +935,8 @@ void PenTool::_redrawAll() { } } - //spanish: simplemente redibujamos la spiro. - //como es un redibujo simplemente no llamamos a la función global sino al final de esta - //Lanzamos solamente el redibujado + // simply redraw the spiro. because its a redrawing, we don't call the global function, + // but we call the redrawing at the ending. this->_bspline_spiro_build(); } @@ -969,12 +966,12 @@ void PenTool::_lastpointMoveScreen(gdouble x, gdouble y) { } void PenTool::_lastpointToCurve() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. if (this->npoints != 5 && !this->spiro && !this->bspline) return; Geom::CubicBezier const * cubic; this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //modificate the last segment of the green curve so it creates the type of node we need if(this->spiro||this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1012,7 +1009,7 @@ void PenTool::_lastpointToCurve() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + //if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(false); } @@ -1023,11 +1020,11 @@ void PenTool::_lastpointToCurve() { void PenTool::_lastpointToLine() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect) it doesn't stop here. if (this->npoints != 5 && !this->bspline) return; - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + // modify the last segment of the green curve so the type of node we want is created. if(this->spiro || this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1059,7 +1056,7 @@ void PenTool::_lastpointToLine() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + // if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(true); } @@ -1248,7 +1245,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0]; } - //spanish: asignamos el valor a un tercio de distancia del último segmento. + // asign the value in a third of the distance of the last segment. if(this->bspline){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } @@ -1258,7 +1255,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { : this->p[3])); this->npoints = 2; - //spanish: eliminamos el último segmento de la curva verde + // delete the last segment of the green curve if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { @@ -1270,7 +1267,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { }else{ this->green_curve->backspace(); } - //spanish: asignamos el valor de this->p[1] a el opuesto de el ultimo segmento de la línea verde + // assign the value of this->p[1] to the oposite of the green line last segment if(this->spiro){ cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { @@ -1285,7 +1282,8 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->state = PenTool::POINT; this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //spanish: redibujamos + + //redraw this->_bspline_spiro_build(); ret = TRUE; } @@ -1360,9 +1358,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t g_string_free(dist, FALSE); } - - -//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +// this function changes the colors red, green and blue making them transparent or not, depending on if spiro is being used. void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; @@ -1736,8 +1732,7 @@ void PenTool::_bspline_spiro_end_anchor_off() } } - -//spanish: preparates the curves for its trasformation into BSline curves. +//prepares the curves for its transformation into BSpline curve. void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) @@ -1766,7 +1761,7 @@ void PenTool::_bspline_spiro_build() } if(!curve->is_empty()){ - //spanish: cerramos la curva si estan cerca los puntos finales de la curva + // close the curve if the final points of the curve are close enough if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1805,7 +1800,7 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { - //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp + // commenting the function doEffect in src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; Geom::PathVector const original_pathv = curve->get_pathvector(); @@ -1945,7 +1940,7 @@ void PenTool::_bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp -//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp +// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; @@ -2178,7 +2173,7 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - //spanish para cancelar linea sin un segmento creado + // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); this->sa = NULL; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 88e528b22..95565abc9 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -49,7 +49,7 @@ public: bool polylines_only; bool polylines_paraxial; - //spanish: propiedad que guarda si el modo Spiro está activo o no + // propiety which saves if Spiro mode is active or not bool spiro; bool bspline; int num_clicks; @@ -88,29 +88,29 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - //spanish: añade los modos spiro y bspline + //adds spiro & bspline modes void _pen_context_set_mode(guint mode); - //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro + //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro void _bspline_spiro_color(); - //spanish: crea un nodo en modo bspline o spiro + //creates a node in bspline or spiro modes void _bspline_spiro(bool shift); - //spanish: crea un nodo de modo spiro o bspline + //creates a node in bspline or spiro modes void _bspline_spiro_on(); - //spanish: crea un nodo de tipo CUSP + //creates a CUSP node void _bspline_spiro_off(); - //spanish: continua una curva existente en modo bspline o spiro + //continues the existing curve in bspline or spiro mode void _bspline_spiro_start_anchor(bool shift); - //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro + //continues the existing curve with the union node in bspline or spiro modes void _bspline_spiro_start_anchor_on(); - //spanish: continua una curva existente con el nodo de union en modo CUSP + //continues an existing curve with the union node in CUSP mode void _bspline_spiro_start_anchor_off(); - //spanish: modifica la "red_curve" cuando se detecta movimiento + //modifies the "red_curve" when it detects movement void _bspline_spiro_motion(bool shift); - //spanish: cierra la curva con el último nodo en modo bspline o spiro + //closes the curve with the last node in bspline or spiro mode void _bspline_spiro_end_anchor_on(); - //spanish: cierra la curva con el último nodo en modo CUSP + //closes the curve with the last node in CUSP mode void _bspline_spiro_end_anchor_off(); - //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. + //CHECK: join all the curves "in game" and we call doEffect function void _bspline_spiro_build(); //function bspline cloned from lpe-bspline.cpp void _bspline_doEffect(SPCurve * curve); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index bd50672af..1ccdee637 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -685,7 +685,7 @@ void PencilTool::_interpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -835,7 +835,7 @@ void PencilTool::_fitAndSplit() { this->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From a9eea1cea2a13f129bcb30f175cea82ffcbcee29 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Mar 2014 20:03:46 +0100 Subject: Translations (bzr r11950.1.279) --- src/ui/tool/curve-drag-point.cpp | 5 +-- src/ui/tool/multi-path-manipulator.cpp | 5 +-- src/ui/tool/node.cpp | 64 ++++++++++++++++---------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 14 +++---- src/ui/tools/freehand-base.cpp | 23 ++++++------ src/ui/tools/node-tool.h | 3 +- src/ui/tools/pen-tool.cpp | 67 ++++++++++++++++++---------------- src/ui/tools/pen-tool.h | 26 ++++++------- src/ui/tools/pencil-tool.cpp | 4 +- 10 files changed, 107 insertions(+), 106 deletions(-) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index ad03cf75d..e5412fdc2 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,7 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - // only update the nodes if the mode is bspline + //spanish: solo actualizamos los nodos si no es bspline if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -89,8 +89,7 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - - //modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed + //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 68aaa77a5..b7f3ac29b 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,10 +671,9 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - - //if the trace is bspline ( mode 2) + //spanish: si es trazado bspline (mode 2) if(mode==2){ - // is this correct ? + //spanish: ¿correcto? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 73460a313..78d8fe833 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //move the handler and its oposite the same proportion + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -184,7 +184,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //move the handler and its oposite the same proportion + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -210,7 +210,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - // moves the handler and its oposite the same proportion + //spanish: mueve el tirador y su opuesto la misma proporción if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -292,7 +292,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - // new double click event to set the handlers of a node to the default proportion, 0.3334% + //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -303,7 +303,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//this function moves the handler and its oposite to the default proportion of 0.3334 +//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -359,8 +359,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" - // by default in live BSpline + //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el + //parametro "steps whith control" del efecto en vivo BSpline if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -370,7 +370,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - //if the snap adjustment is activated and it is not bspline + //spanish: si está activado el ajuste (snap) y no es bspline if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -411,7 +411,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position + //spanish: si es bspline pero no está presionado SHIFT o CONTROL + //lo fija en la posición original if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -431,7 +432,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //sets the bspline strength to 0.0000 + //spanish: marca la fuerza del bspline como 0.0000 if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } @@ -477,9 +478,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - // a trick to mark as bspline if the node has no strength, we are going to use it later - // to show the appropiate messages. We cannot do it in any different way becasue the function is constant - + //spanish: un truco para, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -621,8 +622,8 @@ 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(); - - // save the previous node strength to apply it again once the node is moved + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline(false)){ @@ -637,8 +638,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - - // move the affected handlers. First the node ones, later the adjoining ones. + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -648,7 +649,8 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { - // save the previous node strength to apply it again later when the node is moved + //spanish: guardamos la fuerza anterior del nodo para reaplicarsela + //de nuevo una vez sea movido el nodo double oldPos = 0.0000; if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; @@ -661,8 +663,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - - // move the involved handlers, first the node ones, later the adjoining ones + //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión + //y despues los de los nodos colindantes if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -753,11 +755,9 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - - // define the node strength, depending on being or not bspline traced. - // every time we operate over these handlers in a trace bspline - // that strength needs to be updated. - + //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. + //Cada vez que actuemos sobre dichos tiradores en un trazado + //bspline esta fuerza se tiene que actualizar this->bsplineWeight = 0.0000; if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { @@ -868,8 +868,9 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, - or we give them the default power in curve mode */ + //spanish: en los cambios de tipo de nodo, sobre trazados bspline, + //o bien los mantenemos con potencia 0.0000 en modo esquina + //o les damos la potencia por defecto en modo de curva if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1122,7 +1123,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //this shows the handlers when selecting the nodes + //spanish: esto muestra los tiradores al seleccionar los nodos if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); @@ -1388,10 +1389,9 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - - /* if the node doesnt have strength, it marks it as bspline, we'll use it later - to show the appropiate messages. We cannot do it in any other way, because the - function is constant */ + //spanish: un truco par, si el nodo tiene fuerza, nos marca que es + //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados + //no lo podemos hacer de otra forma al ser constante la funcion bool isBSpline = false; if( this->bsplineWeight != 0.0000) isBSpline = true; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 4393446d9..b7d6951d0 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,7 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //strength value for each node + //spanish: creamos valor de potencia bspline asociado a cada nodo double bsplineWeight; /** diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1cc075603..a6689d93d 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -663,7 +663,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - // if we are removing, we readjust the handlers + //spanish: si se borra, reajustamos los tiradores if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ @@ -1182,7 +1182,7 @@ void PathManipulator::_createControlPointsFromGeometry() } } -//determines if the trace has a bspline effect and the number of steps that it takes +//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza int PathManipulator::BSplineGetSteps(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1200,7 +1200,7 @@ int PathManipulator::BSplineGetSteps(){ return steps; } -// determines if the trace has bspline effect +//spanish: determina si el trazado tiene efecto bspline bool PathManipulator::isBSpline(bool recalculate){ static int BSplineSteps = this->BSplineGetSteps(); if(recalculate){ @@ -1213,7 +1213,7 @@ bool PathManipulator::isBSpline(bool recalculate){ return isBSpline; } -// returns the corresponding strength to the position of a handler +//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1231,13 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } -// moves the handler to the corresponding position +//spanish: mueve el tirador a la posición que le corresponda Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } -// moves the handler to the specified position +//spanish: mueve el tirador a una posición específica Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1263,7 +1263,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } -//moves the node handlers and its oposite handlers to the strength of its nodes +//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 40a257de9..cb6111bd5 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -252,7 +252,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //add the bspline node in the waiting effects + //spanish: añadimos el modo bspline a los efectos en espera if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -496,9 +496,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. - if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because - we modify it when continuing through an anchor. */ + //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente + //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada + //porque la modificamos al continuar por un anchor if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -527,10 +527,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - - /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. - this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and - close incorrectly one of the parts */ + //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor + //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { @@ -549,8 +547,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->unref(); dc->sa->curve->closepath_current(); } - - //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. + //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white + //pasándole la curva de inicio necesaria if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); @@ -681,8 +679,9 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - /* modify the anchoring curve so it is equal to the starting curve. - this curve is modified when it's modified and we need them to be equal to the closing curve */ + //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. + //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en + //la que cerramos el trazado. Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 42f89cd1c..168ec995a 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,8 +14,7 @@ #include #include #include "ui/tools/tool-base.h" - -// we need it to call it from Live Effect +//spanish: lo necesitamos para llamarlo desde el Live Effect #include "selection.h" namespace Inkscape { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index e3bbc72b1..ad77fcb53 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -// we include the necessary files for BSpline & Spiro +//spanish: incluimos los archivos necesarios para las BSpline y Spiro #include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" @@ -166,7 +166,7 @@ PenTool::~PenTool() { void PenTool::setPolylineMode() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - // change the nodes to make space for bspline mode + //spanish: cambiamos los modos para dar cabida al modo bspline this->polylines_only = (mode == 3 || mode == 4); this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -178,7 +178,7 @@ void PenTool::setPolylineMode() { *.Set the mode of draw spiro, and bsplines */ void PenTool::_pen_context_set_mode(guint mode) { - // define the nodes + //spanish: definimos los modos this->spiro = (mode == 1); this->bspline = (mode == 2); } @@ -386,7 +386,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ - //remove the following line to avoid having one node on top of another + //spanish Borrar siguiente linea para evitar un nodo encima de otro _finishSegment(event_dt, bevent.state); _finish( FALSE); return TRUE; @@ -512,7 +512,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { } } - // avoid the creation of a control point so a node is created in the release event + //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -705,7 +705,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { default: break; } - // calls the function "bspline_spiro_motion" when the mouse starts or stops moving + //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. if(this->bspline){ this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); @@ -743,7 +743,9 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(this, event_w); - // if we try to create a node in the same place as another node, we skip + //with this we avoid creating a new point over the existing one + //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. + if((!anchor || anchor == this->sa) && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ return TRUE; } @@ -758,7 +760,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { p = anchor->dp; } this->sa = anchor; - // continue the existing curve + //spanish: continuamos una curva existente if (anchor) { if(this->bspline || this->spiro){ this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; @@ -788,7 +790,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { this->_endpointSnap(p, revent.state); } this->_finishSegment(p, revent.state); - // hude the guide of the penultimate node when closing the curve + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -815,7 +817,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::CLOSE: this->_endpointSnap(p, revent.state); this->_finishSegment(p, revent.state); - // hide the penultimate node guide when closing the curve + //spanish: ocultamos la guia del penultimo nodo al cerrar la curva if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -906,7 +908,7 @@ void PenTool::_redrawAll() { sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); // handles - // hide the handlers in bspline and spiro modes + //spanish: ocultamos los tiradores en modo bspline y spiro if (this->p[0] != this->p[1] && !this->spiro && !this->bspline) { SP_CTRL(this->c1)->moveto(this->p[1]); this->cl1->setCoords(this->p[0], this->p[1]); @@ -920,7 +922,7 @@ void PenTool::_redrawAll() { Geom::Curve const * last_seg = this->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - // hide the handlers in bspline and spiro modes + //spanish: ocultamos los tiradores en modo bspline y spiro if ( cubic && (*cubic)[2] != this->p[0] && !this->spiro && !this->bspline ) { @@ -935,8 +937,9 @@ void PenTool::_redrawAll() { } } - // simply redraw the spiro. because its a redrawing, we don't call the global function, - // but we call the redrawing at the ending. + //spanish: simplemente redibujamos la spiro. + //como es un redibujo simplemente no llamamos a la función global sino al final de esta + //Lanzamos solamente el redibujado this->_bspline_spiro_build(); } @@ -966,12 +969,12 @@ void PenTool::_lastpointMoveScreen(gdouble x, gdouble y) { } void PenTool::_lastpointToCurve() { - // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (this->npoints != 5 && !this->spiro && !this->bspline) return; Geom::CubicBezier const * cubic; this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); - //modificate the last segment of the green curve so it creates the type of node we need + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(this->spiro||this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1009,7 +1012,7 @@ void PenTool::_lastpointToCurve() { this->green_curve->append_continuous(previous, 0.0625); } } - //if the last node is an union with another curve + //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(false); } @@ -1020,11 +1023,11 @@ void PenTool::_lastpointToCurve() { void PenTool::_lastpointToLine() { - // avoid that if the "red_curve" contains only two points ( rect) it doesn't stop here. + //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. if (this->npoints != 5 && !this->bspline) return; - // modify the last segment of the green curve so the type of node we want is created. + //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos if(this->spiro || this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1056,7 +1059,7 @@ void PenTool::_lastpointToLine() { this->green_curve->append_continuous(previous, 0.0625); } } - // if the last node is an union with another curve + //spanish: si el último nodo es una union con otra curva if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(true); } @@ -1245,7 +1248,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0]; } - // asign the value in a third of the distance of the last segment. + //spanish: asignamos el valor a un tercio de distancia del último segmento. if(this->bspline){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } @@ -1255,7 +1258,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { : this->p[3])); this->npoints = 2; - // delete the last segment of the green curve + //spanish: eliminamos el último segmento de la curva verde if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { @@ -1267,7 +1270,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { }else{ this->green_curve->backspace(); } - // assign the value of this->p[1] to the oposite of the green line last segment + //spanish: asignamos el valor de this->p[1] a el opuesto de el ultimo segmento de la línea verde if(this->spiro){ cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { @@ -1282,8 +1285,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->state = PenTool::POINT; this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - - //redraw + //spanish: redibujamos this->_bspline_spiro_build(); ret = TRUE; } @@ -1358,7 +1360,9 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t g_string_free(dist, FALSE); } -// this function changes the colors red, green and blue making them transparent or not, depending on if spiro is being used. + + +//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; @@ -1732,7 +1736,8 @@ void PenTool::_bspline_spiro_end_anchor_off() } } -//prepares the curves for its transformation into BSpline curve. + +//spanish: preparates the curves for its trasformation into BSline curves. void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) @@ -1761,7 +1766,7 @@ void PenTool::_bspline_spiro_build() } if(!curve->is_empty()){ - // close the curve if the final points of the curve are close enough + //spanish: cerramos la curva si estan cerca los puntos finales de la curva if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1800,7 +1805,7 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { - // commenting the function doEffect in src/live_effects/lpe-bspline.cpp + //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; Geom::PathVector const original_pathv = curve->get_pathvector(); @@ -1940,7 +1945,7 @@ void PenTool::_bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp -// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp +//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; @@ -2173,7 +2178,7 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - // cancelate line without a created segment + //spanish para cancelar linea sin un segmento creado this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); this->sa = NULL; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 95565abc9..88e528b22 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -49,7 +49,7 @@ public: bool polylines_only; bool polylines_paraxial; - // propiety which saves if Spiro mode is active or not + //spanish: propiedad que guarda si el modo Spiro está activo o no bool spiro; bool bspline; int num_clicks; @@ -88,29 +88,29 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - //adds spiro & bspline modes + //spanish: añade los modos spiro y bspline void _pen_context_set_mode(guint mode); - //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro + //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro void _bspline_spiro_color(); - //creates a node in bspline or spiro modes + //spanish: crea un nodo en modo bspline o spiro void _bspline_spiro(bool shift); - //creates a node in bspline or spiro modes + //spanish: crea un nodo de modo spiro o bspline void _bspline_spiro_on(); - //creates a CUSP node + //spanish: crea un nodo de tipo CUSP void _bspline_spiro_off(); - //continues the existing curve in bspline or spiro mode + //spanish: continua una curva existente en modo bspline o spiro void _bspline_spiro_start_anchor(bool shift); - //continues the existing curve with the union node in bspline or spiro modes + //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro void _bspline_spiro_start_anchor_on(); - //continues an existing curve with the union node in CUSP mode + //spanish: continua una curva existente con el nodo de union en modo CUSP void _bspline_spiro_start_anchor_off(); - //modifies the "red_curve" when it detects movement + //spanish: modifica la "red_curve" cuando se detecta movimiento void _bspline_spiro_motion(bool shift); - //closes the curve with the last node in bspline or spiro mode + //spanish: cierra la curva con el último nodo en modo bspline o spiro void _bspline_spiro_end_anchor_on(); - //closes the curve with the last node in CUSP mode + //spanish: cierra la curva con el último nodo en modo CUSP void _bspline_spiro_end_anchor_off(); - //CHECK: join all the curves "in game" and we call doEffect function + //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. void _bspline_spiro_build(); //function bspline cloned from lpe-bspline.cpp void _bspline_doEffect(SPCurve * curve); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 1ccdee637..bd50672af 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -685,7 +685,7 @@ void PencilTool::_interpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - // if we are in BSpline we modify the trace to create adhoc nodes + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -835,7 +835,7 @@ void PencilTool::_fitAndSplit() { this->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - // if we are in BSpline we modify the trace to create adhoc nodes + //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From 2aca4771b38314e62530f398222f02d4b9c17be5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Mar 2014 20:09:26 +0100 Subject: Fixing branch problems (bzr r11950.1.280) --- src/ui/dialog/export.cpp | 502 ++++++++++++++++++++++++----------------------- src/ui/dialog/export.h | 48 +++-- 2 files changed, 282 insertions(+), 268 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 340a3dad0..f0a5f1bf5 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -144,11 +144,13 @@ namespace Dialog { /** A list of strings that is used both in the preferences, and in the data fields to describe the various values of \c selection_type. */ static const char * selection_names[SELECTION_NUMBER_OF] = { - "page", "drawing", "selection", "custom"}; + "page", "drawing", "selection", "custom" +}; /** The names on the buttons for the various selection types. */ static const char * selection_labels[SELECTION_NUMBER_OF] = { - N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom") +}; Export::Export (void) : UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT), @@ -201,7 +203,7 @@ Export::Export (void) : /* gets added to the vbox later, but the unit selector is needed earlier than that */ unit_selector.setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); - + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { unit_selector.setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); @@ -232,28 +234,28 @@ Export::Export (void) : #endif x0_adj = createSpinbutton ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaX0Change); + t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaX0Change); x1_adj = createSpinbutton ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaX1Change); + t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaX1Change); width_adj = createSpinbutton ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaWidthChange); + t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaWidthChange); y0_adj = createSpinbutton ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaY0Change); + t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaY0Change); y1_adj = createSpinbutton ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaY1Change); + t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaY1Change); height_adj = createSpinbutton ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaHeightChange); + t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaHeightChange); area_box.pack_start(togglebox, false, false, 3); area_box.pack_start(*t, false, false, 0); @@ -284,27 +286,27 @@ Export::Export (void) : size_box.pack_start(*t); bmwidth_adj = createSpinbutton ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0, - t, 0, 0, - _("_Width:"), _("pixels at"), 0, 1, - &Export::onBitmapWidthChange); + t, 0, 0, + _("_Width:"), _("pixels at"), 0, 1, + &Export::onBitmapWidthChange); xdpi_adj = createSpinbutton ( "xdpi", - prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), - 0.01, 100000.0, 0.1, 1.0, t, 3, 0, - "", _("dp_i"), 2, 1, - &Export::onExportXdpiChange); + prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), + 0.01, 100000.0, 0.1, 1.0, t, 3, 0, + "", _("dp_i"), 2, 1, + &Export::onExportXdpiChange); bmheight_adj = createSpinbutton ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0, - t, 0, 1, - _("_Height:"), _("pixels at"), 0, 1, - &Export::onBitmapHeightChange); + t, 0, 1, + _("_Height:"), _("pixels at"), 0, 1, + &Export::onBitmapHeightChange); /** TODO * There's no way to set ydpi currently, so we use the defaultxdpi value here, too... */ ydpi_adj = createSpinbutton ( "ydpi", prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), - 0.01, 100000.0, 0.1, 1.0, t, 3, 1, - "", _("dpi"), 2, 0, NULL ); + 0.01, 100000.0, 0.1, 1.0, t, 3, 1, + "", _("dpi"), 2, 0, NULL ); singleexport_box.pack_start(size_box); } @@ -482,18 +484,18 @@ void Export::set_default_filename () { #if WITH_GTKMM_3_0 Glib::RefPtr Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max, - float step, float page, - Gtk::Grid *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ) + float step, float page, + Gtk::Grid *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ) #else Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max, - float step, float page, - Gtk::Table *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ) + float step, float page, + Gtk::Table *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ) #endif { #if WITH_GTKMM_3_0 @@ -535,7 +537,9 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl sb->set_sensitive (sensitive); pos++; - if (!ll.empty()) { l->set_mnemonic_widget(*sb);} + if (!ll.empty()) { + l->set_mnemonic_widget(*sb); + } if (!lr.empty()) { l = new Gtk::Label(lr,true); @@ -565,7 +569,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl Glib::ustring Export::create_filepath_from_id (Glib::ustring id, const Glib::ustring &file_entry_text) { if (id.empty()) - { /* This should never happen */ + { /* This should never happen */ id = "bitmap"; } @@ -678,35 +682,35 @@ void Export::onSelectionModified ( guint /*flags*/ ) { Inkscape::Selection * Sel; switch (current_key) { - case SELECTION_DRAWING: - if ( SP_ACTIVE_DESKTOP ) { - SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); - if (bbox) { - setArea ( bbox->left(), - bbox->top(), - bbox->right(), - bbox->bottom()); - } + case SELECTION_DRAWING: + if ( SP_ACTIVE_DESKTOP ) { + SPDocument *doc; + doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); + if (bbox) { + setArea ( bbox->left(), + bbox->top(), + bbox->right(), + bbox->bottom()); } - break; - case SELECTION_SELECTION: - Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); - if (Sel->isEmpty() == false) { - Geom::OptRect bbox = Sel->visualBounds(); - if (bbox) - { - setArea ( bbox->left(), - bbox->top(), - bbox->right(), - bbox->bottom()); - } + } + break; + case SELECTION_SELECTION: + Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); + if (Sel->isEmpty() == false) { + Geom::OptRect bbox = Sel->visualBounds(); + if (bbox) + { + setArea ( bbox->left(), + bbox->top(), + bbox->right(), + bbox->bottom()); } - break; - default: - /* Do nothing for page or for custom */ - break; + } + break; + default: + /* Do nothing for page or for custom */ + break; } return; @@ -738,39 +742,39 @@ void Export::onAreaToggled () various backups. If you modify this without noticing you'll probabaly screw something up. */ switch (key) { - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) - { - bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); - /* Only if there is a selection that we can set - do we break, otherwise we fall through to the - drawing */ - // std::cout << "Using selection: SELECTION" << std::endl; - key = SELECTION_SELECTION; - break; - } - case SELECTION_DRAWING: - /** \todo - * This returns wrong values if the document has a viewBox. - */ - bbox = doc->getRoot()->desktopVisualBounds(); - /* If the drawing is valid, then we'll use it and break - otherwise we drop through to the page settings */ - if (bbox) { - // std::cout << "Using selection: DRAWING" << std::endl; - key = SELECTION_DRAWING; - break; - } - case SELECTION_PAGE: - bbox = Geom::Rect(Geom::Point(0.0, 0.0), - Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); - - // std::cout << "Using selection: PAGE" << std::endl; - key = SELECTION_PAGE; + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) + { + bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); + /* Only if there is a selection that we can set + do we break, otherwise we fall through to the + drawing */ + // std::cout << "Using selection: SELECTION" << std::endl; + key = SELECTION_SELECTION; break; - case SELECTION_CUSTOM: - default: + } + case SELECTION_DRAWING: + /** \todo + * This returns wrong values if the document has a viewBox. + */ + bbox = doc->getRoot()->desktopVisualBounds(); + /* If the drawing is valid, then we'll use it and break + otherwise we drop through to the page settings */ + if (bbox) { + // std::cout << "Using selection: DRAWING" << std::endl; + key = SELECTION_DRAWING; break; + } + case SELECTION_PAGE: + bbox = Geom::Rect(Geom::Point(0.0, 0.0), + Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); + + // std::cout << "Using selection: PAGE" << std::endl; + key = SELECTION_PAGE; + break; + case SELECTION_CUSTOM: + default: + break; } // switch current_key = key; @@ -780,9 +784,9 @@ void Export::onAreaToggled () if ( key != SELECTION_CUSTOM && bbox ) { setArea ( bbox->min()[Geom::X], - bbox->min()[Geom::Y], - bbox->max()[Geom::X], - bbox->max()[Geom::Y]); + bbox->min()[Geom::Y], + bbox->max()[Geom::X], + bbox->max()[Geom::Y]); } } // end of if ( SP_ACTIVE_DESKTOP ) @@ -793,43 +797,43 @@ void Export::onAreaToggled () float xdpi = 0.0, ydpi = 0.0; switch (key) { - case SELECTION_PAGE: - case SELECTION_DRAWING: { - SPDocument * doc = SP_ACTIVE_DOCUMENT; - sp_document_get_export_hints (doc, filename, &xdpi, &ydpi); - - if (filename.empty()) { - if (!doc_export_name.empty()) { - filename = doc_export_name; - } + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + sp_document_get_export_hints (doc, filename, &xdpi, &ydpi); + + if (filename.empty()) { + if (!doc_export_name.empty()) { + filename = doc_export_name; } - break; } - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - - sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi); - - /* If we still don't have a filename -- let's build - one that's nice */ - if (filename.empty()) { - const gchar * id = "object"; - const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); - for(; reprlst != NULL; reprlst = reprlst->next) { - Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; - if (repr->attribute("id")) { - id = repr->attribute("id"); - break; - } - } + break; + } + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - filename = create_filepath_from_id (id, filename_entry.get_text()); + sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), filename, &xdpi, &ydpi); + + /* If we still don't have a filename -- let's build + one that's nice */ + if (filename.empty()) { + const gchar * id = "object"; + const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList(); + for(; reprlst != NULL; reprlst = reprlst->next) { + Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; + if (repr->attribute("id")) { + id = repr->attribute("id"); + break; + } } + + filename = create_filepath_from_id (id, filename_entry.get_text()); } - break; - case SELECTION_CUSTOM: - default: - break; + } + break; + case SELECTION_CUSTOM: + default: + break; } if (!filename.empty()) { @@ -895,8 +899,8 @@ unsigned int Export::onProgressCallback(float value, void *dlg) int evtcount = 0; while ((evtcount < 16) && gdk_events_pending()) { - gtk_main_iteration_do(FALSE); - evtcount += 1; + gtk_main_iteration_do(FALSE); + evtcount += 1; } gtk_main_iteration_do(FALSE); @@ -960,7 +964,7 @@ Glib::ustring Export::filename_add_extension (Glib::ustring filename, Glib::ustr } else { - return filename = filename + "." + extension; + return filename = filename + "." + extension; } } } @@ -1057,9 +1061,9 @@ void Export::onExport () // Do export gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); MessageCleaner msgCleanup(desktop->messageStack()->pushF(Inkscape::IMMEDIATE_MESSAGE, - _("Exporting file %s..."), safeFile), desktop); + _("Exporting file %s..."), safeFile), desktop); MessageCleaner msgFlashCleanup(desktop->messageStack()->flashF(Inkscape::IMMEDIATE_MESSAGE, - _("Exporting file %s..."), safeFile), desktop); + _("Exporting file %s..."), safeFile), desktop); if (!sp_export_png_file (doc, path.c_str(), *area, width, height, dpi, dpi, @@ -1067,7 +1071,7 @@ void Export::onExport () onProgressCallback, (void*)prog_dlg, TRUE, // overwrite without asking hide ? const_cast(sp_desktop_selection(desktop)->itemList()) : NULL - )) { + )) { gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); desktop->messageStack()->flashF(Inkscape::ERROR_MESSAGE, @@ -1096,7 +1100,7 @@ void Export::onExport () } else { Glib::ustring filename = filename_entry.get_text(); - if (filename.empty()){ + if (filename.empty()) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename.")); sp_ui_error_dialog(_("You have to enter a filename")); return; @@ -1125,7 +1129,7 @@ void Export::onExport () Glib::ustring dirname = Glib::path_get_dirname(path); if ( dirname.empty() - || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) + || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) { gchar *safeDir = Inkscape::IO::sanitizeString(dirname.c_str()); gchar *error = g_strdup_printf(_("Directory %s does not exist or is not a directory.\n"), @@ -1151,12 +1155,12 @@ void Export::onExport () /* Do export */ ExportResult status = sp_export_png_file(sp_desktop_document(desktop), path.c_str(), - Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, - nv->pagecolor, - onProgressCallback, (void*)prog_dlg, - FALSE, - hide ? const_cast(sp_desktop_selection(desktop)->itemList()) : NULL - ); + Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, + nv->pagecolor, + onProgressCallback, (void*)prog_dlg, + FALSE, + hide ? const_cast(sp_desktop_selection(desktop)->itemList()) : NULL + ); if (status == EXPORT_ERROR) { gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); @@ -1189,19 +1193,65 @@ void Export::onExport () /* Setup the values in the document */ switch (current_key) { - case SELECTION_PAGE: - case SELECTION_DRAWING: { - SPDocument * doc = SP_ACTIVE_DOCUMENT; - Inkscape::XML::Node * repr = doc->getReprRoot(); - bool modified = false; - - bool saved = DocumentUndo::getUndoSensitive(doc); - DocumentUndo::setUndoSensitive(doc, false); - - gchar const *temp_string = repr->attribute("inkscape:export-filename"); - if (temp_string == NULL || (filename_ext != temp_string)) { - repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); - modified = true; + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node * repr = doc->getReprRoot(); + bool modified = false; + + bool saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); + + gchar const *temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || (filename_ext != temp_string)) { + repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); + modified = true; + } + temp_string = repr->attribute("inkscape:export-xdpi"); + if (temp_string == NULL || xdpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi); + modified = true; + } + temp_string = repr->attribute("inkscape:export-ydpi"); + if (temp_string == NULL || ydpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); + modified = true; + } + DocumentUndo::setUndoSensitive(doc, saved); + + if (modified) { + doc->setModifiedSinceSave(); + } + break; + } + case SELECTION_SELECTION: { + const GSList * reprlst; + SPDocument * doc = SP_ACTIVE_DOCUMENT; + bool modified = false; + + bool saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); + reprlst = sp_desktop_selection(desktop)->reprList(); + + for(; reprlst != NULL; reprlst = reprlst->next) { + Inkscape::XML::Node * repr = static_cast(reprlst->data); + const gchar * temp_string; + Glib::ustring dir = Glib::path_get_dirname(filename.c_str()); + const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI(); + Glib::ustring docdir; + if (docURI) + { + docdir = Glib::path_get_dirname(docURI); + } + if (repr->attribute("id") == NULL || + !(filename_ext.find_last_of(repr->attribute("id")) && + ( !docURI || + (dir == docdir)))) { + temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || (filename_ext != temp_string)) { + repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); + modified = true; + } } temp_string = repr->attribute("inkscape:export-xdpi"); if (temp_string == NULL || xdpi != atof(temp_string)) { @@ -1213,62 +1263,16 @@ void Export::onExport () sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); modified = true; } - DocumentUndo::setUndoSensitive(doc, saved); - - if (modified) { - doc->setModifiedSinceSave(); - } - break; } - case SELECTION_SELECTION: { - const GSList * reprlst; - SPDocument * doc = SP_ACTIVE_DOCUMENT; - bool modified = false; - - bool saved = DocumentUndo::getUndoSensitive(doc); - DocumentUndo::setUndoSensitive(doc, false); - reprlst = sp_desktop_selection(desktop)->reprList(); - - for(; reprlst != NULL; reprlst = reprlst->next) { - Inkscape::XML::Node * repr = static_cast(reprlst->data); - const gchar * temp_string; - Glib::ustring dir = Glib::path_get_dirname(filename.c_str()); - const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI(); - Glib::ustring docdir; - if (docURI) - { - docdir = Glib::path_get_dirname(docURI); - } - if (repr->attribute("id") == NULL || - !(filename_ext.find_last_of(repr->attribute("id")) && - ( !docURI || - (dir == docdir)))) { - temp_string = repr->attribute("inkscape:export-filename"); - if (temp_string == NULL || (filename_ext != temp_string)) { - repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); - modified = true; - } - } - temp_string = repr->attribute("inkscape:export-xdpi"); - if (temp_string == NULL || xdpi != atof(temp_string)) { - sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi); - modified = true; - } - temp_string = repr->attribute("inkscape:export-ydpi"); - if (temp_string == NULL || ydpi != atof(temp_string)) { - sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); - modified = true; - } - } - DocumentUndo::setUndoSensitive(doc, saved); + DocumentUndo::setUndoSensitive(doc, saved); - if (modified) { - doc->setModifiedSinceSave(); - } - break; + if (modified) { + doc->setModifiedSinceSave(); } - default: - break; + break; + } + default: + break; } } @@ -1331,8 +1335,8 @@ void Export::onBrowse () // Copy the selected file name, converting from UTF-8 to UTF-16 std::string dirname = Glib::path_get_dirname(filename.raw()); if ( !Glib::file_test(dirname, Glib::FILE_TEST_EXISTS) || - Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) || - dirname.empty() ) + Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) || + dirname.empty() ) { Glib::ustring tmp; filename = create_filepath_from_id(tmp, tmp); @@ -1407,11 +1411,11 @@ bool Export::bbox_equal(Geom::Rect const &one, Geom::Rect const &two) { double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION); return ( - (fabs(one.min()[Geom::X] - two.min()[Geom::X]) < epsilon) && - (fabs(one.min()[Geom::Y] - two.min()[Geom::Y]) < epsilon) && - (fabs(one.max()[Geom::X] - two.max()[Geom::X]) < epsilon) && - (fabs(one.max()[Geom::Y] - two.max()[Geom::Y]) < epsilon) - ); + (fabs(one.min()[Geom::X] - two.min()[Geom::X]) < epsilon) && + (fabs(one.min()[Geom::Y] - two.min()[Geom::Y]) < epsilon) && + (fabs(one.max()[Geom::X] - two.max()[Geom::X]) < epsilon) && + (fabs(one.max()[Geom::Y] - two.max()[Geom::Y]) < epsilon) + ); } /** @@ -1454,48 +1458,48 @@ void Export::detectSize() { for (int i = 0; i < SELECTION_NUMBER_OF + 1 && - key == SELECTION_NUMBER_OF && - SP_ACTIVE_DESKTOP != NULL; + key == SELECTION_NUMBER_OF && + SP_ACTIVE_DESKTOP != NULL; i++) { switch (this_test[i]) { - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX); + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX); - if ( bbox && bbox_equal(*bbox,current_bbox)) { - key = SELECTION_SELECTION; - } + if ( bbox && bbox_equal(*bbox,current_bbox)) { + key = SELECTION_SELECTION; } - break; - case SELECTION_DRAWING: { - SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + } + break; + case SELECTION_DRAWING: { + SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); + Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); - if ( bbox && bbox_equal(*bbox,current_bbox) ) { - key = SELECTION_DRAWING; - } - break; + if ( bbox && bbox_equal(*bbox,current_bbox) ) { + key = SELECTION_DRAWING; } + break; + } - case SELECTION_PAGE: { - SPDocument *doc; + case SELECTION_PAGE: { + SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::Point x(0.0, 0.0); - Geom::Point y(doc->getWidth().value("px"), - doc->getHeight().value("px")); - Geom::Rect bbox(x, y); + Geom::Point x(0.0, 0.0); + Geom::Point y(doc->getWidth().value("px"), + doc->getHeight().value("px")); + Geom::Rect bbox(x, y); - if (bbox_equal(bbox,current_bbox)) { - key = SELECTION_PAGE; - } + if (bbox_equal(bbox,current_bbox)) { + key = SELECTION_PAGE; + } - break; - } + break; + } default: - break; + break; } } // std::cout << std::endl; @@ -1579,7 +1583,7 @@ void Export::areaYChange (Gtk::Adjustment *adj) height = SP_EXPORT_MIN_SIZE; //key = (const gchar *)g_object_get_data(G_OBJECT (adj), "key"); if (adj == y1_adj) { - //if (!strcmp (key, "y0")) { + //if (!strcmp (key, "y0")) { y1 = y0 + height * DPI_BASE / ydpi; setValuePx(y1_adj, y1); } else { diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 79e597414..6f3c0dfac 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -56,7 +56,9 @@ public: Export (); ~Export (); - static Export &getInstance() { return *new Export(); } + static Export &getInstance() { + return *new Export(); + } private: @@ -97,7 +99,7 @@ private: float getValue (Gtk::Adjustment *adj); float getValuePx (Gtk::Adjustment *adj); #endif - + /** * Helper function to create, style and pack spinbuttons for the export dialog. * @@ -121,20 +123,20 @@ private: */ #if WITH_GTKMM_3_0 Glib::RefPtr createSpinbutton( gchar const *key, float val, float min, float max, - float step, float page, - Gtk::Grid *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ); + float step, float page, + Gtk::Grid *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ); #else Gtk::Adjustment * createSpinbutton( gchar const *key, float val, float min, float max, - float step, float page, - Gtk::Table *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ); + float step, float page, + Gtk::Table *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ); #endif - + /** * One of the area select radio buttons was pressed */ @@ -153,8 +155,12 @@ private: /** * Area X value changed callback */ - void onAreaX0Change() {areaXChange(x0_adj);} ; - void onAreaX1Change() {areaXChange(x1_adj);} ; + void onAreaX0Change() { + areaXChange(x0_adj); + } ; + void onAreaX1Change() { + areaXChange(x1_adj); + } ; #if WITH_GTKMM_3_0 void areaXChange(Glib::RefPtr& adj); #else @@ -164,8 +170,12 @@ private: /** * Area Y value changed callback */ - void onAreaY0Change() {areaYChange(y0_adj);} ; - void onAreaY1Change() {areaYChange(y1_adj);} ; + void onAreaY0Change() { + areaYChange(y0_adj); + } ; + void onAreaY1Change() { + areaYChange(y1_adj); + } ; #if WITH_GTKMM_3_0 void areaYChange(Glib::RefPtr& adj); #else @@ -235,14 +245,14 @@ private: /** * Creates progress dialog for batch exporting. - * + * * @param progress_text Text to be shown in the progress bar */ Gtk::Dialog * create_progress_dialog (Glib::ustring progress_text); /** * Callback to be used in for loop to update the progress bar. - * + * * @param value number between 0 and 1 indicating the fraction of progress (0.17 = 17 % progress) * @param dlg void pointer to the Gtk::Dialog progress dialog */ -- cgit v1.2.3 From c15e77cc2670408ab725ba60c064743a9b61a375 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Mar 2014 20:18:54 +0100 Subject: Fixing branch problems (bzr r11950.1.281) --- src/ui/tool/curve-drag-point.cpp | 5 ++- src/ui/tool/multi-path-manipulator.cpp | 5 ++- src/ui/tool/node.cpp | 64 ++++++++++++++++---------------- src/ui/tool/node.h | 2 +- src/ui/tool/path-manipulator.cpp | 14 +++---- src/ui/tools/freehand-base.cpp | 23 ++++++------ src/ui/tools/node-tool.h | 3 +- src/ui/tools/pen-tool.cpp | 67 ++++++++++++++++------------------ src/ui/tools/pen-tool.h | 26 ++++++------- src/ui/tools/pencil-tool.cpp | 4 +- 10 files changed, 106 insertions(+), 107 deletions(-) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index e5412fdc2..ad03cf75d 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -53,7 +53,7 @@ bool CurveDragPoint::grabbed(GdkEventMotion */*event*/) // delta is a vector equal 1/3 of distance from first to second Geom::Point delta = (second->position() - first->position()) / 3.0; - //spanish: solo actualizamos los nodos si no es bspline + // only update the nodes if the mode is bspline if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + delta); second->back()->move(second->back()->position() - delta); @@ -89,7 +89,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point delta = new_pos - position(); Geom::Point offset0 = ((1-weight)/(3*t*(1-t)*(1-t))) * delta; Geom::Point offset1 = (weight/(3*t*t*(1-t))) * delta; - //spanish: modificado para que, si el trazado es bspline solo actue si está presionada la tecla SHIFT + + //modified so that, if the trace is bspline, it only acts if the SHIFT key is pressed if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index b7f3ac29b..68aaa77a5 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -671,9 +671,10 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G // b) ctrl+del preserves shape (del_preserves_shape is false), and control is pressed // Hence xor guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: si es trazado bspline (mode 2) + + //if the trace is bspline ( mode 2) if(mode==2){ - //spanish: ¿correcto? + // is this correct ? if(del_preserves_shape ^ held_control(event->key)) deleteNodes(false); else diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 78d8fe833..73460a313 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -167,7 +167,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -184,7 +184,7 @@ void Handle::move(Geom::Point const &new_pos) / Geom::L2sq(direction)) * direction; setRelativePos(new_delta); - //spanish: mueve el tirador y su opuesto la misma proporción + //move the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -210,7 +210,7 @@ void Handle::move(Geom::Point const &new_pos) } setPosition(new_pos); - //spanish: mueve el tirador y su opuesto la misma proporción + // moves the handler and its oposite the same proportion if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this)); this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); @@ -292,7 +292,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven break; default: break; } - //spanish: nuevo evento de doble click para resetear a la proporción por defecto, 0.3334%, los tiradores de un nodo + // new double click event to set the handlers of a node to the default proportion, 0.3334% case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -303,7 +303,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven return ControlPoint::_eventHandler(event_context, event); } -//spanish: función que mueve el tirador y su opuesto a la proporción por defecto de 0.3334 +//this function moves the handler and its oposite to the default proportion of 0.3334 void Handle::handle_2button_press(){ if(_pm().isBSpline(false)){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); @@ -359,8 +359,8 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); } new_pos = result; - //spanish: mueve el tirador y su opuesto en X posiciones fijas depenfiendo de la configuración de el - //parametro "steps whith control" del efecto en vivo BSpline + // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" + // by default in live BSpline if(_pm().isBSpline(false)){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); @@ -370,7 +370,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } std::vector unselected; - //spanish: si está activado el ajuste (snap) y no es bspline + //if the snap adjustment is activated and it is not bspline if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { @@ -411,8 +411,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) other()->setPosition(_saved_other_pos); } } - //spanish: si es bspline pero no está presionado SHIFT o CONTROL - //lo fija en la posición original + //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } @@ -432,7 +431,7 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //spanish: marca la fuerza del bspline como 0.0000 + //sets the bspline strength to 0.0000 if(_pm().isBSpline(false)){ _parent->bsplineWeight = 0.0000; } @@ -478,9 +477,9 @@ static double snap_increment_degrees() { Glib::ustring Handle::_getTip(unsigned state) const { char const *more; - //spanish: un truco para, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + // a trick to mark as bspline if the node has no strength, we are going to use it later + // to show the appropiate messages. We cannot do it in any different way becasue the function is constant + bool isBSpline = false; if( _parent->bsplineWeight != 0.0000) isBSpline = true; @@ -622,8 +621,8 @@ 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(); - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + + // save the previous node strength to apply it again once the node is moved double oldPos = 0.0000; Node *n = this; if(_pm().isBSpline(false)){ @@ -638,8 +637,8 @@ void Node::move(Geom::Point const &new_pos) // if the node has a smooth handle after a line segment, it should be kept colinear // with the segment _fixNeighbors(old_pos, new_pos); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the affected handlers. First the node ones, later the adjoining ones. if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -649,8 +648,7 @@ void Node::move(Geom::Point const &new_pos) void Node::transform(Geom::Affine const &m) { - //spanish: guardamos la fuerza anterior del nodo para reaplicarsela - //de nuevo una vez sea movido el nodo + // save the previous node strength to apply it again later when the node is moved double oldPos = 0.0000; if(_pm().isBSpline(false)){ oldPos = this->bsplineWeight; @@ -663,8 +661,8 @@ void Node::transform(Geom::Affine const &m) /* Affine transforms keep handle invariants for smooth and symmetric nodes, * but smooth nodes at ends of linear segments and auto nodes need special treatment */ _fixNeighbors(old_pos, position()); - //spanish: movemos los tiradores involucrados, primero los del nodo en cuestión - //y despues los de los nodos colindantes + + // move the involved handlers, first the node ones, later the adjoining ones if(_pm().isBSpline(false)){ _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); @@ -755,9 +753,11 @@ void Node::showHandles(bool v) if (!_back.isDegenerate()) { _back.setVisible(v); } - //spanish: definimos la fuerza de los nodos,según sea o no trazado bspline. - //Cada vez que actuemos sobre dichos tiradores en un trazado - //bspline esta fuerza se tiene que actualizar + + // define the node strength, depending on being or not bspline traced. + // every time we operate over these handlers in a trace bspline + // that strength needs to be updated. + this->bsplineWeight = 0.0000; if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ if (!_front.isDegenerate()) { @@ -868,9 +868,8 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - //spanish: en los cambios de tipo de nodo, sobre trazados bspline, - //o bien los mantenemos con potencia 0.0000 en modo esquina - //o les damos la potencia por defecto en modo de curva + /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, + or we give them the default power in curve mode */ if(_pm().isBSpline(false)){ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); @@ -1123,7 +1122,7 @@ void Node::_setState(State state) case STATE_CLICKED: mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); - //spanish: esto muestra los tiradores al seleccionar los nodos + //this shows the handlers when selecting the nodes if(_pm().isBSpline(false)){ if(!this->back()->isDegenerate()){ _pm().BSplineHandlePosition(this->back()); @@ -1389,9 +1388,10 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - //spanish: un truco par, si el nodo tiene fuerza, nos marca que es - //del tipo bspline, lo utilizaremos despues para mostras los mensajes apropiados - //no lo podemos hacer de otra forma al ser constante la funcion + + /* if the node doesnt have strength, it marks it as bspline, we'll use it later + to show the appropiate messages. We cannot do it in any other way, because the + function is constant */ bool isBSpline = false; if( this->bsplineWeight != 0.0000) isBSpline = true; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index b7d6951d0..4393446d9 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -187,7 +187,7 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //spanish: creamos valor de potencia bspline asociado a cada nodo + //strength value for each node double bsplineWeight; /** diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index a6689d93d..1cc075603 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -663,7 +663,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite nl.erase(start); start = next; } - //spanish: si se borra, reajustamos los tiradores + // if we are removing, we readjust the handlers if(isBSpline(false)){ double pos = 0.0000; if(start.prev()){ @@ -1182,7 +1182,7 @@ void PathManipulator::_createControlPointsFromGeometry() } } -//spanish: determina si el trazado tiene efecto bspline y el numero de pasos que realiza +//determines if the trace has a bspline effect and the number of steps that it takes int PathManipulator::BSplineGetSteps(){ LivePathEffect::LPEBSpline *lpe_bsp = NULL; @@ -1200,7 +1200,7 @@ int PathManipulator::BSplineGetSteps(){ return steps; } -//spanish: determina si el trazado tiene efecto bspline +// determines if the trace has bspline effect bool PathManipulator::isBSpline(bool recalculate){ static int BSplineSteps = this->BSplineGetSteps(); if(recalculate){ @@ -1213,7 +1213,7 @@ bool PathManipulator::isBSpline(bool recalculate){ return isBSpline; } -//spanish: devuelve la fuerza que le corresponderia a la posicón de un tirador +// returns the corresponding strength to the position of a handler double PathManipulator::BSplineHandlePosition(Handle *h){ using Geom::X; using Geom::Y; @@ -1231,13 +1231,13 @@ double PathManipulator::BSplineHandlePosition(Handle *h){ return pos; } -//spanish: mueve el tirador a la posición que le corresponda +// moves the handler to the corresponding position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ double pos = this->BSplineHandlePosition(h); return BSplineHandleReposition(h,pos); } -//spanish: mueve el tirador a una posición específica +// moves the handler to the specified position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1263,7 +1263,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ return ret; } -//spanish: mueve los tiradores del nodo y sus tiradores opuestos a la potencia de sus nodos +//moves the node handlers and its oposite handlers to the strength of its nodes void PathManipulator::BSplineNodeHandlesReposition(Node *n){ Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index cb6111bd5..40a257de9 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -252,7 +252,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - //spanish: añadimos el modo bspline a los efectos en espera + //add the bspline node in the waiting effects if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } @@ -496,9 +496,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - //spanish: si c esta vacio, puede ser que se haya tratado de contnuar una curva existente - //y se haya cancelado. Si es asi y el modo es bspline o spirolive la curva previa necesita volver a ser seleccionada - //porque la modificamos al continuar por un anchor + /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. + if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because + we modify it when continuing through an anchor. */ if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ SPDesktop *desktop = dc->desktop; @@ -527,8 +527,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - //spanish: si estamos en modo bspline o spirolive, la curva de continuación y finalización es actualizada al continuar o finalizar la curva en un anchor - //esto proboca que la función original no detecte si es la misma curva en el caso de curvas con multiples partes -shift- y cierre de manera erronea una de las partes + + /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. + this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and + close incorrectly one of the parts */ if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { @@ -547,8 +549,8 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->unref(); dc->sa->curve->closepath_current(); } - //spanish: Si la curva tiene un LPE del tipo bspline o spiro ejecutamos spdc_flush_white - //pasándole la curva de inicio necesaria + + //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); @@ -679,9 +681,8 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) } } - //spanish: modificamos la curva de anclaje para que sea igual que la curva de inicio. - //esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en - //la que cerramos el trazado. + /* modify the anchoring curve so it is equal to the starting curve. + this curve is modified when it's modified and we need them to be equal to the closing curve */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 168ec995a..42f89cd1c 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -14,7 +14,8 @@ #include #include #include "ui/tools/tool-base.h" -//spanish: lo necesitamos para llamarlo desde el Live Effect + +// we need it to call it from Live Effect #include "selection.h" namespace Inkscape { diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index ad77fcb53..e3bbc72b1 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -42,7 +42,7 @@ #include "context-fns.h" #include "tools-switch.h" #include "ui/control-manager.h" -//spanish: incluimos los archivos necesarios para las BSpline y Spiro +// we include the necessary files for BSpline & Spiro #include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "live_effects/lpeobject-reference.h" @@ -166,7 +166,7 @@ PenTool::~PenTool() { void PenTool::setPolylineMode() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pen/freehand-mode", 0); - //spanish: cambiamos los modos para dar cabida al modo bspline + // change the nodes to make space for bspline mode this->polylines_only = (mode == 3 || mode == 4); this->polylines_paraxial = (mode == 4); //we call the function which defines the Spiro modes and the BSpline @@ -178,7 +178,7 @@ void PenTool::setPolylineMode() { *.Set the mode of draw spiro, and bsplines */ void PenTool::_pen_context_set_mode(guint mode) { - //spanish: definimos los modos + // define the nodes this->spiro = (mode == 1); this->bspline = (mode == 2); } @@ -386,7 +386,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ - //spanish Borrar siguiente linea para evitar un nodo encima de otro + //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); _finish( FALSE); return TRUE; @@ -512,7 +512,7 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { } } - //spanish: evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar + // avoid the creation of a control point so a node is created in the release event this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL; ret = TRUE; @@ -705,7 +705,7 @@ gint PenTool::_handleMotionNotify(GdkEventMotion const &mevent) { default: break; } - //spanish: lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para. + // calls the function "bspline_spiro_motion" when the mouse starts or stops moving if(this->bspline){ this->_bspline_spiro_color(); this->_bspline_spiro_motion(mevent.state & GDK_SHIFT_MASK); @@ -743,9 +743,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { // Test whether we hit any anchor. SPDrawAnchor *anchor = spdc_test_inside(this, event_w); - //with this we avoid creating a new point over the existing one - //spanish: si intentamos crear un nodo en el mismo sitio que el origen, paramos. - + // if we try to create a node in the same place as another node, we skip if((!anchor || anchor == this->sa) && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ return TRUE; } @@ -760,7 +758,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { p = anchor->dp; } this->sa = anchor; - //spanish: continuamos una curva existente + // continue the existing curve if (anchor) { if(this->bspline || this->spiro){ this->_bspline_spiro_start_anchor(revent.state & GDK_SHIFT_MASK);; @@ -790,7 +788,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { this->_endpointSnap(p, revent.state); } this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hude the guide of the penultimate node when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -817,7 +815,7 @@ gint PenTool::_handleButtonRelease(GdkEventButton const &revent) { case PenTool::CLOSE: this->_endpointSnap(p, revent.state); this->_finishSegment(p, revent.state); - //spanish: ocultamos la guia del penultimo nodo al cerrar la curva + // hide the penultimate node guide when closing the curve if(this->spiro){ sp_canvas_item_hide(this->c1); } @@ -908,7 +906,7 @@ void PenTool::_redrawAll() { sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); // handles - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if (this->p[0] != this->p[1] && !this->spiro && !this->bspline) { SP_CTRL(this->c1)->moveto(this->p[1]); this->cl1->setCoords(this->p[0], this->p[1]); @@ -922,7 +920,7 @@ void PenTool::_redrawAll() { Geom::Curve const * last_seg = this->green_curve->last_segment(); if (last_seg) { Geom::CubicBezier const * cubic = dynamic_cast( last_seg ); - //spanish: ocultamos los tiradores en modo bspline y spiro + // hide the handlers in bspline and spiro modes if ( cubic && (*cubic)[2] != this->p[0] && !this->spiro && !this->bspline ) { @@ -937,9 +935,8 @@ void PenTool::_redrawAll() { } } - //spanish: simplemente redibujamos la spiro. - //como es un redibujo simplemente no llamamos a la función global sino al final de esta - //Lanzamos solamente el redibujado + // simply redraw the spiro. because its a redrawing, we don't call the global function, + // but we call the redrawing at the ending. this->_bspline_spiro_build(); } @@ -969,12 +966,12 @@ void PenTool::_lastpointMoveScreen(gdouble x, gdouble y) { } void PenTool::_lastpointToCurve() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. if (this->npoints != 5 && !this->spiro && !this->bspline) return; Geom::CubicBezier const * cubic; this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + //modificate the last segment of the green curve so it creates the type of node we need if(this->spiro||this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1012,7 +1009,7 @@ void PenTool::_lastpointToCurve() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + //if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(false); } @@ -1023,11 +1020,11 @@ void PenTool::_lastpointToCurve() { void PenTool::_lastpointToLine() { - //spanish: evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui. + // avoid that if the "red_curve" contains only two points ( rect) it doesn't stop here. if (this->npoints != 5 && !this->bspline) return; - //spanish: modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos + // modify the last segment of the green curve so the type of node we want is created. if(this->spiro || this->bspline){ if(!this->green_curve->is_empty()){ Geom::Point A(0,0); @@ -1059,7 +1056,7 @@ void PenTool::_lastpointToLine() { this->green_curve->append_continuous(previous, 0.0625); } } - //spanish: si el último nodo es una union con otra curva + // if the last node is an union with another curve if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ this->_bspline_spiro_start_anchor(true); } @@ -1248,7 +1245,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0]; } - //spanish: asignamos el valor a un tercio de distancia del último segmento. + // asign the value in a third of the distance of the last segment. if(this->bspline){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } @@ -1258,7 +1255,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { : this->p[3])); this->npoints = 2; - //spanish: eliminamos el último segmento de la curva verde + // delete the last segment of the green curve if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { @@ -1270,7 +1267,7 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { }else{ this->green_curve->backspace(); } - //spanish: asignamos el valor de this->p[1] a el opuesto de el ultimo segmento de la línea verde + // assign the value of this->p[1] to the oposite of the green line last segment if(this->spiro){ cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { @@ -1285,7 +1282,8 @@ gint PenTool::_handleKeyPress(GdkEvent *event) { this->state = PenTool::POINT; this->_setSubsequentPoint(pt, true); pen_last_paraxial_dir = !pen_last_paraxial_dir; - //spanish: redibujamos + + //redraw this->_bspline_spiro_build(); ret = TRUE; } @@ -1360,9 +1358,7 @@ void PenTool::_setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_t g_string_free(dist, FALSE); } - - -//spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro +// this function changes the colors red, green and blue making them transparent or not, depending on if spiro is being used. void PenTool::_bspline_spiro_color() { bool remake_green_bpaths = false; @@ -1736,8 +1732,7 @@ void PenTool::_bspline_spiro_end_anchor_off() } } - -//spanish: preparates the curves for its trasformation into BSline curves. +//prepares the curves for its transformation into BSpline curve. void PenTool::_bspline_spiro_build() { if(!this->spiro && !this->bspline) @@ -1766,7 +1761,7 @@ void PenTool::_bspline_spiro_build() } if(!curve->is_empty()){ - //spanish: cerramos la curva si estan cerca los puntos finales de la curva + // close the curve if the final points of the curve are close enough if(Geom::are_near(curve->first_path()->initialPoint(), curve->last_path()->finalPoint())){ curve->closepath_current(); } @@ -1805,7 +1800,7 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { - //spanish: comentado en funcion "doEffect" de src/live_effects/lpe-bspline.cpp + // commenting the function doEffect in src/live_effects/lpe-bspline.cpp if(curve->get_segment_count() < 2) return; Geom::PathVector const original_pathv = curve->get_pathvector(); @@ -1945,7 +1940,7 @@ void PenTool::_bspline_doEffect(SPCurve * curve) } //Spiro function cloned from lpe-spiro.cpp -//spanish: comentado en funcion "doEffect" de src/live_effects/lpe-spiro.cpp +// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp void PenTool::_spiro_doEffect(SPCurve * curve) { using Geom::X; @@ -2178,7 +2173,7 @@ void PenTool::_finish(gboolean const closed) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Drawing finished")); - //spanish para cancelar linea sin un segmento creado + // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); this->sa = NULL; diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 88e528b22..95565abc9 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -49,7 +49,7 @@ public: bool polylines_only; bool polylines_paraxial; - //spanish: propiedad que guarda si el modo Spiro está activo o no + // propiety which saves if Spiro mode is active or not bool spiro; bool bspline; int num_clicks; @@ -88,29 +88,29 @@ private: gint _handleButtonRelease(GdkEventButton const &revent); gint _handle2ButtonPress(GdkEventButton const &bevent); gint _handleKeyPress(GdkEvent *event); - //spanish: añade los modos spiro y bspline + //adds spiro & bspline modes void _pen_context_set_mode(guint mode); - //spanish: esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro + //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro void _bspline_spiro_color(); - //spanish: crea un nodo en modo bspline o spiro + //creates a node in bspline or spiro modes void _bspline_spiro(bool shift); - //spanish: crea un nodo de modo spiro o bspline + //creates a node in bspline or spiro modes void _bspline_spiro_on(); - //spanish: crea un nodo de tipo CUSP + //creates a CUSP node void _bspline_spiro_off(); - //spanish: continua una curva existente en modo bspline o spiro + //continues the existing curve in bspline or spiro mode void _bspline_spiro_start_anchor(bool shift); - //spanish: continua una curva exsitente con el nodo de union en modo bspline o spiro + //continues the existing curve with the union node in bspline or spiro modes void _bspline_spiro_start_anchor_on(); - //spanish: continua una curva existente con el nodo de union en modo CUSP + //continues an existing curve with the union node in CUSP mode void _bspline_spiro_start_anchor_off(); - //spanish: modifica la "red_curve" cuando se detecta movimiento + //modifies the "red_curve" when it detects movement void _bspline_spiro_motion(bool shift); - //spanish: cierra la curva con el último nodo en modo bspline o spiro + //closes the curve with the last node in bspline or spiro mode void _bspline_spiro_end_anchor_on(); - //spanish: cierra la curva con el último nodo en modo CUSP + //closes the curve with the last node in CUSP mode void _bspline_spiro_end_anchor_off(); - //spanish: unimos todas las curvas en juego y llamamos a la función doEffect. + //CHECK: join all the curves "in game" and we call doEffect function void _bspline_spiro_build(); //function bspline cloned from lpe-bspline.cpp void _bspline_doEffect(SPCurve * curve); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index bd50672af..1ccdee637 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -685,7 +685,7 @@ void PencilTool::_interpolate() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); for (int c = 0; c < n_segs; c++) { - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes if(mode == 2){ Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]); BP = Geom::Point(BP[X] + 0.0001,BP[Y] + 0.0001); @@ -835,7 +835,7 @@ void PencilTool::_fitAndSplit() { this->red_curve->moveto(b[0]); using Geom::X; using Geom::Y; - //spanish: si el modo es BSpline modificamos para que el trazado cree los nodos adhoc + // if we are in BSpline we modify the trace to create adhoc nodes Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); if(mode == 2){ -- cgit v1.2.3 From fcffbecabedd7c6bca1312918c918d57fee3cf8c Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 15:24:04 -0500 Subject: Added new swatches dialog (bzr r13090.1.16) --- src/ui/dialog/color-item.cpp | 860 ++++++++--------------------------------- src/ui/dialog/color-item.h | 108 ++---- src/ui/dialog/filedialog.h | 1 + src/ui/dialog/swatches.cpp | 48 +-- src/widgets/desktop-widget.cpp | 2 +- 5 files changed, 204 insertions(+), 815 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 7940c28ae..6eece0c17 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -11,18 +11,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - -#include #include +#include #include #include @@ -45,6 +36,7 @@ #include "xml/repr.h" #include "verbs.h" #include "widgets/gradient-vector.h" +#include "sp-paint-server.h" #include "color.h" // for SP_RGBA32_U_COMPOSE @@ -53,756 +45,206 @@ namespace Inkscape { namespace UI { namespace Dialogs { -static std::vector mimeStrings; -static std::map mimeToInt; - -#if ENABLE_MAGIC_COLORS -// TODO remove this soon: -extern std::vector possible; -#endif // ENABLE_MAGIC_COLORS - - -#if ENABLE_MAGIC_COLORS -static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b ) +bool ColorItem::on_enter_notify_event(GdkEventCrossing* event) { - bool changed = false; - - if ( node ) { - gchar const * val = node->attribute("inkscape:x-fill-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "fill", c ); - - sp_desktop_apply_css_recursive( obj, css, true ); - static_cast(obj)->updateRepr(); - - changed = true; - } - - val = node->attribute("inkscape:x-stroke-tag"); - if ( val && (match == val) ) { - SPObject *obj = document->getObjectByRepr( node ); - - gchar c[64] = {0}; - sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property( css, "stroke", c ); - - sp_desktop_apply_css_recursive( (SPItem*)obj, css, true ); - ((SPItem*)obj)->updateRepr(); - - changed = true; - } - - Inkscape::XML::Node* first = node->firstChild(); - changed |= bruteForce( document, first, match, r, g, b ); - - changed |= bruteForce( document, node->next(), match, r, g, b ); - } - - return changed; -} -#endif // ENABLE_MAGIC_COLORS - -static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(false); - } -} - -static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - item->buttonClicked(true); - } -} - -static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"), - item->def.descr.c_str()); - desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); - g_free(msg); - } - } - return FALSE; -} - -static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { - ColorItem* item = reinterpret_cast(callback_data); - if ( item ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->tipsMessageContext()->clear(); - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"),def); + desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); + g_free(msg); } - return FALSE; + return Gtk::Widget::on_enter_notify_event(event); } -static void dieDieDie( GObject *obj, gpointer user_data ) +bool ColorItem::on_leave_notify_event(GdkEventCrossing* event) { - g_message("die die die %p %p", obj, user_data ); -} - -static bool getBlock( std::string& dst, guchar ch, std::string const & str ) -{ - bool good = false; - std::string::size_type pos = str.find(ch); - if ( pos != std::string::npos ) - { - std::string::size_type pos2 = str.find( '(', pos ); - if ( pos2 != std::string::npos ) { - std::string::size_type endPos = str.find( ')', pos2 ); - if ( endPos != std::string::npos ) { - dst = str.substr( pos2 + 1, (endPos - pos2 - 1) ); - good = true; - } - } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + desktop->tipsMessageContext()->clear(); } - return good; + return Gtk::Widget::on_leave_notify_event(event); } -static bool popVal( guint64& numVal, std::string& str ) +void ColorItem::selection_modified(Selection* selection, guint flags) { - bool good = false; - std::string::size_type endPos = str.find(','); - if ( endPos == std::string::npos ) { - endPos = str.length(); - } - - if ( endPos != std::string::npos && endPos > 0 ) { - std::string xxx = str.substr( 0, endPos ); - const gchar* ptr = xxx.c_str(); - gchar* endPtr = 0; - numVal = g_ascii_strtoull( ptr, &endPtr, 10 ); - if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { - // overflow - } else if ( (numVal == 0) && (endPtr == ptr) ) { - // failed conversion - } else { - good = true; - str.erase( 0, endPos + 1 ); - } - } - - return good; + selection_changed(selection); } -// TODO resolve this more cleanly: -extern gboolean colorItemHandleButtonPress( GtkWidget* /*widget*/, GdkEventButton* event, gpointer user_data); - -static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpointer data ) +void ColorItem::selection_changed(Selection* selection) { - ColorItem* item = reinterpret_cast(data); - if ( item ) + SPItem* item = selection->singleItem(); + SPPaintServer* grad; + if (item && + ( + (item->style->fill.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getFillPaintServer()) ) + && SP_GRADIENT(grad)->getVector() == gradient) || + + (item->style->stroke.isPaintserver() && + SP_IS_GRADIENT( (grad = item->style->getStrokePaintServer()) ) && + SP_GRADIENT(grad)->getVector() == gradient) + ) + ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - int width = 32; - int height = 24; - - if (item->def.getType() != ege::PaintDef::RGB){ - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, width, height, FALSE, &error); - g_free(localFilename); - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); - } else { - GdkPixbuf* pixbuf = 0; - if ( item->getGradient() ){ - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, gradient); - cairo_paint(ct); - cairo_destroy(ct); - cairo_pattern_destroy(gradient); - cairo_surface_flush(s); - - pixbuf = ink_pixbuf_create_from_cairo_surface(s); - } else { - Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); - guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) - | (0x00ff0000 & (item->def.getG() << 16)) - | (0x0000ff00 & (item->def.getB() << 8)); - thumb->fill( fillWith ); - pixbuf = thumb->gobj(); - g_object_ref(G_OBJECT(pixbuf)); - } - gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); + if (!_isSelected) { + _isSelected = true; + queue_draw(); } + } else if (_isSelected) { + _isSelected = false; + queue_draw(); } - -} - -//"drag-drop" -// gboolean dragDropColorData( GtkWidget *widget, -// GdkDragContext *drag_context, -// gint x, -// gint y, -// guint time, -// gpointer user_data) -// { -// // TODO finish - -// return TRUE; -// } - - -SwatchPage::SwatchPage() - : _prefWidth(0) -{ -} - -SwatchPage::~SwatchPage() -{ -} - - -ColorItem::ColorItem(ege::PaintDef::ColorType type) : - def(type), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : - def( r, g, b, name ), - _isFill(false), - _isStroke(false), - _isLive(false), - _linkIsTone(false), - _linkPercent(0), - _linkGray(0), - _linkSrc(0), - _grad(0), - _pattern(0) -{ -} - -ColorItem::~ColorItem() -{ - if (_pattern != NULL) { - cairo_pattern_destroy(_pattern); - } -} - -ColorItem::ColorItem(ColorItem const &other) : - Inkscape::UI::Previewable() -{ - if ( this != &other ) { - *this = other; - } -} - -ColorItem &ColorItem::operator=(ColorItem const &other) -{ - if ( this != &other ) { - def = other.def; - - // TODO - correct linkage - _linkSrc = other._linkSrc; - g_message("Erk!"); - } - return *this; } -void ColorItem::setState( bool fill, bool stroke ) +ColorItem::ColorItem( SPGradient* grad, const gchar* name, SPDesktop* desktop ) : + Glib::ObjectBase("coloritem"), + Gtk::Widget(), + def( name ), + gradient(grad), + _isSelected(false) { - if ( (_isFill != fill) || (_isStroke != stroke) ) { - _isFill = fill; - _isStroke = stroke; - - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - int val = eek_preview_get_linked( preview ); - val &= ~(PREVIEW_FILL | PREVIEW_STROKE); - if ( _isFill ) { - val |= PREVIEW_FILL; - } - if ( _isStroke ) { - val |= PREVIEW_STROKE; - } - eek_preview_set_linked( preview, static_cast(val) ); - } - } - } + set_has_window(true); + add_events(Gdk::BUTTON_PRESS_MASK); + add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + sel_connection = desktop->selection->connectChanged(sigc::mem_fun(*this, &ColorItem::selection_changed)); + mod_connection = desktop->selection->connectModified(sigc::mem_fun(*this, &ColorItem::selection_modified)); + selection_changed(desktop->selection); } -void ColorItem::setGradient(SPGradient *grad) +void ColorItem::on_size_request(Gtk::Requisition* requisition) { - if (_grad != grad) { - _grad = grad; - // TODO regen and push to listeners - } - - setName( gr_prepare_label(_grad) ); + requisition->height = 20; + requisition->width = 20; } -void ColorItem::setName(const Glib::ustring name) +void ColorItem::on_size_allocate(Gtk::Allocation& allocation) { - //def.descr = name; - - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - gtk_widget_set_tooltip_text(GTK_WIDGET(widget->gobj()), name.c_str()); - } - else if ( GTK_IS_LABEL(widget->gobj()) ) { - gtk_label_set_text(GTK_LABEL(widget->gobj()), name.c_str()); - } + set_allocation(allocation); + if (m_refGdkWindow) + { + m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); } } -void ColorItem::setPattern(cairo_pattern_t *pattern) +void ColorItem::on_map() { - if (pattern) { - cairo_pattern_reference(pattern); - } - if (_pattern) { - cairo_pattern_destroy(_pattern); - } - _pattern = pattern; - - _updatePreviews(); + Gtk::Widget::on_map(); } -void ColorItem::_dragGetColorData( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - GtkSelectionData *data, - guint info, - guint /*time*/, - gpointer user_data) +void ColorItem::on_unmap() { - ColorItem* item = reinterpret_cast(user_data); - std::string key; - if ( info < mimeStrings.size() ) { - key = mimeStrings[info]; - } else { - g_warning("ERROR: unknown value (%d)", info); - } - - if ( !key.empty() ) { - char* tmp = 0; - int len = 0; - int format = 0; - item->def.getMIMEData(key, tmp, len, format); - if ( tmp ) { - GdkAtom dataAtom = gdk_atom_intern( key.c_str(), FALSE ); - gtk_selection_data_set( data, dataAtom, format, (guchar*)tmp, len ); - delete[] tmp; - } - } + Gtk::Widget::on_unmap(); } -void ColorItem::_dropDataIn( GtkWidget */*widget*/, - GdkDragContext */*drag_context*/, - gint /*x*/, gint /*y*/, - GtkSelectionData */*data*/, - guint /*info*/, - guint /*event_time*/, - gpointer /*user_data*/) +void ColorItem::on_realize() { + set_realized(); + ensure_style(); + + if(!m_refGdkWindow) + { + //Create the GdkWindow: + + GdkWindowAttr attributes; + memset(&attributes, 0, sizeof(attributes)); + + Gtk::Allocation allocation = get_allocation(); + + //Set initial position and size of the Gdk::Window: + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); + + attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + + m_refGdkWindow = Gdk::Window::create(get_parent_window(), &attributes, + GDK_WA_X | GDK_WA_Y); + set_window(m_refGdkWindow); + + //Attach this widget's style to its Gdk::Window. + style_attach(); + + //make the widget receive expose events + m_refGdkWindow->set_user_data(gobj()); + } } -void ColorItem::_colorDefChanged(void* data) +void ColorItem::on_unrealize() { - ColorItem* item = reinterpret_cast(data); - if ( item ) { - item->_updatePreviews(); - } + m_refGdkWindow.reset(); + + Gtk::Widget::on_unrealize(); } -void ColorItem::_updatePreviews() +bool ColorItem::on_expose_event(GdkEventExpose* event) { - for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { - Gtk::Widget* widget = *it; - if ( IS_EEK_PREVIEW(widget->gobj()) ) { - EekPreview * preview = EEK_PREVIEW(widget->gobj()); - - _regenPreview(preview); - - widget->queue_draw(); - } - } - - for ( std::vector::iterator it = _listeners.begin(); it != _listeners.end(); ++it ) { - guint r = def.getR(); - guint g = def.getG(); - guint b = def.getB(); - - if ( (*it)->_linkIsTone ) { - r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } else { - r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100; - g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100; - b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100; - } - - (*it)->def.setRGB( r, g, b ); - } - - -#if ENABLE_MAGIC_COLORS - // Look for objects using this color + if(m_refGdkWindow) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - SPDocument* document = sp_desktop_document( desktop ); - Inkscape::XML::Node *rroot = document->getReprRoot(); - if ( rroot ) { - - // Find where this thing came from - Glib::ustring paletteName; - bool found = false; - int index = 0; - for ( std::vector::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) { - SwatchPage* curr = *it2; - index = 0; - for ( boost::ptr_vector::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) { - if ( this == &*zz ) { - found = true; - paletteName = curr->_name; - break; - } else { - index++; - } - } - } - - if ( !paletteName.empty() ) { - gchar* str = g_strdup_printf("%d|", index); - paletteName.insert( 0, str ); - g_free(str); - str = 0; - - if ( bruteForce( document, rroot, paletteName, def.getR(), def.getG(), def.getB() ) ) { - SPDocumentUndo::done( document , SP_VERB_DIALOG_SWATCHES, - _("Change color definition")); - } - } - } - } - } -#endif // ENABLE_MAGIC_COLORS - -} - -void ColorItem::_regenPreview(EekPreview * preview) -{ - if ( def.getType() != ege::PaintDef::RGB ) { - using Inkscape::IO::Resource::get_path; - using Inkscape::IO::Resource::ICONS; - using Inkscape::IO::Resource::SYSTEM; - GError *error = NULL; - gsize bytesRead = 0; - gsize bytesWritten = 0; - gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), - -1, - &bytesRead, - &bytesWritten, - &error); - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error); - if (!pixbuf) { - g_warning("Null pixbuf for %p [%s]", localFilename, localFilename ); - } - g_free(localFilename); - - eek_preview_set_pixbuf( preview, pixbuf ); - } - else if ( !_pattern ){ - eek_preview_set_color( preview, - (def.getR() << 8) | def.getR(), - (def.getG() << 8) | def.getG(), - (def.getB() << 8) | def.getB() ); - } else { - // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp - // TODO: the pattern to draw should be in the widget that draws the preview, - // so the preview can be scalable - int w = 128; - int h = 16; - - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); - cairo_t *ct = cairo_create(s); - cairo_set_source(ct, _pattern); - cairo_paint(ct); - cairo_destroy(ct); - cairo_surface_flush(s); - - GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s); - eek_preview_set_pixbuf( preview, pixbuf ); - } - - eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) - | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) - | (_isLive ? PREVIEW_LINK_OTHER:0)) ); -} - -Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) -{ - Gtk::Widget* widget = 0; - if ( style == PREVIEW_STYLE_BLURB) { - Gtk::Label *lbl = new Gtk::Label(def.descr); - lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); - widget = lbl; - } else { - GtkWidget* eekWidget = eek_preview_new(); - EekPreview * preview = EEK_PREVIEW(eekWidget); - Gtk::Widget* newBlot = Glib::wrap(eekWidget); - _regenPreview(preview); - - eek_preview_set_details( preview, - (::ViewType)view, - (::PreviewSize)size, - ratio, - border ); - - def.addCallback( _colorDefChanged, this ); - eek_preview_set_focus_on_click(preview, FALSE); - newBlot->set_tooltip_text(def.descr); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "clicked", - G_CALLBACK(handleClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "alt-clicked", - G_CALLBACK(handleSecondaryClick), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "button-press-event", - G_CALLBACK(colorItemHandleButtonPress), - this); - + Cairo::RefPtr cr = m_refGdkWindow->create_cairo_context(); + if(event) { - std::vector listing = def.getMIMETypes(); - int entryCount = listing.size(); - GtkTargetEntry* entries = new GtkTargetEntry[entryCount]; - GtkTargetEntry* curr = entries; - for ( std::vector::iterator it = listing.begin(); it != listing.end(); ++it ) { - curr->target = g_strdup(it->c_str()); - curr->flags = 0; - if ( mimeToInt.find(*it) == mimeToInt.end() ){ - // these next lines are order-dependent: - mimeToInt[*it] = mimeStrings.size(); - mimeStrings.push_back(*it); - } - curr->info = mimeToInt[curr->target]; - curr++; - } - gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), - GDK_BUTTON1_MASK, - entries, entryCount, - GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); - for ( int i = 0; i < entryCount; i++ ) { - g_free(entries[i].target); - } - delete[] entries; + // clip to the area that needs to be re-exposed so we don't draw any + // more than we need to. + cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); + cr->clip(); } - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-data-get", - G_CALLBACK(ColorItem::_dragGetColorData), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "drag-begin", - G_CALLBACK(colorItemDragBegin), - this ); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "enter-notify-event", - G_CALLBACK(handleEnterNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "leave-notify-event", - G_CALLBACK(handleLeaveNotify), - this); - - g_signal_connect( G_OBJECT(newBlot->gobj()), - "destroy", - G_CALLBACK(dieDieDie), - this); - - - widget = newBlot; - } - - _previews.push_back( widget ); - - return widget; -} - -void ColorItem::buttonClicked(bool secondary) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - char const * attrName = secondary ? "stroke" : "fill"; - - SPCSSAttr *css = sp_repr_css_attr_new(); - Glib::ustring descr; - switch (def.getType()) { - case ege::PaintDef::CLEAR: { - // TODO actually make this clear - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Remove stroke color") : _("Remove fill color"); - break; - } - case ege::PaintDef::NONE: { - sp_repr_css_set_property( css, attrName, "none" ); - descr = secondary? _("Set stroke color to none") : _("Set fill color to none"); - break; - } - case ege::PaintDef::RGB: { - Glib::ustring colorspec; - if ( _grad ){ - colorspec = "url(#"; - colorspec += _grad->getId(); - colorspec += ")"; - } else { - gchar c[64]; - guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff; - sp_svg_write_color(c, sizeof(c), rgba); - colorspec = c; - } - sp_repr_css_set_property( css, attrName, colorspec.c_str() ); - descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"); - break; - } - } - sp_desktop_set_style(desktop, css); - sp_repr_css_attr_unref(css); - - DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); - } -} - -void ColorItem::_wireMagicColors( SwatchPage *colorSet ) -{ - if ( colorSet ) - { - for ( boost::ptr_vector::iterator it = colorSet->_colors.begin(); it != colorSet->_colors.end(); ++it ) - { - std::string::size_type pos = it->def.descr.find("*{"); - if ( pos != std::string::npos ) - { - std::string subby = it->def.descr.substr( pos + 2 ); - std::string::size_type endPos = subby.find("}*"); - if ( endPos != std::string::npos ) - { - subby.erase( endPos ); - //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str()); - //g_message(" '%s'", subby.c_str()); - - if ( subby.find('E') != std::string::npos ) - { - it->def.setEditable( true ); - } - - if ( subby.find('L') != std::string::npos ) - { - it->_isLive = true; - } - - std::string part; - // Tint. index + 1 more val. - if ( getBlock( part, 'T', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - it->_linkTint( colorSet->_colors[colorIndex], percent ); - } - } - } - - // Shade/tone. index + 1 or 2 more val. - if ( getBlock( part, 'S', subby ) ) { - guint64 colorIndex = 0; - if ( popVal( colorIndex, part ) ) { - guint64 percent = 0; - if ( popVal( percent, part ) ) { - guint64 grayLevel = 0; - if ( !popVal( grayLevel, part ) ) { - grayLevel = 0; - } - it->_linkTone( colorSet->_colors[colorIndex], percent, grayLevel ); - } - } - } - - } + if (gradient) { + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + + Cairo::RefPtr checkpat(new Cairo::Pattern(check)); + + cr->set_source(checkpat); + cr->paint(); + + cairo_pattern_t *g = sp_gradient_create_preview_pattern(gradient, get_allocation().get_width()); + Cairo::RefPtr gpat(new Cairo::Pattern(g)); + cr->set_source(gpat); + cr->paint(); + gpat.clear(); + cairo_pattern_destroy(g); + + checkpat.clear(); + + cairo_pattern_destroy(check); + + if (_isSelected) { + cr->set_source_rgb(0, 0, 0); + cr->set_line_width(3); + cr->move_to(0, get_allocation().get_height()); + cr->line_to(0,0); + cr->line_to(get_allocation().get_width(), 0); + cr->stroke(); + cr->move_to(get_allocation().get_width(), 0); + cr->set_source_rgb(1, 1, 1); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->line_to(0, get_allocation().get_height()); + //cr->rectangle(0, 0, get_allocation().get_width(), get_allocation().get_height()); + cr->stroke(); } + } else { + cr->set_source_rgb(1, 1, 1); + cr->paint(); + cr->set_source_rgb(1, 0, 0); + cr->set_line_width(3); + cr->move_to(0,0); + cr->line_to(get_allocation().get_width(), get_allocation().get_height()); + cr->move_to(get_allocation().get_width(), 0); + cr->line_to(0, get_allocation().get_height()); + cr->stroke(); } } + return true; } - -void ColorItem::_linkTint( ColorItem& other, int percent ) -{ - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = false; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = 0; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } -} - -void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel ) +ColorItem::~ColorItem() { - if ( !_linkSrc ) - { - other._listeners.push_back(this); - _linkIsTone = true; - _linkPercent = percent; - if ( _linkPercent > 100 ) - _linkPercent = 100; - if ( _linkPercent < 0 ) - _linkPercent = 0; - _linkGray = grayLevel; - _linkSrc = &other; - - ColorItem::_colorDefChanged(&other); - } + sel_connection.disconnect(); + mod_connection.disconnect(); } } // namespace Dialogs diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 3a0b33193..5d97d8803 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -15,7 +15,11 @@ #include #include "widgets/ege-paint-def.h" -#include "ui/previewable.h" +#include "widgets/eek-preview.h" +#include +#include +#include "desktop.h" +#include "selection.h" class SPGradient; @@ -23,89 +27,43 @@ namespace Inkscape { namespace UI { namespace Dialogs { -class ColorItem; - -class SwatchPage -{ -public: - SwatchPage(); - ~SwatchPage(); - - Glib::ustring _name; - int _prefWidth; - boost::ptr_vector _colors; -}; - /** * The color swatch you see on screen as a clickable box. */ -class ColorItem : public Inkscape::UI::Previewable +class ColorItem : public Gtk::Widget { - friend void _loadPaletteFile( gchar const *filename ); public: - ColorItem( ege::PaintDef::ColorType type ); - ColorItem( unsigned int r, unsigned int g, unsigned int b, - Glib::ustring& name ); + ColorItem( SPGradient * grad, const gchar* name, SPDesktop* desktop ); virtual ~ColorItem(); - ColorItem(ColorItem const &other); - virtual ColorItem &operator=(ColorItem const &other); - virtual Gtk::Widget* getPreview(PreviewStyle style, - ViewType view, - ::PreviewSize size, - guint ratio, - guint border); - void buttonClicked(bool secondary = false); - - void setGradient(SPGradient *grad); - SPGradient * getGradient() const { return _grad; } - void setPattern(cairo_pattern_t *pattern); - void setName(const Glib::ustring name); - - void setState( bool fill, bool stroke ); - bool isFill() { return _isFill; } - bool isStroke() { return _isStroke; } - - ege::PaintDef def; - + + SPGradient * getGradient() { return gradient; } + +protected: + + const gchar* def; + SPGradient * gradient; + virtual bool on_enter_notify_event(GdkEventCrossing* event); + virtual bool on_leave_notify_event(GdkEventCrossing* event); + + virtual void on_size_request(Gtk::Requisition* requisition); + virtual void on_size_allocate(Gtk::Allocation& allocation); + virtual void on_map(); + virtual void on_unmap(); + virtual void on_realize(); + virtual void on_unrealize(); + virtual bool on_expose_event(GdkEventExpose* event); + + Glib::RefPtr m_refGdkWindow; + + private: + void selection_changed(Selection* selection); + void selection_modified(Selection* selection, guint flags); - static void _dropDataIn( GtkWidget *widget, - GdkDragContext *drag_context, - gint x, gint y, - GtkSelectionData *data, - guint info, - guint event_time, - gpointer user_data); - - static void _dragGetColorData( GtkWidget *widget, - GdkDragContext *drag_context, - GtkSelectionData *data, - guint info, - guint time, - gpointer user_data); - - static void _wireMagicColors( SwatchPage *colorSet ); - static void _colorDefChanged(void* data); - - void _updatePreviews(); - void _regenPreview(EekPreview * preview); - - void _linkTint( ColorItem& other, int percent ); - void _linkTone( ColorItem& other, int percent, int grayLevel ); - - std::vector _previews; - - bool _isFill; - bool _isStroke; - bool _isLive; - bool _linkIsTone; - int _linkPercent; - int _linkGray; - ColorItem* _linkSrc; - SPGradient* _grad; - cairo_pattern_t *_pattern; - std::vector _listeners; + sigc::connection sel_connection; + sigc::connection mod_connection; + bool _isSelected; }; } // namespace Dialogs diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index 8dfcf5dce..175031bcf 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -48,6 +48,7 @@ typedef enum { IMPORT_TYPES, EXPORT_TYPES, EXE_TYPES, + SWATCH_TYPES, CUSTOM_TYPE } FileDialogType; diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 2956c6d17..efea4b869 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -67,14 +67,14 @@ #include "svg/svg-color.h" #include "sp-radial-gradient.h" #include "color-rgba.h" +#include "ui/tools/tool-base.h" #include "svg/css-ostringstream.h" -#include "ui/tools/tool-base.h" //event-context.h #include #ifdef WIN32 #include #endif -guint get_group0_keyval(GdkEventKey *event); +//lazy! void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); namespace Inkscape { @@ -1335,10 +1335,10 @@ void SwatchesPanel::_defsChanged() eb->add(*lbl); _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); } - Glib::ustring str1 = Glib::ustring(_("[None]")); - ColorItem* item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str1)); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); - item->setName(_("[None]")); + + ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); + item->set_tooltip_text(_("[None]")); _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); unsigned int i = 1; @@ -1365,11 +1365,10 @@ void SwatchesPanel::_defsChanged() GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); } - Glib::ustring str2 = Glib::ustring(it->label() ? it->label() : it->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str2)); - item->setGradient(grad); - //item->colorItemHandleButtonPress().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(it->label() ? it->label() : it->getId()); + + item = Gtk::manage(new ColorItem(grad, it->label() ? it->label() : it->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(it->label() ? it->label() : it->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1432,11 +1431,10 @@ void SwatchesPanel::_defsChanged() _editDoc.expand_to_path(_storeDoc->get_path(iter)); } - Glib::ustring str3= Glib::ustring(cit->label() ? cit->label() : cit->getId()); - item = Gtk::manage(new ColorItem(NULL, NULL, NULL, str3)); - item->setGradient(grad); - //item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->setName(cit->label() ? cit->label() : cit->getId()); + + item = Gtk::manage(new ColorItem(grad, cit->label() ? cit->label() : cit->getId(), _currentDesktop)); + item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); + item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); if (_showlabels) { _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); } else { @@ -1643,7 +1641,7 @@ bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -1815,7 +1813,7 @@ void SwatchesPanel::_deleteButtonClickedDoc() bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: { @@ -2323,18 +2321,8 @@ void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) } //namespace UI } //namespace Inkscape -//should be okay to add this here -guint get_group0_keyval(GdkEventKey *event) { - guint keyval = 0; - gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( - gdk_display_get_default()), event->hardware_keycode, - (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, - NULL, NULL, NULL); - return keyval; -} - -void -sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) +//really lazy! +void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) { bool intercepted = false; diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 583dbec85..2eba8bb8c 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -358,7 +358,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) { using Inkscape::UI::Dialogs::SwatchesPanel; - dtw->panels = new SwatchesPanel("/embedded/swatches"); + dtw->panels = new SwatchesPanel("/embedded/swatches", false); dtw->panels->setOrientation(SP_ANCHOR_SOUTH); #if GTK_CHECK_VERSION(3,0,0) -- cgit v1.2.3 From a13fdaaa6335ad69b59750a3a9c6b978b921881b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 16:21:29 -0500 Subject: Fixed some swatch sizes (what about the table?) (bzr r13090.1.17) --- src/ui/dialog/swatches.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index efea4b869..91d859f90 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -1333,13 +1333,13 @@ void SwatchesPanel::_defsChanged() lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); } ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); item->set_tooltip_text(_("[None]")); - _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); unsigned int i = 1; for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { @@ -1370,9 +1370,9 @@ void SwatchesPanel::_defsChanged() item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); item->set_tooltip_text(it->label() ? it->label() : it->getId()); if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } i++; @@ -1393,7 +1393,7 @@ void SwatchesPanel::_defsChanged() eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND , 5, 0); + _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); } Gtk::TreeModel::iterator rowiter; @@ -1436,9 +1436,9 @@ void SwatchesPanel::_defsChanged() item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND ); + _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); } i++; } @@ -2072,7 +2072,7 @@ bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& con SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), _scroller(), - _insideTable(1, 2), + _insideTable(1, 1), _insideV(), _insideH(), _buttonsRow(), -- cgit v1.2.3 From 8db893813e5974793db85bad0eb6b32468d29c45 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 19:31:15 -0500 Subject: Makefile fix (bzr r13090.1.18) --- src/ui/dialog/swatches.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 91d859f90..ceda27885 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -1448,9 +1448,11 @@ void SwatchesPanel::_defsChanged() } } } - + //_scroller.resize(1,1); + _insideTable.resize(1,1); _scroller.show_all_children(); _scroller.queue_draw(); + } Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) @@ -2258,6 +2260,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); _swatchesChanged(); + _insideTable.resize(1,1); } SwatchesPanel::~SwatchesPanel() -- cgit v1.2.3 From 50a5b62b327c55b8038b5031d35bf6ae48705485 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 5 Mar 2014 21:08:09 -0500 Subject: Fixed size of swatches widget (bzr r13090.1.19) --- src/ui/dialog/swatches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index ceda27885..c3889db46 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -2102,7 +2102,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); _scroller.add(_insideV); } else { - _scroller.property_height_request() = 45; + _scroller.property_height_request() = 20; _scroller.add(_insideH); } -- cgit v1.2.3 From eb7c3f5dc2737bb22388b040f857117c3a25da6f Mon Sep 17 00:00:00 2001 From: root Date: Thu, 6 Mar 2014 15:21:30 +0100 Subject: Fixed a bug when click over the previuos node in bspline/spiro mode (bzr r11950.1.285) --- src/ui/tools/pen-tool.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index e3bbc72b1..d79803644 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -384,7 +384,6 @@ gint PenTool::_handleButtonPress(GdkEventButton const &bevent) { //with this we avoid creating a new point over the existing one if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ - this->state = PenTool::STOP; if( anchor && anchor == this->sa && this->green_curve->is_empty()){ //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); -- cgit v1.2.3 From c3edf2beebfdf0cbb505d2accbddc4fec17dff7d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 6 Mar 2014 21:05:19 -0500 Subject: Start cleanup for merge into trunk (bzr r13090.1.20) --- src/live_effects/effect.cpp | 8 +- src/live_effects/lpe-fill-between-many.cpp | 3 +- src/live_effects/lpe-jointype.cpp | 5 +- src/live_effects/parameter/originalpatharray.cpp | 12 +- .../parameter/powerstrokepointarray.cpp | 6 +- src/live_effects/parameter/transformedpoint.cpp | 4 +- src/sp-gradient-fns.h | 47 - src/sp-tag-use-reference.cpp | 147 --- src/sp-tag-use-reference.h | 77 -- src/sp-tag-use.cpp | 281 ----- src/sp-tag-use.h | 53 - src/sp-tag.cpp | 240 ---- src/sp-tag.h | 55 - src/ui/dialog/color-item.cpp | 2 +- src/ui/dialog/dialog-manager.cpp | 4 +- src/ui/dialog/lpe-powerstroke-properties.cpp | 8 + src/ui/dialog/swatches.cpp | 1 - src/ui/dialog/tags.cpp | 1182 -------------------- src/ui/dialog/tags.h | 181 --- src/ui/widget/addtoicon.h | 2 +- src/ui/widget/clipmaskicon.h | 2 +- src/ui/widget/highlight-picker.cpp | 10 +- src/ui/widget/highlight-picker.h | 2 +- src/ui/widget/insertordericon.cpp | 7 + src/ui/widget/layertypeicon.h | 2 +- src/verbs.cpp | 8 +- src/verbs.h | 2 +- 27 files changed, 61 insertions(+), 2290 deletions(-) delete mode 100644 src/sp-gradient-fns.h delete mode 100644 src/sp-tag-use-reference.cpp delete mode 100644 src/sp-tag-use-reference.h delete mode 100644 src/sp-tag-use.cpp delete mode 100644 src/sp-tag-use.h delete mode 100644 src/sp-tag.cpp delete mode 100644 src/sp-tag.h delete mode 100644 src/ui/dialog/tags.cpp delete mode 100644 src/ui/dialog/tags.h (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 17b229352..2ffff153c 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -47,7 +47,7 @@ #include "live_effects/lpe-extrude.h" #include "live_effects/lpe-powerstroke.h" #include "live_effects/lpe-clone-original.h" -#include "live_effects/lpe-attach-path.h" +//#include "live_effects/lpe-attach-path.h" #include "live_effects/lpe-fill-between-strokes.h" #include "live_effects/lpe-fill-between-many.h" #include "live_effects/lpe-ellipse_5pts.h" @@ -130,7 +130,7 @@ const Util::EnumData LPETypeData[] = { {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, /* Ponyscape */ - {ATTACH_PATH, N_("Attach path"), "attach_path"}, +// {ATTACH_PATH, N_("Attach path"), "attach_path"}, {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, @@ -258,9 +258,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case CLONE_ORIGINAL: neweffect = static_cast ( new LPECloneOriginal(lpeobj) ); break; - case ATTACH_PATH: + /*case ATTACH_PATH: neweffect = static_cast ( new LPEAttachPath(lpeobj) ); - break; + break;*/ case FILL_BETWEEN_STROKES: neweffect = static_cast ( new LPEFillBetweenStrokes(lpeobj) ); break; diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp index 00cc1fed5..7cf354044 100644 --- a/src/live_effects/lpe-fill-between-many.cpp +++ b/src/live_effects/lpe-fill-between-many.cpp @@ -4,7 +4,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include #include "live_effects/lpe-fill-between-many.h" @@ -16,6 +15,8 @@ #include "sp-text.h" #include "2geom/bezier-curve.h" +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index 97c0a1b8a..93e645783 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -12,6 +12,9 @@ #include +#include "live_effects/parameter/enum.h" +#include "live_effects/pathoutlineprovider.h" + #include "sp-shape.h" #include "style.h" #include "xml/repr.h" @@ -20,11 +23,9 @@ #include "desktop-style.h" #include "svg/css-ostringstream.h" #include "display/curve.h" -#include "live_effects/parameter/enum.h" #include <2geom/path.h> #include <2geom/svg-elliptical-arc.h> -#include "live_effects/pathoutlineprovider.h" #include "lpe-jointype.h" diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 29e4c409c..ed47db28d 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -4,6 +4,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include "live_effects/parameter/originalpatharray.h" #include @@ -89,9 +97,11 @@ OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, _toggle_renderer->signal_toggled().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_reverse_toggled)); col->add_attribute(_toggle_renderer->property_active(), _model->_colReverse); + //quick little hack -- new versions of gtk did not give the item enough space + _scroller.property_height_request() = 120; _scroller.add(_tree); _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scroller.set_shadow_type(Gtk::SHADOW_IN); + //_scroller.set_shadow_type(Gtk::SHADOW_IN); oncanvas_editable = true; diff --git a/src/live_effects/parameter/powerstrokepointarray.cpp b/src/live_effects/parameter/powerstrokepointarray.cpp index ac0000b1a..7fa837689 100644 --- a/src/live_effects/parameter/powerstrokepointarray.cpp +++ b/src/live_effects/parameter/powerstrokepointarray.cpp @@ -4,8 +4,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "ui/dialog/lpe-powerstroke-properties.h" #include "live_effects/parameter/powerstrokepointarray.h" @@ -22,6 +20,8 @@ #include "desktop.h" #include "live_effects/lpeobject.h" +#include + namespace Inkscape { namespace LivePathEffect { @@ -145,7 +145,7 @@ public: virtual Geom::Point knot_get() const; virtual void knot_click(guint state); - /** Checks whether the index falls within the size of the parameter's vector / + // Checks whether the index falls within the size of the parameter's vector bool valid_index(unsigned int index) const { return (_pparam->_vector.size() > index); }; diff --git a/src/live_effects/parameter/transformedpoint.cpp b/src/live_effects/parameter/transformedpoint.cpp index f5b01e267..0d03432c3 100644 --- a/src/live_effects/parameter/transformedpoint.cpp +++ b/src/live_effects/parameter/transformedpoint.cpp @@ -4,8 +4,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "ui/widget/registered-widget.h" #include "live_effects/parameter/transformedpoint.h" #include "sp-lpe-item.h" @@ -17,6 +15,8 @@ #include "desktop.h" #include "verbs.h" +#include + namespace Inkscape { namespace LivePathEffect { diff --git a/src/sp-gradient-fns.h b/src/sp-gradient-fns.h deleted file mode 100644 index e57877256..000000000 --- a/src/sp-gradient-fns.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef SEEN_SP_GRADIENT_FNS_H -#define SEEN_SP_GRADIENT_FNS_H - -/** \file - * Macros and fn declarations related to gradients. - */ - -#include -#include -#include <2geom/forward.h> -#include "sp-gradient-spread.h" -#include "sp-gradient-units.h" - -class SPGradient; -class SPMeshGradient; - -SPGradientSpread sp_gradient_get_spread (SPGradient *gradient); - -/* Gradient repr methods */ -void sp_gradient_repr_write_vector(SPGradient *gr); -void sp_gradient_repr_clear_vector(SPGradient *gr); - -void sp_meshgradient_repr_write(SPMeshGradient *mg); - -cairo_pattern_t *sp_gradient_create_preview_pattern(SPGradient *gradient, double width); - -/** Transforms to/from gradient position space in given environment */ -Geom::Affine sp_gradient_get_g2d_matrix(SPGradient const *gr, Geom::Affine const &ctm, - Geom::Rect const &bbox); -Geom::Affine sp_gradient_get_gs2d_matrix(SPGradient const *gr, Geom::Affine const &ctm, - Geom::Rect const &bbox); -void sp_gradient_set_gs2d_matrix(SPGradient *gr, Geom::Affine const &ctm, Geom::Rect const &bbox, - Geom::Affine const &gs2d); - - -#endif /* !SEEN_SP_GRADIENT_FNS_H */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-tag-use-reference.cpp b/src/sp-tag-use-reference.cpp deleted file mode 100644 index 8e48c0285..000000000 --- a/src/sp-tag-use-reference.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * The reference corresponding to href of element. - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information. - */ - -#include -#include -#include - -#include "enums.h" -#include "sp-tag-use-reference.h" - -#include "display/curve.h" -#include "livarot/Path.h" -#include "preferences.h" -#include "sp-shape.h" -#include "sp-text.h" -#include "uri.h" - - - -bool SPTagUseReference::_acceptObject(SPObject * const obj) const -{ - if (SP_IS_ITEM(obj)) { - SPObject * const owner = getOwner(); - // Refuse references to us or to an ancestor. - for ( SPObject *iter = owner ; iter ; iter = iter->parent ) { - if ( iter == obj ) { - return false; - } - } - return true; - } else { - return false; - } -} - - -static void sp_usepath_href_changed(SPObject *old_ref, SPObject *ref, SPTagUsePath *offset); -static void sp_usepath_delete_self(SPObject *deleted, SPTagUsePath *offset); - -SPTagUsePath::SPTagUsePath(SPObject* i_owner):SPTagUseReference(i_owner) -{ - owner=i_owner; - originalPath = NULL; - sourceDirty=false; - sourceHref = NULL; - sourceRepr = NULL; - sourceObject = NULL; - _changed_connection = changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_usepath_href_changed), this)); // listening to myself, this should be virtual instead - - user_unlink = NULL; -} - -SPTagUsePath::~SPTagUsePath(void) -{ - delete originalPath; - originalPath = NULL; - - _changed_connection.disconnect(); // to do before unlinking - - quit_listening(); - unlink(); -} - -void -SPTagUsePath::link(char *to) -{ - if ( to == NULL ) { - quit_listening(); - unlink(); - } else { - if ( !sourceHref || ( strcmp(to, sourceHref) != 0 ) ) { - g_free(sourceHref); - sourceHref = g_strdup(to); - try { - attach(Inkscape::URI(to)); - } catch (Inkscape::BadURIException &e) { - /* TODO: Proper error handling as per - * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. - */ - g_warning("%s", e.what()); - detach(); - } - } - } -} - -void -SPTagUsePath::unlink(void) -{ - g_free(sourceHref); - sourceHref = NULL; - detach(); -} - -void -SPTagUsePath::start_listening(SPObject* to) -{ - if ( to == NULL ) { - return; - } - sourceObject = to; - sourceRepr = to->getRepr(); - _delete_connection = to->connectDelete(sigc::bind(sigc::ptr_fun(&sp_usepath_delete_self), this)); -} - -void -SPTagUsePath::quit_listening(void) -{ - if ( sourceObject == NULL ) { - return; - } - _delete_connection.disconnect(); - sourceRepr = NULL; - sourceObject = NULL; -} - -static void -sp_usepath_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPTagUsePath *offset) -{ - offset->quit_listening(); - SPItem *refobj = offset->getObject(); - if ( refobj ) { - offset->start_listening(refobj); - } -} - -static void -sp_usepath_delete_self(SPObject */*deleted*/, SPTagUsePath *offset) -{ - offset->owner->deleteObject(); -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use-reference.h b/src/sp-tag-use-reference.h deleted file mode 100644 index 039d2fd7d..000000000 --- a/src/sp-tag-use-reference.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef SEEN_SP_TAG_USE_REFERENCE_H -#define SEEN_SP_TAG_USE_REFERENCE_H - -/* - * The reference corresponding to href of element. - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information. - */ - -#include "sp-object.h" -#include "sp-item.h" -#include -#include -#include - -class Path; - -namespace Inkscape { -namespace XML { - struct Node; -} -} - - -class SPTagUseReference : public Inkscape::URIReference { -public: - SPTagUseReference(SPObject *owner) : URIReference(owner) {} - - SPItem *getObject() const { - return static_cast(URIReference::getObject()); - } - -protected: - virtual bool _acceptObject(SPObject * const obj) const; - -}; - - -class SPTagUsePath : public SPTagUseReference { -public: - Path *originalPath; - bool sourceDirty; - - SPObject *owner; - gchar *sourceHref; - Inkscape::XML::Node *sourceRepr; - SPObject *sourceObject; - - sigc::connection _delete_connection; - sigc::connection _changed_connection; - - SPTagUsePath(SPObject* i_owner); - ~SPTagUsePath(void); - - void link(char* to); - void unlink(void); - void start_listening(SPObject* to); - void quit_listening(void); - void refresh_source(void); - - void (*user_unlink) (SPObject *user); -}; - -#endif /* !SEEN_SP_USE_REFERENCE_H */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use.cpp b/src/sp-tag-use.cpp deleted file mode 100644 index 4c5171bbb..000000000 --- a/src/sp-tag-use.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * SVG implementation - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include -#include "display/drawing-group.h" -#include "attributes.h" -#include "document.h" -#include "sp-object-repr.h" -#include "uri.h" -#include "xml/repr.h" -#include "preferences.h" -#include "style.h" -#include "sp-symbol.h" -#include "sp-tag-use.h" -#include "sp-tag-use-reference.h" - -/* fixme: */ - -static void sp_tag_use_class_init(SPTagUseClass *classname); -static void sp_tag_use_init(SPTagUse *use); -static void sp_tag_use_finalize(GObject *obj); - -static void sp_tag_use_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void sp_tag_use_release(SPObject *object); -static void sp_tag_use_set(SPObject *object, unsigned key, gchar const *value); -static Inkscape::XML::Node *sp_tag_use_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); -static void sp_tag_use_update(SPObject *object, SPCtx *ctx, guint flags); - -static void sp_tag_use_href_changed(SPObject *old_ref, SPObject *ref, SPTagUse *use); - -static SPObjectClass *parent_class; - - -GType -sp_tag_use_get_type(void) -{ - static GType use_type = 0; - if (!use_type) { - GTypeInfo use_info = { - sizeof(SPTagUseClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_tag_use_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(SPTagUse), - 16, /* n_preallocs */ - (GInstanceInitFunc) sp_tag_use_init, - NULL, /* value_table */ - }; - use_type = g_type_register_static(SP_TYPE_OBJECT, "SPTagUse", &use_info, (GTypeFlags)0); - } - return use_type; -} - -static void -sp_tag_use_class_init(SPTagUseClass *classname) -{ - GObjectClass *gobject_class = (GObjectClass *) classname; - SPObjectClass *sp_object_class = (SPObjectClass *) classname; - - parent_class = (SPObjectClass*)g_type_class_peek_parent(classname); - - gobject_class->finalize = sp_tag_use_finalize; - - sp_object_class->build = sp_tag_use_build; - sp_object_class->release = sp_tag_use_release; - sp_object_class->set = sp_tag_use_set; - sp_object_class->write = sp_tag_use_write; - sp_object_class->update = sp_tag_use_update; -} - -static void -sp_tag_use_init(SPTagUse *use) -{ - use->href = NULL; - - new (&use->_changed_connection) sigc::connection(); - - use->ref = new SPTagUseReference(use); - - use->_changed_connection = use->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_tag_use_href_changed), use)); -} - -static void -sp_tag_use_finalize(GObject *obj) -{ - SPTagUse *use = reinterpret_cast(obj); - - if (use->child) { - use->detach(use->child); - use->child = NULL; - } - - use->ref->detach(); - delete use->ref; - use->ref = 0; - - use->_changed_connection.~connection(); - -} - -static void -sp_tag_use_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) parent_class)->build) { - (* ((SPObjectClass *) parent_class)->build)(object, document, repr); - } - - object->readAttr( "xlink:href" ); - - // We don't need to create child here: - // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, - // which will call sp_tag_use_href_changed, and that will take care of the child -} - -static void -sp_tag_use_release(SPObject *object) -{ - SPTagUse *use = SP_TAG_USE(object); - - if (use->child) { - object->detach(use->child); - use->child = NULL; - } - - use->_changed_connection.disconnect(); - - g_free(use->href); - use->href = NULL; - - use->ref->detach(); - - if (((SPObjectClass *) parent_class)->release) { - ((SPObjectClass *) parent_class)->release(object); - } -} - -static void -sp_tag_use_set(SPObject *object, unsigned key, gchar const *value) -{ - SPTagUse *use = SP_TAG_USE(object); - - switch (key) { - case SP_ATTR_XLINK_HREF: { - if ( value && use->href && ( strcmp(value, use->href) == 0 ) ) { - /* No change, do nothing. */ - } else { - g_free(use->href); - use->href = NULL; - if (value) { - // First, set the href field, because sp_tag_use_href_changed will need it. - use->href = g_strdup(value); - - // Now do the attaching, which emits the changed signal. - try { - use->ref->attach(Inkscape::URI(value)); - } catch (Inkscape::BadURIException &e) { - g_warning("%s", e.what()); - use->ref->detach(); - } - } else { - use->ref->detach(); - } - } - break; - } - - default: - if (((SPObjectClass *) parent_class)->set) { - ((SPObjectClass *) parent_class)->set(object, key, value); - } - break; - } -} - -static Inkscape::XML::Node * -sp_tag_use_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) -{ - SPTagUse *use = SP_TAG_USE(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("inkscape:tagref"); - } - - if (((SPObjectClass *) (parent_class))->write) { - ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags); - } - - if (use->ref->getURI()) { - gchar *uri_string = use->ref->getURI()->toString(); - repr->setAttribute("xlink:href", uri_string); - g_free(uri_string); - } - - return repr; -} - -/** - * Returns the ultimate original of a SPTagUse (i.e. the first object in the chain of its originals - * which is not an SPTagUse). If no original is found, NULL is returned (it is the responsibility - * of the caller to make sure that this is handled correctly). - * - * Note that the returned is the clone object, i.e. the child of an SPTagUse (of the argument one for - * the trivial case) and not the "true original". - */ -SPItem * -sp_tag_use_root(SPTagUse *use) -{ - SPObject *orig = use->child; - while (orig && SP_IS_TAG_USE(orig)) { - orig = SP_TAG_USE(orig)->child; - } - if (!orig || !SP_IS_ITEM(orig)) - return NULL; - return SP_ITEM(orig); -} - -static void -sp_tag_use_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPTagUse *use) -{ - if (use->href) { - SPItem *refobj = use->ref->getObject(); - if (refobj) { - Inkscape::XML::Node *childrepr = refobj->getRepr(); - GType type = sp_repr_type_lookup(childrepr); - g_return_if_fail(type > G_TYPE_NONE); - if (g_type_is_a(type, SP_TYPE_ITEM)) { - use->child = (SPObject*) g_object_new(type, 0); - use->attach(use->child, use->lastChild()); - sp_object_unref(use->child, use); - (use->child)->invoke_build(use->document, childrepr, TRUE); - - } - } - } -} - -static void -sp_tag_use_update(SPObject *object, SPCtx *ctx, unsigned flags) -{ - if (((SPObjectClass *) (parent_class))->update) - ((SPObjectClass *) (parent_class))->update(object, ctx, flags); -} - -SPItem *sp_tag_use_get_original(SPTagUse *use) -{ - SPItem *ref = NULL; - if (use){ - if (use->ref){ - ref = use->ref->getObject(); - } - } - return ref; -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use.h b/src/sp-tag-use.h deleted file mode 100644 index 6e068fc21..000000000 --- a/src/sp-tag-use.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __SP_TAG_USE_H__ -#define __SP_TAG_USE_H__ - -/* - * SVG implementation - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include -#include -#include "svg/svg-length.h" -#include "sp-object.h" - - -#define SP_TYPE_TAG_USE (sp_tag_use_get_type ()) -#define SP_TAG_USE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_TAG_USE, SPTagUse)) -#define SP_TAG_USE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_TAG_USE, SPTagUseClass)) -#define SP_IS_TAG_USE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_TAG_USE)) -#define SP_IS_TAG_USE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_TAG_USE)) - -class SPTagUse; -class SPTagUseClass; -class SPTagUseReference; - -struct SPTagUse : public SPObject { - // item built from the original's repr (the visible clone) - // relative to the SPUse itself, it is treated as a child, similar to a grouped item relative to its group - SPObject *child; - - gchar *href; - - // the reference to the original object - SPTagUseReference *ref; - sigc::connection _changed_connection; -}; - -struct SPTagUseClass { - SPObjectClass parent_class; -}; - -GType sp_tag_use_get_type (void); - -SPItem *sp_tag_use_unlink (SPTagUse *use); -SPItem *sp_tag_use_get_original (SPTagUse *use); - -SPItem *sp_tag_use_root(SPTagUse *use); -#endif diff --git a/src/sp-tag.cpp b/src/sp-tag.cpp deleted file mode 100644 index eef55d628..000000000 --- a/src/sp-tag.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/** \file - * SVG implementation - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "attributes.h" -#include "sp-tag.h" -#include "xml/repr.h" -#include - -#define DEBUG_TAG -#ifdef DEBUG_TAG -# define debug(f, a...) { g_print("%s(%d) %s:", \ - __FILE__,__LINE__,__FUNCTION__); \ - g_print(f, ## a); \ - g_print("\n"); \ - } -#else -# define debug(f, a...) /**/ -#endif - -/* Tag base class */ - -static void sp_tag_class_init(SPTagClass *klass); -static void sp_tag_init(SPTag *tag); - -static void sp_tag_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); -static void sp_tag_release(SPObject *object); -static void sp_tag_set(SPObject *object, unsigned int key, gchar const *value); -static void sp_tag_update(SPObject *object, SPCtx *ctx, guint flags); -static Inkscape::XML::Node *sp_tag_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags); - -static SPObjectClass *tag_parent_class; - -GType -sp_tag_get_type() -{ - static GType tag_type = 0; - - if (!tag_type) { - GTypeInfo tag_info = { - sizeof(SPTagClass), - NULL, NULL, - (GClassInitFunc) sp_tag_class_init, - NULL, NULL, - sizeof(SPTag), - 16, - (GInstanceInitFunc) sp_tag_init, - NULL, /* value_table */ - }; - tag_type = g_type_register_static(SP_TYPE_OBJECT, "SPTag", &tag_info, (GTypeFlags)0); - } - return tag_type; -} - -static void -sp_tag_class_init(SPTagClass *klass) -{ - //GObjectClass *gobject_class = (GObjectClass *)klass; - SPObjectClass *sp_object_class = (SPObjectClass *)klass; - - tag_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass); - - sp_object_class->build = sp_tag_build; - sp_object_class->release = sp_tag_release; - sp_object_class->write = sp_tag_write; - sp_object_class->set = sp_tag_set; - sp_object_class->update = sp_tag_update; -} - -static void -sp_tag_init(SPTag *tag) -{ -} - -/* - * Move this SPItem into or after another SPItem in the doc - * \param target - the SPItem to move into or after - * \param intoafter - move to after the target (false), move inside (sublayer) of the target (true) - */ -void SPTag::moveTo(SPObject *target, gboolean intoafter) { - - Inkscape::XML::Node *target_ref = ( target ? target->getRepr() : NULL ); - Inkscape::XML::Node *our_ref = getRepr(); - gboolean first = FALSE; - - if (target_ref == our_ref) { - // Move to ourself ignore - return; - } - - if (!target_ref) { - // Assume move to the "first" in the top node, find the top node - target_ref = our_ref; - while (target_ref->parent() != target_ref->root()) { - target_ref = target_ref->parent(); - } - first = TRUE; - } - - if (intoafter) { - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); - } else if (!first) { - // Same parent, just move - our_ref->parent()->changeOrder(our_ref, target_ref); - } -} - -/** - * Reads the Inkscape::XML::Node, and initializes SPTag variables. For this to get called, - * our name must be associated with a repr via "sp_object_type_register". Best done through - * sp-object-repr.cpp's repr_name_entries array. - */ -static void -sp_tag_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - object->readAttr( "inkscape:expanded" ); - - if (((SPObjectClass *) tag_parent_class)->build) { - ((SPObjectClass *) tag_parent_class)->build(object, document, repr); - } -} - -/** - * Drops any allocated memory. - */ -static void -sp_tag_release(SPObject *object) -{ - /* deal with our children and our selves here */ - - if (((SPObjectClass *) tag_parent_class)->release) - ((SPObjectClass *) tag_parent_class)->release(object); -} - -/** - * Sets a specific value in the SPTag. - */ -static void -sp_tag_set(SPObject *object, unsigned int key, gchar const *value) -{ - SPTag *tag = SP_TAG(object); - - switch (key) - { - case SP_ATTR_INKSCAPE_EXPANDED: - if ( value && !strcmp(value, "true") ) { - tag->setExpanded(true); - } - break; - default: - if (((SPObjectClass *) tag_parent_class)->set) { - ((SPObjectClass *) tag_parent_class)->set(object, key, value); - } - break; - } -} - -void SPTag::setExpanded(bool isexpanded) { - if ( _expanded != isexpanded ){ - _expanded = isexpanded; - } -} - -/** - * Receives update notifications. - */ -static void -sp_tag_update(SPObject *object, SPCtx *ctx, guint flags) -{ - //SPTag *tag = SP_TAG(object); - - if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | - SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { - - /* do something to trigger redisplay, updates? */ - - } - - if (((SPObjectClass *) tag_parent_class)->update) { - ((SPObjectClass *) tag_parent_class)->update(object, ctx, flags); - } -} - -/** - * Writes its settings to an incoming repr object, if any. - */ -static Inkscape::XML::Node * -sp_tag_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) -{ - SPTag *tag = SP_TAG(object); - - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = doc->createElement("inkscape:tag"); - } - - // Inkscape-only object, not copied during an "plain SVG" dump: - if (flags & SP_OBJECT_WRITE_EXT) { - - if (tag->_expanded) { - repr->setAttribute("inkscape:expanded", "true"); - } else { - repr->setAttribute("inkscape:expanded", NULL); - } - } - - if (((SPObjectClass *) tag_parent_class)->write) { - ((SPObjectClass *) tag_parent_class)->write(object, doc, repr, flags); - } - - return repr; -} - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-tag.h b/src/sp-tag.h deleted file mode 100644 index c5eec785a..000000000 --- a/src/sp-tag.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef SP_TAG_H_SEEN -#define SP_TAG_H_SEEN - -/** \file - * SVG implementation - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "sp-object.h" - -/* Skeleton base class */ - -#define SP_TYPE_TAG (sp_tag_get_type()) -#define SP_TAG(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_TAG, SPTag)) -#define SP_IS_TAG(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_TAG)) - -class SPTag; -class SPTagClass; - -class SPTag : public SPObject { -public: - bool _expanded; - - bool expanded() const { return _expanded; } - void setExpanded(bool isexpanded); - - void moveTo(SPObject *target, gboolean intoafter); - -}; - -struct SPTagClass { - SPObjectClass parent_class; -}; - -GType sp_tag_get_type(); - - -#endif /* !SP_SKELETON_H_SEEN */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index 6eece0c17..a1951ec48 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -12,7 +12,6 @@ */ #include -#include #include #include #include @@ -40,6 +39,7 @@ #include "color.h" // for SP_RGBA32_U_COMPOSE +#include namespace Inkscape { namespace UI { diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 1fddbf007..ddf41e0c8 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -111,7 +111,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - //registerFactory("TagsPanel", &create); +// registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -147,7 +147,7 @@ DialogManager::DialogManager() { registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); - //registerFactory("TagsPanel", &create); +// registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/lpe-powerstroke-properties.cpp b/src/ui/dialog/lpe-powerstroke-properties.cpp index cef6f494e..c34351511 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.cpp +++ b/src/ui/dialog/lpe-powerstroke-properties.cpp @@ -13,6 +13,14 @@ * Released under GNU GPL. Read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include "lpe-powerstroke-properties.h" #include #include diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index c3889db46..34885a971 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -43,7 +43,6 @@ #include "path-prefix.h" #include "preferences.h" #include "sp-item.h" -#include "sp-gradient-fns.h" #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp deleted file mode 100644 index 116f9eb0b..000000000 --- a/src/ui/dialog/tags.cpp +++ /dev/null @@ -1,1182 +0,0 @@ -/* - * A simple panel for tags - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "tags.h" -#include -#include -#include -#include - -#include - -#include "desktop.h" -#include "desktop-style.h" -#include "document.h" -#include "document-undo.h" -#include "helper/action.h" -#include "inkscape.h" -#include "layer-fns.h" -#include "layer-manager.h" -#include "preferences.h" -#include "sp-item.h" -#include "sp-object.h" -#include "sp-shape.h" -#include "svg/css-ostringstream.h" -#include "ui/icon-names.h" -#include "ui/widget/layertypeicon.h" -#include "ui/widget/addtoicon.h" -#include "verbs.h" -#include "widgets/icon.h" -#include "xml/node.h" -#include "xml/node-observer.h" -#include "xml/repr.h" -#include "sp-root.h" -//#include "event-context.h" -#include "selection.h" -#include "dialogs/dialog-events.h" -#include "widgets/sp-color-notebook.h" -#include "style.h" -#include "filter-chemistry.h" -#include "filters/blend.h" -#include "filters/gaussian-blur.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "sp-tag.h" -#include "sp-defs.h" -#include "sp-tag-use.h" -#include "sp-tag-use-reference.h" - -//#define DUMP_LAYERS 1 - -namespace Inkscape { -namespace UI { -namespace Dialog { - -using Inkscape::XML::Node; - -TagsPanel& TagsPanel::getInstance() -{ - return *new TagsPanel(); -} - -enum { - COL_ADD = 1 -}; - -enum { - BUTTON_NEW = 0, - BUTTON_TOP, - BUTTON_BOTTOM, - BUTTON_UP, - BUTTON_DOWN, - BUTTON_DELETE, - DRAGNDROP -}; - -class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { -public: - ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : - _pnl(pnl), - _obj(obj), - _repr(repr), - _labelAttr(g_quark_from_string("inkscape:label")) - {} - - ObjectWatcher(TagsPanel* pnl, SPObject* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")) - {} - - virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) - { - if ( _pnl && _obj ) { - _pnl->_objectsChanged( _obj ); - } - } - virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if ( _pnl && _obj ) { - if ( name == _labelAttr ) { - _pnl->_updateObject( _obj); - } - } - } - - TagsPanel* _pnl; - SPObject* _obj; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; -}; - -class TagsPanel::InternalUIBounce -{ -public: - int _actionCode; -}; - -void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) -{ - bool set = false; - - if ( iconName ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - btn.set_relief(Gtk::RELIEF_NONE); - set = true; - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !set && action && action->image ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - set = true; - } - } - } - - btn.set_tooltip_text (tooltip); -} - - -Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) -{ - GtkWidget* iconWidget = 0; - const char* label = 0; - - if ( iconName ) { - iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !iconWidget && action && action->image ) { - iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); - } - - if ( action ) { - label = action->name; - } - } - } - - if ( !label && fallback ) { - label = fallback; - } - - Gtk::Widget* wrapped = 0; - if ( iconWidget ) { - wrapped = manage(Glib::wrap(iconWidget)); - wrapped->show(); - } - - - Gtk::MenuItem* item = 0; - - if (wrapped) { - item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); - } else { - item = Gtk::manage(new Gtk::MenuItem(label, true)); - } - - item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); - _popupMenu.append(*item); - - return *item; -} - -void TagsPanel::_fireAction( unsigned int code ) -{ - if ( _desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(_desktop); - if ( action ) { - sp_action_perform( action, NULL ); - } - } - } -} - -void TagsPanel::_takeAction( int val ) -{ - if ( !_pending ) { - _pending = new InternalUIBounce(); - _pending->_actionCode = val; - Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); - } -} - -bool TagsPanel::_executeAction() -{ - // Make sure selected layer hasn't changed since the action was triggered - if ( _pending) - { - int val = _pending->_actionCode; -// SPObject* target = _pending->_target; - - switch ( val ) { - case BUTTON_NEW: - { - _fireAction( SP_VERB_TAG_NEW ); - } - break; - case BUTTON_TOP: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_TOP ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_FRONT); - } - } - break; - case BUTTON_BOTTOM: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_BOTTOM ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_BACK); - } - } - break; - case BUTTON_UP: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_RAISE ); - } - else - { - _fireAction( SP_VERB_SELECTION_RAISE ); - } - } - break; - case BUTTON_DOWN: - { - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_LOWER ); - } - else - { - _fireAction( SP_VERB_SELECTION_LOWER ); - } - } - break; - case BUTTON_DELETE: - { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * obj = *iter; - if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - break; - case DRAGNDROP: - { - _doTreeMove( ); - } - break; - } - - delete _pending; - _pending = 0; - } - - return false; -} - - -class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord -{ -public: - - ModelColumns() - { - add(_colParentObject); - add(_colObject); - add(_colLabel); - add(_colAddRemove); - add(_colAllowAddRemove); - } - virtual ~ModelColumns() {} - - Gtk::TreeModelColumn _colParentObject; - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; - Gtk::TreeModelColumn _colAddRemove; - Gtk::TreeModelColumn _colAllowAddRemove; -}; - -void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) -{ - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj && obj->parent) { - todelete->push_back(obj); - } -} - -void TagsPanel::_updateObject( SPObject *obj ) { - _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); -} - -bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) -{ - Gtk::TreeModel::Row row = *iter; - if ( obj == row[_model->_colObject] ) - { - /* - * We get notified of layer update here (from layer->setLabel()) before layer->label() is set - * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which - * has the correct value (bug #168351) - */ - //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); - gchar const *label; - SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; - if (use && use->ref->isAttached()) { - label = use->ref->getObject()->getAttribute("inkscape:label"); - } else { - label = obj->getAttribute("inkscape:label"); - } - row[_model->_colLabel] = label ? label : obj->getId(); - row[_model->_colAddRemove] = SP_IS_TAG(obj); - } - - return false; -} - -void TagsPanel::_objectsSelected( Selection *sel ) { - - _selectedConnection.block(); - _tree.get_selection()->unselect_all(); - for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) - { - SPObject *obj = reinterpret_cast(iter->data); - _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); - } - _selectedConnection.unblock(); - _checkTreeSelection(); -} - -bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) -{ - Gtk::TreeModel::Row row = *iter; - SPObject * it = row[_model->_colObject]; - if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) - { - Glib::RefPtr select = _tree.get_selection(); - - select->select(iter); - } - return false; -} - -void TagsPanel::_objectsChanged(SPObject* root) -{ - while (!_objectWatchers.empty()) - { - TagsPanel::ObjectWatcher *w = _objectWatchers.back(); - w->_repr->removeObserver(*w); - _objectWatchers.pop_back(); - delete w; - } - - if (_desktop) { - SPDocument* document = _desktop->doc(); - SPDefs* root = document->getDefs(); - if ( root ) { - _selectedConnection.block(); - _store->clear(); - _addObject( document, root, 0 ); - _selectedConnection.unblock(); - _objectsSelected(_desktop->selection); - _checkTreeSelection(); - } - } -} - -void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) -{ - if ( _desktop && obj ) { - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG(child)) - { - Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; - row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = child->label() ? child->label() : child->getId(); - row[_model->_colAddRemove] = true; - row[_model->_colAllowAddRemove] = true; - - _tree.expand_to_path( _store->get_path(iter) ); - - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); - child->getRepr()->addObserver(*w); - _objectWatchers.push_back(w); - _addObject( doc, child, &row ); - } - } - if (SP_IS_TAG(obj) && obj->children) - { - Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); - Gtk::TreeModel::Row rowitems = *iteritems; - rowitems[_model->_colObject] = NULL; - rowitems[_model->_colParentObject] = obj; - rowitems[_model->_colLabel] = _("Items"); - rowitems[_model->_colAddRemove] = false; - rowitems[_model->_colAllowAddRemove] = false; - - _tree.expand_to_path( _store->get_path(iteritems) ); - - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child)) - { - SPItem *item = SP_TAG_USE(child)->ref->getObject(); - Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; - row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; - row[_model->_colAddRemove] = false; - row[_model->_colAllowAddRemove] = true; - - if (SP_TAG(obj)->expanded()) { - _tree.expand_to_path( _store->get_path(iter) ); - } - - if (item) { - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); - item->getRepr()->addObserver(*w); - _objectWatchers.push_back(w); - } - } - } - } - } -} - -void TagsPanel::_select_tag( SPTag * tag ) -{ - for (SPObject * child = tag->children; child != NULL; child = child->next) - { - if (SP_IS_TAG(child)) { - _select_tag(SP_TAG(child)); - } else if (SP_IS_TAG_USE(child)) { - SPObject * obj = SP_TAG_USE(child)->ref->getObject(); - if (obj) { - if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); - _desktop->selection->add(obj); - } - } - } -} - -void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) -{ - if (iter) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - if (obj) { - if (SP_IS_TAG(obj)) { - _select_tag(SP_TAG(obj)); - } else if (SP_IS_TAG_USE(obj)) { - SPObject * item = SP_TAG_USE(obj)->ref->getObject(); - if (item) { - if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); - _desktop->selection->add(item); - } - } - } - } -} - -void TagsPanel::_pushTreeSelectionToCurrent() -{ - _selectionChangedConnection.block(); - // TODO hunt down the possible API abuse in getting NULL - if ( _desktop && _desktop->currentRoot() ) { - _desktop->selection->clear(); - _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); - } - _selectionChangedConnection.unblock(); - - _checkTreeSelection(); -} - -void TagsPanel::_checkTreeSelection() -{ - bool sensitive = _tree.get_selection()->count_selected_rows() > 0; - bool sensitiveNonTop = true; - bool sensitiveNonBottom = true; -// if ( _tree.get_selection()->count_selected_rows() > 0 ) { -// sensitive = true; -// -// SPObject* inTree = _selectedLayer(); -// if ( inTree ) { -// -// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); -// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); -// -// } -// } - - - for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { - (*it)->set_sensitive( sensitive ); - } - for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { - (*it)->set_sensitive( sensitiveNonTop ); - } - for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { - (*it)->set_sensitive( sensitiveNonBottom ); - } -} - -bool TagsPanel::_handleKeyEvent(GdkEventKey *event) -{ - - switch (get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); - if (iter && !_text_renderer->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj && SP_IS_TAG(obj)) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_renderer->property_editable() = true; - _tree.set_cursor(*path, *_name_column, true); - grab_focus(); - return true; - } - } - } - case GDK_KEY_Delete: { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - if (!todelete.empty()) { - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * obj = *iter; - if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - return true; - } - break; - } - return false; -} - -bool TagsPanel::_handleButtonEvent(GdkEventButton* event) -{ - static unsigned doubleclick = 0; - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { - // TODO - fix to a better is-popup function - Gtk::TreeModel::Path path; - int x = static_cast(event->x); - int y = static_cast(event->y); - if ( _tree.get_path_at_pos( x, y, path ) ) { - _checkTreeSelection(); - _popupMenu.popup(event->button, event->time); - if (_tree.get_selection()->is_selected(path)) { - return true; - } - } - } - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { - // Alt left click on the visible/lock columns - eat this event to keep row selection - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { - if (col == _tree.get_column(COL_ADD-1)) { - down_at_add = true; - return true; - } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { - _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); - _defer_target = path; - } else { - down_at_add = false; - } - } else { - down_at_add = false; - } - } - - if ( event->type == GDK_BUTTON_RELEASE) { - _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); - } - - // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here. - if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { - - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { - if (_defer_target) { - if (_defer_target == path && !(event->x == 0 && event->y == 0)) - { - _tree.set_cursor(path, *col, false); - } - _defer_target = Gtk::TreeModel::Path(); - } else { - Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colObject]; - - if (obj) { - if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { - if (SP_IS_TAG(obj)) { - bool wasadded = false; - for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) - { - SPObject *newobj = reinterpret_cast(iter->data); - bool addchild = true; - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { - addchild = false; - } - } - if (addchild) { - Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); - clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); - obj->appendChild(clone); - wasadded = true; - } - } - if (wasadded) { - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to tag")); - } - } else { - std::vector todelete; - _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); - if (!todelete.empty()) { - for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { - SPObject * tobj = *iter; - if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { - tobj->parent->getRepr()->removeChild(tobj->getRepr()); - } - } - } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); - } - DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from tags")); - } - } - } - } - } - } - - - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } - - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { - Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colObject]; - if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { - // Double click on the Layer name, enable editing - _text_renderer->property_editable() = true; - _tree.set_cursor (path, *_name_column, true); - grab_focus(); - } - } - } - - return false; -} - -void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) -{ - Gtk::TreeModel::Row row = *iter; - SPObject* obj = row[_model->_colObject]; - SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; - if (item) - { - _dnd_source.push_back(item); - } -} - -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) -{ - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - _dnd_into = true; - _dnd_target = _document->getDefs(); - _dnd_source.clear(); - _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); - - if (_dnd_source.empty()) { - return true; - } - - if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _tree.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y > (int)(cell_height * 2/3)) { - Gtk::TreeModel::Path next_path = target_path; - next_path.next(); - if (_store->iter_is_valid(_store->get_iter(next_path))) { - target_path = next_path; - } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_store->iter_is_valid(_store->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - // Drop into the top level - _dnd_target = _document->getDefs(); - _dnd_into = true; - } - } - } - Gtk::TreeModel::iterator iter = _store->get_iter(target_path); - if (_store->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - SPObject *pobj = row[_model->_colParentObject]; - if (obj) { - if (SP_IS_TAG(obj)) { - _dnd_target = SP_TAG(obj); - } else if (SP_IS_TAG(obj->parent)) { - _dnd_target = SP_TAG(obj->parent); - _dnd_into = true; - } - } else if (pobj && SP_IS_TAG(pobj)) { - _dnd_target = SP_TAG(pobj); - _dnd_into = true; - } else { - return true; - } - } - } - - _takeAction(DRAGNDROP); - - return false; -} - -/* - * Move a layer in response to a drag & drop action - */ -void TagsPanel::_doTreeMove( ) -{ - if (_dnd_target) { - for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) - { - SPTag *src = *iter; - if (src != _dnd_target) { - src->moveTo(_dnd_target, _dnd_into); - } - } - _desktop->selection->clear(); - while (!_dnd_source.empty()) - { - SPTag *src = _dnd_source.back(); - _select_tag(src); - _dnd_source.pop_back(); - } - DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, - _("Moved tags")); - } -} - - -void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - _renameObject(row, new_text); - _text_renderer->property_editable() = false; -} - -void TagsPanel::_handleEditingCancelled() -{ - _text_renderer->property_editable() = false; -} - -void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && _desktop) { - SPObject* obj = row[_model->_colObject]; - if ( obj ) { - if (SP_IS_TAG(obj)) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, - _("Rename object")); - } - } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, - _("Rename object")); - } - } - } - } -} - -bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) -{ - return false; -} - -bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) -{ - bool val = true; - if ( !currentlySelected && _toggleEvent ) - { - GdkEvent* event = gtk_get_current_event(); - if ( event ) { - // (keep these checks separate, so we know when to call gdk_event_free() - if ( event->type == GDK_BUTTON_PRESS ) { - GdkEventButton const* target = reinterpret_cast(_toggleEvent); - GdkEventButton const* evtb = reinterpret_cast(event); - - if ( (evtb->window == target->window) - && (evtb->send_event == target->send_event) - && (evtb->time == target->time) - && (evtb->state == target->state) - ) - { - // Ooooh! It's a magic one - val = false; - } - } - gdk_event_free(event); - } - } - return val; -} - -void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) -{ - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_model->_colParentObject]; - if (obj && SP_IS_TAG(obj)) - { - SP_TAG(obj)->setExpanded(isexpanded); - obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - } -} - -/** - * Constructor - */ -TagsPanel::TagsPanel() : - UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), - _rootWatcher(0), - deskTrack(), - _desktop(0), - _document(0), - _model(0), - _pending(0), - _toggleEvent(0), - _defer_target(), - desktopChangeConn() -{ - //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - ModelColumns *zoop = new ModelColumns(); - _model = zoop; - - _store = Gtk::TreeStore::create( *zoop ); - - _tree.set_model( _store ); - _tree.set_headers_visible(false); - _tree.set_reorderable(true); - _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); - - Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); - int addColNum = _tree.append_column("type", *addRenderer) - 1; - Gtk::TreeViewColumn *col = _tree.get_column(addColNum); - if ( col ) { - col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); - col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); - } - - _text_renderer = manage(new Gtk::CellRendererText()); - int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; - _name_column = _tree.get_column(nameColNum); - _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); - - _tree.set_expander_column( *_tree.get_column(nameColNum) ); - - _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); - _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); - _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); - - _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); - _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); - _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); - - _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); - _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); - - _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); - _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); - _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); - - _scroller.add( _tree ); - _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scroller.set_shadow_type(Gtk::SHADOW_IN); - Gtk::Requisition sreq; -#if WITH_GTKMM_3_0 - Gtk::Requisition sreq_natural; - _scroller.get_preferred_size(sreq_natural, sreq); -#else - sreq = _scroller.size_request(); -#endif - int minHeight = 70; - if (sreq.height < minHeight) { - // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar - _scroller.set_size_request(sreq.width, minHeight); - } - - _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); - - _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); - - _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); - - SPDesktop* targetDesktop = getDesktop(); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new tag") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); - _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - -// btn = manage( new Gtk::Button("Dup") ); -// btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); -// _buttonsRow.add( *btn ); - - btn = manage( new Gtk::Button() ); - _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Tag") ); - btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); - _watching.push_back( btn ); - _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - - _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); - _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); - - // ------------------------------------------------------- - { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); - - _popupMenu.show_all_children(); - } - // ------------------------------------------------------- - - - - for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { - (*it)->set_sensitive( false ); - } - for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { - (*it)->set_sensitive( false ); - } - for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { - (*it)->set_sensitive( false ); - } - - setDesktop( targetDesktop ); - - show_all_children(); - - // restorePanelPrefs(); - - // Connect this up last - desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); - deskTrack.connect(GTK_WIDGET(gobj())); -} - -TagsPanel::~TagsPanel() -{ - - setDesktop(NULL); - - if ( _model ) - { - delete _model; - _model = 0; - } - - if (_pending) { - delete _pending; - _pending = 0; - } - - if ( _toggleEvent ) - { - gdk_event_free( _toggleEvent ); - _toggleEvent = 0; - } - - desktopChangeConn.disconnect(); - deskTrack.disconnect(); -} - -void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) -{ - while (!_objectWatchers.empty()) - { - TagsPanel::ObjectWatcher *w = _objectWatchers.back(); - w->_repr->removeObserver(*w); - _objectWatchers.pop_back(); - delete w; - } - - if (_rootWatcher) - { - _rootWatcher->_repr->removeObserver(*_rootWatcher); - delete _rootWatcher; - _rootWatcher = NULL; - } - - _document = document; - - if (document && document->getDefs() && document->getDefs()->getRepr()) - { - _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); - document->getDefs()->getRepr()->addObserver(*_rootWatcher); - _objectsChanged(document->getDefs()); - } -} - -void TagsPanel::setDesktop( SPDesktop* desktop ) -{ - Panel::setDesktop(desktop); - - if ( desktop != _desktop ) { - _documentChangedConnection.disconnect(); - _selectionChangedConnection.disconnect(); - if ( _desktop ) { - _desktop = 0; - } - - _desktop = Panel::getDesktop(); - if ( _desktop ) { - //setLabel( _desktop->doc()->name ); - _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); - _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); - - setDocument(_desktop, _desktop->doc()); - } - } -/* - GSList const *layers = _desktop->doc()->getResourceList( "layer" ); - g_message( "layers list starts at %p", layers ); - for ( GSList const *iter=layers ; iter ; iter = iter->next ) { - SPObject *layer=static_cast(iter->data); - g_message(" {%s} [%s]", layer->id, layer->label() ); - } -*/ - deskTrack.setBase(desktop); -} - - - - - -} //namespace Dialogs -} //namespace UI -} //namespace Inkscape - - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h deleted file mode 100644 index d35dfba01..000000000 --- a/src/ui/dialog/tags.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * A simple dialog for tags UI. - * - * Authors: - * Theodore Janeczko - * - * Copyright (C) Theodore Janeczko 2012 - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef SEEN_TAGS_PANEL_H -#define SEEN_TAGS_PANEL_H - -#include -#include -#include -#include -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/panel.h" -#include "ui/widget/object-composite-settings.h" -#include "desktop-tracker.h" -#include "ui/widget/style-subject.h" -#include "selection.h" -#include "ui/widget/filter-effect-chooser.h" - -class SPObject; -class SPTag; -struct SPColorSelector; - -namespace Inkscape { - -namespace UI { -namespace Dialog { - - -/** - * A panel that displays layers. - */ -class TagsPanel : public UI::Widget::Panel -{ -public: - TagsPanel(); - virtual ~TagsPanel(); - - //virtual void setOrientation( Gtk::AnchorType how ); - - static TagsPanel& getInstance(); - - void setDesktop( SPDesktop* desktop ); - void setDocument( SPDesktop* desktop, SPDocument* document); - -protected: - //virtual void _handleAction( int setId, int itemId ); - friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); -private: - class ModelColumns; - class InternalUIBounce; - class ObjectWatcher; - - TagsPanel(TagsPanel const &); // no copy - TagsPanel &operator=(TagsPanel const &); // no assign - - void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); - void _fireAction( unsigned int code ); - Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); - - bool _handleButtonEvent(GdkEventButton *event); - bool _handleKeyEvent(GdkEventKey *event); - - void _storeDragSource(const Gtk::TreeModel::iterator& iter); - bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); - void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelled(); - - void _doTreeMove(); - void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); - - void _pushTreeSelectionToCurrent(); - void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); - void _select_tag( SPTag * tag ); - - void _checkTreeSelection(); - - void _takeAction( int val ); - bool _executeAction(); - - void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); - - bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); - bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); - - void _updateObject(SPObject *obj); - bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); - - void _objectsSelected(Selection *sel); - bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); - - void _objectsChanged(SPObject *root); - void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); - - void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); - -// std::vector groupConnections; - TagsPanel::ObjectWatcher* _rootWatcher; - std::vector _objectWatchers; - - // Hooked to the layer manager: - sigc::connection _documentChangedConnection; - sigc::connection _selectionChangedConnection; - - sigc::connection _changedConnection; - sigc::connection _addedConnection; - sigc::connection _removedConnection; - - // Internal - sigc::connection _selectedConnection; - sigc::connection _expandedConnection; - sigc::connection _collapsedConnection; - - DesktopTracker deskTrack; - SPDesktop* _desktop; - SPDocument* _document; - ModelColumns* _model; - InternalUIBounce* _pending; - gboolean _dnd_into; - std::vector _dnd_source; - SPObject* _dnd_target; - - GdkEvent* _toggleEvent; - bool down_at_add; - - Gtk::TreeModel::Path _defer_target; - - Glib::RefPtr _store; - std::vector _watching; - std::vector _watchingNonTop; - std::vector _watchingNonBottom; - - Gtk::TreeView _tree; - Gtk::CellRendererText *_text_renderer; - Gtk::TreeView::Column *_name_column; -#if WITH_GTKMM_3_0 - Gtk::Box _buttonsRow; - Gtk::Box _buttonsPrimary; - Gtk::Box _buttonsSecondary; -#else - Gtk::HBox _buttonsRow; - Gtk::HBox _buttonsPrimary; - Gtk::HBox _buttonsSecondary; -#endif - Gtk::ScrolledWindow _scroller; - Gtk::Menu _popupMenu; - Inkscape::UI::Widget::SpinButton _spinBtn; - Gtk::VBox _layersPage; - - sigc::connection desktopChangeConn; - -}; - - - -} //namespace Dialogs -} //namespace UI -} //namespace Inkscape - - - -#endif // SEEN_OBJECTS_PANEL_H - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/addtoicon.h b/src/ui/widget/addtoicon.h index aa8b4148e..9c134d231 100644 --- a/src/ui/widget/addtoicon.h +++ b/src/ui/widget/addtoicon.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/clipmaskicon.h b/src/ui/widget/clipmaskicon.h index f1c1e7628..eca852a83 100644 --- a/src/ui/widget/clipmaskicon.h +++ b/src/ui/widget/clipmaskicon.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/highlight-picker.cpp b/src/ui/widget/highlight-picker.cpp index bf93fa960..2afdc02a6 100644 --- a/src/ui/widget/highlight-picker.cpp +++ b/src/ui/widget/highlight-picker.cpp @@ -7,7 +7,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include "display/cairo-utils.h" #include @@ -16,6 +23,7 @@ #include "widgets/icon.h" #include "widgets/toolbox.h" #include "ui/icon-names.h" +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/highlight-picker.h b/src/ui/widget/highlight-picker.h index 2d7dbc14e..c5fe4c02c 100644 --- a/src/ui/widget/highlight-picker.h +++ b/src/ui/widget/highlight-picker.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { diff --git a/src/ui/widget/insertordericon.cpp b/src/ui/widget/insertordericon.cpp index 9002a99c2..2f06225bc 100644 --- a/src/ui/widget/insertordericon.cpp +++ b/src/ui/widget/insertordericon.cpp @@ -7,6 +7,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif #include "ui/widget/insertordericon.h" diff --git a/src/ui/widget/layertypeicon.h b/src/ui/widget/layertypeicon.h index 4ad3f16fb..6c71ce361 100644 --- a/src/ui/widget/layertypeicon.h +++ b/src/ui/widget/layertypeicon.h @@ -13,9 +13,9 @@ #include "config.h" #endif -#include #include #include +#include namespace Inkscape { namespace UI { diff --git a/src/verbs.cpp b/src/verbs.cpp index 9c0908e93..26e5ce531 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2043,9 +2043,9 @@ void DialogVerb::perform(SPAction *action, void *data) case SP_VERB_DIALOG_OBJECTS: dt->_dlg_mgr->showDialog("ObjectsPanel"); break; - case SP_VERB_DIALOG_TAGS: + /*case SP_VERB_DIALOG_TAGS: dt->_dlg_mgr->showDialog("TagsPanel"); - break; + break;*/ //in a moment my dear case SP_VERB_DIALOG_LIVE_PATH_EFFECT: dt->_dlg_mgr->showDialog("LivePathEffect"); break; @@ -2866,8 +2866,8 @@ Verb *Verb::_base_verbs[] = { N_("View Layers"), INKSCAPE_ICON("dialog-layers")), new DialogVerb(SP_VERB_DIALOG_OBJECTS, "DialogObjects", N_("Object_s..."), N_("View Objects"), INKSCAPE_ICON("dialog-layers")), - new DialogVerb(SP_VERB_DIALOG_TAGS, "DialogObjects", N_("Ta_gs..."), - N_("View Tags"), INKSCAPE_ICON("edit-select-all-layers")), + /*new DialogVerb(SP_VERB_DIALOG_TAGS, "DialogObjects", N_("Ta_gs..."), + N_("View Tags"), INKSCAPE_ICON("edit-select-all-layers")),*/ new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), N_("Manage, edit, and apply path effects"), NULL), new DialogVerb(SP_VERB_DIALOG_FILTER_EFFECTS, "DialogFilterEffects", N_("Filter _Editor..."), diff --git a/src/verbs.h b/src/verbs.h index b8a0b1fd5..1533bbd50 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -290,7 +290,7 @@ enum { SP_VERB_DIALOG_EXTENSIONEDITOR, SP_VERB_DIALOG_LAYERS, SP_VERB_DIALOG_OBJECTS, - SP_VERB_DIALOG_TAGS, +// SP_VERB_DIALOG_TAGS, SP_VERB_DIALOG_LIVE_PATH_EFFECT, SP_VERB_DIALOG_FILTER_EFFECTS, SP_VERB_DIALOG_SVG_FONTS, -- cgit v1.2.3 From fd36e8d406b5ca3bfdc575a949351c6ae4a45c57 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 8 Mar 2014 20:52:27 -0500 Subject: Remove all trace of the Tags dialog Fixed Attach Path and Fill Between Many LPEs Enabled Gradient Meshes (bzr r13090.1.21) --- src/live_effects/effect.cpp | 8 ++++---- src/live_effects/lpe-attach-path.cpp | 4 ++-- src/live_effects/lpe-attach-path.h | 2 +- src/menus-skeleton.h | 1 - src/ui/dialog/swatches.cpp | 1 + 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 2ffff153c..17b229352 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -47,7 +47,7 @@ #include "live_effects/lpe-extrude.h" #include "live_effects/lpe-powerstroke.h" #include "live_effects/lpe-clone-original.h" -//#include "live_effects/lpe-attach-path.h" +#include "live_effects/lpe-attach-path.h" #include "live_effects/lpe-fill-between-strokes.h" #include "live_effects/lpe-fill-between-many.h" #include "live_effects/lpe-ellipse_5pts.h" @@ -130,7 +130,7 @@ const Util::EnumData LPETypeData[] = { {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, /* Ponyscape */ -// {ATTACH_PATH, N_("Attach path"), "attach_path"}, + {ATTACH_PATH, N_("Attach path"), "attach_path"}, {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, @@ -258,9 +258,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case CLONE_ORIGINAL: neweffect = static_cast ( new LPECloneOriginal(lpeobj) ); break; - /*case ATTACH_PATH: + case ATTACH_PATH: neweffect = static_cast ( new LPEAttachPath(lpeobj) ); - break;*/ + break; case FILL_BETWEEN_STROKES: neweffect = static_cast ( new LPEFillBetweenStrokes(lpeobj) ); break; diff --git a/src/live_effects/lpe-attach-path.cpp b/src/live_effects/lpe-attach-path.cpp index b3d5ed9b7..0cceb1cb7 100644 --- a/src/live_effects/lpe-attach-path.cpp +++ b/src/live_effects/lpe-attach-path.cpp @@ -62,9 +62,9 @@ void LPEAttachPath::resetDefaults(SPItem const * item) curve_end_previous_origin = end_path_curve_end.getOrigin(); } -void LPEAttachPath::doBeforeEffect(const SPLPEItem *lpeitem) +void LPEAttachPath::doBeforeEffect(SPLPEItem const *lpeitem) { - lpe_effect = lpeitem; + lpe_effect = const_cast (lpeitem); } void LPEAttachPath::doEffect (SPCurve * curve) diff --git a/src/live_effects/lpe-attach-path.h b/src/live_effects/lpe-attach-path.h index 3dda189d6..390282f90 100644 --- a/src/live_effects/lpe-attach-path.h +++ b/src/live_effects/lpe-attach-path.h @@ -45,7 +45,7 @@ private: ScalarParam end_path_position; TransformedPointParam end_path_curve_start; VectorParam end_path_curve_end; - const SPLPEItem * lpe_effect; + SPLPEItem * lpe_effect; }; }; //namespace LivePathEffect diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 422609390..f1a88cd2d 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -180,7 +180,6 @@ static char const menus_skeleton[] = " \n" " \n" " \n" -" \n" " \n" " \n" " \n" diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 34885a971..2a8471b55 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -6,6 +6,7 @@ * Jon A. Cruz * John Bintz * Abhishek Sharma + * Theodore Janezcko * * Copyright (C) 2005 Jon A. Cruz * Copyright (C) 2008 John Bintz -- cgit v1.2.3 From 9e33a22a12381e538c26580798934eb418f62bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Sun, 9 Mar 2014 22:06:46 -0300 Subject: Shortening code through removal of variable declaration used only at one place. (bzr r11950.6.1) --- src/ui/tools/freehand-base.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 40a257de9..4b7a310e3 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -501,8 +501,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) we modify it when continuing through an anchor. */ if (c->is_empty()) { if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - SPDesktop *desktop = dc->desktop; - spdc_selection_modified(sp_desktop_selection(desktop), 0, dc); + spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); } c->unref(); return; -- cgit v1.2.3 From 4b8c6b64ba7ac54955cc68aa6ad18c67b57ef5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Sun, 9 Mar 2014 23:20:18 -0300 Subject: Removing repeated condition logical test to make the code more readable and easier to follow. (bzr r11950.6.2) --- src/ui/tools/freehand-base.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 4b7a310e3..3f74a5147 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -540,6 +540,11 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) if(Geom::are_near(dc->sa->curve->first_path()->initialPoint(), dc->ea->dp)){ dc->sa->curve->closepath_current(); } + + // if the curve has an bspline or spiro LPE, we execute + // spdc_flush_white, passing the necessary starting curve. + dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); + spdc_flush_white(dc, dc->sa->curve); }else{ if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { c = reverse_then_unref(c); @@ -547,16 +552,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - } - - //if the curve has an bspline or spiro LPE, we execute spdc_flush_white, passing the necessary starting curve. - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - spdc_flush_white(dc, dc->sa->curve); - }else{ spdc_flush_white(dc, NULL); } + return; } -- cgit v1.2.3 From 13c192e2fa564c0a743e13e30b1cf6de9b1a39a6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 12 Mar 2014 08:56:04 -0400 Subject: Reverted swatches Removed a toy effect (not ready yet) Fixed a bug with Livarot General cleanup (bzr r13090.1.23) --- src/display/drawing-item.cpp | 5 +- src/live_effects/Makefile_insert | 4 +- src/live_effects/effect-enum.h | 2 +- src/live_effects/effect.cpp | 10 +- src/live_effects/lpe-jointype.h | 43 - src/live_effects/parameter/originalpatharray.cpp | 7 +- src/live_effects/pathoutlineprovider.h | 766 ------ src/path-chemistry.cpp | 8 + src/splivarot.cpp | 28 +- src/ui/dialog/color-item.cpp | 862 +++++-- src/ui/dialog/color-item.h | 108 +- src/ui/dialog/object-properties.cpp | 1 + src/ui/dialog/objects.cpp | 227 +- src/ui/dialog/swatches.cpp | 2944 +++++++--------------- src/ui/dialog/swatches.h | 153 +- src/widgets/desktop-widget.cpp | 2 +- 16 files changed, 1870 insertions(+), 3300 deletions(-) delete mode 100755 src/live_effects/lpe-jointype.h delete mode 100755 src/live_effects/pathoutlineprovider.h (limited to 'src') diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 13e7b61eb..6c7f99d42 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -808,9 +808,10 @@ DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) { // Sometimes there's no BBOX in state, reason unknown (bug 992817) // I made this not an assert to remove the warning + // This warning clutters the console output, so commented out if (!(_state & STATE_BBOX) || !(_state & STATE_PICK)) { - g_warning("Invalid state when picking: STATE_BBOX = %d, STATE_PICK = %d", - _state & STATE_BBOX, _state & STATE_PICK); + /*g_warning("Invalid state when picking: STATE_BBOX = %d, STATE_PICK = %d", + _state & STATE_BBOX, _state & STATE_PICK);*/ return NULL; } // ignore invisible and insensitive items unless sticky diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 76d7b418f..35a85b4aa 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -92,6 +92,4 @@ ink_common_sources += \ live_effects/lpe-fill-between-many.cpp \ live_effects/lpe-fill-between-many.h \ live_effects/lpe-ellipse_5pts.cpp \ - live_effects/lpe-ellipse_5pts.h \ - live_effects/lpe-jointype.cpp \ - live_effects/lpe-jointype.h + live_effects/lpe-ellipse_5pts.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 46bc56a81..9c76875e9 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -55,7 +55,7 @@ enum EffectType { FILL_BETWEEN_MANY, ELLIPSE_5PTS, BOUNDING_BOX, - JOIN_TYPE, +// JOIN_TYPE, INVALID_LPE // This must be last (I made it such that it is not needed anymore I think..., Don't trust on it being last. - johan) }; diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 17b229352..eac0f79f4 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,7 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#define LPE_ENABLE_TEST_EFFECTS +//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects #ifdef HAVE_CONFIG_H # include "config.h" @@ -52,7 +52,7 @@ #include "live_effects/lpe-fill-between-many.h" #include "live_effects/lpe-ellipse_5pts.h" #include "live_effects/lpe-bounding-box.h" -#include "live_effects/lpe-jointype.h" +//#include "live_effects/lpe-jointype.h" #include "xml/node-event-vector.h" #include "sp-object.h" @@ -109,7 +109,7 @@ const Util::EnumData LPETypeData[] = { {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, {TEXT_LABEL, N_("Text label"), "text_label"}, - {JOIN_TYPE, N_("Join type"), "join_type"}, +// {JOIN_TYPE, N_("Join type"), "join_type"}, #endif /* 0.46 */ {BEND_PATH, N_("Bend"), "bend_path"}, @@ -273,9 +273,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case BOUNDING_BOX: neweffect = static_cast ( new LPEBoundingBox(lpeobj) ); break; - case JOIN_TYPE: + /*case JOIN_TYPE: neweffect = static_cast ( new LPEJoinType(lpeobj) ); - break; + break;*/ default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h deleted file mode 100755 index db113c66a..000000000 --- a/src/live_effects/lpe-jointype.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Authors: - * Liam P White - * - * Copyright (C) 2014 Authors - * - * Released under GNU GPL v2, read the file COPYING for more information - */ -#ifndef INKSCAPE_LPE_JOINTYPE_H -#define INKSCAPE_LPE_JOINTYPE_H - -#include "live_effects/effect.h" -#include "live_effects/parameter/parameter.h" -#include "live_effects/parameter/point.h" -#include "live_effects/parameter/enum.h" - -namespace Inkscape { -namespace LivePathEffect { - -class LPEJoinType : public Effect { -public: - LPEJoinType(LivePathEffectObject *lpeobject); - virtual ~LPEJoinType(); - - virtual void doOnApply(SPLPEItem const* lpeitem); - virtual void doOnRemove(SPLPEItem const* lpeitem); - virtual std::vector doEffect_path (std::vector const & path_in); - -private: - LPEJoinType(const LPEJoinType&); - LPEJoinType& operator=(const LPEJoinType&); - - ScalarParam line_width; - EnumParam linecap_type; - EnumParam linejoin_type; - ScalarParam miter_limit; - BoolParam attempt_force_join; - bool was_initialized; -}; - -} //namespace LivePathEffect -} //namespace Inkscape - -#endif diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index ed47db28d..514c9e23e 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -31,7 +32,6 @@ #include "uri.h" #include "display/curve.h" -#include #include <2geom/coord.h> #include <2geom/point.h> #include "sp-shape.h" @@ -97,8 +97,9 @@ OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, _toggle_renderer->signal_toggled().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_reverse_toggled)); col->add_attribute(_toggle_renderer->property_active(), _model->_colReverse); - //quick little hack -- new versions of gtk did not give the item enough space - _scroller.property_height_request() = 120; + //quick little hack -- newer versions of gtk gave the item zero space allotment + _scroller.set_size_request(-1, 120); + _scroller.add(_tree); _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); //_scroller.set_shadow_type(Gtk::SHADOW_IN); diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h deleted file mode 100755 index 8aa2e38ad..000000000 --- a/src/live_effects/pathoutlineprovider.h +++ /dev/null @@ -1,766 +0,0 @@ -#pragma once - -#include <2geom/path.h> -#include <2geom/circle.h> -#include <2geom/sbasis-to-bezier.h> -#include <2geom/shape.h> -#include <2geom/transforms.h> -#include <2geom/path-sink.h> - -#include -#include - -enum LineJoinType { - LINEJOIN_STRAIGHT, - LINEJOIN_ROUND, - LINEJOIN_POINTY, - LINEJOIN_REFLECTED, - LINEJOIN_EXTRAPOLATED -}; - -namespace Geom -{ - /** - * Refer to: Weisstein, Eric W. "Circle-Circle Intersection." - From MathWorld--A Wolfram Web Resource. - http://mathworld.wolfram.com/Circle-CircleIntersection.html - * - * @return 0 if no intersection - * @return 1 if one circle is contained in the other - * @return 2 if intersections are found (they are written to p0 and p1) - */ - static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, - Point & p0, Point & p1) - { - Point X0 = circle0.center(); - double r0 = circle0.ray(); - Point X1 = circle1.center(); - double r1 = circle1.ray(); - - /* dx and dy are the vertical and horizontal distances between - * the circle centers. - */ - Point D = X1 - X0; - - /* Determine the straight-line distance between the centers. */ - double d = L2(D); - - /* Check for solvability. */ - if (d > (r0 + r1)) - { - /* no solution. circles do not intersect. */ - return 0; - } - if (d <= fabs(r0 - r1)) - { - /* no solution. one circle is contained in the other */ - return 1; - } - - /* 'point 2' is the point where the line through the circle - * intersection points crosses the line between the circle - * centers. - */ - - /* Determine the distance from point 0 to point 2. */ - double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; - - /* Determine the coordinates of point 2. */ - Point p2 = X0 + D * (a/d); - - /* Determine the distance from point 2 to either of the - * intersection points. - */ - double h = std::sqrt((r0*r0) - (a*a)); - - /* Now determine the offsets of the intersection points from - * point 2. - */ - Point r = (h/d)*rot90(D); - - /* Determine the absolute intersection points. */ - p0 = p2 + r; - p1 = p2 - r; - - return 2; - } - /** - * Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t. - * Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt). - */ - static Circle touching_circle( D2 const &curve, double t, double tol=0.01 ) - { - D2 dM=derivative(curve); - if ( are_near(L2sq(dM(t)),0.) ) { - dM=derivative(dM); - } - if ( are_near(L2sq(dM(t)),0.) ) { // try second time - dM=derivative(dM); - } - Piecewise > unitv = unitVector(dM,tol); - Piecewise dMlength = dot(Piecewise >(dM),unitv); - Piecewise k = cross(derivative(unitv),unitv); - k = divide(k,dMlength,tol,3); - double curv = k(t); // note that this value is signed - - Geom::Point normal = unitTangentAt(curve, t).cw(); - double radius = 1/curv; - Geom::Point center = curve(t) + radius*normal; - return Geom::Circle(center, fabs(radius)); - } - - static std::vector split_at_cusps(const Geom::Path& in) - { - Geom::PathVector out = Geom::PathVector(); - Geom::Path temp = Geom::Path(); - - for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) - { - temp = Geom::Path(); - temp.append(in[path_descr]); - out.push_back(temp); - } - - return out; - } - - static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) - { - std::vector temp; - sbasis_to_bezier(temp, sbasis_in, 4); - return Geom::CubicBezier( temp ); - } - - static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, - Geom::Point const & origin_b, Geom::Point const & vector_b) - { - Geom::Coord denom = cross(vector_b, vector_a); - if (!Geom::are_near(denom,0.)){ - Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom; - return origin_a + t * vector_a; - } - return boost::none; - } -} - -namespace Outline -{ - - typedef Geom::D2 D2SB; - typedef Geom::Piecewise PWD2; - - static void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve*cbc2, Geom::Point endPt, double miter_limit) -{ - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - if (cross.empty()) - { - Geom::Path pth; - pth.append(*cbc1); - - Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); - - pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); - - - Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.); - Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0); - - Geom::Point points[2]; - int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]); - if (solutions == 2) - { - Geom::Point sol(0,0); - if ( dot(tang2,points[0]-endPt) > 0 ) - { - // points[0] is bad, choose points[1] - sol = points[1]; - } - else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1] - // points[1] is bad, choose points[0] - sol = points[0]; - } - else - { - // both points are good, choose nearest - sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? - points[0] : points[1]; - } - Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true); - Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true); - - if (arc0) - { - path_builder.append (arc0->toSBasis()); - delete arc0; - arc0 = NULL; - } - - if (arc1) - { - path_builder.append (arc1->toSBasis()); - delete arc1; - arc1 = NULL; - } - } - else - { - path_builder.appendNew (endPt); - } - } - else - { - path_builder.appendNew (endPt); - } -} - static Geom::Path half_outline_extrp(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) - { - Geom::PathVector pv = split_at_cusps(path_in); - unsigned m; - Path path_outline = Path(); - Path path_tangent = Path(); - - Geom::Point initialPoint; - Geom::Point endPoint; - - Geom::Path path_builder = Geom::Path(); - Geom::PathVector * pathvec; - - //load the first portion in before the loop starts - { - path_outline = Path(); - path_outline.LoadPath(pv[0], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - //now half of first cusp has been loaded - - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - //instead of array accessing twice, dereferencing used for clarity - initialPoint = (*pathvec)[0].initialPoint(); - - path_builder.start(initialPoint); - path_builder.append( (*pathvec)[0] ); - - path_outline = Path(); - path_outline.LoadPath(pv[1], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - - path_builder.append( (*pathvec)[0] ); - - //always set pointers null after deleting - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - for (m = 2; m < pv.size(); m++) - { - path_outline = Path(); - path_outline.LoadPath(pv[m], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - path_builder.append( (*pathvec)[0] ); - - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - return path_builder; - } - - //Create a reflected outline join. - //Note: it is generally recommended to let half_outline do this for you! - //path_builder: the path to append the curves to - //cbc1: the curve before the join - //cbc2: the curve after the join - //endPt: the point to end at - //miter_limit: the miter parameter - static void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit) - { - //the most important work for the reflected join is done here - - //determine where we are in the path. If we're on the inside, ignore - //and just lineTo. On the outside, we'll do a little reflection magic :) - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - if (cross.empty()) - { - //probably on the outside of the corner - Geom::Path pth; - pth.append(*cbc1); - - Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); - - //reflect curves along the bevel - D2SB newcurve1 = pth.toPwSb()[0] * - Geom::reflection ( -Geom::rot90(tang1) , - cbc1->finalPoint() ); - - Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1)); - - pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); - - D2SB newcurve2 = pth.toPwSb()[0] * - Geom::reflection ( -Geom::rot90(tang2) , - cbc2->initialPoint() ); - Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2)); - - cross = Geom::crossings(bzr1, bzr2); - if ( cross.empty() ) - { - //std::cout << "Oops, no crossings!" << std::endl; - //curves didn't cross; default to miter - /*boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) - { - path_builder.appendNew (*p); - }*/ - //bevel - path_builder.appendNew( endPt ); - } - else - { - //join - std::pair sub1 = bzr1.subdivide(cross[0].ta); - std::pair sub2 = bzr2.subdivide(cross[0].tb); - - //@TODO joins have a strange tendency to cross themselves twice. Check this. - - //sections commented out are for general stability - path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); - path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); - } - } - else // cross.empty() - { - //probably on the inside of the corner - path_builder.appendNew ( endPt ); - } - } - - /** @brief Converts a path to one half of an outline. - * path_in: The input path to use. (To create the other side use path_in.reverse() ) - * line_width: the line width to use (usually you want to divide this by 2) - * linecap_type: (not used here) the cap to apply. Passed to libvarot. - * miter_limit: the miter parameter - */ - static Geom::Path half_outline(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) - { - Geom::PathVector pv = split_at_cusps(path_in); - unsigned m; - Path path_outline = Path(); - Path path_tangent = Path(); - //needed for closing the path - Geom::Point initialPoint; - Geom::Point endPoint; - - //some issues prevented me from using a PathBuilder here - //it seems like PathBuilder::peek() gave me a null reference exception - //and I was unable to get a stack trace on Windows, so had to switch to Linux - //to see what the hell was wrong. :( - //I wasted five hours opening it in IDAPro, VS2012, and GDB Windows - - /*Program received signal SIGSEGV, Segmentation fault. - 0x00000000006539ac in get_curves (this=0x0) - at /usr/include/c++/4.6/bits/locale_facets.h:1077 - 1077 { return __c; } - */ - - Geom::Path path_builder = Geom::Path(); - Geom::PathVector * pathvec; - - //load the first portion in before the loop starts - { - path_outline = Path(); - path_outline.LoadPath(pv[0], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - //now half of first cusp has been loaded - - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - //instead of array accessing twice, dereferencing used for clarity - initialPoint = (*pathvec)[0].initialPoint(); - - path_builder.start(initialPoint); - path_builder.append( (*pathvec)[0] ); - - path_outline = Path(); - path_outline.LoadPath(pv[1], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - - path_builder.append( (*pathvec)[0] ); - - //always set pointers null after deleting - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - for (m = 2; m < pv.size(); m++) - { - path_outline = Path(); - path_outline.LoadPath(pv[m], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - path_builder.append( (*pathvec)[0] ); - - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - return path_builder; - } - - static Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim) - { - Path p = Path(); - Path outlinepath = Path(); - for (unsigned i = 0; i < path_in.size(); i++) - { - p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); - } - - Geom::PathVector path_out; - for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) - { - if (path_in[lmnop].size() > 1) - { - Geom::Path p_init; - Geom::Path p_rev; - Geom::PathBuilder pb = Geom::PathBuilder(); - - if ( !path_in[lmnop].closed() ) - { - p_init = Outline::half_outline( path_in[lmnop], -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline( path_in[lmnop].reverse(), -line_width, butt, - miter_lim ); - - pb.moveTo(p_init.initialPoint() ); - pb.append(p_init); - - //cap - if (butt == butt_straight) { - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } - - pb.append(p_rev); - - if (butt == butt_straight) { - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); - //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); - - pb.lineTo(p_init.initialPoint() ); - } - } - else - { - //final join - //refer to half_outline for documentation - Geom::Path p_almost = path_in[lmnop]; - p_almost.appendNew ( path_in[lmnop].initialPoint() ); - p_init = Outline::half_outline( p_almost, -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline( p_almost.reverse(), -line_width, butt, - miter_lim ); - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - - //this is a kludge, because I can't find how to make this work properly - bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), - path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == - (path_in[lmnop] [path_in[lmnop].size()].length())); - - p_almost = p_init; - if (lastIsLinear) - { - p_almost.erase_last(); p_almost.erase_last(); - } - - //outside test - Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); - Geom::Curve* cbc2 = p_almost[0].duplicate(); - - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //this is the outside path - - //reuse the old one - p_init = p_almost; - Outline::reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside, carry on :-) - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - - p_almost = p_rev; - if (lastIsLinear) - { - p_almost.erase(p_almost.begin() ); - p_almost.erase(p_almost.begin() ); - } - - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - - cbc1 = p_almost[p_almost.size() - 1].duplicate(); - cbc2 = p_almost[0].duplicate(); - - cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //outside path - - p_init = p_almost; - reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - //pb.closePath(); - pb.flush(); - Geom::PathVector pv_np = pb.peek(); - //hack - for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) - { - path_out.push_back( pv_np[abcd] ); - } - } - else - { - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - p.Outline(&outlinepath, line_width / 2, join, butt, miter_lim); - std::vector *pv_p = outlinepath.MakePathVector(); - //hack - path_out.push_back( (*pv_p)[0].reverse() ); - delete pv_p; - } - } - return path_out; - } - static Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim) - { - Path p = Path(); - Path outlinepath = Path(); - for (unsigned i = 0; i < path_in.size(); i++) - { - p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); - } - - Geom::PathVector path_out; - for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) - { - if (path_in[lmnop].size() > 1) - { - Geom::Path p_init; - Geom::Path p_rev; - Geom::PathBuilder pb = Geom::PathBuilder(); - - if ( !path_in[lmnop].closed() ) - { - p_init = Outline::half_outline_extrp( path_in[lmnop], -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline_extrp( path_in[lmnop].reverse(), -line_width, butt, - miter_lim ); - - pb.moveTo(p_init.initialPoint() ); - pb.append(p_init); - - //cap - if (butt == butt_straight) { - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } - - pb.append(p_rev); - - if (butt == butt_straight) { - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); - //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); - - pb.lineTo(p_init.initialPoint() ); - } - } - else - { - //final join - //refer to half_outline for documentation - Geom::Path p_almost = path_in[lmnop]; - p_almost.appendNew ( path_in[lmnop].initialPoint() ); - p_init = Outline::half_outline_extrp( p_almost, -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline_extrp( p_almost.reverse(), -line_width, butt, - miter_lim ); - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - - //this is a kludge, because I can't find how to make this work properly - bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), - path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == - (path_in[lmnop] [path_in[lmnop].size()].length())); - - p_almost = p_init; - if (lastIsLinear) - { - p_almost.erase_last(); p_almost.erase_last(); - } - - //outside test - Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); - Geom::Curve* cbc2 = p_almost[0].duplicate(); - - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //this is the outside path - - //reuse the old one - p_init = p_almost; - Outline::extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside, carry on :-) - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - - p_almost = p_rev; - if (lastIsLinear) - { - p_almost.erase(p_almost.begin() ); - p_almost.erase(p_almost.begin() ); - } - - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - - cbc1 = p_almost[p_almost.size() - 1].duplicate(); - cbc2 = p_almost[0].duplicate(); - - cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //outside path - - p_init = p_almost; - extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - //pb.closePath(); - pb.flush(); - Geom::PathVector pv_np = pb.peek(); - //hack - for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) - { - path_out.push_back( pv_np[abcd] ); - } - } - else - { - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - p.Outline(&outlinepath, line_width / 2, join_pointy, butt, miter_lim); - std::vector *pv_p = outlinepath.MakePathVector(); - //hack - path_out.push_back( (*pv_p)[0].reverse() ); - delete pv_p; - } - } - return path_out; - } - - -} // namespace Outline - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 5f478435d..456af3731 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -22,6 +22,7 @@ #include "xml/repr.h" #include "svg/svg.h" #include "display/curve.h" +#include "color.h" #include #include #include "sp-path.h" @@ -438,6 +439,10 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec gchar *title = item->title(); // remember description gchar *desc = item->desc(); + // remember highlight color + guint32 highlight_color = 0; + if (item->isHighlightSet()) + highlight_color = item->highlight_color(); // It's going to resurrect, so we delete without notifying listeners. item->deleteObject(false); @@ -455,6 +460,9 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec newObj->setDesc(desc); g_free(desc); } + if (highlight_color && newObj) { + SP_ITEM(newObj)->setHighlightColor( highlight_color ); + } // move to the saved position repr->setPosition(pos > 0 ? pos : 0); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 5c7b389ff..1eab73b62 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -1339,6 +1339,10 @@ sp_selected_path_outline(SPDesktop *desktop) gchar *title = item->title(); // remember description gchar *desc = item->desc(); + // remember highlight color + guint32 highlight_color = 0; + if (item->isHighlightSet()) + highlight_color = item->highlight_color(); if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether @@ -1381,6 +1385,9 @@ sp_selected_path_outline(SPDesktop *desktop) if (desc) { newitem->setDesc(desc); } + if (highlight_color && newitem) { + newitem->setHighlightColor( highlight_color ); + } SPShape *shape = SP_SHAPE(item); @@ -1456,13 +1463,23 @@ sp_selected_path_outline(SPDesktop *desktop) g_repr, xml_doc, doc ); } } + //bug 1290573: completely destroy the old object first to prevent + //an ID clash, which has issues on undo + curve->unref(); + selection->remove(item); + item->deleteObject(false); selection->add(g_repr); Inkscape::GC::release(g_repr); - - } else { + } else + { + //bug 1290573: completely destroy the old object first to prevent + //an ID clash, which has issues on undo + curve->unref(); + selection->remove(item); + item->deleteObject(false); // add the new repr to the parent parent->appendChild(repr); @@ -1481,6 +1498,9 @@ sp_selected_path_outline(SPDesktop *desktop) if (desc) { newitem->setDesc(desc); } + if (highlight_color && newitem) { + newitem->setHighlightColor( highlight_color ); + } selection->add(repr); @@ -1488,10 +1508,6 @@ sp_selected_path_outline(SPDesktop *desktop) Inkscape::GC::release(repr); - curve->unref(); - selection->remove(item); - item->deleteObject(false); - } if (title) { g_free(title); diff --git a/src/ui/dialog/color-item.cpp b/src/ui/dialog/color-item.cpp index a1951ec48..bab7e18e1 100644 --- a/src/ui/dialog/color-item.cpp +++ b/src/ui/dialog/color-item.cpp @@ -11,8 +11,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include +#endif + #include +#include #include #include @@ -35,216 +45,766 @@ #include "xml/repr.h" #include "verbs.h" #include "widgets/gradient-vector.h" -#include "sp-paint-server.h" #include "color.h" // for SP_RGBA32_U_COMPOSE -#include namespace Inkscape { namespace UI { namespace Dialogs { +static std::vector mimeStrings; +static std::map mimeToInt; + -bool ColorItem::on_enter_notify_event(GdkEventCrossing* event) +#if ENABLE_MAGIC_COLORS +// TODO remove this soon: +extern std::vector possible; +#endif // ENABLE_MAGIC_COLORS + + +#if ENABLE_MAGIC_COLORS +static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"),def); - desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); - g_free(msg); + bool changed = false; + + if ( node ) { + gchar const * val = node->attribute("inkscape:x-fill-tag"); + if ( val && (match == val) ) { + SPObject *obj = document->getObjectByRepr( node ); + + gchar c[64] = {0}; + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, "fill", c ); + + sp_desktop_apply_css_recursive( obj, css, true ); + static_cast(obj)->updateRepr(); + + changed = true; + } + + val = node->attribute("inkscape:x-stroke-tag"); + if ( val && (match == val) ) { + SPObject *obj = document->getObjectByRepr( node ); + + gchar c[64] = {0}; + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) ); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, "stroke", c ); + + sp_desktop_apply_css_recursive( (SPItem*)obj, css, true ); + ((SPItem*)obj)->updateRepr(); + + changed = true; + } + + Inkscape::XML::Node* first = node->firstChild(); + changed |= bruteForce( document, first, match, r, g, b ); + + changed |= bruteForce( document, node->next(), match, r, g, b ); } - return Gtk::Widget::on_enter_notify_event(event); + + return changed; +} +#endif // ENABLE_MAGIC_COLORS + +static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(false); + } +} + +static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(true); + } +} + +static gboolean handleEnterNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + gchar* msg = g_strdup_printf(_("Color: %s; Click to set fill, Shift+click to set stroke"), + item->def.descr.c_str()); + desktop->tipsMessageContext()->set(Inkscape::INFORMATION_MESSAGE, msg); + g_free(msg); + } + } + return FALSE; +} + +static gboolean handleLeaveNotify( GtkWidget* /*widget*/, GdkEventCrossing* /*event*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + desktop->tipsMessageContext()->clear(); + } + } + return FALSE; } -bool ColorItem::on_leave_notify_event(GdkEventCrossing* event) +static void dieDieDie( GObject *obj, gpointer user_data ) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if ( desktop ) { - desktop->tipsMessageContext()->clear(); + g_message("die die die %p %p", obj, user_data ); +} + +static bool getBlock( std::string& dst, guchar ch, std::string const & str ) +{ + bool good = false; + std::string::size_type pos = str.find(ch); + if ( pos != std::string::npos ) + { + std::string::size_type pos2 = str.find( '(', pos ); + if ( pos2 != std::string::npos ) { + std::string::size_type endPos = str.find( ')', pos2 ); + if ( endPos != std::string::npos ) { + dst = str.substr( pos2 + 1, (endPos - pos2 - 1) ); + good = true; + } + } } - return Gtk::Widget::on_leave_notify_event(event); + return good; } -void ColorItem::selection_modified(Selection* selection, guint flags) +static bool popVal( guint64& numVal, std::string& str ) { - selection_changed(selection); + bool good = false; + std::string::size_type endPos = str.find(','); + if ( endPos == std::string::npos ) { + endPos = str.length(); + } + + if ( endPos != std::string::npos && endPos > 0 ) { + std::string xxx = str.substr( 0, endPos ); + const gchar* ptr = xxx.c_str(); + gchar* endPtr = 0; + numVal = g_ascii_strtoull( ptr, &endPtr, 10 ); + if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { + // overflow + } else if ( (numVal == 0) && (endPtr == ptr) ) { + // failed conversion + } else { + good = true; + str.erase( 0, endPos + 1 ); + } + } + + return good; } -void ColorItem::selection_changed(Selection* selection) +// TODO resolve this more cleanly: +extern gboolean colorItemHandleButtonPress( GtkWidget* /*widget*/, GdkEventButton* event, gpointer user_data); + +static void colorItemDragBegin( GtkWidget */*widget*/, GdkDragContext* dc, gpointer data ) { - SPItem* item = selection->singleItem(); - SPPaintServer* grad; - if (item && - ( - (item->style->fill.isPaintserver() && - SP_IS_GRADIENT( (grad = item->style->getFillPaintServer()) ) - && SP_GRADIENT(grad)->getVector() == gradient) || - - (item->style->stroke.isPaintserver() && - SP_IS_GRADIENT( (grad = item->style->getStrokePaintServer()) ) && - SP_GRADIENT(grad)->getVector() == gradient) - ) - ) + ColorItem* item = reinterpret_cast(data); + if ( item ) { - if (!_isSelected) { - _isSelected = true; - queue_draw(); + using Inkscape::IO::Resource::get_path; + using Inkscape::IO::Resource::ICONS; + using Inkscape::IO::Resource::SYSTEM; + int width = 32; + int height = 24; + + if (item->def.getType() != ege::PaintDef::RGB){ + GError *error = NULL; + gsize bytesRead = 0; + gsize bytesWritten = 0; + gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), + -1, + &bytesRead, + &bytesWritten, + &error); + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_scale(localFilename, width, height, FALSE, &error); + g_free(localFilename); + gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); + } else { + GdkPixbuf* pixbuf = 0; + if ( item->getGradient() ){ + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(item->getGradient(), width); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, gradient); + cairo_paint(ct); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_surface_flush(s); + + pixbuf = ink_pixbuf_create_from_cairo_surface(s); + } else { + Glib::RefPtr thumb = Gdk::Pixbuf::create( Gdk::COLORSPACE_RGB, false, 8, width, height ); + guint32 fillWith = (0xff000000 & (item->def.getR() << 24)) + | (0x00ff0000 & (item->def.getG() << 16)) + | (0x0000ff00 & (item->def.getB() << 8)); + thumb->fill( fillWith ); + pixbuf = thumb->gobj(); + g_object_ref(G_OBJECT(pixbuf)); + } + gtk_drag_set_icon_pixbuf( dc, pixbuf, 0, 0 ); } - } else if (_isSelected) { - _isSelected = false; - queue_draw(); } + +} + +//"drag-drop" +// gboolean dragDropColorData( GtkWidget *widget, +// GdkDragContext *drag_context, +// gint x, +// gint y, +// guint time, +// gpointer user_data) +// { +// // TODO finish + +// return TRUE; +// } + + +SwatchPage::SwatchPage() + : _prefWidth(0) +{ } -ColorItem::ColorItem( SPGradient* grad, const gchar* name, SPDesktop* desktop ) : - Glib::ObjectBase("coloritem"), - Gtk::Widget(), - def( name ), - gradient(grad), - _isSelected(false) +SwatchPage::~SwatchPage() { - set_has_window(true); - add_events(Gdk::BUTTON_PRESS_MASK); - add_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); - sel_connection = desktop->selection->connectChanged(sigc::mem_fun(*this, &ColorItem::selection_changed)); - mod_connection = desktop->selection->connectModified(sigc::mem_fun(*this, &ColorItem::selection_modified)); - selection_changed(desktop->selection); } -void ColorItem::on_size_request(Gtk::Requisition* requisition) + +ColorItem::ColorItem(ege::PaintDef::ColorType type) : + def(type), + _isFill(false), + _isStroke(false), + _isLive(false), + _linkIsTone(false), + _linkPercent(0), + _linkGray(0), + _linkSrc(0), + _grad(0), + _pattern(0) { - requisition->height = 20; - requisition->width = 20; } -void ColorItem::on_size_allocate(Gtk::Allocation& allocation) +ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : + def( r, g, b, name ), + _isFill(false), + _isStroke(false), + _isLive(false), + _linkIsTone(false), + _linkPercent(0), + _linkGray(0), + _linkSrc(0), + _grad(0), + _pattern(0) { - set_allocation(allocation); - if (m_refGdkWindow) - { - m_refGdkWindow->move_resize( allocation.get_x(), allocation.get_y(), allocation.get_width(), allocation.get_height() ); +} + +ColorItem::~ColorItem() +{ + if (_pattern != NULL) { + cairo_pattern_destroy(_pattern); + } +} + +ColorItem::ColorItem(ColorItem const &other) : + Inkscape::UI::Previewable() +{ + if ( this != &other ) { + *this = other; + } +} + +ColorItem &ColorItem::operator=(ColorItem const &other) +{ + if ( this != &other ) { + def = other.def; + + // TODO - correct linkage + _linkSrc = other._linkSrc; + g_message("Erk!"); + } + return *this; +} + +void ColorItem::setState( bool fill, bool stroke ) +{ + if ( (_isFill != fill) || (_isStroke != stroke) ) { + _isFill = fill; + _isStroke = stroke; + + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + EekPreview * preview = EEK_PREVIEW(widget->gobj()); + + int val = eek_preview_get_linked( preview ); + val &= ~(PREVIEW_FILL | PREVIEW_STROKE); + if ( _isFill ) { + val |= PREVIEW_FILL; + } + if ( _isStroke ) { + val |= PREVIEW_STROKE; + } + eek_preview_set_linked( preview, static_cast(val) ); + } + } + } +} + +void ColorItem::setGradient(SPGradient *grad) +{ + if (_grad != grad) { + _grad = grad; + // TODO regen and push to listeners } + + setName( gr_prepare_label(_grad) ); } -void ColorItem::on_map() +void ColorItem::setName(const Glib::ustring name) { - Gtk::Widget::on_map(); + //def.descr = name; + + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + gtk_widget_set_tooltip_text(GTK_WIDGET(widget->gobj()), name.c_str()); + } + else if ( GTK_IS_LABEL(widget->gobj()) ) { + gtk_label_set_text(GTK_LABEL(widget->gobj()), name.c_str()); + } + } } -void ColorItem::on_unmap() +void ColorItem::setPattern(cairo_pattern_t *pattern) { - Gtk::Widget::on_unmap(); + if (pattern) { + cairo_pattern_reference(pattern); + } + if (_pattern) { + cairo_pattern_destroy(_pattern); + } + _pattern = pattern; + + _updatePreviews(); } -void ColorItem::on_realize() +void ColorItem::_dragGetColorData( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + GtkSelectionData *data, + guint info, + guint /*time*/, + gpointer user_data) +{ + ColorItem* item = reinterpret_cast(user_data); + std::string key; + if ( info < mimeStrings.size() ) { + key = mimeStrings[info]; + } else { + g_warning("ERROR: unknown value (%d)", info); + } + + if ( !key.empty() ) { + char* tmp = 0; + int len = 0; + int format = 0; + item->def.getMIMEData(key, tmp, len, format); + if ( tmp ) { + GdkAtom dataAtom = gdk_atom_intern( key.c_str(), FALSE ); + gtk_selection_data_set( data, dataAtom, format, (guchar*)tmp, len ); + delete[] tmp; + } + } +} + +void ColorItem::_dropDataIn( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + gint /*x*/, gint /*y*/, + GtkSelectionData */*data*/, + guint /*info*/, + guint /*event_time*/, + gpointer /*user_data*/) { - set_realized(); - ensure_style(); - - if(!m_refGdkWindow) - { - //Create the GdkWindow: - - GdkWindowAttr attributes; - memset(&attributes, 0, sizeof(attributes)); - - Gtk::Allocation allocation = get_allocation(); - - //Set initial position and size of the Gdk::Window: - attributes.x = allocation.get_x(); - attributes.y = allocation.get_y(); - attributes.width = allocation.get_width(); - attributes.height = allocation.get_height(); - - attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - - m_refGdkWindow = Gdk::Window::create(get_parent_window(), &attributes, - GDK_WA_X | GDK_WA_Y); - set_window(m_refGdkWindow); - - //Attach this widget's style to its Gdk::Window. - style_attach(); - - //make the widget receive expose events - m_refGdkWindow->set_user_data(gobj()); - } } -void ColorItem::on_unrealize() +void ColorItem::_colorDefChanged(void* data) { - m_refGdkWindow.reset(); - - Gtk::Widget::on_unrealize(); + ColorItem* item = reinterpret_cast(data); + if ( item ) { + item->_updatePreviews(); + } } -bool ColorItem::on_expose_event(GdkEventExpose* event) +void ColorItem::_updatePreviews() { - if(m_refGdkWindow) + for ( std::vector::iterator it = _previews.begin(); it != _previews.end(); ++it ) { + Gtk::Widget* widget = *it; + if ( IS_EEK_PREVIEW(widget->gobj()) ) { + EekPreview * preview = EEK_PREVIEW(widget->gobj()); + + _regenPreview(preview); + + widget->queue_draw(); + } + } + + for ( std::vector::iterator it = _listeners.begin(); it != _listeners.end(); ++it ) { + guint r = def.getR(); + guint g = def.getG(); + guint b = def.getB(); + + if ( (*it)->_linkIsTone ) { + r = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * r) ) / 100; + g = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * g) ) / 100; + b = ( ((*it)->_linkPercent * (*it)->_linkGray) + ((100 - (*it)->_linkPercent) * b) ) / 100; + } else { + r = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * r) ) / 100; + g = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * g) ) / 100; + b = ( ((*it)->_linkPercent * 255) + ((100 - (*it)->_linkPercent) * b) ) / 100; + } + + (*it)->def.setRGB( r, g, b ); + } + + +#if ENABLE_MAGIC_COLORS + // Look for objects using this color { - Cairo::RefPtr cr = m_refGdkWindow->create_cairo_context(); - if(event) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + SPDocument* document = sp_desktop_document( desktop ); + Inkscape::XML::Node *rroot = document->getReprRoot(); + if ( rroot ) { + + // Find where this thing came from + Glib::ustring paletteName; + bool found = false; + int index = 0; + for ( std::vector::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) { + SwatchPage* curr = *it2; + index = 0; + for ( boost::ptr_vector::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) { + if ( this == &*zz ) { + found = true; + paletteName = curr->_name; + break; + } else { + index++; + } + } + } + + if ( !paletteName.empty() ) { + gchar* str = g_strdup_printf("%d|", index); + paletteName.insert( 0, str ); + g_free(str); + str = 0; + + if ( bruteForce( document, rroot, paletteName, def.getR(), def.getG(), def.getB() ) ) { + SPDocumentUndo::done( document , SP_VERB_DIALOG_SWATCHES, + _("Change color definition")); + } + } + } + } + } +#endif // ENABLE_MAGIC_COLORS + +} + +void ColorItem::_regenPreview(EekPreview * preview) +{ + if ( def.getType() != ege::PaintDef::RGB ) { + using Inkscape::IO::Resource::get_path; + using Inkscape::IO::Resource::ICONS; + using Inkscape::IO::Resource::SYSTEM; + GError *error = NULL; + gsize bytesRead = 0; + gsize bytesWritten = 0; + gchar *localFilename = g_filename_from_utf8( get_path(SYSTEM, ICONS, "remove-color.png"), + -1, + &bytesRead, + &bytesWritten, + &error); + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file(localFilename, &error); + if (!pixbuf) { + g_warning("Null pixbuf for %p [%s]", localFilename, localFilename ); + } + g_free(localFilename); + + eek_preview_set_pixbuf( preview, pixbuf ); + } + else if ( !_pattern ){ + eek_preview_set_color( preview, + (def.getR() << 8) | def.getR(), + (def.getG() << 8) | def.getG(), + (def.getB() << 8) | def.getB() ); + } else { + // These correspond to PREVIEW_PIXBUF_WIDTH and VBLOCK from swatches.cpp + // TODO: the pattern to draw should be in the widget that draws the preview, + // so the preview can be scalable + int w = 128; + int h = 16; + + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + cairo_t *ct = cairo_create(s); + cairo_set_source(ct, _pattern); + cairo_paint(ct); + cairo_destroy(ct); + cairo_surface_flush(s); + + GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s); + eek_preview_set_pixbuf( preview, pixbuf ); + } + + eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) + | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) + | (_isLive ? PREVIEW_LINK_OTHER:0)) ); +} + +Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio, guint border) +{ + Gtk::Widget* widget = 0; + if ( style == PREVIEW_STYLE_BLURB) { + Gtk::Label *lbl = new Gtk::Label(def.descr); + lbl->set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + widget = lbl; + } else { + GtkWidget* eekWidget = eek_preview_new(); + EekPreview * preview = EEK_PREVIEW(eekWidget); + Gtk::Widget* newBlot = Glib::wrap(eekWidget); + _regenPreview(preview); + + eek_preview_set_details( preview, + (::ViewType)view, + (::PreviewSize)size, + ratio, + border ); + + def.addCallback( _colorDefChanged, this ); + eek_preview_set_focus_on_click(preview, FALSE); + newBlot->set_tooltip_text(def.descr); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "clicked", + G_CALLBACK(handleClick), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "alt-clicked", + G_CALLBACK(handleSecondaryClick), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "button-press-event", + G_CALLBACK(colorItemHandleButtonPress), + this); + { - // clip to the area that needs to be re-exposed so we don't draw any - // more than we need to. - cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); - cr->clip(); + std::vector listing = def.getMIMETypes(); + int entryCount = listing.size(); + GtkTargetEntry* entries = new GtkTargetEntry[entryCount]; + GtkTargetEntry* curr = entries; + for ( std::vector::iterator it = listing.begin(); it != listing.end(); ++it ) { + curr->target = g_strdup(it->c_str()); + curr->flags = 0; + if ( mimeToInt.find(*it) == mimeToInt.end() ){ + // these next lines are order-dependent: + mimeToInt[*it] = mimeStrings.size(); + mimeStrings.push_back(*it); + } + curr->info = mimeToInt[curr->target]; + curr++; + } + gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), + GDK_BUTTON1_MASK, + entries, entryCount, + GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); + for ( int i = 0; i < entryCount; i++ ) { + g_free(entries[i].target); + } + delete[] entries; } - if (gradient) { - cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); - - Cairo::RefPtr checkpat(new Cairo::Pattern(check)); - - cr->set_source(checkpat); - cr->paint(); - - cairo_pattern_t *g = sp_gradient_create_preview_pattern(gradient, get_allocation().get_width()); - Cairo::RefPtr gpat(new Cairo::Pattern(g)); - cr->set_source(gpat); - cr->paint(); - gpat.clear(); - cairo_pattern_destroy(g); - - checkpat.clear(); - - cairo_pattern_destroy(check); - - if (_isSelected) { - cr->set_source_rgb(0, 0, 0); - cr->set_line_width(3); - cr->move_to(0, get_allocation().get_height()); - cr->line_to(0,0); - cr->line_to(get_allocation().get_width(), 0); - cr->stroke(); - cr->move_to(get_allocation().get_width(), 0); - cr->set_source_rgb(1, 1, 1); - cr->line_to(get_allocation().get_width(), get_allocation().get_height()); - cr->line_to(0, get_allocation().get_height()); - //cr->rectangle(0, 0, get_allocation().get_width(), get_allocation().get_height()); - cr->stroke(); + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-data-get", + G_CALLBACK(ColorItem::_dragGetColorData), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-begin", + G_CALLBACK(colorItemDragBegin), + this ); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "enter-notify-event", + G_CALLBACK(handleEnterNotify), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "leave-notify-event", + G_CALLBACK(handleLeaveNotify), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "destroy", + G_CALLBACK(dieDieDie), + this); + + + widget = newBlot; + } + + _previews.push_back( widget ); + + return widget; +} + +void ColorItem::buttonClicked(bool secondary) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + char const * attrName = secondary ? "stroke" : "fill"; + + SPCSSAttr *css = sp_repr_css_attr_new(); + Glib::ustring descr; + switch (def.getType()) { + case ege::PaintDef::CLEAR: { + // TODO actually make this clear + sp_repr_css_set_property( css, attrName, "none" ); + descr = secondary? _("Remove stroke color") : _("Remove fill color"); + break; + } + case ege::PaintDef::NONE: { + sp_repr_css_set_property( css, attrName, "none" ); + descr = secondary? _("Set stroke color to none") : _("Set fill color to none"); + break; + } +//mark + case ege::PaintDef::RGB: { + Glib::ustring colorspec; + if ( _grad ){ + colorspec = "url(#"; + colorspec += _grad->getId(); + colorspec += ")"; + } else { + gchar c[64]; + guint32 rgba = (def.getR() << 24) | (def.getG() << 16) | (def.getB() << 8) | 0xff; + sp_svg_write_color(c, sizeof(c), rgba); + colorspec = c; + } +//end mark + sp_repr_css_set_property( css, attrName, colorspec.c_str() ); + descr = secondary? _("Set stroke color from swatch") : _("Set fill color from swatch"); + break; } - } else { - cr->set_source_rgb(1, 1, 1); - cr->paint(); - cr->set_source_rgb(1, 0, 0); - cr->set_line_width(3); - cr->move_to(0,0); - cr->line_to(get_allocation().get_width(), get_allocation().get_height()); - cr->move_to(get_allocation().get_width(), 0); - cr->line_to(0, get_allocation().get_height()); - cr->stroke(); } + sp_desktop_set_style(desktop, css); + sp_repr_css_attr_unref(css); + + DocumentUndo::done( sp_desktop_document(desktop), SP_VERB_DIALOG_SWATCHES, descr.c_str() ); } - return true; } -ColorItem::~ColorItem() +void ColorItem::_wireMagicColors( SwatchPage *colorSet ) +{ + if ( colorSet ) + { + for ( boost::ptr_vector::iterator it = colorSet->_colors.begin(); it != colorSet->_colors.end(); ++it ) + { + std::string::size_type pos = it->def.descr.find("*{"); + if ( pos != std::string::npos ) + { + std::string subby = it->def.descr.substr( pos + 2 ); + std::string::size_type endPos = subby.find("}*"); + if ( endPos != std::string::npos ) + { + subby.erase( endPos ); + //g_message("FOUND MAGIC at '%s'", (*it)->def.descr.c_str()); + //g_message(" '%s'", subby.c_str()); + + if ( subby.find('E') != std::string::npos ) + { + it->def.setEditable( true ); + } + + if ( subby.find('L') != std::string::npos ) + { + it->_isLive = true; + } + + std::string part; + // Tint. index + 1 more val. + if ( getBlock( part, 'T', subby ) ) { + guint64 colorIndex = 0; + if ( popVal( colorIndex, part ) ) { + guint64 percent = 0; + if ( popVal( percent, part ) ) { + it->_linkTint( colorSet->_colors[colorIndex], percent ); + } + } + } + + // Shade/tone. index + 1 or 2 more val. + if ( getBlock( part, 'S', subby ) ) { + guint64 colorIndex = 0; + if ( popVal( colorIndex, part ) ) { + guint64 percent = 0; + if ( popVal( percent, part ) ) { + guint64 grayLevel = 0; + if ( !popVal( grayLevel, part ) ) { + grayLevel = 0; + } + it->_linkTone( colorSet->_colors[colorIndex], percent, grayLevel ); + } + } + } + + } + } + } + } +} + + +void ColorItem::_linkTint( ColorItem& other, int percent ) +{ + if ( !_linkSrc ) + { + other._listeners.push_back(this); + _linkIsTone = false; + _linkPercent = percent; + if ( _linkPercent > 100 ) + _linkPercent = 100; + if ( _linkPercent < 0 ) + _linkPercent = 0; + _linkGray = 0; + _linkSrc = &other; + + ColorItem::_colorDefChanged(&other); + } +} + +void ColorItem::_linkTone( ColorItem& other, int percent, int grayLevel ) { - sel_connection.disconnect(); - mod_connection.disconnect(); + if ( !_linkSrc ) + { + other._listeners.push_back(this); + _linkIsTone = true; + _linkPercent = percent; + if ( _linkPercent > 100 ) + _linkPercent = 100; + if ( _linkPercent < 0 ) + _linkPercent = 0; + _linkGray = grayLevel; + _linkSrc = &other; + + ColorItem::_colorDefChanged(&other); + } } } // namespace Dialogs diff --git a/src/ui/dialog/color-item.h b/src/ui/dialog/color-item.h index 5d97d8803..3a0b33193 100644 --- a/src/ui/dialog/color-item.h +++ b/src/ui/dialog/color-item.h @@ -15,11 +15,7 @@ #include #include "widgets/ege-paint-def.h" -#include "widgets/eek-preview.h" -#include -#include -#include "desktop.h" -#include "selection.h" +#include "ui/previewable.h" class SPGradient; @@ -27,43 +23,89 @@ namespace Inkscape { namespace UI { namespace Dialogs { +class ColorItem; + +class SwatchPage +{ +public: + SwatchPage(); + ~SwatchPage(); + + Glib::ustring _name; + int _prefWidth; + boost::ptr_vector _colors; +}; + /** * The color swatch you see on screen as a clickable box. */ -class ColorItem : public Gtk::Widget +class ColorItem : public Inkscape::UI::Previewable { + friend void _loadPaletteFile( gchar const *filename ); public: - ColorItem( SPGradient * grad, const gchar* name, SPDesktop* desktop ); + ColorItem( ege::PaintDef::ColorType type ); + ColorItem( unsigned int r, unsigned int g, unsigned int b, + Glib::ustring& name ); virtual ~ColorItem(); - - SPGradient * getGradient() { return gradient; } - -protected: - - const gchar* def; - SPGradient * gradient; - virtual bool on_enter_notify_event(GdkEventCrossing* event); - virtual bool on_leave_notify_event(GdkEventCrossing* event); - - virtual void on_size_request(Gtk::Requisition* requisition); - virtual void on_size_allocate(Gtk::Allocation& allocation); - virtual void on_map(); - virtual void on_unmap(); - virtual void on_realize(); - virtual void on_unrealize(); - virtual bool on_expose_event(GdkEventExpose* event); - - Glib::RefPtr m_refGdkWindow; - - + ColorItem(ColorItem const &other); + virtual ColorItem &operator=(ColorItem const &other); + virtual Gtk::Widget* getPreview(PreviewStyle style, + ViewType view, + ::PreviewSize size, + guint ratio, + guint border); + void buttonClicked(bool secondary = false); + + void setGradient(SPGradient *grad); + SPGradient * getGradient() const { return _grad; } + void setPattern(cairo_pattern_t *pattern); + void setName(const Glib::ustring name); + + void setState( bool fill, bool stroke ); + bool isFill() { return _isFill; } + bool isStroke() { return _isStroke; } + + ege::PaintDef def; + private: - void selection_changed(Selection* selection); - void selection_modified(Selection* selection, guint flags); - sigc::connection sel_connection; - sigc::connection mod_connection; - bool _isSelected; + static void _dropDataIn( GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data); + + static void _dragGetColorData( GtkWidget *widget, + GdkDragContext *drag_context, + GtkSelectionData *data, + guint info, + guint time, + gpointer user_data); + + static void _wireMagicColors( SwatchPage *colorSet ); + static void _colorDefChanged(void* data); + + void _updatePreviews(); + void _regenPreview(EekPreview * preview); + + void _linkTint( ColorItem& other, int percent ); + void _linkTone( ColorItem& other, int percent, int grayLevel ); + + std::vector _previews; + + bool _isFill; + bool _isStroke; + bool _isLive; + bool _linkIsTone; + int _linkPercent; + int _linkGray; + ColorItem* _linkSrc; + SPGradient* _grad; + cairo_pattern_t *_pattern; + std::vector _listeners; }; } // namespace Dialogs diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 82b2cf6b1..8f36cba43 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -467,6 +467,7 @@ void ObjectProperties::label_changed(void) blocked = true; /* Retrieve the label widget for the object's id */ + //bug 1290573: getId() crashes after undo (cannot create string from NULL ptr) gchar *id = g_strdup(EntryID.get_text().c_str()); g_strcanon (id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); if (!strcmp (id, item->getId())) { diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index ebfa16f02..2095546fb 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -3,6 +3,7 @@ * * Authors: * Theodore Janeczko + * Tweaked by Liam P White for use in Inkscape * * Copyright (C) Theodore Janeczko 2012 * @@ -17,20 +18,31 @@ #include #include #include +#include #include #include "desktop.h" #include "desktop-style.h" +#include "dialogs/dialog-events.h" #include "document.h" #include "document-undo.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" #include "helper/action.h" #include "inkscape.h" +#include "layer-manager.h" #include "preferences.h" +#include "selection.h" +#include "sp-clippath.h" +#include "sp-mask.h" #include "sp-item.h" #include "sp-object.h" +#include "sp-root.h" #include "sp-shape.h" -#include "svg/css-ostringstream.h" +#include "style.h" +#include "tools-switch.h" #include "ui/icon-names.h" #include "ui/widget/imagetoggler.h" #include "ui/widget/layertypeicon.h" @@ -38,29 +50,16 @@ #include "ui/widget/clipmaskicon.h" #include "ui/widget/highlight-picker.h" #include "ui/tools/node-tool.h" +#include "ui/tools/tool-base.h" #include "verbs.h" +#include "widgets/sp-color-notebook.h" #include "widgets/icon.h" #include "xml/node.h" #include "xml/node-observer.h" #include "xml/repr.h" -#include "sp-root.h" -//#include "event-context.h" -#include "selection.h" -#include "dialogs/dialog-events.h" -#include "widgets/sp-color-notebook.h" -#include "style.h" -#include "filter-chemistry.h" -#include "filters/blend.h" -#include "filters/gaussian-blur.h" -#include "sp-clippath.h" -#include "sp-mask.h" -#include "layer-manager.h" -#include "tools-switch.h" //#define DUMP_LAYERS 1 -guint get_group0_keyval(GdkEventKey *event); - namespace Inkscape { namespace UI { namespace Dialog { @@ -82,7 +81,7 @@ enum { COL_VISIBLE = 1, COL_LOCKED, COL_TYPE, - COL_INSERTORDER, +// COL_INSERTORDER, COL_CLIPMASK, COL_HIGHLIGHT }; @@ -106,8 +105,8 @@ enum { BUTTON_LOCK_ALL, BUTTON_UNLOCK_ALL, BUTTON_SETCLIP, - BUTTON_CLIPGROUP, - BUTTON_SETINVCLIP, +// BUTTON_CLIPGROUP, +// BUTTON_SETINVCLIP, BUTTON_UNSETCLIP, BUTTON_SETMASK, BUTTON_UNSETMASK, @@ -214,7 +213,7 @@ public: add(_colType); add(_colHighlight); add(_colClipMask); - add(_colInsertOrder); + //add(_colInsertOrder); } virtual ~ModelColumns() {} @@ -225,7 +224,7 @@ public: Gtk::TreeModelColumn _colType; Gtk::TreeModelColumn _colHighlight; Gtk::TreeModelColumn _colClipMask; - Gtk::TreeModelColumn _colInsertOrder; + //Gtk::TreeModelColumn _colInsertOrder; }; /** @@ -352,13 +351,19 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); Gtk::TreeModel::Row row = *iter; row[_model->_colObject] = item; - row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + //this seems to crash on convert stroke to path then undo (probably no ID?) + try { + row[_model->_colLabel] = item->label() ? item->label() : item->getId(); + } catch (...) { + row[_model->_colLabel] = Glib::ustring("getId_failure"); + g_critical("item->getId() failed, using \"getId_failure\""); + } row[_model->_colVisible] = !item->isHidden(); row[_model->_colLocked] = !item->isSensitive(); row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00; row[_model->_colClipMask] = item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0); - row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; //If our parent object is a group and it's expanded, expand the tree if (SP_IS_GROUP(obj) && SP_GROUP(obj)->expanded()) @@ -388,7 +393,10 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) */ void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { //Find the object in the tree store and update it + + //mark _store->foreach_iter( sigc::bind(sigc::mem_fun(*this, &ObjectsPanel::_checkForUpdated), obj) ); + //end mark if (recurse) { for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) @@ -419,7 +427,7 @@ bool ObjectsPanel::_checkForUpdated(const Gtk::TreeIter& iter, SPObject* obj) row[_model->_colType] = group ? (group->layerMode() == SPGroup::LAYER ? 2 : 1) : 0; row[_model->_colHighlight] = item ? (item->isHighlightSet() ? item->highlight_color() : item->highlight_color() & 0xffffff00) : 0; row[_model->_colClipMask] = item ? (item->clip_ref && item->clip_ref->getObject() ? 1 : (item->mask_ref && item->mask_ref->getObject() ? 2 : 0)) : 0; - row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; + //row[_model->_colInsertOrder] = group ? (group->insertBottom() ? 2 : 1) : 0; return true; } @@ -685,7 +693,9 @@ void ObjectsPanel::_setLockedIter( const Gtk::TreeModel::iterator& iter, const b bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) { - switch (get_group0_keyval(event)) { + bool empty = _desktop->selection->isEmpty(); + + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_F2: @@ -702,68 +712,33 @@ bool ObjectsPanel::_handleKeyEvent(GdkEventKey *event) } break; case GDK_Home: - { //Move item(s) to top of containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_TOP ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_FRONT ); - } - return true; - } + _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT ); + break; case GDK_End: - { //Move item(s) to bottom of containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_TO_BOTTOM ); - } - else - { - _fireAction( SP_VERB_SELECTION_TO_BACK ); - } - return true; - } + _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK ); + break; case GDK_KEY_Page_Up: { //Move item(s) up in containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_RAISE ); - } - else - { - if (event->state & GDK_SHIFT_MASK) { - _fireAction( SP_VERB_LAYER_MOVE_TO_NEXT ); - } else { - _fireAction( SP_VERB_SELECTION_RAISE ); - } - } - return true; + int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_NEXT : SP_VERB_SELECTION_RAISE; + _fireAction( empty ? SP_VERB_LAYER_RAISE : ch ); + break; } case GDK_KEY_Page_Down: { //Move item(s) down in containing group/layer - if (_desktop->selection->isEmpty()) - { - _fireAction( SP_VERB_LAYER_LOWER ); - } - else - { - if (event->state & GDK_SHIFT_MASK) { - _fireAction( SP_VERB_LAYER_MOVE_TO_PREV ); - } else { - _fireAction( SP_VERB_SELECTION_LOWER ); - } - } - return true; + int ch = event->state & GDK_SHIFT_MASK ? SP_VERB_LAYER_MOVE_TO_PREV : SP_VERB_SELECTION_LOWER; + _fireAction( empty ? SP_VERB_LAYER_LOWER : ch ); + break; } + //TODO: Handle Ctrl-A, etc. + default: + return false; } - return false; + return true; } /** @@ -809,7 +784,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) return true; } else if (col == _tree.get_column(COL_LOCKED-1) || col == _tree.get_column(COL_TYPE-1) || - col == _tree.get_column(COL_INSERTORDER - 1) || + //col == _tree.get_column(COL_INSERTORDER - 1) || col == _tree.get_column(COL_HIGHLIGHT-1)) { //Click on an icon column, eat this event to keep row selection return true; @@ -926,7 +901,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, newValue? _("Layer to group") : _("Group to layer")); } - } else if (col == _tree.get_column(COL_INSERTORDER - 1)) { + } /*else if (col == _tree.get_column(COL_INSERTORDER - 1)) { if (SP_IS_GROUP(item)) { //Toggle the current item's insert order @@ -938,7 +913,7 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_OBJECTS, newValue? _("Set insert mode bottom") : _("Set insert mode top")); } - } else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { + }*/ else if (col == _tree.get_column(COL_HIGHLIGHT - 1)) { //Clear the highlight targets _highlight_target.clear(); if (_tree.get_selection()->is_selected(path)) @@ -1474,7 +1449,7 @@ void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) target->setHighlightColor(rgba); target->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); } - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); + DocumentUndo::maybeDone(SP_ACTIVE_DOCUMENT, "highlight", SP_VERB_DIALOG_OBJECTS, _("Set object highlight color")); } /** @@ -1689,13 +1664,13 @@ ObjectsPanel::ObjectsPanel() : col->add_attribute( typeRenderer->property_active(), _model->_colType ); } - //Insert order - Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); + //Insert order (LiamW: unused) + /*Inkscape::UI::Widget::InsertOrderIcon * insertRenderer = Gtk::manage( new Inkscape::UI::Widget::InsertOrderIcon()); int insertColNum = _tree.append_column("type", *insertRenderer) - 1; col = _tree.get_column(insertColNum); if ( col ) { col->add_attribute( insertRenderer->property_active(), _model->_colInsertOrder ); - } + }*/ //Clip/mask Inkscape::UI::Widget::ClipMaskIcon * clipRenderer = Gtk::manage( new Inkscape::UI::Widget::ClipMaskIcon()); @@ -1807,43 +1782,102 @@ ObjectsPanel::ObjectsPanel() : SPDesktop* targetDesktop = getDesktop(); //Set up the button row + + + //Add object/layer Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_ADD, _("New Layer") ); + btn->set_tooltip_text(_("Add layer...")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + Gtk::Image *image_add = Gtk::manage(new Gtk::Image()); + image_add->set_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_add); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_NEW) ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + //Remove object btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_REMOVE, _("Remove") ); + btn->set_tooltip_text(_("Remove object")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + Gtk::Image *image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + //Move to bottom btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GOTO_BOTTOM, _("Move To Bottom") ); + btn->set_tooltip_text(_("Move To Bottom")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-bottom"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_BOTTOM) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - + + //Move down btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GO_DOWN, _("Move Down") ); + btn->set_tooltip_text(_("Move Down")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_DOWN) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + //Move up btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GO_UP, _("Move Up") ); + btn->set_tooltip_text(_("Move Up")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_UP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); + //Move to top btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_GOTO_TOP, _("Move To Top") ); + btn->set_tooltip_text(_("Move To Top")); +#if GTK_CHECK_VERSION(3,10,0) + btn->set_image_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); +#else + image_remove = Gtk::manage(new Gtk::Image()); + image_remove->set_from_icon_name(INKSCAPE_ICON("go-top"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image(*image_remove); +#endif + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_TOP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = Gtk::manage( new Gtk::Button() ); - _styleButton( *btn, GTK_STOCK_UNINDENT, _("Collapse All") ); + //Collapse all + btn = Gtk::manage( new Gtk::Button(Gtk::Stock::UNINDENT) ); + btn->set_tooltip_text(_("Collapse All")); + btn->set_relief(Gtk::RELIEF_NONE); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &ObjectsPanel::_takeAction), (int)BUTTON_COLLAPSE_ALL) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); @@ -2042,15 +2076,6 @@ void ObjectsPanel::setDesktop( SPDesktop* desktop ) //should be okay to put these here because they are never referenced anywhere else using namespace Inkscape::UI::Tools; -guint get_group0_keyval(GdkEventKey *event) { - guint keyval = 0; - gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( - gdk_display_get_default()), event->hardware_keycode, - (GdkModifierType) event->state, 0 /*event->key.group*/, &keyval, - NULL, NULL, NULL); - return keyval; -} - void SPItem::setHighlightColor(guint32 const color) { g_free(_highlightColor); @@ -2065,7 +2090,7 @@ void SPItem::setHighlightColor(guint32 const color) NodeTool *tool = 0; if (SP_ACTIVE_DESKTOP ) { - ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); tools_switch(tool->desktop, TOOLS_NODES); @@ -2079,7 +2104,7 @@ void SPItem::unsetHighlightColor() _highlightColor = NULL; NodeTool *tool = 0; if (SP_ACTIVE_DESKTOP ) { - ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); tools_switch(tool->desktop, TOOLS_NODES); diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 2a8471b55..807618b4d 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -6,7 +6,6 @@ * Jon A. Cruz * John Bintz * Abhishek Sharma - * Theodore Janezcko * * Copyright (C) 2005 Jon A. Cruz * Copyright (C) 2008 John Bintz @@ -21,7 +20,6 @@ #include "swatches.h" #include -#include #include #include @@ -47,6 +45,7 @@ #include "sp-gradient.h" #include "sp-gradient-vector.h" #include "style.h" +#include "ui/previewholder.h" #include "widgets/desktop-widget.h" #include "widgets/gradient-vector.h" #include "widgets/eek-preview.h" @@ -57,2305 +56,1130 @@ #include "verbs.h" #include "gradient-chemistry.h" #include "helper/action.h" -#include "xml/node-observer.h" -#include "xml/repr.h" -#include "sp-pattern.h" -#include "icon-size.h" -#include "widgets/icon.h" -#include "filedialog.h" -#include "sp-stop.h" -#include "svg/svg-color.h" -#include "sp-radial-gradient.h" -#include "color-rgba.h" -#include "ui/tools/tool-base.h" -#include "svg/css-ostringstream.h" -#include -#ifdef WIN32 -#include -#endif - -//lazy! -void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill); +#include "helper/action-context.h" namespace Inkscape { namespace UI { namespace Dialogs { -#define SWATCHES_FILE_NAME "swatches.svg" - -static char* trim( char* str ) { - char* ret = str; - while ( *str && (*str == ' ' || *str == '\t') ) { - str++; - } - ret = str; - while ( *str ) { - str++; - } - str--; - while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { - *str-- = 0; - } - return ret; -} - -static void skipWhitespace( char*& str ) { - while ( *str == ' ' || *str == '\t' ) { - str++; - } -} - -static bool parseNum( char*& str, int& val ) { - val = 0; - while ( '0' <= *str && *str <= '9' ) { - val = val * 10 + (*str - '0'); - str++; - } - bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); - return retval; -} - -static char * SwatchFile; -static SPDocument * SwatchDocument; -static unsigned int page_suffix; - -static void loadPalletFile() -{ - if (!SwatchDocument) { - SwatchFile=g_build_filename(INKSCAPE_PALETTESDIR, _("swatches.svg"), NULL); - SwatchDocument=SPDocument::createNewDoc (SwatchFile, TRUE); - if (!SwatchDocument) { - SwatchDocument = SPDocument::createNewDoc(NULL, TRUE, true); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - } -} - -static void addStop( Inkscape::XML::Node *parent, Glib::ustring const &color, gfloat opacity, gchar const *offset ) -{ -#ifdef SP_GR_VERBOSE - g_message("addStop(%p, %s, %d, %s)", parent, color.c_str(), opacity, offset); -#endif - Inkscape::XML::Node *stop = parent->document()->createElement("svg:stop"); - { - gchar *tmp = g_strdup_printf( "stop-color:%s;stop-opacity:%f;", color.c_str(), opacity < 0.0 ? 0.0 : (opacity > 1.0 ? 1.0 : opacity) ); - stop->setAttribute( "style", tmp ); - g_free(tmp); - } - - stop->setAttribute( "offset", offset ); - - parent->appendChild(stop); - Inkscape::GC::release(stop); -} - -static SPGroup* importGPL(SPDocument* doc, const gchar* full) -{ - SPGroup* ret = NULL; - if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { - - /*Load the pallet file here*/ - char block[1024]; - FILE *f = Inkscape::IO::fopen_utf8name( full, "r" ); - if ( f ) { - char* result = fgets( block, sizeof(block), f ); - if ( result ) { - if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { - bool inHeader = true; - bool hasErr = false; - - Inkscape::XML::Node * page = doc->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (doc->getObjectById(id)); - - page->setAttribute("id", id); - - do { - result = fgets( block, sizeof(block), f ); - block[sizeof(block) - 1] = 0; - if ( result ) { - if ( block[0] == '#' ) { - // ignore comment - } else { - char *ptr = block; - // very simple check for header versus entry - while ( *ptr == ' ' || *ptr == '\t' ) { - ptr++; - } - if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { - // blank line. skip it. - } else if ( '0' <= *ptr && *ptr <= '9' ) { - // should be an entry link - inHeader = false; - ptr = block; - Glib::ustring name(""); - skipWhitespace(ptr); - if ( *ptr ) { - int r = 0; - int g = 0; - int b = 0; - hasErr = parseNum(ptr, r); - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, g); - } - if ( !hasErr ) { - skipWhitespace(ptr); - hasErr = parseNum(ptr, b); - } - if ( !hasErr && *ptr ) { - char* n = trim(ptr); - if (n != NULL) { - name = g_dpgettext2(NULL, "Palette", n); - } - } - if ( !hasErr ) { - // Add the entry now - - Inkscape::XML::Node *grad = doc->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute("inkscape:label", name.c_str()); - grad->setAttribute( "osb:paint", "solid", 0 ); - SPColor color((float)r / 255, (float)g / 255, (float)b / 255); - addStop(grad, color.toString(), 1, "0"); - page->appendChild(grad); - Inkscape::GC::release(grad); - } - } else { - hasErr = true; - } - } else { - if ( !inHeader ) { - // Hmmm... probably bad. Not quite the format we want? - hasErr = true; - } else { - char* sep = strchr(result, ':'); - if ( sep ) { - *sep = 0; - char* val = trim(sep + 1); - char* name = trim(result); - if ( *name ) { - if ( strcmp( "Name", name ) == 0 ) - { - page->setAttribute("inkscape:label", val); - } - } else { - // error - hasErr = true; - } - } else { - // error - hasErr = true; - } - } - } - } - } - } while ( result && !hasErr ); - if ( !hasErr ) { - doc->getDefs()->appendChild(page); - Inkscape::GC::release(page); - SPObject* obj = doc->getObjectByRepr(page); - if (SP_IS_GROUP(obj)) { - ret = SP_GROUP(obj); - } - #if ENABLE_MAGIC_COLORS - ColorItem::_wireMagicColors( onceMore ); - #endif // ENABLE_MAGIC_COLORS - } else { - delete page; - } - } - } - - fclose(f); - } - /* end loading the pallet file*/ - } - return ret; -} - -SwatchesPanel& SwatchesPanel::getInstance() -{ - return *new SwatchesPanel(); -} - -class SwatchesPanel::StopWatcher : public Inkscape::XML::NodeObserver { -public: - StopWatcher(SwatchesPanel* pnl, SPStop* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()) - { - _repr->addObserver(*this); - } - - ~StopWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ){} - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ){} - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj) { - _pnl->_defsChanged( ); - } - } +#define VBLOCK 16 +#define PREVIEW_PIXBUF_WIDTH 128 - SwatchesPanel* _pnl; - SPStop* _obj; - Inkscape::XML::Node* _repr; -}; +void _loadPaletteFile( gchar const *filename, gboolean user=FALSE ); -class SwatchesPanel::GradientWatcher : public Inkscape::XML::NodeObserver { -public: - GradientWatcher(SwatchesPanel* pnl, SPGradient* obj) : - _pnl(pnl), - _obj(obj), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")), - _swatchAttr(g_quark_from_string("osb:paint")) - { - _repr->addObserver(*this); - } - - ~GradientWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch()) { - _pnl->_defsChanged( ); - } - } - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch() ) { - _pnl->_defsChanged( ); - } - } - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &/*child*/, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) - { - if ( _pnl && _obj && _obj->isSwatch() ) { - _pnl->_defsChanged( ); - } - } - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj && ((_obj->isSwatch() && name == _labelAttr) || name == _swatchAttr)) { - _pnl->_defsChanged( ); - } - } - - SwatchesPanel* _pnl; - SPGradient* _obj; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; - GQuark _swatchAttr; -}; - -class SwatchesPanel::SwatchWatcher : public Inkscape::XML::NodeObserver { -public: - SwatchWatcher(SwatchesPanel* pnl, SPObject* obj, bool builtIn) : - _pnl(pnl), - _obj(obj), - _builtIn(builtIn), - _repr(obj->getRepr()), - _labelAttr(g_quark_from_string("inkscape:label")), - _swatchAttr(g_quark_from_string("osb:paint")) - { - _repr->addObserver(*this); - } - - ~SwatchWatcher() { - _repr->removeObserver(*this); - } - - virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj) { - SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); - if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - } - virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) - { - if ( _pnl && _obj) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - virtual void notifyChildOrderChanged( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*old_prev*/, Inkscape::XML::Node */*new_prev*/ ) - { - if ( _pnl && _obj) { - SPObject *childobj = _builtIn ? SwatchDocument->getObjectByRepr(&child) : (_pnl->_currentDocument ? _pnl->_currentDocument->getObjectByRepr(&child) : 0); - if (childobj && ((SP_IS_GRADIENT(childobj) && SP_GRADIENT(childobj)->hasStops()) || SP_IS_GROUP(childobj))) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } - } - virtual void notifyContentChanged( Inkscape::XML::Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} - virtual void notifyAttributeChanged( Inkscape::XML::Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { - if (_pnl && _obj && name == _labelAttr) { - if (_builtIn) { - _pnl->_swatchesChanged( ); - } else { - _pnl->_defsChanged( ); - } - } - } +std::list userSwatchPages; +std::list systemSwatchPages; +static std::map docPalettes; +static std::vector docTrackings; +static std::map docPerPanel; - SwatchesPanel* _pnl; - SPObject* _obj; - bool _builtIn; - Inkscape::XML::Node* _repr; - GQuark _labelAttr; - GQuark _swatchAttr; -}; -class SwatchesPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +class SwatchesPanelHook : public SwatchesPanel { public: - - ModelColumns() - { - add(_colObject); - add(_colLabel); - } - virtual ~ModelColumns() {} - - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; + static void convertGradient( GtkMenuItem *menuitem, gpointer userData ); + static void deleteGradient( GtkMenuItem *menuitem, gpointer userData ); }; -class SwatchesPanel::ModelColumnsDoc : public Gtk::TreeModel::ColumnRecord -{ -public: - - ModelColumnsDoc() - { - add(_colObject); - add(_colLabel); - add(_colPixbuf); +static void handleClick( GtkWidget* /*widget*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(false); } - virtual ~ModelColumnsDoc() {} - - Gtk::TreeModelColumn _colObject; - Gtk::TreeModelColumn _colLabel; - Gtk::TreeModelColumn > _colPixbuf; -}; +} -static void StripChildGroups(Inkscape::XML::Node * node, SPObject* addTo) -{ - for (Inkscape::XML::Node * it = node->firstChild(); it != NULL;) { - if (!strcmp(it->name(), "svg:g")) { - Inkscape::XML::Node * todel = it; - it = it->next(); - node->removeChild(todel); - } else { - it = it->next(); - } +static void handleSecondaryClick( GtkWidget* /*widget*/, gint /*arg1*/, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(true); } - addTo->appendChildRepr(node); } -static void BubbleChildGroups(Inkscape::XML::Node * node, SPObject* addTo) +static GtkWidget* popupMenu = 0; +static GtkWidget *popupSubHolder = 0; +static GtkWidget *popupSub = 0; +static std::vector popupItems; +static std::vector popupExtras; +static ColorItem* bounceTarget = 0; +static SwatchesPanel* bouncePanel = 0; + +static void redirClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) { - std::queue groups; - for (Inkscape::XML::Node * it = node->firstChild(); it != NULL; ) { - if (!strcmp(it->name(), "svg:g")) { - groups.push(it->duplicate(addTo->document->getReprDoc())); - Inkscape::XML::Node * todel = it; - it = it->next(); - node->removeChild(todel); - } else { - it = it->next(); - } - } - addTo->appendChildRepr(node); - while (!groups.empty()) { - Inkscape::XML::Node * it = groups.front(); - groups.pop(); - BubbleChildGroups(it, addTo); - Inkscape::GC::release(it); + if ( bounceTarget ) { + handleClick( GTK_WIDGET(menuitem), bounceTarget ); } } -void SwatchesPanel::_addSwatchButtonClicked(SPGroup* swatch, bool recurse) +static void redirSecondaryClick( GtkMenuItem *menuitem, gpointer /*user_data*/ ) { - if (_currentDocument) { - if (swatch && SP_IS_GROUP(swatch) ) { - Inkscape::XML::Node * copy = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); - if (recurse) { - BubbleChildGroups(copy, _currentDocument->getDefs()); - } else { - StripChildGroups(copy, _currentDocument->getDefs()); - } - Inkscape::GC::release(copy); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); - } + if ( bounceTarget ) { + handleSecondaryClick( GTK_WIDGET(menuitem), 0, bounceTarget ); } } -void SwatchesPanel::_importButtonClicked(bool addToDoc, bool addToBI) +static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) { - if (addToDoc || addToBI) { - //# Get the current directory for finding files - static Glib::ustring open_path; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - if(open_path.empty()) - { - Glib::ustring attr = prefs->getString("/dialogs/open/path"); - if (!attr.empty()) open_path = attr; - } - - //# Test if the open_path directory exists - if (!Inkscape::IO::file_test(open_path.c_str(), - (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) - open_path = ""; - - #ifdef WIN32 - //# If no open path, default to our win32 documents folder - if (open_path.empty()) - { - // The path to the My Documents folder is read from the - // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal" - HKEY key = NULL; - if(RegOpenKeyExA(HKEY_CURRENT_USER, - "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", - 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) - { - WCHAR utf16path[_MAX_PATH]; - DWORD value_type; - DWORD data_size = sizeof(utf16path); - if(RegQueryValueExW(key, L"Personal", NULL, &value_type, - (BYTE*)utf16path, &data_size) == ERROR_SUCCESS) - { - g_assert(value_type == REG_SZ); - gchar *utf8path = g_utf16_to_utf8( - (const gunichar2*)utf16path, -1, NULL, NULL, NULL); - if(utf8path) - { - open_path = Glib::ustring(utf8path); - g_free(utf8path); + if ( gr ) { + bool shown = false; + if ( desktop && desktop->doc() ) { + Inkscape::Selection *selection = sp_desktop_selection( desktop ); + GSList const *items = selection->itemList(); + if (items) { + SPStyle *query = sp_style_new( desktop->doc() ); + int result = objects_query_fillstroke(const_cast(items), query, true); + if ( (result == QUERY_STYLE_MULTIPLE_SAME) || (result == QUERY_STYLE_SINGLE) ) { + // could be pertinent + if (query->fill.isPaintserver()) { + SPPaintServer* server = query->getFillPaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* grad = SP_GRADIENT(server); + if ( grad->isSwatch() && grad->getId() == gr->getId()) { + desktop->_dlg_mgr->showDialog("FillAndStroke"); + shown = true; + } + } } } + sp_style_unref(query); } } - #endif - - //# If no open path, default to our home directory - if (open_path.empty()) - { - open_path = g_get_home_dir(); - open_path.append(G_DIR_SEPARATOR_S); - } - Gtk::Window * parent = SP_ACTIVE_DESKTOP->getToplevel(); - //# Create a dialog - Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = - Inkscape::UI::Dialog::FileOpenDialog::create( - *parent, open_path, - Inkscape::UI::Dialog::SWATCH_TYPES, - _("Select file to open")); - - //# Show the dialog - bool const success = openDialogInstance->show(); - - //# Save the folder the user selected for later - open_path = openDialogInstance->getCurrentDirectory(); - - if (!success) - { - delete openDialogInstance; - return; - } - - //# User selected something. Get name and type - Glib::ustring fileName = openDialogInstance->getFilename(); - - //# We no longer need the file dialog object - delete it - delete openDialogInstance; - openDialogInstance = NULL; - - - if (!fileName.empty()) - { - Glib::ustring newFileName = Glib::filename_to_utf8(fileName); - - if ( newFileName.size() > 0) - fileName = newFileName; - else - g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); - - open_path = Glib::path_get_dirname (fileName); - open_path.append(G_DIR_SEPARATOR_S); - prefs->setString("/dialogs/open/path", open_path); - - SPDocument* importdoc = SPDocument::createNewDoc(fileName.c_str(), true); - Inkscape::XML::Node * page = NULL; - if (importdoc && importdoc->getDefs()) { - if (addToBI) { - page = SwatchDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (SwatchDocument->getObjectById(id)); - - page->setAttribute("id", id); - gchar* name = g_path_get_basename(importdoc->getName()); - page->setAttribute("inkscape:label", name); - g_free(name); - } - - for (SPObject* it = importdoc->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GROUP(it)) { - if (page) { - Inkscape::XML::Node * copy = it->getRepr()->duplicate(SwatchDocument->getReprDoc()); - page->appendChild(copy); - } - if (addToDoc) { - _addSwatchButtonClicked(SP_GROUP(it), false); - } - } - } - if (page) { - SwatchDocument->getDefs()->appendChildRepr(page); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - - importdoc->doUnref(); + if (!shown) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/dialogs/gradienteditor/showlegacy", false)) { + // Legacy gradient dialog + GtkWidget *dialog = sp_gradient_vector_editor_new( gr ); + gtk_widget_show( dialog ); } else { - SPGroup* g = importGPL(addToBI ? SwatchDocument : _currentDocument, fileName.c_str()); - if (addToBI) { - if (addToDoc) { - _addSwatchButtonClicked(g, false); + // Invoke the gradient tool + Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT ); + if ( verb ) { + SPAction *action = verb->get_action( Inkscape::ActionContext( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP ) ); + if ( action ) { + sp_action_perform( action, NULL ); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } else { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add swatches to document")); } } } } } -void SwatchesPanel::SetSelectedFill(SPGradient* swatch) +static void editGradient( GtkMenuItem */*menuitem*/, gpointer /*user_data*/ ) { - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->fill.isSet()) { - if (it->style->fill.isPaintserver()) { - SPPaintServer * server = it->style->getFillPaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = swatch->getRepr(); - if (repr != drepr && grad != swatch) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { - Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); - swatch->appendChildRepr(clone); - Inkscape::GC::release(clone); - } - swatch->setSwatch(); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); - } - } - } else if (it->style->fill.isColor()) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - addStop(swatch->getRepr(), it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); - swatch->setSwatch(); - if (!_noLink.get_active()) { - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + SPDocument *doc = desktop ? desktop->doc() : 0; + if (doc) { + std::string targetName(bounceTarget->def.descr); + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( targetName == grad->getId() ) { + editGradientImpl( desktop, grad ); + break; } } } } } -void SwatchesPanel::SetSelectedStroke(SPGradient* swatch) +void SwatchesPanelHook::convertGradient( GtkMenuItem * /*menuitem*/, gpointer userData ) { - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->stroke.isSet()) { - if (it->style->stroke.isPaintserver()) { - SPPaintServer * server = it->style->getStrokePaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = swatch->getRepr(); - if (repr != drepr && grad != swatch) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - for (SPStop* news = grad->getVector()->getFirstStop(); news != NULL; news = news->getNextStop()) { - Inkscape::XML::Node* clone = news->getRepr()->duplicate(_currentDocument->getReprDoc()); - swatch->appendChildRepr(clone); - Inkscape::GC::release(clone); - } - swatch->setSwatch(); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(swatch), SP_IS_RADIALGRADIENT(swatch) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Gradient Swatch")); - } - } - } else if (it->style->stroke.isColor()) { - while (SPStop* olds = swatch->getFirstStop()) { - olds->deleteObject(); - } - addStop(swatch->getRepr(), it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); - swatch->setSwatch(); - if (!_noLink.get_active()) { - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set Color Swatch")); + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + SPDocument *doc = desktop ? desktop->doc() : 0; + gint index = GPOINTER_TO_INT(userData); + if ( doc && (index >= 0) && (static_cast(index) < popupItems.size()) ) { + Glib::ustring targetName = popupItems[index]; + + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( targetName == grad->getId() ) { + grad->setSwatch(); + DocumentUndo::done(doc, SP_VERB_CONTEXT_GRADIENT, + _("Add gradient stop")); + break; } } } } } -void SwatchesPanel::MoveSwatchDown(SPGradient* swatch) +void SwatchesPanelHook::deleteGradient( GtkMenuItem */*menuitem*/, gpointer /*userData*/ ) { - if (_currentDocument && swatch) { - SPObject* next = swatch->next; - while (next && (!SP_IS_GRADIENT(next) || !(SP_GRADIENT(next)->isSwatch()))) { - next = next->next; - } - if (next) { - Inkscape::XML::Node* repr = swatch->getRepr(); - repr->parent()->changeOrder(repr, next->getRepr()); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Right")); - } + if ( bounceTarget ) { + SwatchesPanel* swp = bouncePanel; + SPDesktop* desktop = swp ? swp->getDesktop() : 0; + sp_gradient_unset_swatch(desktop, bounceTarget->def.descr); } } -void SwatchesPanel::MoveSwatchUp(SPGradient* swatch) +static SwatchesPanel* findContainingPanel( GtkWidget *widget ) { - if (_currentDocument && swatch) { - SPObject* g = NULL; - SPObject* next = swatch->parent->firstChild(); - while (next && next != swatch) { - if (SP_IS_GRADIENT(next) && SP_GRADIENT(next)->isSwatch()) { - g = next; - } - next = next->next; - } - if (g) { - g = g->getPrev(); - Inkscape::XML::Node* repr = swatch->getRepr(); - repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Left")); - } - } -} + SwatchesPanel *swp = 0; -void SwatchesPanel::RemoveSwatch(SPGradient* swatch) -{ - if (_currentDocument) { - if (swatch->isReferenced()) { - Inkscape::XML::Node * repr = swatch->getRepr(); - repr->parent()->removeChild(repr); - _currentDocument->getDefs()->getRepr()->appendChild(repr); - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); - } else { - swatch->deleteObject(false); - } + std::map rawObjects; + for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { + rawObjects[GTK_WIDGET(it->first->gobj())] = it->first; } -} -void SwatchesPanel::_setSelectionSwatch(SPGradient* swatch, bool isStroke) -{ - if (_currentDocument) { - if (swatch) { - if (_noLink.get_active()) { - if (swatch->isSolid()) { - ColorRGBA rgba(swatch->getFirstStop()->getEffectiveColor().toRGBA32(swatch->getFirstStop()->opacity)); - sp_desktop_set_color(_currentDesktop, rgba, false, !isStroke); - } else { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); - - Inkscape::XML::Node * clone = swatch->getRepr()->duplicate(_currentDocument->getReprDoc()); - _currentDocument->getDefs()->appendChildRepr(clone); - SPGradient* grad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - Inkscape::GC::release(clone); - grad->setSwatch(false); - SPGradient* normalized = sp_gradient_ensure_vector_normalized(grad); -// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { -// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); -// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); -// } - sp_desktop_set_style(_currentDesktop, css); - sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); - sp_repr_css_attr_unref (css); - } - } else { - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, isStroke ? "stroke-opacity" : "fill-opacity", "1.0"); - - SPGradient* normalized = sp_gradient_ensure_vector_normalized(swatch); -// for (GSList const * it = _currentDesktop->selection->itemList(); it != NULL; it = it->next) { -// sp_desktop_apply_css_recursive(SP_ITEM(it->data), css, true); -// sp_item_set_gradient(SP_ITEM(it->data), normalized, SP_IS_RADIALGRADIENT(normalized) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, isStroke ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); -// } - sp_desktop_set_style(_currentDesktop, css); - sp_desktop_set_gradient(_currentDesktop, normalized, !isStroke); - sp_repr_css_attr_unref (css); - } - } else { - SPCSSAttr *css = sp_repr_css_attr_new (); - sp_repr_css_set_property (css, isStroke ? "stroke" : "fill", "none"); - sp_desktop_set_style(_currentDesktop, css); - } - if (isStroke) { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item stroke swatch")); - } else { - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Set item fill swatch")); + for (GtkWidget* curr = widget; curr && !swp; curr = gtk_widget_get_parent(curr)) { + if (rawObjects.find(curr) != rawObjects.end()) { + swp = rawObjects[curr]; } } -} - -void SwatchesPanel::_swatchClicked(GdkEventButton* event, SPGradient* swatch) -{ - if (_currentDesktop) { - if (event->button == 3) { - Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi; - - Glib::ustring us = Glib::ustring::compose("%1", swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]")); - mi = Gtk::manage(new Gtk::MenuItem(swatch ? (swatch->label() ? swatch->label() : swatch->getId()) : _("[None]"))); - Gtk::Label* namelbl = dynamic_cast(mi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - mi->show(); - mi->set_sensitive(false); - menu->append(*mi); - - Gtk::SeparatorMenuItem* sep; - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, false)); - mi->show(); - mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setSelectionSwatch), swatch, true)); - mi->show(); - mi->set_sensitive(_currentDesktop && !_currentDesktop->selection->isEmpty()); - menu->append(*mi); - - if (swatch) { - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedFill), swatch)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Set to Selected Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::SetSelectedStroke), swatch)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Left"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchUp), swatch)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Right"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveSwatchDown), swatch)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::RemoveSwatch), swatch)); - mi->show(); - menu->append(*mi); - } - menu->popup(event->button, event->time); - } else if (!_currentDesktop->selection->isEmpty()) { - _setSelectionSwatch(swatch, event->state & GDK_SHIFT_MASK); - } - } + return swp; } -void SwatchesPanel::MoveDown(SPGroup* page) +static void removeit( GtkWidget *widget, gpointer data ) { - if (_currentDocument && page) { - SPObject* next = page->next; - while (next && !SP_IS_GROUP(next)) { - next = next->next; - } - if (next) { - Inkscape::XML::Node* repr = page->getRepr(); - repr->parent()->changeOrder(repr, next->getRepr()); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Down")); - } - } + gtk_container_remove( GTK_CONTAINER(data), widget ); } -void SwatchesPanel::MoveUp(SPGroup* page) -{ - if (_currentDocument && page) { - SPObject* g = NULL; - SPObject* next = page->parent->firstChild(); - while (next && next != page) { - if (SP_IS_GROUP(next)) { - g = next; - } - next = next->next; - } - if (g) { - g = g->getPrev(); - Inkscape::XML::Node* repr = page->getRepr(); - repr->parent()->changeOrder(repr, g ? g->getRepr() : NULL); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Move Swatch Up")); - } - } -} +/* extern'ed from colot-item.cpp */ +gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ); -void SwatchesPanel::Remove(SPGroup* page) +gboolean colorItemHandleButtonPress( GtkWidget* widget, GdkEventButton* event, gpointer user_data ) { - if (_currentDocument && page) { - std::vector toMove; - for(SPObject* obj = page->firstChild(); obj != NULL; obj = obj->next) { - if (SP_IS_GRADIENT(obj)) { - SPGradient* grad = SP_GRADIENT(obj); - if (grad->isReferenced()) { - toMove.push_back(grad->getRepr()); - } + gboolean handled = FALSE; + + if ( event && (event->button == 3) && (event->type == GDK_BUTTON_PRESS) ) { + SwatchesPanel* swp = findContainingPanel( widget ); + + if ( !popupMenu ) { + popupMenu = gtk_menu_new(); + GtkWidget* child = 0; + + //TRANSLATORS: An item in context menu on a colour in the swatches + child = gtk_menu_item_new_with_label(_("Set fill")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(redirClick), + user_data); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + + //TRANSLATORS: An item in context menu on a colour in the swatches + child = gtk_menu_item_new_with_label(_("Set stroke")); + + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(redirSecondaryClick), + user_data); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + + child = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_menu_item_new_with_label(_("Delete")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(SwatchesPanelHook::deleteGradient), + user_data ); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + gtk_widget_set_sensitive( child, FALSE ); + + child = gtk_menu_item_new_with_label(_("Edit...")); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(editGradient), + user_data ); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + popupExtras.push_back(child); + + child = gtk_menu_item_new_with_label(_("Convert")); + gtk_menu_shell_append(GTK_MENU_SHELL(popupMenu), child); + //popupExtras.push_back(child); + //gtk_widget_set_sensitive( child, FALSE ); + { + popupSubHolder = child; + popupSub = gtk_menu_new(); + gtk_menu_item_set_submenu( GTK_MENU_ITEM(child), popupSub ); } + + gtk_widget_show_all(popupMenu); } - while (!toMove.empty()) { - Inkscape::XML::Node * repr = toMove.back(); - toMove.pop_back(); - repr->parent()->removeChild(repr); - _currentDocument->getDefs()->getRepr()->appendChild(repr); - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(false); - } - page->deleteObject(false); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Remove Swatch Group")); - } -} -void SwatchesPanel::AddSelectedFill(SPGroup* page) -{ - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->fill.isSet()) { - if (it->style->fill.isPaintserver()) { - SPPaintServer * server = it->style->getFillPaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - if (_noLink.get_active()) { - Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - clone->setAttribute( "osb:paint", "gradient", 0 ); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else if (grad->isSwatch()) { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); - if (repr->parent() != drepr) { - repr->parent()->removeChild(repr); - drepr->appendChild(repr); - } - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } - } - } else if (it->style->fill.isColor()) { - Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute( "osb:paint", "solid", 0 ); - addStop(grad, it->style->fill.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->fill_opacity.value), "0"); - if (page) { - page->appendChild(grad); - } else { - _currentDocument->getDefs()->appendChild(grad); - } - SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); - Inkscape::GC::release(grad); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_FILL); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); - } + if ( user_data ) { + ColorItem* item = reinterpret_cast(user_data); + bool show = swp && (swp->getSelectedIndex() == 0); + for ( std::vector::iterator it = popupExtras.begin(); it != popupExtras.end(); ++ it) { + gtk_widget_set_sensitive(*it, show); } - } - } -} -void SwatchesPanel::AddSelectedStroke(SPGroup* page) -{ - if (_currentDesktop && _currentDocument) { - SPItem* it = _currentDesktop->selection->singleItem(); - if (it) { - if (it->style->stroke.isSet()) { - if (it->style->stroke.isPaintserver()) { - SPPaintServer * server = it->style->getStrokePaintServer(); - if (SP_IS_GRADIENT(server)) { - SPGradient *grad = SP_GRADIENT(server)->getVector(); - if (_noLink.get_active()) { - Inkscape::XML::Node * clone = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - clone->setAttribute( "osb:paint", "gradient", 0 ); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); + bounceTarget = item; + bouncePanel = swp; + popupItems.clear(); + if ( popupMenu ) { + gtk_container_foreach(GTK_CONTAINER(popupSub), removeit, popupSub); + bool processed = false; + GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); + if ( wdgt ) { + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); + if ( dtw && dtw->desktop ) { + // Pick up all gradients with vectors + const GSList *gradients = (dtw->desktop->doc())->getResourceList("gradient"); + gint index = 0; + for (const GSList *curr = gradients; curr; curr = curr->next) { + SPGradient* grad = SP_GRADIENT(curr->data); + if ( grad->hasStops() && !grad->isSwatch() ) { + //gl = g_slist_prepend(gl, curr->data); + processed = true; + GtkWidget *child = gtk_menu_item_new_with_label(grad->getId()); + gtk_menu_shell_append(GTK_MENU_SHELL(popupSub), child); + + popupItems.push_back(grad->getId()); + g_signal_connect( G_OBJECT(child), + "activate", + G_CALLBACK(SwatchesPanelHook::convertGradient), + GINT_TO_POINTER(index) ); + index++; } - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else if (grad->isSwatch()) { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * clone = repr->duplicate(_currentDocument->getReprDoc()); - if (page) { - page->appendChildRepr(clone); - } else { - _currentDocument->getDefs()->appendChildRepr(clone); - } - SPGradient *newgrad = SP_GRADIENT(_currentDocument->getObjectByRepr(clone)); - - sp_item_set_gradient(it, sp_gradient_ensure_vector_normalized(newgrad), SP_IS_RADIALGRADIENT(newgrad) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - Inkscape::GC::release(clone); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); - } else { - Inkscape::XML::Node * repr = grad->getRepr(); - Inkscape::XML::Node * drepr = page ? page->getRepr() : _currentDocument->getDefs()->getRepr(); - if (repr->parent() != drepr) { - repr->parent()->removeChild(repr); - drepr->appendChild(repr); - } - SP_GRADIENT(_currentDocument->getObjectByRepr(repr))->setSwatch(); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Gradient Swatch")); } + + gtk_widget_show_all(popupSub); } - } else if (it->style->stroke.isColor()) { - Inkscape::XML::Node *grad = _currentDocument->getReprDoc()->createElement("svg:linearGradient"); - grad->setAttribute( "osb:paint", "solid", 0 ); - addStop(grad, it->style->stroke.value.color.toString(), SP_SCALE24_TO_FLOAT(it->style->stroke_opacity.value), "0"); - if (page) { - page->appendChild(grad); - } else { - _currentDocument->getDefs()->appendChild(grad); - } - SPGradient* normalized = sp_gradient_ensure_vector_normalized(SP_GRADIENT(_currentDocument->getObjectByRepr(grad))); - Inkscape::GC::release(grad); - if (!_noLink.get_active()) { - sp_item_set_gradient(it, normalized, SP_GRADIENT_TYPE_LINEAR, Inkscape::FOR_STROKE); - } - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Add Color Swatch")); } + gtk_widget_set_sensitive( popupSubHolder, processed ); + + gtk_menu_popup(GTK_MENU(popupMenu), NULL, NULL, NULL, NULL, event->button, event->time); + handled = TRUE; } } } -} -void SwatchesPanel::_addBIButtonClicked(GdkEventButton* event) -{ - if (popUpImportMenu) { - popUpImportMenu->popup(event->button, event->time); - } + return handled; } -void SwatchesPanel::NewGroupBI() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = SwatchDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (SwatchDocument->getObjectById(id)); - - page->setAttribute("id", id); - - SwatchDocument->getDefs()->appendChild(page); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } -} -void SwatchesPanel::NewGroup() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("New Swatch Group")); +static char* trim( char* str ) { + char* ret = str; + while ( *str && (*str == ' ' || *str == '\t') ) { + str++; } -} - -void SwatchesPanel::SaveAs() -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - - std::vector toMove; - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->isSwatch()) { - toMove.push_back(grad->getRepr()); - } - } - } - while (!toMove.empty()) { - Inkscape::XML::Node* repr = toMove.back(); - toMove.pop_back(); - repr->parent()->removeChild(repr); - page->appendChild(repr); - } - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Save Swatch Group")); + ret = str; + while ( *str ) { + str++; } -} - -void SwatchesPanel::Duplicate(SPGroup* oldpage) -{ - if (_currentDocument) { - Inkscape::XML::Node * page = _currentDocument->getReprDoc()->createElement("svg:g"); - gchar *id=NULL; - do { - g_free(id); - id = g_strdup_printf("page%d", page_suffix++); - } while (_currentDocument->getObjectById(id)); - - page->setAttribute("id", id); - if (oldpage->label()) page->setAttribute("inkscape:label", oldpage->label()); - - for (SPObject *it = oldpage->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->isSwatch()) { - Inkscape::XML::Node * copy = grad->getRepr()->duplicate(_currentDocument->getReprDoc()); - page->appendChild(copy); - Inkscape::GC::release(copy); - } - } - } - _currentDocument->getDefs()->appendChild(page); - DocumentUndo::done(_currentDocument, SP_VERB_DIALOG_SWATCHES, _("Duplicate Swatch Group")); + str--; + while ( str > ret && (( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n') ) { + *str-- = 0; } + return ret; } -void SwatchesPanel::_lblClick(GdkEventButton* event, SPGroup* page) -{ - Gtk::Menu * menu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi; - Glib::ustring us = Glib::ustring::compose("%1", page ? (page->label() ? page->label() : page->getId()) : _("[Base]")); - mi = Gtk::manage(new Gtk::MenuItem(page ? (page->label() ? page->label() : page->getId()) : _("[Base]"))); - Gtk::Label* namelbl = dynamic_cast(mi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - mi->show(); - mi->set_sensitive(false); - menu->append(*mi); - - Gtk::SeparatorMenuItem* sep; - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Fill"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedFill), page)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Add Selected Stroke"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::AddSelectedStroke), page)); - mi->show(); - mi->set_sensitive(_currentDesktop && _currentDesktop->selection->singleItem()); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - if (page) { - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Up"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveUp), page)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Move Down"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::MoveDown), page)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Duplicate"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Duplicate), page)); - mi->show(); - menu->append(*mi); - - sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - menu->append(*sep); - - mi = Gtk::manage(new Gtk::MenuItem(_("Remove"))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::Remove), page)); - mi->show(); - menu->append(*mi); - } else { - mi = Gtk::manage(new Gtk::MenuItem(_("Create New Group"))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); - mi->show(); - menu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Save As New Group"))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::SaveAs)); - mi->show(); - menu->append(*mi); +static void skipWhitespace( char*& str ) { + while ( *str == ' ' || *str == '\t' ) { + str++; } - - menu->popup(event->button, event->time); } -void SwatchesPanel::_defsChanged() -{ - if (_storeDoc) { - _storeDoc->clear(); - } - - while (!docWatchers.empty()) { - Inkscape::XML::NodeObserver* w = docWatchers.back(); - docWatchers.pop_back(); - delete w; - } - - std::vector tableChildren = _insideTable.get_children(); - for (std::vector::iterator c = tableChildren.begin(); c != tableChildren.end(); ++c) { - _insideTable.remove(**c); +static bool parseNum( char*& str, int& val ) { + val = 0; + while ( '0' <= *str && *str <= '9' ) { + val = val * 10 + (*str - '0'); + str++; } - - if (_currentDocument) { - Gtk::EventBox* eb; - Gtk::Label* lbl; - if (_showlabels) { - eb = Gtk::manage(new Gtk::EventBox()); - eb->add_events(Gdk::BUTTON_PRESS_MASK); - eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), NULL)); - - lbl = Gtk::manage(new Gtk::Label(_("[Base]"))); - eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); - } - - ColorItem* item = Gtk::manage(new ColorItem(NULL, _("[None]"), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), NULL)); - item->set_tooltip_text(_("[None]")); - _insideTable.attach( *item, _showlabels ? 1 : 0, _showlabels ? 2 : 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); - - unsigned int i = 1; - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GRADIENT(it)) { - SPGradient* grad = SP_GRADIENT(it); - if (grad->hasStops()) { - - GradientWatcher* w = new GradientWatcher(this, grad); - docWatchers.push_back(w); - - if (grad->isSwatch()) { - - for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { - StopWatcher* sw = new StopWatcher(this, s); - docWatchers.push_back(sw); - } + bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); + return retval; +} - if (_storeDoc) { - Gtk::TreeModel::iterator iter = _storeDoc->append(); - Gtk::TreeModel::Row row = *iter; - row[_modelDoc->_colObject] = grad; - row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); - GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); - row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - } - item = Gtk::manage(new ColorItem(grad, it->label() ? it->label() : it->getId(), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->set_tooltip_text(it->label() ? it->label() : it->getId()); - if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); +void _loadPaletteFile( gchar const *filename, gboolean user/*=FALSE*/ ) +{ + char block[1024]; + FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); + if ( f ) { + char* result = fgets( block, sizeof(block), f ); + if ( result ) { + if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { + bool inHeader = true; + bool hasErr = false; + + SwatchPage *onceMore = new SwatchPage(); + + do { + result = fgets( block, sizeof(block), f ); + block[sizeof(block) - 1] = 0; + if ( result ) { + if ( block[0] == '#' ) { + // ignore comment } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); - } - - i++; - } - } - } - } - - for (SPObject *it = _currentDocument->getDefs()->firstChild(); it != NULL; it = it->next) { - if (SP_IS_GROUP(it)) { - SwatchWatcher* w = new SwatchWatcher(this, it, false); - docWatchers.push_back(w); - - if (_showlabels) { - i += 20 - (i % 20); - eb = Gtk::manage(new Gtk::EventBox()); - eb->add_events(Gdk::BUTTON_PRESS_MASK); - eb->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_lblClick), SP_GROUP(it))); - lbl = Gtk::manage(new Gtk::Label(it->label() ? it->label() : it->getId())); - eb->add(*lbl); - _insideTable.attach( *eb, 0, 1, i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ , 5, 0); - } - - Gtk::TreeModel::iterator rowiter; - - if (_storeDoc) { - rowiter = _storeDoc->append(); - Gtk::TreeModel::Row row = *rowiter; - row[_modelDoc->_colObject] = it; - row[_modelDoc->_colLabel] = it->label() ? it->label() : it->getId(); - } - - for (SPObject *cit = it->firstChild(); cit != NULL; cit = cit->next) { - if (SP_IS_GRADIENT(cit)) { - SPGradient* grad = SP_GRADIENT(cit); - - if (grad->hasStops()) { - - GradientWatcher* w = new GradientWatcher(this, grad); - docWatchers.push_back(w); - - if (grad->isSwatch()) { - - for (SPStop* s = grad->getFirstStop(); s != NULL; s = s->getNextStop()) { - StopWatcher* sw = new StopWatcher(this, s); - docWatchers.push_back(sw); - } - - if (_storeDoc && rowiter) { - Gtk::TreeModel::iterator iter = _storeDoc->append(rowiter->children()); - Gtk::TreeModel::Row row = *iter; - row[_modelDoc->_colObject] = grad; - row[_modelDoc->_colLabel] = grad->label() ? grad->label() : grad->getId(); - GdkPixbuf* pixb = sp_gradient_to_pixbuf (grad, 64, 18); - row[_modelDoc->_colPixbuf] = Glib::wrap(pixb); - - _editDoc.expand_to_path(_storeDoc->get_path(iter)); + char *ptr = block; + // very simple check for header versus entry + while ( *ptr == ' ' || *ptr == '\t' ) { + ptr++; + } + if ( (*ptr == 0) || (*ptr == '\r') || (*ptr == '\n') ) { + // blank line. skip it. + } else if ( '0' <= *ptr && *ptr <= '9' ) { + // should be an entry link + inHeader = false; + ptr = block; + Glib::ustring name(""); + skipWhitespace(ptr); + if ( *ptr ) { + int r = 0; + int g = 0; + int b = 0; + hasErr = parseNum(ptr, r); + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, g); + } + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, b); + } + if ( !hasErr && *ptr ) { + char* n = trim(ptr); + if (n != NULL) { + name = g_dpgettext2(NULL, "Palette", n); + } + } + if ( !hasErr ) { + // Add the entry now + Glib::ustring nameStr(name); + ColorItem* item = new ColorItem( r, g, b, nameStr ); + onceMore->_colors.push_back(item); + } + } else { + hasErr = true; } - - item = Gtk::manage(new ColorItem(grad, cit->label() ? cit->label() : cit->getId(), _currentDesktop)); - item->signal_button_press_event().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_swatchClicked), grad)); - item->set_tooltip_text(cit->label() ? cit->label() : cit->getId()); - if (_showlabels) { - _insideTable.attach( *item, 1 + (i % 20), 2 + (i % 20), i / 20, i / 20 + 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); + } else { + if ( !inHeader ) { + // Hmmm... probably bad. Not quite the format we want? + hasErr = true; } else { - _insideTable.attach( *item, i, i + 1, 0, 1, Gtk::FILL/*|Gtk::EXPAND*/, Gtk::FILL/*|Gtk::EXPAND*/ ); + char* sep = strchr(result, ':'); + if ( sep ) { + *sep = 0; + char* val = trim(sep + 1); + char* name = trim(result); + if ( *name ) { + if ( strcmp( "Name", name ) == 0 ) + { + onceMore->_name = val; + } + else if ( strcmp( "Columns", name ) == 0 ) + { + gchar* endPtr = 0; + guint64 numVal = g_ascii_strtoull( val, &endPtr, 10 ); + if ( (numVal == G_MAXUINT64) && (ERANGE == errno) ) { + // overflow + } else if ( (numVal == 0) && (endPtr == val) ) { + // failed conversion + } else { + onceMore->_prefWidth = numVal; + } + } + } else { + // error + hasErr = true; + } + } else { + // error + hasErr = true; + } } - i++; } } } + } while ( result && !hasErr ); + if ( !hasErr ) { + if (user) + userSwatchPages.push_back(onceMore); + else + systemSwatchPages.push_back(onceMore); +#if ENABLE_MAGIC_COLORS + ColorItem::_wireMagicColors( onceMore ); +#endif // ENABLE_MAGIC_COLORS + } else { + delete onceMore; } } } - } - //_scroller.resize(1,1); - _insideTable.resize(1,1); - _scroller.show_all_children(); - _scroller.queue_draw(); - -} -Gtk::MenuItem* SwatchesPanel::_addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow) -{ - Gtk::MenuItem* mi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId(),1)); - Gtk::Menu* m = NULL; - - Gtk::TreeModel::Row* r; - if (_store) { - Gtk::TreeModel::iterator iter = parentRow ? _store->append(parentRow->children()) : _store->append(); - Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = group; - row[_model->_colLabel] = group->label() ? group->label() : group->getId(); - - if (SP_IS_GROUP(group->parent) && SP_GROUP(group->parent)->expanded()) { - _editBI.expand_to_path(_store->get_path(iter)); - } - r = &row; - } else { - r = NULL; - } - - bool hasswatches = false; - for (SPObject * obj = group->firstChild(); obj != NULL; obj = obj->next) - { - if (SP_IS_GROUP(obj)) { - if (!m) { - m = manage(new Gtk::Menu()); - m->show_all(); - mi->set_submenu(*m); - - Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(_("[All]"))); - basemi->show(); - Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); - if (namelbl) { - namelbl->set_markup(_("[All]")); - } - basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, true)); - m->append(*basemi); - - Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - m->append(*sep); - } - SwatchWatcher* w = new SwatchWatcher(this, obj, true); - rootWatchers.push_back(w); - m->append(*_addSwatchGroup(SP_GROUP(obj), r)); - } else if (SP_IS_GRADIENT(obj)) { - hasswatches = true; - } + fclose(f); } - if (!m) { - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); - } else if (hasswatches) { - Glib::ustring us = Glib::ustring::compose("%1", group->label() ? group->label() : group->getId()); - Gtk::MenuItem* basemi = manage(new Gtk::MenuItem(group->label() ? group->label() : group->getId())); - basemi->show(); - Gtk::Label* namelbl = dynamic_cast(basemi->get_child()); - if (namelbl) { - namelbl->set_markup(us); - } - basemi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_addSwatchButtonClicked), group, false)); - m->prepend(*basemi); - } - mi->show(); - return mi; } -void SwatchesPanel::_swatchesChanged() -{ - while (!rootWatchers.empty()) { - Inkscape::XML::NodeObserver* w = rootWatchers.back(); - rootWatchers.pop_back(); - delete w; - } +static bool +compare_swatch_names(SwatchPage const *a, SwatchPage const *b) { - std::vector menuChildren = popUpMenu->get_children(); - for (std::vector::iterator c = menuChildren.begin(); c != menuChildren.end(); ++c) { - popUpMenu->remove(**c); - } - - if (_store) { - _store->clear(); - } - - Gtk::MenuItem* mi; - - for (SPObject * obj = SwatchDocument->getDefs()->firstChild(); obj != NULL; obj = obj->next) - { - if (SP_IS_GROUP(obj)) { - SwatchWatcher* w = new SwatchWatcher(this, obj, true); - rootWatchers.push_back(w); - popUpMenu->append(*_addSwatchGroup(SP_GROUP(obj), NULL)); - - } - } - Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); - sep->show(); - popUpMenu->append(*sep); - - mi = manage(new Gtk::MenuItem(_("New Swatch Group..."),1)); - mi->signal_activate().connect(sigc::mem_fun(*this, &SwatchesPanel::NewGroup)); - mi->show(); - popUpMenu->append(*mi); - - mi = manage(new Gtk::MenuItem(_("Add Swatch File..."),1)); - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, false)); - mi->show(); - popUpMenu->append(*mi); - - mi = manage(new Gtk::MenuItem(_("Import Swatch File..."),1)); - mi->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), true, true)); - mi->show(); - popUpMenu->append(*mi); + return g_utf8_collate(a->_name.c_str(), b->_name.c_str()) < 0; } -void SwatchesPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ) +static void loadEmUp() { - bool set = false; - - if ( iconName ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - btn.set_relief(Gtk::RELIEF_NONE); - set = true; - } - - if ( desktop ) { - Verb *verb = Verb::get( code ); - if ( verb ) { - SPAction *action = verb->get_action(desktop); - if ( !set && action && action->image ) { - GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); - gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); - set = true; + static bool beenHere = false; + gboolean userPalete = true; + if ( !beenHere ) { + beenHere = true; + + std::list sources; + sources.push_back( profile_path("palettes") ); + sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); + sources.push_back( g_strdup(CREATE_PALETTESDIR) ); + + // Use this loop to iterate through a list of possible document locations. + while (!sources.empty()) { + gchar *dirname = sources.front(); + if ( Inkscape::IO::file_test( dirname, G_FILE_TEST_EXISTS ) + && Inkscape::IO::file_test( dirname, G_FILE_TEST_IS_DIR )) { + GError *err = 0; + GDir *directory = g_dir_open(dirname, 0, &err); + if (!directory) { + gchar *safeDir = Inkscape::IO::sanitizeString(dirname); + g_warning(_("Palettes directory (%s) is unavailable."), safeDir); + g_free(safeDir); + } else { + gchar *filename = 0; + while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { + gchar* lower = g_ascii_strdown( filename, -1 ); +// if ( g_str_has_suffix(lower, ".gpl") ) { + if ( !g_str_has_suffix(lower, "~") ) { + gchar* full = g_build_filename(dirname, filename, NULL); + if ( !Inkscape::IO::file_test( full, G_FILE_TEST_IS_DIR ) ) { + _loadPaletteFile(full, userPalete); + } + g_free(full); + } +// } + g_free(lower); + } + g_dir_close(directory); + } } + + // toss the dirname + g_free(dirname); + sources.pop_front(); + userPalete = false; } } - - btn.set_tooltip_text (fallback); - if ( !set ) { - btn.set_label( fallback ); - } -} + // Sort the list of swatches by name, grouped by user/system + userSwatchPages.sort(compare_swatch_names); + systemSwatchPages.sort(compare_swatch_names); -void SwatchesPanel::_addButtonClicked(GdkEventButton* event) { - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3 || event->button == 1) ) { - if (popUpMenu) { - popUpMenu->popup(event->button, event->time); - } - } } -void SwatchesPanel::NoLinkToggled() { - static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring nolink = Glib::ustring::compose("%1/nolink", _prefs_path); - prefs->setBool(nolink, _noLink.get_active()); -} -bool SwatchesPanel::_handleButtonEvent(GdkEventButton *event) -{ - static unsigned doubleclick = 0; - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _editBI.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnBI) { - // Double click on the Layer name, enable editing - _text_rendererBI->property_editable() = true; - _editBI.set_cursor (path, *_name_columnBI, true); - grab_focus(); - } - } - - return false; +SwatchesPanel& SwatchesPanel::getInstance() +{ + return *new SwatchesPanel(); } -bool SwatchesPanel::_handleKeyEvent(GdkEventKey *event) + +/** + * Constructor + */ +SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : + Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, "", true), + _holder(0), + _clear(0), + _remove(0), + _currentIndex(0), + _currentDesktop(0), + _currentDocument(0) { - switch (Inkscape::UI::Tools::get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter && !_text_rendererBI->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_rendererBI->property_editable() = true; - _editBI.set_cursor(*path, *_name_columnBI, true); - grab_focus(); - return true; + Gtk::RadioMenuItem* hotItem = 0; + _holder = new PreviewHolder(); + _clear = new ColorItem( ege::PaintDef::CLEAR ); + _remove = new ColorItem( ege::PaintDef::NONE ); + if (docPalettes.empty()) { + SwatchPage *docPalette = new SwatchPage(); + + docPalette->_name = "Auto"; + docPalettes[0] = docPalette; + } + + loadEmUp(); + if ( !systemSwatchPages.empty() ) { + SwatchPage* first = 0; + int index = 0; + Glib::ustring targetName; + if ( !_prefs_path.empty() ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + targetName = prefs->getString(_prefs_path + "/palette"); + if (!targetName.empty()) { + if (targetName == "Auto") { + first = docPalettes[0]; + } else { + //index++; + std::vector pages = _getSwatchSets(); + for ( std::vector::iterator iter = pages.begin(); iter != pages.end(); ++iter ) { + if ( (*iter)->_name == targetName ) { + first = *iter; + break; + } + index++; + } } } } - case GDK_KEY_Delete: { - - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_model->_colObject]; - if (obj) { - obj->deleteObject(false); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } + + if ( !first ) { + first = docPalettes[0]; + _currentIndex = 0; + } else { + _currentIndex = index; + } + + _rebuild(); + + Gtk::RadioMenuItem::Group groupOne; + + int i = 0; + std::vector swatchSets = _getSwatchSets(); + for ( std::vector::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { + SwatchPage* curr = *it; + Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); + if ( curr == first ) { + hotItem = single; } - return true; + _regItem( single, 3, i ); + + i++; } - break; } - return false; -} -void SwatchesPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _editBI.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; + if (Glib::ustring(prefsPath) == "/dialogs/swatches") { + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + get_preferred_size(sreq_natural, sreq); +#else + sreq = size_request(); +#endif + int minHeight = 60; + if (sreq.height < minHeight) { + set_size_request(70, minHeight); + } + } - _renameObject(row, new_text); - _text_rendererBI->property_editable() = false; -} + _getContents()->pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET); + _setTargetFillable(_holder); -void SwatchesPanel::_handleEditingCancelled() -{ - _text_rendererBI->property_editable() = false; -} + show_all_children(); -void SwatchesPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && SwatchDocument) { - SPObject* obj = row[_model->_colObject]; - if ( obj ) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); - } - } + restorePanelPrefs(); + if ( hotItem ) { + hotItem->set_active(); } } -void SwatchesPanel::_setCollapsed(SPGroup * group) +SwatchesPanel::~SwatchesPanel() { - group->setExpanded(false); - group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - for (SPObject *iter = group->children; iter != NULL; iter = iter->next) - { - if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + _trackDocument( this, 0 ); + + _documentConnection.disconnect(); + _selChanged.disconnect(); + + if ( _clear ) { + delete _clear; + } + if ( _remove ) { + delete _remove; + } + if ( _holder ) { + delete _holder; } } -void SwatchesPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +void SwatchesPanel::setOrientation(SPAnchorType how) { - Gtk::TreeModel::Row row = *iter; + // Must call the parent class or bad things might happen + Inkscape::UI::Widget::Panel::setOrientation( how ); - SPObject* obj = row[_model->_colObject]; - if (obj && SP_IS_GROUP(obj)) + if ( _holder ) { - if (isexpanded) - { - SP_GROUP(obj)->setExpanded(isexpanded); - obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - } - else - { - _setCollapsed(SP_GROUP(obj)); - } + _holder->setOrientation(SP_ANCHOR_SOUTH); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } -void SwatchesPanel::_deleteButtonClicked() +void SwatchesPanel::setDesktop( SPDesktop* desktop ) { - Gtk::TreeModel::iterator iter = _editBI.get_selection()->get_selected(); - if (iter) { - Gtk::TreeModel::Row row = *iter; - SPObject* obj = row[_model->_colObject]; - if (obj) { - obj->deleteObject(false); - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); + if ( desktop != _currentDesktop ) { + if ( _currentDesktop ) { + _documentConnection.disconnect(); + _selChanged.disconnect(); } - } -} -bool SwatchesPanel::_handleButtonEventDoc(GdkEventButton* event) -{ - static unsigned doubleclick = 0; - - if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { - // TODO - fix to a better is-popup function - Gtk::TreeModel::Path path; - int x = static_cast(event->x); - int y = static_cast(event->y); - if ( _editDoc.get_path_at_pos( x, y, path ) ) { - Gtk::TreeModel::Children::iterator iter = _editDoc.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; - - SPObject* obj = row[_modelDoc->_colObject]; - if (SP_IS_GRADIENT(obj)) { - _swatchClicked(event, SP_GRADIENT(obj)); - } else if (SP_IS_GROUP(obj)) { - _lblClick(event, SP_GROUP(obj)); - } else { - _lblClick(event, NULL); - } - } else { - _lblClick(event, NULL); - } - } - - if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { - doubleclick = 1; - } + _currentDesktop = desktop; - if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { - doubleclick = 0; - Gtk::TreeModel::Path path; - Gtk::TreeViewColumn* col = 0; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - if ( _editDoc.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_columnDoc) { - // Double click on the Layer name, enable editing - _text_rendererDoc->property_editable() = true; - _editDoc.set_cursor (path, *_name_columnDoc, true); - grab_focus(); + if ( desktop ) { + _currentDesktop->selection->connectChanged( + sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + _currentDesktop->selection->connectModified( + sigc::hide(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection)))); + + _currentDesktop->connectToolSubselectionChanged( + sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + + sigc::bound_mem_functor1 first = sigc::mem_fun(*this, &SwatchesPanel::_setDocument); + sigc::slot base2 = first; + sigc::slot slot2 = sigc::hide<0>( base2 ); + _documentConnection = desktop->connectDocumentReplaced( slot2 ); + + _setDocument( desktop->doc() ); + } else { + _setDocument(0); } } - - return false; } -void SwatchesPanel::_deleteButtonClickedDoc() + +class DocTrack { - Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); - if (iter) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_modelDoc->_colObject]; - if (SP_IS_GRADIENT(obj)) { - RemoveSwatch(SP_GRADIENT(obj)); - } else if (SP_IS_GROUP(obj)) { - Remove(SP_GROUP(obj)); +public: + DocTrack(SPDocument *doc, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : + doc(doc->doRef()), + updatePending(false), + lastGradientUpdate(0.0), + gradientRsrcChanged(gradientRsrcChanged), + defsChanged(defsChanged), + defsModified(defsModified) + { + if ( !timer ) { + timer = new Glib::Timer(); + refreshTimer = Glib::signal_timeout().connect( sigc::ptr_fun(handleTimerCB), 33 ); } + timerRefCount++; } -} -bool SwatchesPanel::_handleKeyEventDoc(GdkEventKey *event) -{ - switch (Inkscape::UI::Tools::get_group0_keyval(event)) { - case GDK_KEY_Return: - case GDK_KEY_KP_Enter: - case GDK_KEY_F2: { - Gtk::TreeModel::iterator iter = _editDoc.get_selection()->get_selected(); - if (iter && !_text_rendererDoc->property_editable()) { - Gtk::TreeRow row = *iter; - SPObject * obj = row[_modelDoc->_colObject]; - if (obj) { - Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); - // Edit the layer label - _text_rendererDoc->property_editable() = true; - _editDoc.set_cursor(*path, *_name_columnDoc, true); - grab_focus(); - return true; - } + ~DocTrack() + { + timerRefCount--; + if ( timerRefCount <= 0 ) { + refreshTimer.disconnect(); + timerRefCount = 0; + if ( timer ) { + timer->stop(); + delete timer; + timer = 0; } } - case GDK_KEY_Delete: { - - _deleteButtonClickedDoc(); - return true; + if (doc) { + gradientRsrcChanged.disconnect(); + defsChanged.disconnect(); + defsModified.disconnect(); + doc->doUnref(); + doc = NULL; } - break; } - return false; -} -void SwatchesPanel::_renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name) -{ - if ( row && SwatchDocument) { - SPObject* obj = row[_modelDoc->_colObject]; - if ( obj ) { - gchar const* oldLabel = obj->label(); - if ( !name.empty() && (!oldLabel || name != oldLabel) ) { - obj->setLabel(name.c_str()); - } - } - } -} + static bool handleTimerCB(); -void SwatchesPanel::_handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text) -{ - Gtk::TreeModel::iterator iter = _editDoc.get_model()->get_iter(path); - Gtk::TreeModel::Row row = *iter; + /** + * Checks if update should be queued or executed immediately. + * + * @return true if the update was queued and should not be immediately executed. + */ + static bool queueUpdateIfNeeded(SPDocument *doc); - _renameObjectDoc(row, new_text); - _text_rendererDoc->property_editable() = false; -} + static Glib::Timer *timer; + static int timerRefCount; + static sigc::connection refreshTimer; -void SwatchesPanel::_handleEditingCancelledDoc() -{ - _text_rendererDoc->property_editable() = false; -} + SPDocument *doc; + bool updatePending; + double lastGradientUpdate; + sigc::connection gradientRsrcChanged; + sigc::connection defsChanged; + sigc::connection defsModified; -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool SwatchesPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +private: + DocTrack(DocTrack const &); // no copy + DocTrack &operator=(DocTrack const &); // no assign +}; + +Glib::Timer *DocTrack::timer = 0; +int DocTrack::timerRefCount = 0; +sigc::connection DocTrack::refreshTimer; + +static const double DOC_UPDATE_THREASHOLD = 0.090; + +bool DocTrack::handleTimerCB() { - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - bool _dnd_top = false; - _dnd_into = false; - _dnd_target = SwatchDocument->getDefs()->lastChild(); - Gtk::TreeModel::iterator itersel = _editBI.get_selection()->get_selected(); - if (!itersel) { - return true; - } - Gtk::TreeModel::Row rowsel = *itersel; - _dnd_source = rowsel[_model->_colObject]; + double now = timer->elapsed(); - if (!_dnd_source) { - return true; - } - - if (_editBI.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _editBI.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y < (int)(cell_height * 1/3)) { - Gtk::TreeModel::Path next_path = target_path; - if (next_path.prev()) { - target_path = next_path; - } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_store->iter_is_valid(_store->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - _dnd_top = true; - // Drop into the top level - _dnd_target = NULL; - } - } - } - if (!_dnd_top) { - Gtk::TreeModel::iterator iter = _store->get_iter(target_path); - if (_store->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_model->_colObject]; - if (obj) { - _dnd_target = obj; - } - } + std::vector needCallback; + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->updatePending && ( (now - track->lastGradientUpdate) >= DOC_UPDATE_THREASHOLD) ) { + needCallback.push_back(track); } } - - if (_dnd_source != _dnd_target) { - - Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; - Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); - - if (target_ref != our_ref) { - if (!target_ref) { - target_ref = SwatchDocument->getDefs()->getRepr(); - if (target_ref != our_ref->parent()) { - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else { - our_ref->parent()->changeOrder(our_ref, NULL); - } - } else if (_dnd_into) { - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); - } else { - // Same parent, just move - our_ref->parent()->changeOrder(our_ref, target_ref); - } + + for (std::vector::iterator it = needCallback.begin(); it != needCallback.end(); ++it) { + DocTrack *track = *it; + if ( std::find(docTrackings.begin(), docTrackings.end(), track) != docTrackings.end() ) { // Just in case one gets deleted while we are looping + // Note: calling handleDefsModified will call queueUpdateIfNeeded and thus update the time and flag. + SwatchesPanel::handleDefsModified(track->doc); } - sp_repr_save_file(SwatchDocument->getReprDoc(), SwatchFile, SP_SVG_NS_URI); } return true; } -/* - * Drap and drop within the tree - * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer - */ -bool SwatchesPanel::_handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time) +bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) { - int cell_x = 0, cell_y = 0; - Gtk::TreeModel::Path target_path; - Gtk::TreeView::Column *target_column; - - bool _dnd_top = false; - _dnd_into = false; - _dnd_target = _currentDocument->getDefs()->lastChild(); - Gtk::TreeModel::iterator itersel = _editDoc.get_selection()->get_selected(); - if (!itersel) { - return true; - } - Gtk::TreeModel::Row rowsel = *itersel; - _dnd_source = rowsel[_modelDoc->_colObject]; - - if (!_dnd_source) { - return true; - } - - if (_editDoc.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { - // Are we before, inside or after the drop layer - Gdk::Rectangle rect; - _editDoc.get_background_area (target_path, *target_column, rect); - int cell_height = rect.get_height(); - _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); - if (cell_y < (int)(cell_height * 1/3)) { - Gtk::TreeModel::Path next_path = target_path; - if (next_path.prev()) { - target_path = next_path; + bool deferProcessing = false; + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->doc == doc ) { + double now = timer->elapsed(); + double elapsed = now - track->lastGradientUpdate; + + if ( elapsed < DOC_UPDATE_THREASHOLD ) { + deferProcessing = true; + track->updatePending = true; } else { - // Dragging to the "end" - Gtk::TreeModel::Path up_path = target_path; - up_path.up(); - if (_storeDoc->iter_is_valid(_storeDoc->get_iter(up_path))) { - // Drop into parent - target_path = up_path; - _dnd_into = true; - } else { - _dnd_top = true; - // Drop into the top level - _dnd_target = NULL; - } + track->lastGradientUpdate = now; + track->updatePending = false; } + + break; } - if (!_dnd_top) { - Gtk::TreeModel::iterator iter = _storeDoc->get_iter(target_path); - if (_storeDoc->iter_is_valid(iter)) { - Gtk::TreeModel::Row row = *iter; - SPObject *obj = row[_modelDoc->_colObject]; - if (obj) { - _dnd_target = obj; - if (SP_IS_GRADIENT(obj)) { - _dnd_into = false; - if (SP_IS_GROUP(_dnd_source)) { - _dnd_target = obj->parent; - } - } else if (SP_IS_GROUP(_dnd_source)) { - _dnd_into = false; + } + return deferProcessing; +} + +void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) +{ + SPDocument *oldDoc = NULL; + if (docPerPanel.find(panel) != docPerPanel.end()) { + oldDoc = docPerPanel[panel]; + if (!oldDoc) { + docPerPanel.erase(panel); // Should not be needed, but clean up just in case. + } + } + if (oldDoc != document) { + if (oldDoc) { + docPerPanel[panel] = NULL; + bool found = false; + for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { + found = (it->second == document); + } + if (!found) { + for (std::vector::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ + if ((*it)->doc == oldDoc) { + delete *it; + docTrackings.erase(it); + break; } } } } - } - - if (_dnd_source != _dnd_target) { - - Inkscape::XML::Node *target_ref = _dnd_target ? _dnd_target->getRepr() : NULL; - Inkscape::XML::Node *our_ref = _dnd_source->getRepr(); - - if (target_ref != our_ref) { - if (!target_ref) { - target_ref = _currentDocument->getDefs()->getRepr(); - if (target_ref != our_ref->parent()) { - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else { - our_ref->parent()->changeOrder(our_ref, NULL); + + if (document) { + bool found = false; + for (std::map::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { + found = (it->second == document); + } + docPerPanel[panel] = document; + if (!found) { + sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) ); + sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) ); + sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) ); + + DocTrack *dt = new DocTrack(document, conn1, conn2, conn3); + docTrackings.push_back(dt); + + if (docPalettes.find(document) == docPalettes.end()) { + SwatchPage *docPalette = new SwatchPage(); + docPalette->_name = "Auto"; + docPalettes[document] = docPalette; } - } else if (_dnd_into) { - // Move this inside of the target at the end - our_ref->parent()->removeChild(our_ref); - target_ref->addChild(our_ref, NULL); - } else if (target_ref->parent() != our_ref->parent()) { - // Change in parent, need to remove and add - our_ref->parent()->removeChild(our_ref); - target_ref->parent()->addChild(our_ref, target_ref); - } else { - // Same parent, just move - our_ref->parent()->changeOrder(our_ref, target_ref); } } - DocumentUndo::done( _currentDocument , SP_VERB_DIALOG_SWATCHES, - _("Moved Swatches")); } - - return true; } +void SwatchesPanel::_setDocument( SPDocument *document ) +{ + if ( document != _currentDocument ) { + _trackDocument(this, document); + _currentDocument = document; + handleGradientsChange( document ); + } +} -/** - * Constructor - */ -SwatchesPanel::SwatchesPanel(gchar const* prefsPath, bool showLabels) : - Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_SWATCHES, ""), - _scroller(), - _insideTable(1, 1), - _insideV(), - _insideH(), - _buttonsRow(), - _outsideV(), - _noLink(_("Don't Link")), - _showlabels(showLabels), - _store(0), - _scrollerBI(), - _editBI(), - _buttonsRowBI(), - _editBIV(), - _storeDoc(0), - _scrollerDoc(), - _editDoc(), - _buttonsRowDoc(), - _editDocV(), - _notebook(), - rootWatcher(0), - docWatcher(0), - _currentDesktop(0), - _currentDocument(0) +static void recalcSwatchContents(SPDocument* doc, + boost::ptr_vector &tmpColors, + std::map &previewMappings, + std::map &gradMappings) { - _insideH.pack_start(_insideTable, Gtk::PACK_SHRINK); - if (_showlabels) { - _insideV.pack_start(_insideH, Gtk::PACK_SHRINK); - _scroller.add(_insideV); - } else { - _scroller.property_height_request() = 20; - _scroller.add(_insideH); + std::vector newList; + + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( grad->isSwatch() ) { + newList.push_back(SP_GRADIENT(item->data)); + } } - - popUpMenu = manage( new Gtk::Menu() ); - popUpMenu->show_all_children(); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Add Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked) ); - _buttonsRow.pack_start(*btn, Gtk::PACK_SHRINK); - -// btn = manage( new Gtk::Button() ); -// _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_DISCONNECT, C_("Unlink", "New") ); -// _buttonsRow.pack_end(*btn, Gtk::PACK_SHRINK); - - static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring nolink = Glib::ustring::compose("%1/nolink", prefsPath); - _noLink.set_tooltip_text(_("Don't link swatches")); - _noLink.set_active(prefs->getBool(nolink, false)); - _noLink.signal_toggled().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NoLinkToggled)); - _buttonsRow.pack_end(_noLink, Gtk::PACK_SHRINK); - - _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scroller.set_shadow_type(Gtk::SHADOW_NONE); - - if (_showlabels) { - _outsideV.pack_end(_buttonsRow, Gtk::PACK_SHRINK); - _outsideV.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); - - _notebook.append_page(_outsideV, "Use"); - + + if ( !newList.empty() ) { + std::reverse(newList.begin(), newList.end()); + for ( std::vector::iterator it = newList.begin(); it != newList.end(); ++it ) { - ModelColumnsDoc *zoop = new ModelColumnsDoc(); - _modelDoc = zoop; + SPGradient* grad = *it; - _storeDoc = Gtk::TreeStore::create( *zoop ); + cairo_surface_t *preview = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + PREVIEW_PIXBUF_WIDTH, VBLOCK); + cairo_t *ct = cairo_create(preview); - _editDoc.set_model( _storeDoc ); - _editDoc.set_headers_visible(false); - _editDoc.set_reorderable(true); - _editDoc.enable_model_drag_dest (Gdk::ACTION_MOVE); + Glib::ustring name( grad->getId() ); + ColorItem* item = new ColorItem( 0, 0, 0, name ); - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::mem_fun(*this, &SwatchesPanel::_addButtonClicked)); - _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + cairo_pattern_t *check = ink_cairo_pattern_create_checkerboard(); + cairo_pattern_t *gradient = sp_gradient_create_preview_pattern(grad, PREVIEW_PIXBUF_WIDTH); + cairo_set_source(ct, check); + cairo_paint(ct); + cairo_set_source(ct, gradient); + cairo_paint(ct); - btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClickedDoc))); - _buttonsRowDoc.pack_start(*btn, Gtk::PACK_SHRINK); + cairo_destroy(ct); + cairo_pattern_destroy(gradient); + cairo_pattern_destroy(check); - _pixbuf_rendererDoc = manage(new Gtk::CellRendererPixbuf()); - int pixbufColNum = _editDoc.append_column("Pixbuf", *_pixbuf_rendererDoc) - 1; - _pixbuf_columnDoc = _editDoc.get_column(pixbufColNum); - _pixbuf_columnDoc->add_attribute(_pixbuf_rendererDoc->property_pixbuf(), _modelDoc->_colPixbuf); - - _text_rendererDoc = manage(new Gtk::CellRendererText()); - int nameColNum = _editDoc.append_column("Name", *_text_rendererDoc) - 1; - _name_columnDoc = _editDoc.get_column(nameColNum); - _name_columnDoc->add_attribute(_text_rendererDoc->property_text(), _modelDoc->_colLabel); + cairo_pattern_t *prevpat = cairo_pattern_create_for_surface(preview); + cairo_surface_destroy(preview); - _text_rendererDoc->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditedDoc) ); - _text_rendererDoc->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelledDoc) ); + previewMappings[item] = prevpat; + + tmpColors.push_back(item); + gradMappings[item] = grad; + } + } +} - _editDoc.set_expander_column( *_editDoc.get_column(nameColNum) ); +void SwatchesPanel::handleGradientsChange(SPDocument *document) +{ + SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; + if (docPalette) { + boost::ptr_vector tmpColors; + std::map tmpPrevs; + std::map tmpGrads; + recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); - _editDoc.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); - _editDoc.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEventDoc), false ); - _editDoc.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEventDoc), false ); + for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + it->first->setPattern(it->second); + cairo_pattern_destroy(it->second); + } - _editDoc.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDropDoc), false); + for (std::map::iterator it = tmpGrads.begin(); it != tmpGrads.end(); ++it) { + it->first->setGradient(it->second); + } - _scrollerDoc.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scrollerDoc.set_shadow_type(Gtk::SHADOW_IN); - _scrollerDoc.add(_editDoc); + docPalette->_colors.swap(tmpColors); - _editDocV.pack_start(_scrollerDoc, Gtk::PACK_EXPAND_WIDGET); - _editDocV.pack_end(_buttonsRowDoc, Gtk::PACK_SHRINK); + // Figure out which SwatchesPanel instances are affected and update them. - _notebook.append_page(_editDocV, "Edit"); - } - - { - popUpImportMenu = Gtk::manage(new Gtk::Menu()); - - Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("New Swatch Group..."))); - mi->signal_activate().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::NewGroupBI)); - mi->show(); - popUpImportMenu->append(*mi); - - mi = Gtk::manage(new Gtk::MenuItem(_("Import Swatch File..."))); - mi->signal_activate().connect_notify(sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_importButtonClicked), false, true)); - mi->show(); - popUpImportMenu->append(*mi); - - ModelColumns *zoop = new ModelColumns(); - _model = zoop; - - _store = Gtk::TreeStore::create( *zoop ); - - _editBI.set_model( _store ); - _editBI.set_headers_visible(false); - _editBI.set_reorderable(true); - _editBI.enable_model_drag_dest (Gdk::ACTION_MOVE); - - Gtk::Button* btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_NEW, GTK_STOCK_ADD, _("Import Swatch") ); - btn->signal_button_press_event().connect_notify(sigc::mem_fun(*this, &SwatchesPanel::_addBIButtonClicked)); - _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); - - btn = manage( new Gtk::Button() ); - _styleButton( *btn, SP_ACTIVE_DESKTOP, SP_VERB_LAYER_DELETE, GTK_STOCK_DELETE, _("Delete Swatch") ); - btn->signal_button_press_event().connect_notify( sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_deleteButtonClicked))); - _buttonsRowBI.pack_start(*btn, Gtk::PACK_SHRINK); - - _text_rendererBI = manage(new Gtk::CellRendererText()); - int nameColNum = _editBI.append_column("Name", *_text_rendererBI) - 1; - _name_columnBI = _editBI.get_column(nameColNum); - _name_columnBI->add_attribute(_text_rendererBI->property_text(), _model->_colLabel); - - _text_rendererBI->signal_edited().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEdited) ); - _text_rendererBI->signal_editing_canceled().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleEditingCancelled) ); - - _editBI.set_expander_column( *_editBI.get_column(nameColNum) ); - - _editBI.signal_button_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); - _editBI.signal_button_release_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleButtonEvent), false ); - _editBI.signal_key_press_event().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleKeyEvent), false ); - - _editBI.signal_drag_drop().connect( sigc::mem_fun(*this, &SwatchesPanel::_handleDragDrop), false); - _editBI.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), false)); - _editBI.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &SwatchesPanel::_setExpanded), true)); - - _scrollerBI.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); - _scrollerBI.set_shadow_type(Gtk::SHADOW_IN); - _scrollerBI.add(_editBI); - - _editBIV.pack_start(_scrollerBI, Gtk::PACK_EXPAND_WIDGET); - _editBIV.pack_end(_buttonsRowBI, Gtk::PACK_SHRINK); - - _notebook.append_page(_editBIV, "Edit Built-In"); + for (std::map::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { + if (it->second == document) { + SwatchesPanel* swp = it->first; + std::vector pages = swp->_getSwatchSets(); + SwatchPage* curr = pages[swp->_currentIndex]; + if (curr == docPalette) { + swp->_rebuild(); + } + } } - - _getContents()->pack_end(_notebook, Gtk::PACK_EXPAND_WIDGET); - } else { - //_outsideV.pack_end(_scroller, Gtk::PACK_SHRINK); - _buttonsRow.pack_end(_scroller, Gtk::PACK_EXPAND_WIDGET); - //_getContents()->pack_end(_outsideV, Gtk::PACK_SHRINK); - _getContents()->pack_end(_buttonsRow, Gtk::PACK_SHRINK); } - - loadPalletFile(); - - rootWatcher = new SwatchWatcher(this, SwatchDocument->getDefs(), true); - SwatchDocument->getDefs()->getRepr()->addObserver(*rootWatcher); - _swatchesChanged(); - _insideTable.resize(1,1); } -SwatchesPanel::~SwatchesPanel() +void SwatchesPanel::handleDefsModified(SPDocument *document) { - if (rootWatcher) { - rootWatcher->_repr->removeObserver(*rootWatcher); - delete rootWatcher; + SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; + if (docPalette && !DocTrack::queueUpdateIfNeeded(document) ) { + boost::ptr_vector tmpColors; + std::map tmpPrevs; + std::map tmpGrads; + recalcSwatchContents(document, tmpColors, tmpPrevs, tmpGrads); + + if ( tmpColors.size() != docPalette->_colors.size() ) { + handleGradientsChange(document); + } else { + int cap = std::min(docPalette->_colors.size(), tmpColors.size()); + for (int i = 0; i < cap; i++) { + ColorItem *newColor = &tmpColors[i]; + ColorItem *oldColor = &docPalette->_colors[i]; + if ( (newColor->def.getType() != oldColor->def.getType()) || + (newColor->def.getR() != oldColor->def.getR()) || + (newColor->def.getG() != oldColor->def.getG()) || + (newColor->def.getB() != oldColor->def.getB()) ) { + oldColor->def.setRGB(newColor->def.getR(), newColor->def.getG(), newColor->def.getB()); + } + if (tmpGrads.find(newColor) != tmpGrads.end()) { + oldColor->setGradient(tmpGrads[newColor]); + } + if ( tmpPrevs.find(newColor) != tmpPrevs.end() ) { + oldColor->setPattern(tmpPrevs[newColor]); + } + } + } + + for (std::map::iterator it = tmpPrevs.begin(); it != tmpPrevs.end(); ++it) { + cairo_pattern_destroy(it->second); + } } - - if (docWatcher) { - docWatcher->_repr->removeObserver(*docWatcher); - delete docWatcher; +} + + +std::vector SwatchesPanel::_getSwatchSets() const +{ + std::vector tmp; + if (docPalettes.find(_currentDocument) != docPalettes.end()) { + tmp.push_back(docPalettes[_currentDocument]); } - _documentConnection.disconnect(); - _selChanged.disconnect(); + tmp.insert(tmp.end(), userSwatchPages.begin(), userSwatchPages.end()); + tmp.insert(tmp.end(), systemSwatchPages.begin(), systemSwatchPages.end()); + + return tmp; } -void SwatchesPanel::setDesktop( SPDesktop* desktop ) +void SwatchesPanel::_updateFromSelection() { - Inkscape::UI::Widget::Panel::setDesktop(desktop); - if ( desktop != _currentDesktop ) { - if ( _currentDesktop ) { - _documentConnection.disconnect(); - _selChanged.disconnect(); + SwatchPage *docPalette = (docPalettes.find(_currentDocument) != docPalettes.end()) ? docPalettes[_currentDocument] : 0; + if ( docPalette ) { + Glib::ustring fillId; + Glib::ustring strokeId; + + SPStyle *tmpStyle = sp_style_new( sp_desktop_document(_currentDesktop) ); + int result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_FILL ); + switch (result) { + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: + case QUERY_STYLE_MULTIPLE_SAME: + { + if (tmpStyle->fill.set && tmpStyle->fill.isPaintserver()) { + SPPaintServer* server = tmpStyle->getFillPaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* target = 0; + SPGradient* grad = SP_GRADIENT(server); + + if ( grad->isSwatch() ) { + target = grad; + } else if ( grad->ref ) { + SPGradient *tmp = grad->ref->getObject(); + if ( tmp && tmp->isSwatch() ) { + target = tmp; + } + } + if ( target ) { + //XML Tree being used directly here while it shouldn't be + gchar const* id = target->getRepr()->attribute("id"); + if ( id ) { + fillId = id; + } + } + } + } + break; + } } - _currentDesktop = desktop; + result = sp_desktop_query_style( _currentDesktop, tmpStyle, QUERY_STYLE_PROPERTY_STROKE ); + switch (result) { + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: + case QUERY_STYLE_MULTIPLE_SAME: + { + if (tmpStyle->stroke.set && tmpStyle->stroke.isPaintserver()) { + SPPaintServer* server = tmpStyle->getStrokePaintServer(); + if ( SP_IS_GRADIENT(server) ) { + SPGradient* target = 0; + SPGradient* grad = SP_GRADIENT(server); + if ( grad->isSwatch() ) { + target = grad; + } else if ( grad->ref ) { + SPGradient *tmp = grad->ref->getObject(); + if ( tmp && tmp->isSwatch() ) { + target = tmp; + } + } + if ( target ) { + //XML Tree being used directly here while it shouldn't be + gchar const* id = target->getRepr()->attribute("id"); + if ( id ) { + strokeId = id; + } + } + } + } + break; + } + } + sp_style_unref(tmpStyle); - if ( desktop ) { - //_currentDesktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &SwatchesPanel::_updateFromSelection))); + for ( boost::ptr_vector::iterator it = docPalette->_colors.begin(); it != docPalette->_colors.end(); ++it ) { + ColorItem* item = &*it; + bool isFill = (fillId == item->def.descr); + bool isStroke = (strokeId == item->def.descr); + item->setState( isFill, isStroke ); + } + } +} - _documentConnection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &SwatchesPanel::_setDocument)); +void SwatchesPanel::_handleAction( int setId, int itemId ) +{ + switch( setId ) { + case 3: + { + std::vector pages = _getSwatchSets(); + if ( itemId >= 0 && itemId < static_cast(pages.size()) ) { + _currentIndex = itemId; - _setDocument( desktop, desktop->doc() ); - } else { - _setDocument(0, 0); + if ( !_prefs_path.empty() ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); + } + + _rebuild(); + } } + break; } } -void SwatchesPanel::_setDocument( SPDesktop* desktop, SPDocument *document ) +void SwatchesPanel::_rebuild() { - if ( document != _currentDocument ) { - if (docWatcher) { - docWatcher->_repr->removeObserver(*docWatcher); - delete docWatcher; - docWatcher = NULL; - } - _currentDocument = document; - - if (_currentDocument) { - docWatcher = new SwatchWatcher(this, _currentDocument->getDefs(), false); - _currentDocument->getDefs()->getRepr()->addObserver(*docWatcher); - } - _defsChanged(); + std::vector pages = _getSwatchSets(); + SwatchPage* curr = pages[_currentIndex]; + _holder->clear(); + + if ( curr->_prefWidth > 0 ) { + _holder->setColumnPref( curr->_prefWidth ); } + _holder->freezeUpdates(); + // TODO restore once 'clear' works _holder->addPreview(_clear); + _holder->addPreview(_remove); + for ( boost::ptr_vector::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { + _holder->addPreview(&*it); + } + _holder->thawUpdates(); } } //namespace Dialogs } //namespace UI } //namespace Inkscape -//really lazy! -void sp_desktop_set_gradient(SPDesktop *desktop, SPGradient* gradient, bool fill) -{ - - bool intercepted = false; - - if (gradient->isSolid()) { - ColorRGBA color(gradient->getFirstStop()->getEffectiveColor().toRGBA32(gradient->getFirstStop()->opacity)); - guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]); - gchar b[64]; - sp_svg_write_color(b, sizeof(b), rgba); - SPCSSAttr *css = sp_repr_css_attr_new(); - if (fill) { - sp_repr_css_set_property(css, "fill", b); - Inkscape::CSSOStringStream osalpha; - osalpha << color[3]; - sp_repr_css_set_property(css, "fill-opacity", osalpha.str().c_str()); - } else { - sp_repr_css_set_property(css, "stroke", b); - Inkscape::CSSOStringStream osalpha; - osalpha << color[3]; - sp_repr_css_set_property(css, "stroke-opacity", osalpha.str().c_str()); - } - intercepted = desktop->_set_style_signal.emit(css); - } - - if (!intercepted) { - for (const GSList *it = desktop->selection->itemList(); it != NULL; it = it->next) { - sp_item_set_gradient(SP_ITEM(it->data), gradient, SP_IS_RADIALGRADIENT(gradient) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, !fill ? Inkscape::FOR_STROKE : Inkscape::FOR_FILL); - } - } -} /* Local Variables: diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index cb8f87962..ca4c1687d 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -12,161 +12,64 @@ #include "ui/widget/panel.h" #include "enums.h" -#include "sp-object.h" -#include "sp-item-group.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sp-gradient.h" -#include "xml/node-observer.h" namespace Inkscape { namespace UI { +class PreviewHolder; + namespace Dialogs { +class ColorItem; +class SwatchPage; +class DocTrack; + /** * A panel that displays paint swatches. */ class SwatchesPanel : public Inkscape::UI::Widget::Panel { public: - SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches", bool showLabels = true); + SwatchesPanel(gchar const* prefsPath = "/dialogs/swatches"); virtual ~SwatchesPanel(); - + static SwatchesPanel& getInstance(); + virtual void setOrientation(SPAnchorType how); + virtual void setDesktop( SPDesktop* desktop ); virtual SPDesktop* getDesktop() {return _currentDesktop;} + virtual int getSelectedIndex() {return _currentIndex;} // temporary + protected: + static void handleGradientsChange(SPDocument *document); + + virtual void _updateFromSelection(); + virtual void _handleAction( int setId, int itemId ); + virtual void _setDocument( SPDocument *document ); + virtual void _rebuild(); - virtual void _setDocument( SPDesktop* desktop, SPDocument *document ); + virtual std::vector _getSwatchSets() const; private: - class ModelColumns; - class ModelColumnsDoc; - - class StopWatcher; - class GradientWatcher; - class SwatchWatcher; - SwatchesPanel(SwatchesPanel const &); // no copy SwatchesPanel &operator=(SwatchesPanel const &); // no assign - - void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback ); - - void _setSelectionSwatch(SPGradient* swatchItem, bool isStroke); - - void NoLinkToggled(); - void NewGroup(); - void NewGroupBI(); - void _addBIButtonClicked(GdkEventButton* event); - void Duplicate(SPGroup* page); - void SaveAs(); - void AddSelectedFill(SPGroup* page); - void AddSelectedStroke(SPGroup* page); - void MoveUp(SPGroup* page); - void MoveDown(SPGroup* page); - void Remove(SPGroup* page); - - void SetSelectedFill(SPGradient* swatch); - void SetSelectedStroke(SPGradient* swatch); - void MoveSwatchUp(SPGradient* swatch); - void MoveSwatchDown(SPGradient* swatch); - void RemoveSwatch(SPGradient* swatch); - - void _lblClick(GdkEventButton* event, SPGroup* page); - void _addSwatchButtonClicked(SPGroup* swatch, bool recurse); - void _defsChanged(); - void _importButtonClicked(bool addToDoc, bool addToBI); - void _deleteButtonClicked(); - void _addButtonClicked(GdkEventButton* event); - void _swatchClicked(GdkEventButton* event, SPGradient* swatchItem); - - Gtk::MenuItem* _addSwatchGroup(SPGroup* group, Gtk::TreeModel::Row* parentRow); - void _swatchesChanged(); - - bool _handleButtonEvent(GdkEventButton *event); - bool _handleKeyEvent(GdkEventKey *event); - - void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelled(); - void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); - - void _setCollapsed(SPGroup * group); - void _setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded); - - void _deleteButtonClickedDoc(); - bool _handleButtonEventDoc(GdkEventButton* event); - bool _handleKeyEventDoc(GdkEventKey *event); - - void _handleEditedDoc(const Glib::ustring& path, const Glib::ustring& new_text); - void _handleEditingCancelledDoc(); - void _renameObjectDoc(Gtk::TreeModel::Row row, const Glib::ustring& name); - - bool _handleDragDropDoc(const Glib::RefPtr& context, int x, int y, guint time); - bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); - - Gtk::Menu *popUpMenu; - Gtk::Menu *popUpImportMenu; - - Gtk::ScrolledWindow _scroller; - Gtk::Table _insideTable; - Gtk::VBox _insideV; - Gtk::HBox _insideH; - Gtk::HBox _buttonsRow; - Gtk::VBox _outsideV; - Gtk::CheckButton _noLink; - bool _showlabels; - - SwatchesPanel::ModelColumns* _model; - Glib::RefPtr _store; - - Gtk::CellRendererText *_text_rendererBI; - Gtk::TreeView::Column *_name_columnBI; - Gtk::ScrolledWindow _scrollerBI; - Gtk::TreeView _editBI; - Gtk::HBox _buttonsRowBI; - Gtk::VBox _editBIV; - - SwatchesPanel::ModelColumnsDoc* _modelDoc; - Glib::RefPtr _storeDoc; - - Gtk::CellRendererText *_text_rendererDoc; - Gtk::CellRendererPixbuf *_pixbuf_rendererDoc; - Gtk::TreeView::Column *_name_columnDoc; - Gtk::TreeView::Column *_pixbuf_columnDoc; - Gtk::ScrolledWindow _scrollerDoc; - Gtk::TreeView _editDoc; - Gtk::HBox _buttonsRowDoc; - Gtk::VBox _editDocV; - - Gtk::Notebook _notebook; - - SwatchWatcher* rootWatcher; - std::vector rootWatchers; - - std::vector docWatchers; - SwatchWatcher* docWatcher; + static void _trackDocument( SwatchesPanel *panel, SPDocument *document ); + static void handleDefsModified(SPDocument *document); + + PreviewHolder* _holder; + ColorItem* _clear; + ColorItem* _remove; + int _currentIndex; SPDesktop* _currentDesktop; SPDocument* _currentDocument; - - bool _dnd_into; - SPObject* _dnd_source; - SPObject* _dnd_target; sigc::connection _documentConnection; sigc::connection _selChanged; + + friend class DocTrack; }; } //namespace Dialogs diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 2eba8bb8c..361a54a90 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -358,7 +358,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) { using Inkscape::UI::Dialogs::SwatchesPanel; - dtw->panels = new SwatchesPanel("/embedded/swatches", false); + dtw->panels = new SwatchesPanel("/embedded/swatches" /*false*/); dtw->panels->setOrientation(SP_ANCHOR_SOUTH); #if GTK_CHECK_VERSION(3,0,0) -- cgit v1.2.3 From 232d5c9f3cda7f24f4c3019c3c312f81f8797011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Fri, 14 Mar 2014 01:20:33 -0300 Subject: Small code simplification (bzr r11950.7.1) --- src/ui/tool/path-manipulator.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 1cc075603..f8cc58e3b 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1206,11 +1206,7 @@ bool PathManipulator::isBSpline(bool recalculate){ if(recalculate){ BSplineSteps = this->BSplineGetSteps(); } - bool isBSpline = false; - if(BSplineSteps>0){ - isBSpline = true; - } - return isBSpline; + return BSplineSteps > 0; } // returns the corresponding strength to the position of a handler -- cgit v1.2.3 From ed6364b83dafb3d1b9cbedfa6675817833e9fdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Fri, 14 Mar 2014 01:21:08 -0300 Subject: Adding default argument to PathManipulator::isBSpline. Default argument is used when function is called with missing arguments. The default was chosen to 'true', because it is the safest value in this context. From now on, the function can be called like "_pm.isBSpline()", which is more intuitive. Still, I haven't studied the code enough to determine if this cache behaviour (force the user to think if cache is correct) is appropriate. (bzr r11950.7.2) --- src/ui/tool/path-manipulator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 5186bfc95..594f56ff9 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(bool recalculate); + bool isBSpline(bool recalculate = true); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); -- cgit v1.2.3 From f9d1d1a8a33eee7fd7977361d2d559697f0fb56d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Mar 2014 18:35:31 +0100 Subject: =?UTF-8?q?disabling=20cache=20approach=20for=20isBSpline=20functi?= =?UTF-8?q?on,=20pointed=20by=20Vin=C3=ADcius?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.296) --- src/ui/tool/path-manipulator.cpp | 15 ++++++++------- src/ui/tool/path-manipulator.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index f8cc58e3b..adc70bc38 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -145,7 +145,7 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - isBSpline(true); + isBSpline(/*true*/); } PathManipulator::~PathManipulator() @@ -1201,11 +1201,12 @@ int PathManipulator::BSplineGetSteps(){ } // determines if the trace has bspline effect -bool PathManipulator::isBSpline(bool recalculate){ - static int BSplineSteps = this->BSplineGetSteps(); - if(recalculate){ - BSplineSteps = this->BSplineGetSteps(); - } +bool PathManipulator::isBSpline(/*bool recalculate*/){ + /*static*/ int BSplineSteps = this->BSplineGetSteps(); + // Taking out the static dont need this part + //if(recalculate){ + // BSplineSteps = this->BSplineGetSteps(); + //} return BSplineSteps > 0; } @@ -1282,7 +1283,7 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; - isBSpline(true); + isBSpline(/*true*/); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 594f56ff9..67590832d 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(bool recalculate = true); + bool isBSpline(/*bool recalculate = true*/); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); -- cgit v1.2.3 From eb3102790b3c0eb1ce7131d2c4edceab5978ce88 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Mar 2014 18:38:27 +0100 Subject: simplify the code in isBSpline (bzr r11950.1.297) --- src/ui/tool/path-manipulator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index adc70bc38..3e54acddf 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1202,12 +1202,13 @@ int PathManipulator::BSplineGetSteps(){ // determines if the trace has bspline effect bool PathManipulator::isBSpline(/*bool recalculate*/){ - /*static*/ int BSplineSteps = this->BSplineGetSteps(); // Taking out the static dont need this part + // static int BSplineSteps = this->BSplineGetSteps(); //if(recalculate){ // BSplineSteps = this->BSplineGetSteps(); //} - return BSplineSteps > 0; + //return BSplineSteps > 0; + return this->BSplineGetSteps() > 0; } // returns the corresponding strength to the position of a handler -- cgit v1.2.3 From acc3de4356672491bcdd795fbac6b80ee2faf27d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 17 Mar 2014 00:57:12 +0100 Subject: Fix to solve static var in isBSpline function (bzr r11950.1.298) --- src/ui/tool/path-manipulator.cpp | 21 ++++++++++----------- src/ui/tool/path-manipulator.h | 3 ++- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 3e54acddf..841ab659a 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -145,7 +145,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); _createControlPointsFromGeometry(); - isBSpline(/*true*/); + //Define if the path is BSpline on construction + isBSpline(true); } PathManipulator::~PathManipulator() @@ -664,7 +665,7 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite start = next; } // if we are removing, we readjust the handlers - if(isBSpline(false)){ + if(isBSpline()){ double pos = 0.0000; if(start.prev()){ pos = BSplineHandlePosition(start.prev()->back()); @@ -1201,14 +1202,11 @@ int PathManipulator::BSplineGetSteps(){ } // determines if the trace has bspline effect -bool PathManipulator::isBSpline(/*bool recalculate*/){ - // Taking out the static dont need this part - // static int BSplineSteps = this->BSplineGetSteps(); - //if(recalculate){ - // BSplineSteps = this->BSplineGetSteps(); - //} - //return BSplineSteps > 0; - return this->BSplineGetSteps() > 0; +bool PathManipulator::isBSpline(bool recalculate){ + if(recalculate){ + _is_bspline = this->BSplineGetSteps() > 0; + } + return _is_bspline; } // returns the corresponding strength to the position of a handler @@ -1284,7 +1282,8 @@ void PathManipulator::BSplineNodeHandlesReposition(Node *n){ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) { Geom::PathBuilder builder; - isBSpline(/*true*/); + //Refresh if is bspline some times -think on path change selection, this value get lost + isBSpline(true); for (std::list::iterator spi = _subpaths.begin(); spi != _subpaths.end(); ) { SubpathPtr subpath = *spi; if (subpath->empty()) { diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 67590832d..f15533021 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,7 +106,7 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(/*bool recalculate = true*/); + bool isBSpline(bool recalculate = true); double BSplineHandlePosition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h); Geom::Point BSplineHandleReposition(Handle *h,double pos); @@ -152,6 +152,7 @@ private: bool _show_path_direction; bool _live_outline; bool _live_objects; + bool _is_bspline; Glib::ustring _lpe_key; friend class PathManipulatorObserver; -- cgit v1.2.3 From 95b10e0707ee0e16055d5e514e1d05c929d49b5a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 18 Mar 2014 17:34:31 -0600 Subject: Added in new toy effect "Taper Strokes," readded a missing header file, bugfixes (bzr r13090.1.25) --- src/live_effects/Makefile_insert | 6 +- src/live_effects/effect-enum.h | 3 +- src/live_effects/effect.cpp | 13 +- src/live_effects/lpe-jointype.h | 43 ++ src/live_effects/lpe-taperstroke.cpp | 536 +++++++++++++++++++++++ src/live_effects/lpe-taperstroke.h | 73 ++++ src/live_effects/pathoutlineprovider.h | 766 +++++++++++++++++++++++++++++++++ src/ui/clipboard.cpp | 9 + 8 files changed, 1443 insertions(+), 6 deletions(-) create mode 100755 src/live_effects/lpe-jointype.h create mode 100644 src/live_effects/lpe-taperstroke.cpp create mode 100644 src/live_effects/lpe-taperstroke.h create mode 100755 src/live_effects/pathoutlineprovider.h (limited to 'src') diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 35a85b4aa..b19f417ae 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -92,4 +92,8 @@ ink_common_sources += \ live_effects/lpe-fill-between-many.cpp \ live_effects/lpe-fill-between-many.h \ live_effects/lpe-ellipse_5pts.cpp \ - live_effects/lpe-ellipse_5pts.h + live_effects/lpe-ellipse_5pts.h \ + live_effects/lpe-jointype.cpp \ + live_effects/lpe-jointype.h \ + live_effects/lpe-taperstroke.cpp \ + live_effects/lpe-taperstroke.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 9c76875e9..c53d64699 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -55,7 +55,8 @@ enum EffectType { FILL_BETWEEN_MANY, ELLIPSE_5PTS, BOUNDING_BOX, -// JOIN_TYPE, + JOIN_TYPE, + TAPER_STROKE, INVALID_LPE // This must be last (I made it such that it is not needed anymore I think..., Don't trust on it being last. - johan) }; diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index eac0f79f4..d6840e5b8 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -52,7 +52,8 @@ #include "live_effects/lpe-fill-between-many.h" #include "live_effects/lpe-ellipse_5pts.h" #include "live_effects/lpe-bounding-box.h" -//#include "live_effects/lpe-jointype.h" +#include "live_effects/lpe-jointype.h" +#include "live_effects/lpe-taperstroke.h" #include "xml/node-event-vector.h" #include "sp-object.h" @@ -109,7 +110,8 @@ const Util::EnumData LPETypeData[] = { {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, {TEXT_LABEL, N_("Text label"), "text_label"}, -// {JOIN_TYPE, N_("Join type"), "join_type"}, + {JOIN_TYPE, N_("Join type"), "join_type"}, + {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, #endif /* 0.46 */ {BEND_PATH, N_("Bend"), "bend_path"}, @@ -273,9 +275,12 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case BOUNDING_BOX: neweffect = static_cast ( new LPEBoundingBox(lpeobj) ); break; - /*case JOIN_TYPE: + case JOIN_TYPE: neweffect = static_cast ( new LPEJoinType(lpeobj) ); - break;*/ + break; + case TAPER_STROKE: + neweffect = static_cast ( new LPETaperStroke(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h new file mode 100755 index 000000000..db113c66a --- /dev/null +++ b/src/live_effects/lpe-jointype.h @@ -0,0 +1,43 @@ +/* Authors: + * Liam P White + * + * Copyright (C) 2014 Authors + * + * Released under GNU GPL v2, read the file COPYING for more information + */ +#ifndef INKSCAPE_LPE_JOINTYPE_H +#define INKSCAPE_LPE_JOINTYPE_H + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/point.h" +#include "live_effects/parameter/enum.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEJoinType : public Effect { +public: + LPEJoinType(LivePathEffectObject *lpeobject); + virtual ~LPEJoinType(); + + virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void doOnRemove(SPLPEItem const* lpeitem); + virtual std::vector doEffect_path (std::vector const & path_in); + +private: + LPEJoinType(const LPEJoinType&); + LPEJoinType& operator=(const LPEJoinType&); + + ScalarParam line_width; + EnumParam linecap_type; + EnumParam linejoin_type; + ScalarParam miter_limit; + BoolParam attempt_force_join; + bool was_initialized; +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp new file mode 100644 index 000000000..e6eed3abe --- /dev/null +++ b/src/live_effects/lpe-taperstroke.cpp @@ -0,0 +1,536 @@ +/** + * @file + * Taper Stroke path effect, provided as an alternative to Power Strokes + * for otherwise constant-width paths. + * + * Authors: + * Liam P White + * + * Copyright (C) 2014 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-taperstroke.h" + +// You might need to include other 2geom files. You can add them here: +#include <2geom/path.h> +#include <2geom/shape.h> +#include "pathoutlineprovider.h" +#include "display/curve.h" +#include "svg/svg.h" + +//#include + +#include "knot-holder-entity.h" +#include "knotholder.h" + +namespace Inkscape { +namespace LivePathEffect { + +namespace TpS { + class KnotHolderEntityAttachBegin : public LPEKnotHolderEntity { + public: + KnotHolderEntityAttachBegin(LPETaperStroke * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; + class KnotHolderEntityAttachEnd : public LPEKnotHolderEntity { + public: + KnotHolderEntityAttachEnd(LPETaperStroke * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; +} // TpS + +static const Util::EnumData JoinType[] = { + {LINEJOIN_STRAIGHT, N_("Beveled"), "bevel"}, + {LINEJOIN_ROUND, N_("Rounded"), "round"}, + {LINEJOIN_REFLECTED, N_("Reflected"), "reflected"}, + {LINEJOIN_POINTY, N_("Miter"), "miter"}, + {LINEJOIN_EXTRAPOLATED, N_("Extrapolated"), "extrapolated"} +}; + +static const Util::EnumDataConverter JoinTypeConverter(JoinType, sizeof (JoinType)/sizeof(*JoinType)); + +LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), + attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), + smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.2), + join_type(_("Join type"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), + miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 30.) +{ + /* uncomment the following line to have the original path displayed while the item is selected */ + show_orig_path = true; + _provides_knotholder_entities = true; + + attach_start.param_set_digits(3); + attach_end.param_set_digits(3); + + registerParameter( dynamic_cast(&attach_start) ); + registerParameter( dynamic_cast(&attach_end) ); + registerParameter( dynamic_cast(&smoothing) ); + registerParameter( dynamic_cast(&join_type) ); + registerParameter( dynamic_cast(&miter_limit) ); +} + +LPETaperStroke::~LPETaperStroke() +{ + +} + +unsigned curveOrder (const Geom::Curve* curve_in) +{ + using namespace Geom; + //cast it + const CubicBezier *cbc = dynamic_cast(curve_in); + if (cbc) return 3; + const QuadraticBezier * qbc = dynamic_cast(curve_in); + if (qbc) return 2; + const BezierCurveN<1U> * lbc = dynamic_cast *>(curve_in); + if (lbc) return 1; + //BezierCurveN<0> * dbc = dynamic_cast *> (curve_in); + return 0; +} + +Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_tolerance = 0.01) +{ + Geom::Path path_out = Geom::Path(); + + for (unsigned i = 0; i < path_in.size(); i++) + { + path_out.append(path_in[i]); + if (path_in.size() == 1) + break; + + //determine order of curve + int order = curveOrder(&path_in[i]); + + Geom::Point start_point; + Geom::Point cross_point = path_in[i].finalPoint(); + Geom::Point end_point; + + g_assert(path_in[i].finalPoint() == path_in[i+1].initialPoint()); + + //can you tell that the following expressions have been shaped by + //repeated compiler errors? ;) + switch (order) + { + case 3: + start_point = (dynamic_cast(&path_in[i]))->operator[] (2); + break; + case 2: + start_point = (dynamic_cast(&path_in[i]))->operator[] (1); + break; + case 1: + default: + start_point = path_in[i].initialPoint(); + } + + order = curveOrder(&path_in[i+1]); + + switch (order) + { + case 3: + end_point = (dynamic_cast(&path_in[i+1]))->operator[] (1); + break; + case 2: + end_point = (dynamic_cast(&path_in[i+1]))->operator[] (1); + break; + case 1: + default: + end_point = path_in[i+1].finalPoint(); + } + if (!are_collinear(start_point, cross_point, end_point, smooth_tolerance)) + break; + } + return path_out; +} + +Geom::Curve * subdivide_at(const Geom::Curve* curve_in, Geom::Coord time, bool first) +{ + //the only reason for this function is the lack of a subdivide function in the Curve class. + //you have to cast to Beziers to be able to use subdivide(t) + unsigned order = curveOrder(curve_in); + Geom::Curve* curve_out = curve_in->duplicate(); + switch (order) + { + //these need to be scoped because of the variable 'c' + case 3: + { + Geom::CubicBezier c = first ? (dynamic_cast (curve_out))->subdivide(time).first : + (dynamic_cast (curve_out))->subdivide(time).second; + if (curve_out) delete curve_out; + curve_out = c.duplicate(); + break; + } + case 2: + { + Geom::QuadraticBezier c = first ? (dynamic_cast(curve_out))->subdivide(time).first : + (dynamic_cast(curve_out))->subdivide(time).second; + if (curve_out) delete curve_out; + curve_out = c.duplicate(); + break; + } + case 1: + { + Geom::BezierCurveN<1> c = first ? (dynamic_cast* >(curve_out))->subdivide(time).first : + (dynamic_cast* >(curve_out))->subdivide(time).second; + if (curve_out) delete curve_out; + curve_out = c.duplicate(); + break; + } + } + return curve_out; +} + +Geom::Piecewise > stretch_along(Geom::Piecewise > pwd2_in, Geom::Path pattern, double width); + +Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) +{ + //there is a pretty good chance that people will try to drag the knots + //on top of each other, so block it + + unsigned size = path_in[0].size(); + if (size == return_at_first_cusp(path_in[0]).size()) { + //check to see if the knots were dragged over each other + //if so, reset the end offset + if ( attach_start >= (size - attach_end) ) { + attach_end.param_set_value( size - attach_start ); + } + } + + //don't ever let it be zero + if (attach_start <= 0) { + attach_start.param_set_value( 0.0001 ); + } + if (attach_end <= 0) { + attach_end.param_set_value( 0.0001 ); + } + + /*if (size != return_at_first_cusp(path_in[0]).size()) { //will get to this in a bit + //check to see if either knot was dragged past their allowed amount + volatile unsigned size_p_start = (unsigned)attach_start; + volatile unsigned size_p_end = (unsigned)attach_end; + + //maximum allowed value in either direction is return_at_first_cusp(path_in[0]).size + volatile unsigned allowed_p_start = return_at_first_cusp(path_in[0]).size(); + volatile unsigned allowed_p_end = return_at_first_cusp(path_in[0].reverse()).size(); + + if (size_p_start > allowed_p_start) { + attach_start.param_set_value(allowed_p_start - 0.0001); + } else if (size_p_end > allowed_p_end) { + attach_end.param_set_value(allowed_p_end - 0.0001); + } + }*/ + + //Path::operator () means get point at time t + start_attach_point = return_at_first_cusp(path_in[0])(attach_start); + end_attach_point = return_at_first_cusp(path_in[0].reverse())(attach_end); + Geom::PathVector pathv_out; + + pathv_out = doEffect_simplePath(path_in); + + + //now for the fun stuff. Right? RIGHT? + + //decide on case + + //first case: taper on both sides + if (true/*pathv_out[0].length() != 0.001 && pathv_out[2].length() != 0.001*/) { + Geom::PathVector real_pathv; + + //Construct the pattern + + Geom::PathVector pat_vec = sp_svg_read_pathv("M 1,0 1,1 C 0.5,1 0,0.5 0,0.5 0,0.5 0.5,0 1,0 Z"); + + Geom::Piecewise > pwd2; + pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], 40)); + + real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0]); + + Geom::PathVector sht_path; + sht_path.push_back(pathv_out[1]); + sht_path = Outline::outlinePath_extr(sht_path, 40, LINEJOIN_STRAIGHT, butt_straight, 30); + + real_pathv.push_back(sht_path[0]); + + pat_vec = sp_svg_read_pathv("M 0,0 0,1 C 0.5,1 1,0.5 1,0.5 1,0.5 0.5,0 0,0 Z"); + + pwd2 = Geom::Piecewise > (); + pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], 40)); + real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0].reverse()); + + //clever union + //Geom::Shape shape1 = Geom::sanitize(Geom::PathVector(1, real_pathv[0])); + //Geom::Shape shape2 = Geom::sanitize(Geom::PathVector(1, real_pathv[1])); + //Geom::Shape shape3 = Geom::boolop(shape1, shape2, Geom::BOOLOP_UNION); + + //shape2 = Geom::sanitize(Geom::PathVector(1, real_pathv[2])); + //shape1 = Geom::boolop(shape3, shape2, Geom::BOOLOP_UNION); + + //real_pathv = Geom::desanitize(shape1); + return real_pathv; + } + + return pathv_out; +} + +//in all cases, this should return a PathVector with three elements. +Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & path_in) +{ + unsigned size = path_in[0].size(); + + //do subdivision and get out + unsigned loc = (unsigned)attach_start; + Geom::Curve * curve_start = path_in[0] [loc].duplicate(); + + std::vector pathv_out; + Geom::Path path_out = Geom::Path(); + + Geom::Path trimmed_start = Geom::Path(); + Geom::Path trimmed_end = Geom::Path(); + + for (unsigned i = 0; i < loc; i++) { + trimmed_start.append(path_in[0] [i]); + } + + #define OVERLAP 0.001 + + trimmed_start.append(*subdivide_at(curve_start, (attach_start - loc) + OVERLAP, true)); + curve_start = subdivide_at(curve_start, attach_start - loc, false); + + //special case: path is one segment long + //special case: what if the two knots occupy the same segment? + if ((size == 1) || ( size - unsigned(attach_end) - 1 == loc )) + { + Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_start); + //it is just a dumb segment + //we have to do some shifting here because the value changed when we reduced the length + //of the previous segment. + trimmed_end.append(*subdivide_at(curve_start, t - OVERLAP, false)); + for (unsigned j = (size - attach_end) + 1; j < size; j++) { + trimmed_end.append(path_in[0] [j]); + } + + curve_start = subdivide_at(curve_start, t, true); + path_out.append(*curve_start); + pathv_out.push_back(trimmed_start); + pathv_out.push_back(path_out); + pathv_out.push_back(trimmed_end); + return pathv_out; + } + + pathv_out.push_back(trimmed_start); + + //append almost all of the rest of the path, ignore the curves that the knot is past (we'll get to it in a minute) + path_out.append(*curve_start); + + for (unsigned k = loc + 1; k < (size - unsigned(attach_end)) - 1; k++) { + path_out.append(path_in[0] [k]); + } + + //deal with the last segment in a very similar fashion to the first + loc = size - attach_end; + + Geom::Curve * curve_end = path_in[0] [loc].duplicate(); + + Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); + + trimmed_end.append(*subdivide_at(curve_end, t - OVERLAP, false)); + curve_end = subdivide_at(curve_end, t, true); + + for (unsigned j = (size - attach_end) + 1; j < size; j++) { + trimmed_end.append(path_in[0] [j]); + } + + path_out.append(*curve_end); + pathv_out.push_back(path_out); + + pathv_out.push_back(trimmed_end); + + if (curve_end) delete curve_end; + if (curve_start) delete curve_start; + return pathv_out; +} + + +//most of the below code is verbatim from Pattern Along Path. However, it needed a little +//tweaking to get it to work right in this case. +Geom::Piecewise > stretch_along(Geom::Piecewise > pwd2_in, Geom::Path pattern, double prop_scale) +{ + using namespace Geom; + + // Don't allow empty path parameter: + if ( pattern.empty() ) { + return pwd2_in; + } + +/* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */ + Piecewise > output; + std::vector > > pre_output; + + D2 > patternd2 = make_cuts_independent(pattern.toPwSb()); + Piecewise x0 = Piecewise(patternd2[0]); + Piecewise y0 = Piecewise(patternd2[1]); + OptInterval pattBndsX = bounds_exact(x0); + OptInterval pattBndsY = bounds_exact(y0); + if (pattBndsX && pattBndsY) { + x0 -= pattBndsX->min(); + y0 -= pattBndsY->middle(); + + double xspace = 0; + double noffset = 0; + double toffset = 0; + /*if (prop_units.get_value() && pattBndsY){ + xspace *= pattBndsX->extent(); + noffset *= pattBndsY->extent(); + toffset *= pattBndsX->extent(); + }*/ + + //Prevent more than 90% overlap... + if (xspace < -pattBndsX->extent()*.9) { + xspace = -pattBndsX->extent()*.9; + } + + y0+=noffset; + + std::vector > > paths_in; + paths_in = split_at_discontinuities(pwd2_in); + + for (unsigned idx = 0; idx < paths_in.size(); idx++){ + Geom::Piecewise > path_i = paths_in[idx]; + Piecewise x = x0; + Piecewise y = y0; + Piecewise > uskeleton = arc_length_parametrization(path_i,2,.1); + uskeleton = remove_short_cuts(uskeleton,.01); + Piecewise > n = rot90(derivative(uskeleton)); + n = force_continuity(remove_short_cuts(n,.1)); + + int nbCopies = 0; + double scaling = 1; + nbCopies = 1; + scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); + + double pattWidth = pattBndsX->extent() * scaling; + + if (scaling != 1.0) { + x*=scaling; + } + if ( false ) { + y*=(scaling*prop_scale); + } else { + if (prop_scale != 1.0) y *= prop_scale; + } + x += toffset; + + double offs = 0; + for (int i=0; i > output_piece = compose(uskeleton,x+offs)+y*compose(n,x+offs); + std::vector > > splited_output_piece = split_at_discontinuities(output_piece); + pre_output.insert(pre_output.end(), splited_output_piece.begin(), splited_output_piece.end() ); + }else{ + output.concat(compose(uskeleton,x+offs)+y*compose(n,x+offs)); + } + offs+=pattWidth; + } + } + /*if (false){ + pre_output = fuse_nearby_ends(pre_output, fuse_tolerance); + for (unsigned i=0; icreate( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Start point of the taper"), SP_KNOT_SHAPE_CIRCLE ); + knotholder->add(e); + } + { + KnotHolderEntity *e = new TpS::KnotHolderEntityAttachEnd(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("End point of the taper"), SP_KNOT_SHAPE_CIRCLE ); + knotholder->add(e); + } +} + +namespace TpS { + void KnotHolderEntityAttachBegin::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) + { + using namespace Geom; + + LPETaperStroke* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); + Geom::PathVector pathv = curve->get_pathvector(); + Piecewise > pwd2; + Geom::Path p_in = return_at_first_cusp(pathv[0]); + pwd2.concat(p_in.toPwSb()); + + double t0 = nearest_point(s, pwd2); + lpe->attach_start.param_set_value(t0); + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); + } + void KnotHolderEntityAttachEnd::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) + { + using namespace Geom; + + LPETaperStroke* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); + Geom::PathVector pathv = curve->get_pathvector(); + Piecewise > pwd2; + Geom::Path p_in = return_at_first_cusp(pathv[0].reverse()); + pwd2.concat(p_in.toPwSb()); + + double t0 = nearest_point(s, pwd2); + lpe->attach_end.param_set_value(t0); + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); + } + Geom::Point KnotHolderEntityAttachBegin::knot_get() const + { + LPETaperStroke const * lpe = dynamic_cast (_effect); + return lpe->start_attach_point; + } + Geom::Point KnotHolderEntityAttachEnd::knot_get() const + { + LPETaperStroke const * lpe = dynamic_cast (_effect); + return lpe->end_attach_point; + } +} + + +/* ######################## */ + +} //namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-taperstroke.h b/src/live_effects/lpe-taperstroke.h new file mode 100644 index 000000000..f2fe03533 --- /dev/null +++ b/src/live_effects/lpe-taperstroke.h @@ -0,0 +1,73 @@ +/** @file + * @brief Taper Stroke path effect (meant as a replacement for using Power Strokes for tapering) + */ +/* Authors: + * Liam P White + * Copyright (C) 2014 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_LPE_SKELETON_H +#define INKSCAPE_LPE_SKELETON_H + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/enum.h" +#include "live_effects/parameter/vector.h" + +namespace Inkscape { +namespace LivePathEffect { + +namespace TpS { + // we need a separate namespace to avoid clashes with other LPEs + class KnotHolderEntityAttachBegin; + class KnotHolderEntityAttachEnd; +} + +class LPETaperStroke : public Effect { +public: + LPETaperStroke(LivePathEffectObject *lpeobject); + virtual ~LPETaperStroke(); + + virtual Geom::PathVector doEffect_path (Geom::PathVector const& path_in); + Geom::PathVector doEffect_simplePath(Geom::PathVector const& path_in); + + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); + + friend class TpS::KnotHolderEntityAttachBegin; + friend class TpS::KnotHolderEntityAttachEnd; +private: + ScalarParam attach_start; + ScalarParam attach_end; + ScalarParam smoothing; + EnumParam join_type; + ScalarParam miter_limit; + + Geom::Point start_attach_point; + Geom::Point end_attach_point; + + LPETaperStroke(const LPETaperStroke&); + LPETaperStroke& operator=(const LPETaperStroke&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +//because Windoze is stupid +# ifdef WIN32 +# include "lpe-taperstroke.cpp" +# endif + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h new file mode 100755 index 000000000..8aa2e38ad --- /dev/null +++ b/src/live_effects/pathoutlineprovider.h @@ -0,0 +1,766 @@ +#pragma once + +#include <2geom/path.h> +#include <2geom/circle.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/shape.h> +#include <2geom/transforms.h> +#include <2geom/path-sink.h> + +#include +#include + +enum LineJoinType { + LINEJOIN_STRAIGHT, + LINEJOIN_ROUND, + LINEJOIN_POINTY, + LINEJOIN_REFLECTED, + LINEJOIN_EXTRAPOLATED +}; + +namespace Geom +{ + /** + * Refer to: Weisstein, Eric W. "Circle-Circle Intersection." + From MathWorld--A Wolfram Web Resource. + http://mathworld.wolfram.com/Circle-CircleIntersection.html + * + * @return 0 if no intersection + * @return 1 if one circle is contained in the other + * @return 2 if intersections are found (they are written to p0 and p1) + */ + static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, + Point & p0, Point & p1) + { + Point X0 = circle0.center(); + double r0 = circle0.ray(); + Point X1 = circle1.center(); + double r1 = circle1.ray(); + + /* dx and dy are the vertical and horizontal distances between + * the circle centers. + */ + Point D = X1 - X0; + + /* Determine the straight-line distance between the centers. */ + double d = L2(D); + + /* Check for solvability. */ + if (d > (r0 + r1)) + { + /* no solution. circles do not intersect. */ + return 0; + } + if (d <= fabs(r0 - r1)) + { + /* no solution. one circle is contained in the other */ + return 1; + } + + /* 'point 2' is the point where the line through the circle + * intersection points crosses the line between the circle + * centers. + */ + + /* Determine the distance from point 0 to point 2. */ + double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; + + /* Determine the coordinates of point 2. */ + Point p2 = X0 + D * (a/d); + + /* Determine the distance from point 2 to either of the + * intersection points. + */ + double h = std::sqrt((r0*r0) - (a*a)); + + /* Now determine the offsets of the intersection points from + * point 2. + */ + Point r = (h/d)*rot90(D); + + /* Determine the absolute intersection points. */ + p0 = p2 + r; + p1 = p2 - r; + + return 2; + } + /** + * Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t. + * Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt). + */ + static Circle touching_circle( D2 const &curve, double t, double tol=0.01 ) + { + D2 dM=derivative(curve); + if ( are_near(L2sq(dM(t)),0.) ) { + dM=derivative(dM); + } + if ( are_near(L2sq(dM(t)),0.) ) { // try second time + dM=derivative(dM); + } + Piecewise > unitv = unitVector(dM,tol); + Piecewise dMlength = dot(Piecewise >(dM),unitv); + Piecewise k = cross(derivative(unitv),unitv); + k = divide(k,dMlength,tol,3); + double curv = k(t); // note that this value is signed + + Geom::Point normal = unitTangentAt(curve, t).cw(); + double radius = 1/curv; + Geom::Point center = curve(t) + radius*normal; + return Geom::Circle(center, fabs(radius)); + } + + static std::vector split_at_cusps(const Geom::Path& in) + { + Geom::PathVector out = Geom::PathVector(); + Geom::Path temp = Geom::Path(); + + for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) + { + temp = Geom::Path(); + temp.append(in[path_descr]); + out.push_back(temp); + } + + return out; + } + + static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) + { + std::vector temp; + sbasis_to_bezier(temp, sbasis_in, 4); + return Geom::CubicBezier( temp ); + } + + static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, + Geom::Point const & origin_b, Geom::Point const & vector_b) + { + Geom::Coord denom = cross(vector_b, vector_a); + if (!Geom::are_near(denom,0.)){ + Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom; + return origin_a + t * vector_a; + } + return boost::none; + } +} + +namespace Outline +{ + + typedef Geom::D2 D2SB; + typedef Geom::Piecewise PWD2; + + static void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve*cbc2, Geom::Point endPt, double miter_limit) +{ + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + if (cross.empty()) + { + Geom::Path pth; + pth.append(*cbc1); + + Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); + + pth = Geom::Path(); + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + + Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.); + Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0); + + Geom::Point points[2]; + int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]); + if (solutions == 2) + { + Geom::Point sol(0,0); + if ( dot(tang2,points[0]-endPt) > 0 ) + { + // points[0] is bad, choose points[1] + sol = points[1]; + } + else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1] + // points[1] is bad, choose points[0] + sol = points[0]; + } + else + { + // both points are good, choose nearest + sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? + points[0] : points[1]; + } + Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true); + Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true); + + if (arc0) + { + path_builder.append (arc0->toSBasis()); + delete arc0; + arc0 = NULL; + } + + if (arc1) + { + path_builder.append (arc1->toSBasis()); + delete arc1; + arc1 = NULL; + } + } + else + { + path_builder.appendNew (endPt); + } + } + else + { + path_builder.appendNew (endPt); + } +} + static Geom::Path half_outline_extrp(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) + { + Geom::PathVector pv = split_at_cusps(path_in); + unsigned m; + Path path_outline = Path(); + Path path_tangent = Path(); + + Geom::Point initialPoint; + Geom::Point endPoint; + + Geom::Path path_builder = Geom::Path(); + Geom::PathVector * pathvec; + + //load the first portion in before the loop starts + { + path_outline = Path(); + path_outline.LoadPath(pv[0], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + //now half of first cusp has been loaded + + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + //instead of array accessing twice, dereferencing used for clarity + initialPoint = (*pathvec)[0].initialPoint(); + + path_builder.start(initialPoint); + path_builder.append( (*pathvec)[0] ); + + path_outline = Path(); + path_outline.LoadPath(pv[1], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + + path_builder.append( (*pathvec)[0] ); + + //always set pointers null after deleting + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + for (m = 2; m < pv.size(); m++) + { + path_outline = Path(); + path_outline.LoadPath(pv[m], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + path_builder.append( (*pathvec)[0] ); + + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + return path_builder; + } + + //Create a reflected outline join. + //Note: it is generally recommended to let half_outline do this for you! + //path_builder: the path to append the curves to + //cbc1: the curve before the join + //cbc2: the curve after the join + //endPt: the point to end at + //miter_limit: the miter parameter + static void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit) + { + //the most important work for the reflected join is done here + + //determine where we are in the path. If we're on the inside, ignore + //and just lineTo. On the outside, we'll do a little reflection magic :) + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + if (cross.empty()) + { + //probably on the outside of the corner + Geom::Path pth; + pth.append(*cbc1); + + Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); + + //reflect curves along the bevel + D2SB newcurve1 = pth.toPwSb()[0] * + Geom::reflection ( -Geom::rot90(tang1) , + cbc1->finalPoint() ); + + Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1)); + + pth = Geom::Path(); + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + D2SB newcurve2 = pth.toPwSb()[0] * + Geom::reflection ( -Geom::rot90(tang2) , + cbc2->initialPoint() ); + Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2)); + + cross = Geom::crossings(bzr1, bzr2); + if ( cross.empty() ) + { + //std::cout << "Oops, no crossings!" << std::endl; + //curves didn't cross; default to miter + /*boost::optional p = intersection_point (cbc1->finalPoint(), tang1, + cbc2->initialPoint(), tang2); + if (p) + { + path_builder.appendNew (*p); + }*/ + //bevel + path_builder.appendNew( endPt ); + } + else + { + //join + std::pair sub1 = bzr1.subdivide(cross[0].ta); + std::pair sub2 = bzr2.subdivide(cross[0].tb); + + //@TODO joins have a strange tendency to cross themselves twice. Check this. + + //sections commented out are for general stability + path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); + path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); + } + } + else // cross.empty() + { + //probably on the inside of the corner + path_builder.appendNew ( endPt ); + } + } + + /** @brief Converts a path to one half of an outline. + * path_in: The input path to use. (To create the other side use path_in.reverse() ) + * line_width: the line width to use (usually you want to divide this by 2) + * linecap_type: (not used here) the cap to apply. Passed to libvarot. + * miter_limit: the miter parameter + */ + static Geom::Path half_outline(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) + { + Geom::PathVector pv = split_at_cusps(path_in); + unsigned m; + Path path_outline = Path(); + Path path_tangent = Path(); + //needed for closing the path + Geom::Point initialPoint; + Geom::Point endPoint; + + //some issues prevented me from using a PathBuilder here + //it seems like PathBuilder::peek() gave me a null reference exception + //and I was unable to get a stack trace on Windows, so had to switch to Linux + //to see what the hell was wrong. :( + //I wasted five hours opening it in IDAPro, VS2012, and GDB Windows + + /*Program received signal SIGSEGV, Segmentation fault. + 0x00000000006539ac in get_curves (this=0x0) + at /usr/include/c++/4.6/bits/locale_facets.h:1077 + 1077 { return __c; } + */ + + Geom::Path path_builder = Geom::Path(); + Geom::PathVector * pathvec; + + //load the first portion in before the loop starts + { + path_outline = Path(); + path_outline.LoadPath(pv[0], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + //now half of first cusp has been loaded + + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + //instead of array accessing twice, dereferencing used for clarity + initialPoint = (*pathvec)[0].initialPoint(); + + path_builder.start(initialPoint); + path_builder.append( (*pathvec)[0] ); + + path_outline = Path(); + path_outline.LoadPath(pv[1], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + + path_builder.append( (*pathvec)[0] ); + + //always set pointers null after deleting + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + for (m = 2; m < pv.size(); m++) + { + path_outline = Path(); + path_outline.LoadPath(pv[m], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + path_builder.append( (*pathvec)[0] ); + + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + return path_builder; + } + + static Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim) + { + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + Geom::PathVector path_out; + for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) + { + if (path_in[lmnop].size() > 1) + { + Geom::Path p_init; + Geom::Path p_rev; + Geom::PathBuilder pb = Geom::PathBuilder(); + + if ( !path_in[lmnop].closed() ) + { + p_init = Outline::half_outline( path_in[lmnop], -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline( path_in[lmnop].reverse(), -line_width, butt, + miter_lim ); + + pb.moveTo(p_init.initialPoint() ); + pb.append(p_init); + + //cap + if (butt == butt_straight) { + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } + + pb.append(p_rev); + + if (butt == butt_straight) { + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); + //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); + + pb.lineTo(p_init.initialPoint() ); + } + } + else + { + //final join + //refer to half_outline for documentation + Geom::Path p_almost = path_in[lmnop]; + p_almost.appendNew ( path_in[lmnop].initialPoint() ); + p_init = Outline::half_outline( p_almost, -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline( p_almost.reverse(), -line_width, butt, + miter_lim ); + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + + //this is a kludge, because I can't find how to make this work properly + bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), + path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == + (path_in[lmnop] [path_in[lmnop].size()].length())); + + p_almost = p_init; + if (lastIsLinear) + { + p_almost.erase_last(); p_almost.erase_last(); + } + + //outside test + Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); + Geom::Curve* cbc2 = p_almost[0].duplicate(); + + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //this is the outside path + + //reuse the old one + p_init = p_almost; + Outline::reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside, carry on :-) + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + + p_almost = p_rev; + if (lastIsLinear) + { + p_almost.erase(p_almost.begin() ); + p_almost.erase(p_almost.begin() ); + } + + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + + cbc1 = p_almost[p_almost.size() - 1].duplicate(); + cbc2 = p_almost[0].duplicate(); + + cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //outside path + + p_init = p_almost; + reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + //pb.closePath(); + pb.flush(); + Geom::PathVector pv_np = pb.peek(); + //hack + for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) + { + path_out.push_back( pv_np[abcd] ); + } + } + else + { + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + p.Outline(&outlinepath, line_width / 2, join, butt, miter_lim); + std::vector *pv_p = outlinepath.MakePathVector(); + //hack + path_out.push_back( (*pv_p)[0].reverse() ); + delete pv_p; + } + } + return path_out; + } + static Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim) + { + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + Geom::PathVector path_out; + for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) + { + if (path_in[lmnop].size() > 1) + { + Geom::Path p_init; + Geom::Path p_rev; + Geom::PathBuilder pb = Geom::PathBuilder(); + + if ( !path_in[lmnop].closed() ) + { + p_init = Outline::half_outline_extrp( path_in[lmnop], -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline_extrp( path_in[lmnop].reverse(), -line_width, butt, + miter_lim ); + + pb.moveTo(p_init.initialPoint() ); + pb.append(p_init); + + //cap + if (butt == butt_straight) { + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } + + pb.append(p_rev); + + if (butt == butt_straight) { + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); + //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); + + pb.lineTo(p_init.initialPoint() ); + } + } + else + { + //final join + //refer to half_outline for documentation + Geom::Path p_almost = path_in[lmnop]; + p_almost.appendNew ( path_in[lmnop].initialPoint() ); + p_init = Outline::half_outline_extrp( p_almost, -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline_extrp( p_almost.reverse(), -line_width, butt, + miter_lim ); + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + + //this is a kludge, because I can't find how to make this work properly + bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), + path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == + (path_in[lmnop] [path_in[lmnop].size()].length())); + + p_almost = p_init; + if (lastIsLinear) + { + p_almost.erase_last(); p_almost.erase_last(); + } + + //outside test + Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); + Geom::Curve* cbc2 = p_almost[0].duplicate(); + + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //this is the outside path + + //reuse the old one + p_init = p_almost; + Outline::extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside, carry on :-) + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + + p_almost = p_rev; + if (lastIsLinear) + { + p_almost.erase(p_almost.begin() ); + p_almost.erase(p_almost.begin() ); + } + + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + + cbc1 = p_almost[p_almost.size() - 1].duplicate(); + cbc2 = p_almost[0].duplicate(); + + cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //outside path + + p_init = p_almost; + extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + //pb.closePath(); + pb.flush(); + Geom::PathVector pv_np = pb.peek(); + //hack + for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) + { + path_out.push_back( pv_np[abcd] ); + } + } + else + { + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + p.Outline(&outlinepath, line_width / 2, join_pointy, butt, miter_lim); + std::vector *pv_p = outlinepath.MakePathVector(); + //hack + path_out.push_back( (*pv_p)[0].reverse() ); + delete pv_p; + } + } + return path_out; + } + + +} // namespace Outline + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 8e2502545..2dabf1884 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -601,6 +601,12 @@ Glib::ustring ClipboardManagerImpl::getPathParameter(SPDesktop* desktop) */ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) { + //https://bugs.launchpad.net/inkscape/+bug/1293979 + //basically, when we do a depth-first search, we're stopping + //at the first object to be or . + //but that could then return the id of the object's + //clip path or mask, not the original path! + SPDocument *tempdoc = _retrieveClipboard(); // any target will do here if ( tempdoc == NULL ) { _userWarn(desktop, _("Nothing on the clipboard.")); @@ -608,6 +614,9 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) } Inkscape::XML::Node *root = tempdoc->getReprRoot(); + //1293979: strip out the defs of the document + root->removeChild(tempdoc->getDefs()->getRepr()); + Inkscape::XML::Node *repr = sp_repr_lookup_name(root, "svg:path", -1); // unlimited search depth if ( repr == NULL ) { repr = sp_repr_lookup_name(root, "svg:text", -1); -- cgit v1.2.3 From ba99347e1308e6d183aaaf6e8d5f65cce4f4b74b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 18 Mar 2014 21:00:36 -0600 Subject: Fix a compiler error on Windows (bzr r13090.1.27) --- src/live_effects/effect.cpp | 2 +- src/live_effects/lpe-taperstroke.cpp | 26 ++++++++++++++------------ src/live_effects/lpe-taperstroke.h | 6 +----- 3 files changed, 16 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index d6840e5b8..337fe631f 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,7 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects +#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index e6eed3abe..2cdc09376 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -55,6 +55,7 @@ static const Util::EnumDataConverter JoinTypeConverter(JoinType, sizeo LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), + line_width(_("Stroke width"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 3), attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.2), @@ -67,7 +68,9 @@ LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : attach_start.param_set_digits(3); attach_end.param_set_digits(3); - + + + registerParameter( dynamic_cast(&line_width) ); registerParameter( dynamic_cast(&attach_start) ); registerParameter( dynamic_cast(&attach_end) ); registerParameter( dynamic_cast(&smoothing) ); @@ -235,31 +238,30 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //now for the fun stuff. Right? RIGHT? - //decide on case - - //first case: taper on both sides - if (true/*pathv_out[0].length() != 0.001 && pathv_out[2].length() != 0.001*/) { + if (true) { Geom::PathVector real_pathv; - //Construct the pattern - - Geom::PathVector pat_vec = sp_svg_read_pathv("M 1,0 1,1 C 0.5,1 0,0.5 0,0.5 0,0.5 0.5,0 1,0 Z"); + //Construct the pattern (pat_str stands for pattern string) + char* pat_str = new char[200]; + sprintf(pat_str, "M 1,0 1,1 C %5.5f,1 0,0.5 0,0.5 0,0.5 %5.5f,0 1,0 Z", (double)smoothing, (double)smoothing); + Geom::PathVector pat_vec = sp_svg_read_pathv(pat_str); Geom::Piecewise > pwd2; - pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], 40)); + pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], line_width)); real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0]); Geom::PathVector sht_path; sht_path.push_back(pathv_out[1]); - sht_path = Outline::outlinePath_extr(sht_path, 40, LINEJOIN_STRAIGHT, butt_straight, 30); + sht_path = Outline::outlinePath_extr(sht_path, line_width, LINEJOIN_STRAIGHT, butt_straight, miter_limit); real_pathv.push_back(sht_path[0]); - pat_vec = sp_svg_read_pathv("M 0,0 0,1 C 0.5,1 1,0.5 1,0.5 1,0.5 0.5,0 0,0 Z"); + sprintf(pat_str, "M 0,0 0,1 C %5.5f,1 1,0.5 1,0.5 1,0.5 %5.5f,0 0,0 Z", (double)smoothing, (double)smoothing); + pat_vec = sp_svg_read_pathv(pat_str); pwd2 = Geom::Piecewise > (); - pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], 40)); + pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], line_width)); real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0].reverse()); //clever union diff --git a/src/live_effects/lpe-taperstroke.h b/src/live_effects/lpe-taperstroke.h index f2fe03533..7cb8bc85e 100644 --- a/src/live_effects/lpe-taperstroke.h +++ b/src/live_effects/lpe-taperstroke.h @@ -38,6 +38,7 @@ public: friend class TpS::KnotHolderEntityAttachBegin; friend class TpS::KnotHolderEntityAttachEnd; private: + ScalarParam line_width; ScalarParam attach_start; ScalarParam attach_end; ScalarParam smoothing; @@ -54,11 +55,6 @@ private: } //namespace LivePathEffect } //namespace Inkscape -//because Windoze is stupid -# ifdef WIN32 -# include "lpe-taperstroke.cpp" -# endif - #endif /* -- cgit v1.2.3 From c1c76126846e36fab78a51e5acec475b4de5ea44 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 19 Mar 2014 21:54:30 +0100 Subject: This think fix su_v related bug on continuous paths in BSpline or Spiro mode (bzr r11950.1.301) --- src/ui/tools/freehand-base.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 3f74a5147..67b603ab0 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -495,7 +495,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Blue2 dc->blue2_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - + /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because we modify it when continuing through an anchor. */ @@ -614,6 +614,18 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) bool has_lpe = false; Inkscape::XML::Node *repr; + + /* if we are in bspline or spirolive the anchors curves, if exist, needs to be selected again because + we modify it when continuing through an anchor. */ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if ( ((dc->sa && !dc->sa->curve->is_empty()) || + (dc->ea && !dc->ea->curve->is_empty())) && + (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) + ) { + spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); + } + if (dc->white_item) { repr = dc->white_item->getRepr(); has_lpe = SP_LPE_ITEM(dc->white_item)->hasPathEffectRecursive(); -- cgit v1.2.3 From c6e50a519c55220ccd4efdd6a7a7dbe51cf9fa04 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 19 Mar 2014 22:49:07 +0100 Subject: Fixing suv mac bug continuing existing bsplines/spiro paths (bzr r11950.1.303) --- src/ui/tools/freehand-base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 67b603ab0..d34ca2142 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -566,7 +566,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) s = reverse_then_unref(s); } s->append_continuous(c, 0.0625); - c->unref(); + c->reset(); c = s; } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; -- cgit v1.2.3 From 988c4a1639ca097634e336d49ad92eb1eb576f31 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 19 Mar 2014 23:05:50 +0100 Subject: Fix a bug when starting path with change from bspline to spiro and inverse (bzr r11950.1.304) --- src/ui/tools/pen-tool.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index d79803644..75dd6a32b 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1445,6 +1445,10 @@ void PenTool::_bspline_spiro_off() void PenTool::_bspline_spiro_start_anchor(bool shift) { + if(this->sa->curve->is_empty()){ + return; + } + LivePathEffect::LPEBSpline *lpe_bsp = NULL; if (SP_IS_LPE_ITEM(this->white_item) && SP_LPE_ITEM(this->white_item)->hasPathEffect()){ @@ -1474,9 +1478,6 @@ void PenTool::_bspline_spiro_start_anchor(bool shift) if(!this->spiro && !this->bspline) return; - if(this->sa->curve->is_empty()) - return; - if(shift) this->_bspline_spiro_start_anchor_off(); else -- cgit v1.2.3 From 67a180fdd31fd8dd06be4df75356509001295458 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 01:48:37 +0100 Subject: Refactor of anchors (bzr r11950.1.306) --- src/ui/tools/freehand-base.cpp | 97 +++++++++++++++++------------------------- src/ui/tools/freehand-base.h | 2 + src/ui/tools/pen-tool.cpp | 18 ++++---- 3 files changed, 50 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index d34ca2142..5897ce0ee 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -492,17 +492,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->red_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->red_bpath), NULL); - // Blue2 - dc->blue2_curve->reset(); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); - - /* if c is empty, it might be that the user was trying to continue an existing curve and cancelled. - if this is the case and we are in bspline or spirolive the previous curve needs to be selected again because - we modify it when continuing through an anchor. */ if (c->is_empty()) { - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); - } c->unref(); return; } @@ -526,50 +516,43 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) { // We hit bot start and end of single curve, closing paths dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path.")); - - /* if we are in bspline or spirolive mode, the continuation and ending curve are updated when continuing or ending the curve in an anchor. - this causes that the original function doesn't detect if it's the same curve in case the curves have multiples parts -shift- and - close incorrectly one of the parts */ + if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { + c = reverse_then_unref(c); + } if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { - dc->sa->curve = reverse_then_unref(dc->sa->curve); - } - dc->sa->curve->append_continuous(c, 0.0625); + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + dc->sc->append_continuous(c, 0.0625); c->unref(); - if(Geom::are_near(dc->sa->curve->first_path()->initialPoint(), dc->ea->dp)){ - dc->sa->curve->closepath_current(); - } - - // if the curve has an bspline or spiro LPE, we execute - // spdc_flush_white, passing the necessary starting curve. - dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - spdc_flush_white(dc, dc->sa->curve); + dc->sc->closepath_current(); }else{ - if (dc->sa->start && !(dc->sa->curve->is_closed()) ) { - c = reverse_then_unref(c); - } dc->sa->curve->append_continuous(c, 0.0625); c->unref(); dc->sa->curve->closepath_current(); - spdc_flush_white(dc, NULL); } - + spdc_flush_white(dc, NULL); return; } // Step C - test start if (dc->sa) { SPCurve *s = dc->sa->curve; + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + s = dc->sc; + } dc->white_curves = g_slist_remove(dc->white_curves, s); if (dc->sa->start) { s = reverse_then_unref(s); } s->append_continuous(c, 0.0625); - c->reset(); + c->unref(); c = s; } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + e = dc->ec; + } dc->white_curves = g_slist_remove(dc->white_curves, e); if (!dc->ea->start) { e = reverse_then_unref(e); @@ -577,16 +560,30 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c->append_continuous(e, 0.0625); e->unref(); } + + spdc_flush_white(dc, c); + c->unref(); } static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) { SPCurve *c; - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (dc->white_curves) { g_assert(dc->white_item); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + if(dc->sa){ + dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); + dc->white_curves = g_slist_append(dc->white_curves, dc->sc); + } + if(dc->ea){ + dc->white_curves = g_slist_remove(dc->white_curves, dc->ea->curve); + dc->white_curves = g_slist_append(dc->white_curves, dc->ec); + } + } c = SPCurve::concat(dc->white_curves); g_slist_free(dc->white_curves); dc->white_curves = NULL; @@ -615,17 +612,6 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) bool has_lpe = false; Inkscape::XML::Node *repr; - /* if we are in bspline or spirolive the anchors curves, if exist, needs to be selected again because - we modify it when continuing through an anchor. */ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if ( ((dc->sa && !dc->sa->curve->is_empty()) || - (dc->ea && !dc->ea->curve->is_empty())) && - (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) - ) { - spdc_selection_modified(sp_desktop_selection(dc->desktop), 0, dc); - } - if (dc->white_item) { repr = dc->white_item->getRepr(); has_lpe = SP_LPE_ITEM(dc->white_item)->hasPathEffectRecursive(); @@ -689,19 +675,6 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) active = na; } } - - /* modify the anchoring curve so it is equal to the starting curve. - this curve is modified when it's modified and we need them to be equal to the closing curve */ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) && - dc->sa && !dc->red_curve->is_empty() && !dc->green_anchor){ - if(active){ - active->curve = dc->sa->curve; - active->curve->ref(); - } - } - return active; } @@ -750,6 +723,14 @@ static void spdc_free_colors(FreehandBase *dc) dc->blue2_curve = dc->blue2_curve->unref(); } + if (dc->sc) { + dc->sc = dc->sc->unref(); + } + + if (dc->ec) { + dc->ec = dc->ec->unref(); + } + // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index d5c2fc9ba..266e22783 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -74,9 +74,11 @@ public: // Start anchor SPDrawAnchor *sa; + SPCurve * sc; // End anchor SPDrawAnchor *ea; + SPCurve * ec; /* type of the LPE that is to be applied automatically to a finished path (if any) */ Inkscape::LivePathEffect::EffectType waiting_LPE_type; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 75dd6a32b..1701cf5d9 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1516,8 +1516,8 @@ void PenTool::_bspline_spiro_start_anchor_on() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } void PenTool::_bspline_spiro_start_anchor_off() @@ -1542,8 +1542,8 @@ void PenTool::_bspline_spiro_start_anchor_off() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } } @@ -1677,8 +1677,8 @@ void PenTool::_bspline_spiro_end_anchor_on() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } } @@ -1726,8 +1726,8 @@ void PenTool::_bspline_spiro_end_anchor_off() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sa->curve->reset(); - this->sa->curve = tmpCurve; + this->sc->reset(); + this->sc = tmpCurve; } } } @@ -1742,7 +1742,7 @@ void PenTool::_bspline_spiro_build() SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start if(this->sa && !this->sa->curve->is_empty()){ - curve = this->sa->curve->copy(); + curve = this->sc->copy(); if (this->sa->start) { curve = curve->create_reverse(); } -- cgit v1.2.3 From 9c0d852d84da8af9cbb07ee2ed0488390225f126 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 03:27:13 +0100 Subject: Full refactor of path continuations in bspline-spirolive mode, I think no more suv mac crashes, but need to be full tested again because a lot of things changed. (bzr r11950.1.308) --- src/ui/tools/freehand-base.cpp | 37 +++++++++++++++---------------------- src/ui/tools/freehand-base.h | 4 ++-- src/ui/tools/pen-tool.cpp | 5 ++--- src/ui/tools/pencil-tool.cpp | 3 +++ 4 files changed, 22 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 5897ce0ee..cecf0c0ca 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -92,7 +92,9 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , white_curves(NULL) , white_anchors(NULL) , sa(NULL) + , sc(NULL) , ea(NULL) + , ec(NULL) , waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE) , red_curve_is_valid(false) , anchor_statusbar(false) @@ -153,6 +155,12 @@ void FreehandBase::setup() { this->green_anchor = NULL; this->green_closed = FALSE; + // Create start anchor alternative curve + this->sc = new SPCurve(); + + // Create end anchor alternative curve + this->ec = new SPCurve(); + this->attach = TRUE; spdc_attach_selection(this, this->selection); } @@ -524,6 +532,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->sc->append_continuous(c, 0.0625); c->unref(); dc->sc->closepath_current(); + if(dc->sa){ + dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); + dc->white_curves = g_slist_append(dc->white_curves, dc->sc); + } }else{ dc->sa->curve->append_continuous(c, 0.0625); c->unref(); @@ -536,11 +548,11 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) // Step C - test start if (dc->sa) { SPCurve *s = dc->sa->curve; + dc->white_curves = g_slist_remove(dc->white_curves, s); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ s = dc->sc; } - dc->white_curves = g_slist_remove(dc->white_curves, s); if (dc->sa->start) { s = reverse_then_unref(s); } @@ -549,11 +561,11 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) c = s; } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; + dc->white_curves = g_slist_remove(dc->white_curves, e); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ e = dc->ec; } - dc->white_curves = g_slist_remove(dc->white_curves, e); if (!dc->ea->start) { e = reverse_then_unref(e); } @@ -570,20 +582,9 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) { SPCurve *c; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (dc->white_curves) { g_assert(dc->white_item); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - if(dc->sa){ - dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - dc->white_curves = g_slist_append(dc->white_curves, dc->sc); - } - if(dc->ea){ - dc->white_curves = g_slist_remove(dc->white_curves, dc->ea->curve); - dc->white_curves = g_slist_append(dc->white_curves, dc->ec); - } - } c = SPCurve::concat(dc->white_curves); g_slist_free(dc->white_curves); dc->white_curves = NULL; @@ -723,14 +724,6 @@ static void spdc_free_colors(FreehandBase *dc) dc->blue2_curve = dc->blue2_curve->unref(); } - if (dc->sc) { - dc->sc = dc->sc->unref(); - } - - if (dc->ec) { - dc->ec = dc->ec->unref(); - } - // Green while (dc->green_bpaths) { sp_canvas_item_destroy(SP_CANVAS_ITEM(dc->green_bpaths->data)); diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 266e22783..c134c5352 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -74,11 +74,11 @@ public: // Start anchor SPDrawAnchor *sa; - SPCurve * sc; + SPCurve *sc; // End anchor SPDrawAnchor *ea; - SPCurve * ec; + SPCurve *ec; /* type of the LPE that is to be applied automatically to a finished path (if any) */ Inkscape::LivePathEffect::EffectType waiting_LPE_type; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 1701cf5d9..3ef9b96af 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1516,7 +1516,6 @@ void PenTool::_bspline_spiro_start_anchor_on() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); this->sc = tmpCurve; } @@ -1542,7 +1541,6 @@ void PenTool::_bspline_spiro_start_anchor_off() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); this->sc = tmpCurve; } @@ -1677,7 +1675,6 @@ void PenTool::_bspline_spiro_end_anchor_on() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); this->sc = tmpCurve; } } @@ -2176,6 +2173,8 @@ void PenTool::_finish(gboolean const closed) { // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); + this->sc = NULL; + this->ec = NULL; this->sa = NULL; this->ea = NULL; diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 1ccdee637..8fe01a852 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -203,6 +203,7 @@ gint PencilTool::_handleButtonPress(GdkEventButton const &bevent) { } if (anchor) { p = anchor->dp; + this->sc = anchor->curve; desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); } else { m.setup(desktop); @@ -380,6 +381,7 @@ gint PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /* Finish segment now */ if (anchor) { p = anchor->dp; + this->ec = anchor->curve; } else { this->_endpointSnap(p, revent.state); } @@ -406,6 +408,7 @@ gint PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /// \todo fixme: Clean up what follows (Lauris) if (anchor) { p = anchor->dp; + this->ec = anchor->curve; } else { Geom::Point p_end = p; this->_endpointSnap(p_end, revent.state); -- cgit v1.2.3 From 8dee559ebb54fa7e1ef995b71713c0685b333d60 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 03:35:35 +0100 Subject: Removed persistent blue line (bzr r11950.1.309) --- src/ui/tools/freehand-base.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index cecf0c0ca..ac98be2cf 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -493,6 +493,10 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue_bpath), NULL); + // Blue2 + dc->blue2_curve->reset(); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue2_bpath), NULL); + // Red if (dc->red_curve_is_valid) { c->append_continuous(dc->red_curve, 0.0625); -- cgit v1.2.3 From 1ee8c21b5cfe9efa827eed7ab5e31fe28a9b4ae1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 20 Mar 2014 03:39:27 +0100 Subject: Fixed bug continuing cusp nodes (bzr r11950.1.310) --- src/ui/tools/pen-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 3ef9b96af..cea8e67e6 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1563,7 +1563,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ }else if(!this->green_curve->is_empty()){ tmpCurve = this->green_curve->copy(); }else{ - tmpCurve = this->sa->curve->copy(); + tmpCurve = this->sc->copy(); if(this->sa->start) tmpCurve = tmpCurve->create_reverse(); } -- cgit v1.2.3 From 9a04c985ec628dc749a8a82d94bcf47d482a4f63 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 20 Mar 2014 17:09:57 -0400 Subject: Fix a linker error ("static") (hopefully) Resolve compiler errors with GTK3+ (bzr r13090.1.28) --- src/live_effects/Makefile_insert | 1 + src/live_effects/effect.cpp | 2 +- src/live_effects/lpe-taperstroke.cpp | 162 ++++-- src/live_effects/lpe-taperstroke.h | 9 +- src/live_effects/pathoutlineprovider.cpp | 840 +++++++++++++++++++++++++++++++ src/live_effects/pathoutlineprovider.h | 791 +---------------------------- src/ui/dialog/objects.cpp | 3 +- 7 files changed, 999 insertions(+), 809 deletions(-) create mode 100755 src/live_effects/pathoutlineprovider.cpp mode change 100755 => 100644 src/live_effects/pathoutlineprovider.h (limited to 'src') diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index b19f417ae..ac7c33e2f 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -93,6 +93,7 @@ ink_common_sources += \ live_effects/lpe-fill-between-many.h \ live_effects/lpe-ellipse_5pts.cpp \ live_effects/lpe-ellipse_5pts.h \ + live_effects/pathoutlineprovider.cpp \ live_effects/lpe-jointype.cpp \ live_effects/lpe-jointype.h \ live_effects/lpe-taperstroke.cpp \ diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 337fe631f..d6840e5b8 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,7 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects +//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 2cdc09376..a862417d7 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -13,11 +13,20 @@ #include "live_effects/lpe-taperstroke.h" -// You might need to include other 2geom files. You can add them here: #include <2geom/path.h> #include <2geom/shape.h> +#include <2geom/path.h> +#include <2geom/circle.h> +#include <2geom/sbasis-to-bezier.h> #include "pathoutlineprovider.h" #include "display/curve.h" +#include "sp-shape.h" +#include "style.h" +#include "xml/repr.h" +#include "sp-paint-server.h" +#include "svg/svg-color.h" +#include "desktop-style.h" +#include "svg/css-ostringstream.h" #include "svg/svg.h" //#include @@ -58,7 +67,7 @@ LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : line_width(_("Stroke width"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 3), attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), - smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.2), + smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), join_type(_("Join type"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 30.) { @@ -83,21 +92,93 @@ LPETaperStroke::~LPETaperStroke() } -unsigned curveOrder (const Geom::Curve* curve_in) +//from LPEPowerStroke -- sets fill if stroke color because we will +//be converting to a fill to make the new join. + +void LPETaperStroke::doOnApply(SPLPEItem const* lpeitem) { - using namespace Geom; - //cast it - const CubicBezier *cbc = dynamic_cast(curve_in); - if (cbc) return 3; - const QuadraticBezier * qbc = dynamic_cast(curve_in); - if (qbc) return 2; - const BezierCurveN<1U> * lbc = dynamic_cast *>(curve_in); - if (lbc) return 1; - //BezierCurveN<0> * dbc = dynamic_cast *> (curve_in); - return 0; + if (SP_IS_SHAPE(lpeitem)) { + SPLPEItem* item = const_cast(lpeitem); + double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed : 1.; + + SPCSSAttr *css = sp_repr_css_attr_new (); + if (lpeitem->style->stroke.isSet()) { + if (lpeitem->style->stroke.isPaintserver()) { + SPPaintServer * server = lpeitem->style->getStrokePaintServer(); + if (server) { + Glib::ustring str; + str += "url(#"; + str += server->getId(); + str += ")"; + sp_repr_css_set_property (css, "fill", str.c_str()); + } + } else if (lpeitem->style->stroke.isColor()) { + gchar c[64]; + sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value))); + sp_repr_css_set_property (css, "fill", c); + } else { + sp_repr_css_set_property (css, "fill", "none"); + } + } else { + sp_repr_css_unset_property (css, "fill"); + } + + sp_repr_css_set_property(css, "stroke", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); + + line_width.param_set_value(width); + } else { + g_warning("LPE Join Type can only be applied to paths (not groups)."); + } } -Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_tolerance = 0.01) +//from LPEPowerStroke -- sets stroke color from existing fill color + +void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem) +{ + + if (SP_IS_SHAPE(lpeitem)) { + SPLPEItem *item = const_cast(lpeitem); + + SPCSSAttr *css = sp_repr_css_attr_new (); + if (lpeitem->style->fill.isSet()) { + if (lpeitem->style->fill.isPaintserver()) { + SPPaintServer * server = lpeitem->style->getFillPaintServer(); + if (server) { + Glib::ustring str; + str += "url(#"; + str += server->getId(); + str += ")"; + sp_repr_css_set_property (css, "stroke", str.c_str()); + } + } else if (lpeitem->style->fill.isColor()) { + gchar c[64]; + sp_svg_write_color (c, sizeof(c), lpeitem->style->stroke.value.color.toRGBA32(SP_SCALE24_TO_FLOAT(lpeitem->style->stroke_opacity.value))); + sp_repr_css_set_property (css, "stroke", c); + } else { + sp_repr_css_set_property (css, "stroke", "none"); + } + } else { + sp_repr_css_unset_property (css, "stroke"); + } + + Inkscape::CSSOStringStream os; + os << fabs(line_width); + sp_repr_css_set_property (css, "stroke-width", os.str().c_str()); + + sp_repr_css_set_property(css, "fill", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); + item->updateRepr(); + } +} + +//actual effect impl here + +Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_tolerance = 0.05) { Geom::Path path_out = Geom::Path(); @@ -108,7 +189,7 @@ Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_toler break; //determine order of curve - int order = curveOrder(&path_in[i]); + int order = Outline::bezierOrder(&path_in[i]); Geom::Point start_point; Geom::Point cross_point = path_in[i].finalPoint(); @@ -131,7 +212,7 @@ Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_toler start_point = path_in[i].initialPoint(); } - order = curveOrder(&path_in[i+1]); + order = Outline::bezierOrder(&path_in[i+1]); switch (order) { @@ -155,7 +236,7 @@ Geom::Curve * subdivide_at(const Geom::Curve* curve_in, Geom::Coord time, bool f { //the only reason for this function is the lack of a subdivide function in the Curve class. //you have to cast to Beziers to be able to use subdivide(t) - unsigned order = curveOrder(curve_in); + unsigned order = Outline::bezierOrder(curve_in); Geom::Curve* curve_out = curve_in->duplicate(); switch (order) { @@ -211,22 +292,25 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) if (attach_end <= 0) { attach_end.param_set_value( 0.0001 ); } + + //don't let it be integer + if (double(unsigned(attach_start)) == attach_start) { + attach_start.param_set_value(attach_start - 0.0001); + } + if (double(unsigned(attach_end)) == attach_end) { + attach_end.param_set_value(attach_end - 0.0001); + } - /*if (size != return_at_first_cusp(path_in[0]).size()) { //will get to this in a bit - //check to see if either knot was dragged past their allowed amount - volatile unsigned size_p_start = (unsigned)attach_start; - volatile unsigned size_p_end = (unsigned)attach_end; - - //maximum allowed value in either direction is return_at_first_cusp(path_in[0]).size - volatile unsigned allowed_p_start = return_at_first_cusp(path_in[0]).size(); - volatile unsigned allowed_p_end = return_at_first_cusp(path_in[0].reverse()).size(); - - if (size_p_start > allowed_p_start) { - attach_start.param_set_value(allowed_p_start - 0.0001); - } else if (size_p_end > allowed_p_end) { - attach_end.param_set_value(allowed_p_end - 0.0001); - } - }*/ + unsigned allowed_start = return_at_first_cusp(path_in[0]).size(); + + unsigned allowed_end = return_at_first_cusp(path_in[0].reverse()).size(); + + if ((unsigned)attach_start >= allowed_start) { + attach_start.param_set_value((double)allowed_start - 0.0001); + } + if ((unsigned)attach_end >= allowed_end) { + attach_end.param_set_value((double)allowed_end - 0.0001); + } //Path::operator () means get point at time t start_attach_point = return_at_first_cusp(path_in[0])(attach_start); @@ -242,8 +326,8 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) Geom::PathVector real_pathv; //Construct the pattern (pat_str stands for pattern string) - char* pat_str = new char[200]; - sprintf(pat_str, "M 1,0 1,1 C %5.5f,1 0,0.5 0,0.5 0,0.5 %5.5f,0 1,0 Z", (double)smoothing, (double)smoothing); + char pat_str[200]; + sprintf(pat_str, "M 1,0 1,1 C %5.5f,1 0,0.5 0,0.5 0,0.5 %5.5f,0 1,0 Z", 1 - (double)smoothing, 1 - (double)smoothing); Geom::PathVector pat_vec = sp_svg_read_pathv(pat_str); Geom::Piecewise > pwd2; @@ -253,12 +337,13 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) Geom::PathVector sht_path; sht_path.push_back(pathv_out[1]); - sht_path = Outline::outlinePath_extr(sht_path, line_width, LINEJOIN_STRAIGHT, butt_straight, miter_limit); + sht_path = Outline::PathVectorOutline(sht_path, line_width, butt_straight, static_cast(join_type.get_value()) , miter_limit); real_pathv.push_back(sht_path[0]); - sprintf(pat_str, "M 0,0 0,1 C %5.5f,1 1,0.5 1,0.5 1,0.5 %5.5f,0 0,0 Z", (double)smoothing, (double)smoothing); - pat_vec = sp_svg_read_pathv(pat_str); + char pat_str_1[200]; + sprintf(pat_str_1, "M 0,0 0,1 C %5.5f,1 1,0.5 1,0.5 1,0.5 %5.5f,0 0,0 Z", (double)smoothing, (double)smoothing); + pat_vec = sp_svg_read_pathv(pat_str_1); pwd2 = Geom::Piecewise > (); pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], line_width)); @@ -298,7 +383,7 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa trimmed_start.append(path_in[0] [i]); } - #define OVERLAP 0.001 + #define OVERLAP (0.001 / (line_width < 1 ? 1 : line_width)) trimmed_start.append(*subdivide_at(curve_start, (attach_start - loc) + OVERLAP, true)); curve_start = subdivide_at(curve_start, attach_start - loc, false); @@ -451,6 +536,7 @@ Geom::Piecewise > stretch_along(Geom::Piecewise +#include <2geom/path.h> +#include <2geom/circle.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/shape.h> +#include <2geom/transforms.h> +#include <2geom/path-sink.h> + +namespace Geom +{ + /** + * Refer to: Weisstein, Eric W. "Circle-Circle Intersection." + From MathWorld--A Wolfram Web Resource. + http://mathworld.wolfram.com/Circle-CircleIntersection.html + * + * @return 0 if no intersection + * @return 1 if one circle is contained in the other + * @return 2 if intersections are found (they are written to p0 and p1) + */ + static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, + Point & p0, Point & p1) + { + Point X0 = circle0.center(); + double r0 = circle0.ray(); + Point X1 = circle1.center(); + double r1 = circle1.ray(); + + /* dx and dy are the vertical and horizontal distances between + * the circle centers. + */ + Point D = X1 - X0; + + /* Determine the straight-line distance between the centers. */ + double d = L2(D); + + /* Check for solvability. */ + if (d > (r0 + r1)) + { + /* no solution. circles do not intersect. */ + return 0; + } + if (d <= fabs(r0 - r1)) + { + /* no solution. one circle is contained in the other */ + return 1; + } + + /* 'point 2' is the point where the line through the circle + * intersection points crosses the line between the circle + * centers. + */ + + /* Determine the distance from point 0 to point 2. */ + double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; + + /* Determine the coordinates of point 2. */ + Point p2 = X0 + D * (a/d); + + /* Determine the distance from point 2 to either of the + * intersection points. + */ + double h = std::sqrt((r0*r0) - (a*a)); + + /* Now determine the offsets of the intersection points from + * point 2. + */ + Point r = (h/d)*rot90(D); + + /* Determine the absolute intersection points. */ + p0 = p2 + r; + p1 = p2 - r; + + return 2; + } + /** + * Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t. + * Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt). + */ + static Circle touching_circle( D2 const &curve, double t, double tol=0.01 ) + { + D2 dM=derivative(curve); + if ( are_near(L2sq(dM(t)),0.) ) { + dM=derivative(dM); + } + if ( are_near(L2sq(dM(t)),0.) ) { // try second time + dM=derivative(dM); + } + Piecewise > unitv = unitVector(dM,tol); + Piecewise dMlength = dot(Piecewise >(dM),unitv); + Piecewise k = cross(derivative(unitv),unitv); + k = divide(k,dMlength,tol,3); + double curv = k(t); // note that this value is signed + + Geom::Point normal = unitTangentAt(curve, t).cw(); + double radius = 1/curv; + Geom::Point center = curve(t) + radius*normal; + return Geom::Circle(center, fabs(radius)); + } + + static std::vector split_at_cusps(const Geom::Path& in) + { + Geom::PathVector out = Geom::PathVector(); + Geom::Path temp = Geom::Path(); + + for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) + { + temp = Geom::Path(); + temp.append(in[path_descr]); + out.push_back(temp); + } + + return out; + } + + static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) + { + std::vector temp; + sbasis_to_bezier(temp, sbasis_in, 4); + return Geom::CubicBezier( temp ); + } + + static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, + Geom::Point const & origin_b, Geom::Point const & vector_b) + { + Geom::Coord denom = cross(vector_b, vector_a); + if (!Geom::are_near(denom,0.)){ + Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom; + return origin_a + t * vector_a; + } + return boost::none; + } +} + +namespace Outline +{ + +typedef Geom::D2 D2SB; +typedef Geom::Piecewise PWD2; + +unsigned bezierOrder (const Geom::Curve* curve_in) +{ + using namespace Geom; + //cast it + const CubicBezier *cbc = dynamic_cast(curve_in); + if (cbc) return 3; + const QuadraticBezier * qbc = dynamic_cast(curve_in); + if (qbc) return 2; + const BezierCurveN<1U> * lbc = dynamic_cast *>(curve_in); + if (lbc) return 1; + return 0; +} + +//returns true if the angle formed by the curves and their handles +//is >180 clockwise, otherwise false. +bool outside_angle (const Geom::Curve* cbc1, const Geom::Curve* cbc2) +{ + Geom::Point start_point = cbc1->initialPoint(); + Geom::Point end_point = cbc2->finalPoint(); + unsigned order = bezierOrder(cbc1); + switch (order) + { + case 3: + start_point = ( dynamic_cast(cbc1) )->operator [] (2); + break; + case 2: + start_point = ( dynamic_cast(cbc1) )->operator [] (1); + break; + } + order = bezierOrder(cbc2); + switch (order) + { + case 3: + end_point = ( dynamic_cast(cbc2) )->operator [] (1); + break; + case 2: + end_point = ( dynamic_cast(cbc2) )->operator[] (1); + break; + } + return false; +} + +void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve*cbc2, Geom::Point endPt, double miter_limit) +{ + + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + if (cross.empty()) + { + Geom::Path pth; + pth.append(*cbc1); + + //Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); + + pth = Geom::Path(); + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + + Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.); + Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0); + + Geom::Point points[2]; + int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]); + if (solutions == 2) + { + Geom::Point sol(0,0); + if ( dot(tang2,points[0]-endPt) > 0 ) + { + // points[0] is bad, choose points[1] + sol = points[1]; + } + else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1] + // points[1] is bad, choose points[0] + sol = points[0]; + } + else + { + // both points are good, choose nearest + sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? + points[0] : points[1]; + } + Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true); + Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true); + + if (arc0) + { + path_builder.append (arc0->toSBasis()); + delete arc0; + arc0 = NULL; + } + + if (arc1) + { + path_builder.append (arc1->toSBasis()); + delete arc1; + arc1 = NULL; + } + } + else + { + path_builder.appendNew (endPt); + } + } + else + { + path_builder.appendNew (endPt); + } +} + Geom::Path half_outline_extrp(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) + { + Geom::PathVector pv = split_at_cusps(path_in); + unsigned m; + Path path_outline = Path(); + Path path_tangent = Path(); + + Geom::Point initialPoint; + Geom::Point endPoint; + + Geom::Path path_builder = Geom::Path(); + Geom::PathVector * pathvec; + + //load the first portion in before the loop starts + { + path_outline = Path(); + path_outline.LoadPath(pv[0], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + //now half of first cusp has been loaded + + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + //instead of array accessing twice, dereferencing used for clarity + initialPoint = (*pathvec)[0].initialPoint(); + + path_builder.start(initialPoint); + path_builder.append( (*pathvec)[0] ); + + path_outline = Path(); + path_outline.LoadPath(pv[1], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + + path_builder.append( (*pathvec)[0] ); + + //always set pointers null after deleting + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + for (m = 2; m < pv.size(); m++) + { + path_outline = Path(); + path_outline.LoadPath(pv[m], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + path_builder.append( (*pathvec)[0] ); + + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + return path_builder; + } + + //Create a reflected outline join. + //Note: it is generally recommended to let half_outline do this for you! + //path_builder: the path to append the curves to + //cbc1: the curve before the join + //cbc2: the curve after the join + //endPt: the point to end at + //miter_limit: the miter parameter + void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit) + { + //the most important work for the reflected join is done here + + //determine where we are in the path. If we're on the inside, ignore + //and just lineTo. On the outside, we'll do a little reflection magic :) + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + if (cross.empty()) + { + //probably on the outside of the corner + Geom::Path pth; + pth.append(*cbc1); + + Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); + + //reflect curves along the bevel + D2SB newcurve1 = pth.toPwSb()[0] * + Geom::reflection ( -Geom::rot90(tang1) , + cbc1->finalPoint() ); + + Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1)); + + pth = Geom::Path(); + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + D2SB newcurve2 = pth.toPwSb()[0] * + Geom::reflection ( -Geom::rot90(tang2) , + cbc2->initialPoint() ); + Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2)); + + cross = Geom::crossings(bzr1, bzr2); + if ( cross.empty() ) + { + //std::cout << "Oops, no crossings!" << std::endl; + //curves didn't cross; default to miter + /*boost::optional p = intersection_point (cbc1->finalPoint(), tang1, + cbc2->initialPoint(), tang2); + if (p) + { + path_builder.appendNew (*p); + }*/ + //bevel + path_builder.appendNew( endPt ); + } + else + { + //join + std::pair sub1 = bzr1.subdivide(cross[0].ta); + std::pair sub2 = bzr2.subdivide(cross[0].tb); + + //@TODO joins have a strange tendency to cross themselves twice. Check this. + + //sections commented out are for general stability + path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); + path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); + } + } + else // cross.empty() + { + //probably on the inside of the corner + path_builder.appendNew ( endPt ); + } + } + + /** @brief Converts a path to one half of an outline. + * path_in: The input path to use. (To create the other side use path_in.reverse() ) + * line_width: the line width to use (usually you want to divide this by 2) + * linecap_type: (not used here) the cap to apply. Passed to libvarot. + * miter_limit: the miter parameter + */ + Geom::Path half_outline(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) + { + Geom::PathVector pv = split_at_cusps(path_in); + unsigned m; + Path path_outline = Path(); + Path path_tangent = Path(); + //needed for closing the path + Geom::Point initialPoint; + Geom::Point endPoint; + + //some issues prevented me from using a PathBuilder here + //it seems like PathBuilder::peek() gave me a null reference exception + //and I was unable to get a stack trace on Windows, so had to switch to Linux + //to see what the hell was wrong. :( + //I wasted five hours opening it in IDAPro, VS2012, and GDB Windows + + /*Program received signal SIGSEGV, Segmentation fault. + 0x00000000006539ac in get_curves (this=0x0) + at /usr/include/c++/4.6/bits/locale_facets.h:1077 + 1077 { return __c; } + */ + + Geom::Path path_builder = Geom::Path(); + Geom::PathVector * pathvec; + + //load the first portion in before the loop starts + { + path_outline = Path(); + path_outline.LoadPath(pv[0], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + //now half of first cusp has been loaded + + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + //instead of array accessing twice, dereferencing used for clarity + initialPoint = (*pathvec)[0].initialPoint(); + + path_builder.start(initialPoint); + path_builder.append( (*pathvec)[0] ); + + path_outline = Path(); + path_outline.LoadPath(pv[1], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + path_tangent = Path(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + + path_builder.append( (*pathvec)[0] ); + + //always set pointers null after deleting + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + for (m = 2; m < pv.size(); m++) + { + path_outline = Path(); + path_outline.LoadPath(pv[m], Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); + + delete pathvec; pathvec = NULL; + pathvec = path_tangent.MakePathVector(); + + Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); + Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); + + reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); + path_builder.append( (*pathvec)[0] ); + + delete pathvec; pathvec = NULL; + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + + return path_builder; + } + + Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim) + { + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + Geom::PathVector path_out; + for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) + { + if (path_in[lmnop].size() > 1) + { + Geom::Path p_init; + Geom::Path p_rev; + Geom::PathBuilder pb = Geom::PathBuilder(); + + if ( !path_in[lmnop].closed() ) + { + p_init = Outline::half_outline( path_in[lmnop], -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline( path_in[lmnop].reverse(), -line_width, butt, + miter_lim ); + + pb.moveTo(p_init.initialPoint() ); + pb.append(p_init); + + //cap + if (butt == butt_straight) { + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } + + pb.append(p_rev); + + if (butt == butt_straight) { + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); + //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); + + pb.lineTo(p_init.initialPoint() ); + } + } + else + { + //final join + //refer to half_outline for documentation + Geom::Path p_almost = path_in[lmnop]; + p_almost.appendNew ( path_in[lmnop].initialPoint() ); + p_init = Outline::half_outline( p_almost, -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline( p_almost.reverse(), -line_width, butt, + miter_lim ); + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + + //this is a kludge, because I can't find how to make this work properly + bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), + path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == + (path_in[lmnop] [path_in[lmnop].size()].length())); + + p_almost = p_init; + if (lastIsLinear) + { + p_almost.erase_last(); p_almost.erase_last(); + } + + //outside test + Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); + Geom::Curve* cbc2 = p_almost[0].duplicate(); + + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //this is the outside path + + //reuse the old one + p_init = p_almost; + Outline::reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside, carry on :-) + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + + p_almost = p_rev; + if (lastIsLinear) + { + p_almost.erase(p_almost.begin() ); + p_almost.erase(p_almost.begin() ); + } + + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + + cbc1 = p_almost[p_almost.size() - 1].duplicate(); + cbc2 = p_almost[0].duplicate(); + + cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //outside path + + p_init = p_almost; + reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + //pb.closePath(); + pb.flush(); + Geom::PathVector pv_np = pb.peek(); + //hack + for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) + { + path_out.push_back( pv_np[abcd] ); + } + } + else + { + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + p.Outline(&outlinepath, line_width / 2, join, butt, miter_lim); + std::vector *pv_p = outlinepath.MakePathVector(); + //hack + path_out.push_back( (*pv_p)[0].reverse() ); + delete pv_p; + } + } + return path_out; + } + Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim) + { + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + Geom::PathVector path_out; + for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) + { + if (path_in[lmnop].size() > 1) + { + Geom::Path p_init; + Geom::Path p_rev; + Geom::PathBuilder pb = Geom::PathBuilder(); + + if ( !path_in[lmnop].closed() ) + { + p_init = Outline::half_outline_extrp( path_in[lmnop], -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline_extrp( path_in[lmnop].reverse(), -line_width, butt, + miter_lim ); + + pb.moveTo(p_init.initialPoint() ); + pb.append(p_init); + + //cap + if (butt == butt_straight) { + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + pb.lineTo(p_rev.initialPoint() ); + } + + pb.append(p_rev); + + if (butt == butt_straight) { + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_round) { + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); + } else if (butt == butt_square) { + //don't know what to do + pb.lineTo(p_init.initialPoint() ); + } else if (butt == butt_pointy) { + //don't know what to do + //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); + //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); + + pb.lineTo(p_init.initialPoint() ); + } + } + else + { + //final join + //refer to half_outline for documentation + Geom::Path p_almost = path_in[lmnop]; + p_almost.appendNew ( path_in[lmnop].initialPoint() ); + p_init = Outline::half_outline_extrp( p_almost, -line_width, butt, + miter_lim ); + p_rev = Outline::half_outline_extrp( p_almost.reverse(), -line_width, butt, + miter_lim ); + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + + //this is a kludge, because I can't find how to make this work properly + bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), + path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == + (path_in[lmnop] [path_in[lmnop].size()].length())); + + p_almost = p_init; + if (lastIsLinear) + { + p_almost.erase_last(); p_almost.erase_last(); + } + + //outside test + Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); + Geom::Curve* cbc2 = p_almost[0].duplicate(); + + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //this is the outside path + + //reuse the old one + p_init = p_almost; + Outline::extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside, carry on :-) + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + + p_almost = p_rev; + if (lastIsLinear) + { + p_almost.erase(p_almost.begin() ); + p_almost.erase(p_almost.begin() ); + } + + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + + cbc1 = p_almost[p_almost.size() - 1].duplicate(); + cbc2 = p_almost[0].duplicate(); + + cross = Geom::crossings(*cbc1, *cbc2); + + if (cross.empty()) + { + //outside path + + p_init = p_almost; + extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); + pb.moveTo(p_init.initialPoint()); pb.append(p_init); + } + else + { + //inside + pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); + } + delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; + } + //pb.closePath(); + pb.flush(); + Geom::PathVector pv_np = pb.peek(); + //hack + for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) + { + path_out.push_back( pv_np[abcd] ); + } + } + else + { + p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); + p.Outline(&outlinepath, line_width / 2, join_pointy, butt, miter_lim); + std::vector *pv_p = outlinepath.MakePathVector(); + //hack + path_out.push_back( (*pv_p)[0].reverse() ); + delete pv_p; + } + } + return path_out; + } + +Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtType linecap_type, + join_typ linejoin_type, double miter_limit) +{ + std::vector path_out = std::vector(); + if (path_in.empty()) + { + return path_out; + } + Path p = Path(); + Path outlinepath = Path(); + for (unsigned i = 0; i < path_in.size(); i++) + { + p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); + } + + #define miter_lim fabs(line_width * miter_limit) + + //magic! + if (linejoin_type <= 2) + { + p.Outline(&outlinepath, line_width / 2, linejoin_type, + linecap_type, miter_lim); + //fix memory leak + std::vector *pv_p = outlinepath.MakePathVector(); + path_out = *pv_p; + delete pv_p; + + } else if (linejoin_type == 3) { + //reflected arc join + path_out = outlinePath(path_in, line_width, linejoin_type, + linecap_type , miter_lim); + + } else if (linejoin_type == 4) { + //extrapolated arc join + path_out = outlinePath_extr(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim); + + } + + #undef miter_lim + return path_out; +} + +} // namespace Outline + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h old mode 100755 new mode 100644 index 8aa2e38ad..1a363c35b --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -1,766 +1,25 @@ -#pragma once - -#include <2geom/path.h> -#include <2geom/circle.h> -#include <2geom/sbasis-to-bezier.h> -#include <2geom/shape.h> -#include <2geom/transforms.h> -#include <2geom/path-sink.h> - -#include -#include - -enum LineJoinType { - LINEJOIN_STRAIGHT, - LINEJOIN_ROUND, - LINEJOIN_POINTY, - LINEJOIN_REFLECTED, - LINEJOIN_EXTRAPOLATED -}; - -namespace Geom -{ - /** - * Refer to: Weisstein, Eric W. "Circle-Circle Intersection." - From MathWorld--A Wolfram Web Resource. - http://mathworld.wolfram.com/Circle-CircleIntersection.html - * - * @return 0 if no intersection - * @return 1 if one circle is contained in the other - * @return 2 if intersections are found (they are written to p0 and p1) - */ - static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, - Point & p0, Point & p1) - { - Point X0 = circle0.center(); - double r0 = circle0.ray(); - Point X1 = circle1.center(); - double r1 = circle1.ray(); - - /* dx and dy are the vertical and horizontal distances between - * the circle centers. - */ - Point D = X1 - X0; - - /* Determine the straight-line distance between the centers. */ - double d = L2(D); - - /* Check for solvability. */ - if (d > (r0 + r1)) - { - /* no solution. circles do not intersect. */ - return 0; - } - if (d <= fabs(r0 - r1)) - { - /* no solution. one circle is contained in the other */ - return 1; - } - - /* 'point 2' is the point where the line through the circle - * intersection points crosses the line between the circle - * centers. - */ - - /* Determine the distance from point 0 to point 2. */ - double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; - - /* Determine the coordinates of point 2. */ - Point p2 = X0 + D * (a/d); - - /* Determine the distance from point 2 to either of the - * intersection points. - */ - double h = std::sqrt((r0*r0) - (a*a)); - - /* Now determine the offsets of the intersection points from - * point 2. - */ - Point r = (h/d)*rot90(D); - - /* Determine the absolute intersection points. */ - p0 = p2 + r; - p1 = p2 - r; - - return 2; - } - /** - * Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t. - * Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt). - */ - static Circle touching_circle( D2 const &curve, double t, double tol=0.01 ) - { - D2 dM=derivative(curve); - if ( are_near(L2sq(dM(t)),0.) ) { - dM=derivative(dM); - } - if ( are_near(L2sq(dM(t)),0.) ) { // try second time - dM=derivative(dM); - } - Piecewise > unitv = unitVector(dM,tol); - Piecewise dMlength = dot(Piecewise >(dM),unitv); - Piecewise k = cross(derivative(unitv),unitv); - k = divide(k,dMlength,tol,3); - double curv = k(t); // note that this value is signed - - Geom::Point normal = unitTangentAt(curve, t).cw(); - double radius = 1/curv; - Geom::Point center = curve(t) + radius*normal; - return Geom::Circle(center, fabs(radius)); - } - - static std::vector split_at_cusps(const Geom::Path& in) - { - Geom::PathVector out = Geom::PathVector(); - Geom::Path temp = Geom::Path(); - - for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) - { - temp = Geom::Path(); - temp.append(in[path_descr]); - out.push_back(temp); - } - - return out; - } - - static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) - { - std::vector temp; - sbasis_to_bezier(temp, sbasis_in, 4); - return Geom::CubicBezier( temp ); - } - - static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, - Geom::Point const & origin_b, Geom::Point const & vector_b) - { - Geom::Coord denom = cross(vector_b, vector_a); - if (!Geom::are_near(denom,0.)){ - Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom; - return origin_a + t * vector_a; - } - return boost::none; - } -} - -namespace Outline -{ - - typedef Geom::D2 D2SB; - typedef Geom::Piecewise PWD2; - - static void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve*cbc2, Geom::Point endPt, double miter_limit) -{ - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - if (cross.empty()) - { - Geom::Path pth; - pth.append(*cbc1); - - Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); - - pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); - - - Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.); - Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0); - - Geom::Point points[2]; - int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]); - if (solutions == 2) - { - Geom::Point sol(0,0); - if ( dot(tang2,points[0]-endPt) > 0 ) - { - // points[0] is bad, choose points[1] - sol = points[1]; - } - else if ( dot(tang2,points[1]-endPt) > 0 ) { // points[0] could be good, now check points[1] - // points[1] is bad, choose points[0] - sol = points[0]; - } - else - { - // both points are good, choose nearest - sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? - points[0] : points[1]; - } - Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true); - Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true); - - if (arc0) - { - path_builder.append (arc0->toSBasis()); - delete arc0; - arc0 = NULL; - } - - if (arc1) - { - path_builder.append (arc1->toSBasis()); - delete arc1; - arc1 = NULL; - } - } - else - { - path_builder.appendNew (endPt); - } - } - else - { - path_builder.appendNew (endPt); - } -} - static Geom::Path half_outline_extrp(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) - { - Geom::PathVector pv = split_at_cusps(path_in); - unsigned m; - Path path_outline = Path(); - Path path_tangent = Path(); - - Geom::Point initialPoint; - Geom::Point endPoint; - - Geom::Path path_builder = Geom::Path(); - Geom::PathVector * pathvec; - - //load the first portion in before the loop starts - { - path_outline = Path(); - path_outline.LoadPath(pv[0], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - //now half of first cusp has been loaded - - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - //instead of array accessing twice, dereferencing used for clarity - initialPoint = (*pathvec)[0].initialPoint(); - - path_builder.start(initialPoint); - path_builder.append( (*pathvec)[0] ); - - path_outline = Path(); - path_outline.LoadPath(pv[1], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - - path_builder.append( (*pathvec)[0] ); - - //always set pointers null after deleting - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - for (m = 2; m < pv.size(); m++) - { - path_outline = Path(); - path_outline.LoadPath(pv[m], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - extrapolate_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - path_builder.append( (*pathvec)[0] ); - - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - return path_builder; - } - - //Create a reflected outline join. - //Note: it is generally recommended to let half_outline do this for you! - //path_builder: the path to append the curves to - //cbc1: the curve before the join - //cbc2: the curve after the join - //endPt: the point to end at - //miter_limit: the miter parameter - static void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit) - { - //the most important work for the reflected join is done here - - //determine where we are in the path. If we're on the inside, ignore - //and just lineTo. On the outside, we'll do a little reflection magic :) - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - if (cross.empty()) - { - //probably on the outside of the corner - Geom::Path pth; - pth.append(*cbc1); - - Geom::Point tang1 = Geom::unitTangentAt(pth.toPwSb()[0], 1); - - //reflect curves along the bevel - D2SB newcurve1 = pth.toPwSb()[0] * - Geom::reflection ( -Geom::rot90(tang1) , - cbc1->finalPoint() ); - - Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1)); - - pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); - - D2SB newcurve2 = pth.toPwSb()[0] * - Geom::reflection ( -Geom::rot90(tang2) , - cbc2->initialPoint() ); - Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2)); - - cross = Geom::crossings(bzr1, bzr2); - if ( cross.empty() ) - { - //std::cout << "Oops, no crossings!" << std::endl; - //curves didn't cross; default to miter - /*boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) - { - path_builder.appendNew (*p); - }*/ - //bevel - path_builder.appendNew( endPt ); - } - else - { - //join - std::pair sub1 = bzr1.subdivide(cross[0].ta); - std::pair sub2 = bzr2.subdivide(cross[0].tb); - - //@TODO joins have a strange tendency to cross themselves twice. Check this. - - //sections commented out are for general stability - path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); - path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); - } - } - else // cross.empty() - { - //probably on the inside of the corner - path_builder.appendNew ( endPt ); - } - } - - /** @brief Converts a path to one half of an outline. - * path_in: The input path to use. (To create the other side use path_in.reverse() ) - * line_width: the line width to use (usually you want to divide this by 2) - * linecap_type: (not used here) the cap to apply. Passed to libvarot. - * miter_limit: the miter parameter - */ - static Geom::Path half_outline(const Geom::Path& path_in, double line_width, ButtType linecap_type, double miter_limit) - { - Geom::PathVector pv = split_at_cusps(path_in); - unsigned m; - Path path_outline = Path(); - Path path_tangent = Path(); - //needed for closing the path - Geom::Point initialPoint; - Geom::Point endPoint; - - //some issues prevented me from using a PathBuilder here - //it seems like PathBuilder::peek() gave me a null reference exception - //and I was unable to get a stack trace on Windows, so had to switch to Linux - //to see what the hell was wrong. :( - //I wasted five hours opening it in IDAPro, VS2012, and GDB Windows - - /*Program received signal SIGSEGV, Segmentation fault. - 0x00000000006539ac in get_curves (this=0x0) - at /usr/include/c++/4.6/bits/locale_facets.h:1077 - 1077 { return __c; } - */ - - Geom::Path path_builder = Geom::Path(); - Geom::PathVector * pathvec; - - //load the first portion in before the loop starts - { - path_outline = Path(); - path_outline.LoadPath(pv[0], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - //now half of first cusp has been loaded - - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - //instead of array accessing twice, dereferencing used for clarity - initialPoint = (*pathvec)[0].initialPoint(); - - path_builder.start(initialPoint); - path_builder.append( (*pathvec)[0] ); - - path_outline = Path(); - path_outline.LoadPath(pv[1], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - path_tangent = Path(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - - path_builder.append( (*pathvec)[0] ); - - //always set pointers null after deleting - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - for (m = 2; m < pv.size(); m++) - { - path_outline = Path(); - path_outline.LoadPath(pv[m], Geom::Affine(), false, false); - path_outline.OutsideOutline(&path_tangent, line_width / 2, join_straight, linecap_type, 10); - - delete pathvec; pathvec = NULL; - pathvec = path_tangent.MakePathVector(); - - Geom::Curve *cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve *cbc2 = (*pathvec)[0][0].duplicate(); - - reflect_curves(path_builder, cbc1, cbc2, (*pathvec)[0].initialPoint(), miter_limit ); - path_builder.append( (*pathvec)[0] ); - - delete pathvec; pathvec = NULL; - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - - return path_builder; - } - - static Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim) - { - Path p = Path(); - Path outlinepath = Path(); - for (unsigned i = 0; i < path_in.size(); i++) - { - p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); - } - - Geom::PathVector path_out; - for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) - { - if (path_in[lmnop].size() > 1) - { - Geom::Path p_init; - Geom::Path p_rev; - Geom::PathBuilder pb = Geom::PathBuilder(); - - if ( !path_in[lmnop].closed() ) - { - p_init = Outline::half_outline( path_in[lmnop], -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline( path_in[lmnop].reverse(), -line_width, butt, - miter_lim ); - - pb.moveTo(p_init.initialPoint() ); - pb.append(p_init); - - //cap - if (butt == butt_straight) { - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } - - pb.append(p_rev); - - if (butt == butt_straight) { - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); - //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); - - pb.lineTo(p_init.initialPoint() ); - } - } - else - { - //final join - //refer to half_outline for documentation - Geom::Path p_almost = path_in[lmnop]; - p_almost.appendNew ( path_in[lmnop].initialPoint() ); - p_init = Outline::half_outline( p_almost, -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline( p_almost.reverse(), -line_width, butt, - miter_lim ); - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - - //this is a kludge, because I can't find how to make this work properly - bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), - path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == - (path_in[lmnop] [path_in[lmnop].size()].length())); - - p_almost = p_init; - if (lastIsLinear) - { - p_almost.erase_last(); p_almost.erase_last(); - } - - //outside test - Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); - Geom::Curve* cbc2 = p_almost[0].duplicate(); - - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //this is the outside path - - //reuse the old one - p_init = p_almost; - Outline::reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside, carry on :-) - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - - p_almost = p_rev; - if (lastIsLinear) - { - p_almost.erase(p_almost.begin() ); - p_almost.erase(p_almost.begin() ); - } - - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - - cbc1 = p_almost[p_almost.size() - 1].duplicate(); - cbc2 = p_almost[0].duplicate(); - - cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //outside path - - p_init = p_almost; - reflect_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - //pb.closePath(); - pb.flush(); - Geom::PathVector pv_np = pb.peek(); - //hack - for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) - { - path_out.push_back( pv_np[abcd] ); - } - } - else - { - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - p.Outline(&outlinepath, line_width / 2, join, butt, miter_lim); - std::vector *pv_p = outlinepath.MakePathVector(); - //hack - path_out.push_back( (*pv_p)[0].reverse() ); - delete pv_p; - } - } - return path_out; - } - static Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim) - { - Path p = Path(); - Path outlinepath = Path(); - for (unsigned i = 0; i < path_in.size(); i++) - { - p.LoadPath(path_in[i], Geom::Affine(), false, ( (i==0) ? false : true)); - } - - Geom::PathVector path_out; - for (unsigned lmnop = 0; lmnop < path_in.size(); lmnop++) - { - if (path_in[lmnop].size() > 1) - { - Geom::Path p_init; - Geom::Path p_rev; - Geom::PathBuilder pb = Geom::PathBuilder(); - - if ( !path_in[lmnop].closed() ) - { - p_init = Outline::half_outline_extrp( path_in[lmnop], -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline_extrp( path_in[lmnop].reverse(), -line_width, butt, - miter_lim ); - - pb.moveTo(p_init.initialPoint() ); - pb.append(p_init); - - //cap - if (butt == butt_straight) { - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_rev.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - pb.lineTo(p_rev.initialPoint() ); - } - - pb.append(p_rev); - - if (butt == butt_straight) { - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_round) { - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, p_init.initialPoint() ); - } else if (butt == butt_square) { - //don't know what to do - pb.lineTo(p_init.initialPoint() ); - } else if (butt == butt_pointy) { - //don't know what to do - //Geom::Point end_deriv = Geom::unitTangentAt( Geom::reverse(path_in[lmnop].toPwSb()[path_in[lmnop].size()]), 0); - //double radius = 0.5 * Geom::distance(path_in[lmnop].finalPoint(), p_rev.initialPoint()); - - pb.lineTo(p_init.initialPoint() ); - } - } - else - { - //final join - //refer to half_outline for documentation - Geom::Path p_almost = path_in[lmnop]; - p_almost.appendNew ( path_in[lmnop].initialPoint() ); - p_init = Outline::half_outline_extrp( p_almost, -line_width, butt, - miter_lim ); - p_rev = Outline::half_outline_extrp( p_almost.reverse(), -line_width, butt, - miter_lim ); - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - - //this is a kludge, because I can't find how to make this work properly - bool lastIsLinear = ( (Geom::distance(path_in[lmnop].finalPoint(), - path_in[lmnop] [path_in[lmnop].size() - 1].finalPoint())) == - (path_in[lmnop] [path_in[lmnop].size()].length())); - - p_almost = p_init; - if (lastIsLinear) - { - p_almost.erase_last(); p_almost.erase_last(); - } - - //outside test - Geom::Curve* cbc1 = p_almost[p_almost.size() - 1].duplicate(); - Geom::Curve* cbc2 = p_almost[0].duplicate(); - - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //this is the outside path - - //reuse the old one - p_init = p_almost; - Outline::extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside, carry on :-) - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - - p_almost = p_rev; - if (lastIsLinear) - { - p_almost.erase(p_almost.begin() ); - p_almost.erase(p_almost.begin() ); - } - - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - - cbc1 = p_almost[p_almost.size() - 1].duplicate(); - cbc2 = p_almost[0].duplicate(); - - cross = Geom::crossings(*cbc1, *cbc2); - - if (cross.empty()) - { - //outside path - - p_init = p_almost; - extrapolate_curves(p_init, cbc1, cbc2, p_almost.initialPoint(), miter_lim ); - pb.moveTo(p_init.initialPoint()); pb.append(p_init); - } - else - { - //inside - pb.moveTo(p_almost.initialPoint()); pb.append(p_almost); - } - delete cbc1; delete cbc2; cbc1 = cbc2 = NULL; - } - //pb.closePath(); - pb.flush(); - Geom::PathVector pv_np = pb.peek(); - //hack - for (unsigned abcd = 0; abcd < pv_np.size(); abcd++) - { - path_out.push_back( pv_np[abcd] ); - } - } - else - { - p.LoadPath(path_in[lmnop], Geom::Affine(), false, false); - p.Outline(&outlinepath, line_width / 2, join_pointy, butt, miter_lim); - std::vector *pv_p = outlinepath.MakePathVector(); - //hack - path_out.push_back( (*pv_p)[0].reverse() ); - delete pv_p; - } - } - return path_out; - } - - -} // namespace Outline - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +#ifndef _SEEN_PATH_OUTLINE_H +#define _SEEN_PATH_OUTLINE_H + +#include +#include + +enum LineJoinType { + LINEJOIN_STRAIGHT, + LINEJOIN_ROUND, + LINEJOIN_POINTY, + LINEJOIN_REFLECTED, + LINEJOIN_EXTRAPOLATED +}; + +namespace Outline +{ + unsigned bezierOrder (const Geom::Curve* curve_in); + std::vector PathVectorOutline(std::vector const & path_in, double line_width, ButtType linecap_type, + join_typ linejoin_type, double miter_limit); + + Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim); + Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim); +} + +#endif // _SEEN_PATH_OUTLINE_H diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 338233042..85583a0e7 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -1887,8 +1887,9 @@ ObjectsPanel::ObjectsPanel() : btn = Gtk::manage( new Gtk::Button() ); btn->set_tooltip_text(_("Collapse All")); #if GTK_CHECK_VERSION(3,10,0) - btn->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); + btn->set_image_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else + image_remove = Gtk::manage(new Gtk::Image()); image_remove->set_from_icon_name(INKSCAPE_ICON("gtk-unindent-ltr"), Gtk::ICON_SIZE_SMALL_TOOLBAR); btn->set_image(*image_remove); #endif -- cgit v1.2.3 From 7d6a2eac770b159a51183add6917eaec36729d80 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 23 Mar 2014 17:25:49 -0400 Subject: tiny bugfix for Taper Strokes (bzr r13090.1.30) --- src/live_effects/lpe-taperstroke.cpp | 54 ++++++++++++++++++++------------ src/live_effects/pathoutlineprovider.cpp | 33 +++++++++++++++++++ src/live_effects/pathoutlineprovider.h | 1 + 3 files changed, 68 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index a862417d7..0e709f3ac 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -324,40 +324,54 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) if (true) { Geom::PathVector real_pathv; + Geom::Path real_path; //Construct the pattern (pat_str stands for pattern string) - char pat_str[200]; - sprintf(pat_str, "M 1,0 1,1 C %5.5f,1 0,0.5 0,0.5 0,0.5 %5.5f,0 1,0 Z", 1 - (double)smoothing, 1 - (double)smoothing); - Geom::PathVector pat_vec = sp_svg_read_pathv(pat_str); + std::stringstream pat_str; + pat_str << "M 1,0 1,1 C " << 1 - (double)smoothing << ",1 0,0.5 0,0.5 0,0.5 " << 1 - double(smoothing) << ",0 1,0"; + + Geom::PathVector pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); Geom::Piecewise > pwd2; pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], line_width)); - real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0]); + Geom::Path throwaway_path = path_from_piecewise(pwd2, 0.001)[0].reverse(); + throwaway_path.erase_last(); - Geom::PathVector sht_path; - sht_path.push_back(pathv_out[1]); - sht_path = Outline::PathVectorOutline(sht_path, line_width, butt_straight, static_cast(join_type.get_value()) , miter_limit); + real_path.append(throwaway_path); //wtf - real_pathv.push_back(sht_path[0]); + throwaway_path = Outline::PathOutsideOutline(pathv_out[1], + line_width, static_cast(join_type.get_value()), miter_limit); + + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); - char pat_str_1[200]; - sprintf(pat_str_1, "M 0,0 0,1 C %5.5f,1 1,0.5 1,0.5 1,0.5 %5.5f,0 0,0 Z", (double)smoothing, (double)smoothing); - pat_vec = sp_svg_read_pathv(pat_str_1); + std::stringstream pat_str_1; + pat_str_1 << "M 0,0 0,1 C " << (double)smoothing << ",1 1,0.5 1,0.5 1,0.5 " << double(smoothing) << ",0 0,0"; + pat_vec = sp_svg_read_pathv(pat_str_1.str().c_str()); pwd2 = Geom::Piecewise > (); pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], line_width)); - real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0].reverse()); - //clever union - //Geom::Shape shape1 = Geom::sanitize(Geom::PathVector(1, real_pathv[0])); - //Geom::Shape shape2 = Geom::sanitize(Geom::PathVector(1, real_pathv[1])); - //Geom::Shape shape3 = Geom::boolop(shape1, shape2, Geom::BOOLOP_UNION); + throwaway_path = Geom::Path(); + throwaway_path = path_from_piecewise(pwd2, 0.001)[0]; + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); + + throwaway_path = Geom::Path(); + throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), + line_width, static_cast(join_type.get_value()), miter_limit); + + //throwaway_path = throwaway_path.reverse(); + throwaway_path.setInitial(real_path.finalPoint()); + + real_path.append(throwaway_path); + //real_path.close(); + + real_pathv.push_back(real_path); - //shape2 = Geom::sanitize(Geom::PathVector(1, real_pathv[2])); - //shape1 = Geom::boolop(shape3, shape2, Geom::BOOLOP_UNION); + //real_pathv.push_back(path_from_piecewise(pwd2, 0.001)[0].reverse()); - //real_pathv = Geom::desanitize(shape1); return real_pathv; } @@ -383,7 +397,7 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa trimmed_start.append(path_in[0] [i]); } - #define OVERLAP (0.001 / (line_width < 1 ? 1 : line_width)) + #define OVERLAP 0 /*(0.001 / (line_width < 1 ? 1 : line_width))*/ trimmed_start.append(*subdivide_at(curve_start, (attach_start - loc) + OVERLAP, true)); curve_start = subdivide_at(curve_start, attach_start - loc, false); diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index e62f516c9..302756c7c 100755 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -825,6 +825,39 @@ Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line #undef miter_lim return path_out; } +Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit) +{ + + #define miter_lim fabs(line_width * miter_limit) + + Geom::Path path_out; + + if (linejoin_type <= LINEJOIN_POINTY || path_in.size() <= 1) { + + Geom::PathVector * pathvec; + + Path path_tangent = Path(); + Path path_outline = Path(); + path_outline.LoadPath(path_in, Geom::Affine(), false, false); + path_outline.OutsideOutline(&path_tangent, line_width / 2, static_cast(linejoin_type), butt_straight, miter_lim); + + pathvec = path_tangent.MakePathVector(); + path_out = pathvec[0]/* deref pointer */[0]/*actual object ref*/; + delete pathvec; + return path_out; + } + else if (linejoin_type == LINEJOIN_REFLECTED) { + //reflected half outline + Geom::PathVector pathvec; pathvec.push_back(path_in); + path_out = half_outline(path_in, line_width, butt_straight, miter_lim); + return path_out; + } + else if (linejoin_type == LINEJOIN_EXTRAPOLATED) { + path_out = half_outline_extrp(path_in, line_width, butt_straight, miter_lim); + return path_out; + } + return path_out; +} } // namespace Outline diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h index 1a363c35b..4133f47c2 100644 --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -20,6 +20,7 @@ namespace Outline Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, JoinType join, ButtType butt, double miter_lim); Geom::PathVector outlinePath_extr(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim); + Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit); } #endif // _SEEN_PATH_OUTLINE_H -- cgit v1.2.3 From f7943d80067732ec4a0565077b26b32562a150d3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 27 Mar 2014 01:31:58 +0100 Subject: Adding cout << output to check bug in Geom::are_near (bzr r11950.1.314) --- src/live_effects/lpe-bspline.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index c19eda8f0..df98f0897 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -39,6 +39,7 @@ #include "inkscape.h" #include "desktop.h" +#include using Inkscape::DocumentUndo; @@ -347,14 +348,24 @@ LPEBSpline::changeWeight(double weightValue) bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint){ + using Geom::X; + using Geom::Y; + std::cout << "\n"; + std::cout << ":: Executed -> nodeIsSelected(Geom::Point nodePoint) ::\n"; + std::cout << "Want to check the argument -nodePoint- is in points vector \n"; + std::cout << "nodePoint::X=" << nodePoint[X] << ";Y=" << nodePoint[Y] << "\n"; + std::cout << "Checking points std::vector\n"; if(points.size() > 0){ - for(std::vector::iterator i = points.begin(); i != points.end();){ - Geom::Point p = static_cast(*i); + for(std::vector::iterator i = points.begin(); i != points.end(); ++i){ + Geom::Point p = *i; + std::cout << "p::X=" << p[X] << ";Y=" << p[Y] << "\n"; + std::cout << "Are near? "; if(Geom::are_near(p, nodePoint)){ + std::cout << "YES\n"; return true; - points.erase(i); + }else{ + std::cout << "NO\n"; } - i++; } } return false; @@ -367,17 +378,21 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) using Geom::Y; SPDesktop *desktop = inkscape_active_desktop(); if(INK_IS_NODE_TOOL(desktop->event_context)){ + std::cout << ":: Start -> doBSplineFromWidget(SPCurve * curve, double weightValue) ::\n"; + std::cout << "Inserting nodes selected into std::vector 'points'\n"; Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); Inkscape::UI::ControlPointSelection::Set &selection = nt->_selected_nodes->allPoints(); points.clear(); std::vector::iterator pbegin; for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i){ if ((*i)->selected()) { - Inkscape::UI::Node *n = static_cast(*i); + Inkscape::UI::Node *n = dynamic_cast(*i); pbegin = points.begin(); points.insert(pbegin,desktop->doc2dt(n->position())); + std::cout << "inserting point::X=" << desktop->doc2dt(n->position())[X] << ";Y=" << desktop->doc2dt(n->position())[Y] << "\n"; } } + std::cout << "End inserting selected nodes into vector\n"; } //bool hasNodesSelected = LPEBspline::hasNodesSelected(); if(curve->get_segment_count() < 2) @@ -629,6 +644,7 @@ LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) curve->append(nCurve,false); nCurve->reset(); delete nCurve; + std::cout << ":: End ::\n"; } } -- cgit v1.2.3 From f928fc556c8d7824dd920171b5de534cee4fe4ad Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 26 Mar 2014 21:32:07 -0400 Subject: Small performance and bug fixes (bzr r13090.1.33) --- src/live_effects/effect.cpp | 2 +- src/live_effects/lpe-taperstroke.cpp | 169 +++++++++++++++++++++-------------- 2 files changed, 101 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index d6840e5b8..337fe631f 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,7 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects +#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 91b8fd7bc..4ae1de923 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -232,9 +232,9 @@ Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_toler return path_out; } -Geom::Curve * subdivide_at(const Geom::Curve* curve_in, Geom::Coord time, bool first); Geom::Piecewise > stretch_along(Geom::Piecewise > pwd2_in, Geom::Path pattern, double width); + Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) { Geom::Path first_cusp = return_at_first_cusp(path_in[0]); @@ -255,21 +255,21 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) } //don't ever let it be zero - if (attach_start <= 0) { + if (attach_start <= 0.00000001) { attach_start.param_set_value( 0.00000001 ); + zeroStart = true; } - if (attach_end <= 0) { + if (attach_end <= 0.00000001) { attach_end.param_set_value( 0.00000001 ); + zeroEnd = true; } //don't let it be integer if (double(unsigned(attach_start)) == attach_start) { attach_start.param_set_value(attach_start - 0.00000001); - zeroStart = true; } if (double(unsigned(attach_end)) == attach_end) { - attach_end.param_set_value(attach_end - 0.00000001); - zeroStart = true; + attach_end.param_set_value(attach_end - 0.00000001); } unsigned allowed_start = first_cusp.size(); @@ -302,14 +302,11 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) if (!zeroStart) { //Construct the pattern (pat_str stands for pattern string) (yes, this is easier, trust me) std::stringstream pat_str; - pat_str << "M 1,0 1,1 C " << 1 - (double)smoothing << ",1 0,0.5 0,0.5 0,0.5 " << 1 - double(smoothing) << ",0 1,0"; + pat_str << "M 1,0 C " << 1 - (double)smoothing << ",0 0,0.5 0,0.5 0,0.5 " << 1 - (double)smoothing << ",1 1,1"; - pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); - - pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], line_width)); - - throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0].reverse(); - throwaway_path.erase_last(); //wtf + pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); + pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], line_width)); + throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; real_path.append(throwaway_path); } @@ -317,8 +314,12 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) throwaway_path = Outline::PathOutsideOutline(pathv_out[1], line_width, static_cast(join_type.get_value()), miter_limit); - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); + if (!zeroStart) { + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); + } else { + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + } if (!zeroEnd) { //append the ending taper @@ -336,10 +337,13 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //append the inside outline of the path (against direction) throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), line_width, static_cast(join_type.get_value()), miter_limit); - - throwaway_path.setInitial(real_path.finalPoint()); - - real_path.append(throwaway_path); + + if (!zeroEnd) { + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); + } else { + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + } real_path.close(); real_pathv.push_back(real_path); @@ -355,7 +359,7 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa //do subdivision and get out unsigned loc = (unsigned)attach_start; Geom::Curve * curve_start = path_in[0] [loc].duplicate(); - + std::vector pathv_out; Geom::Path path_out = Geom::Path(); @@ -365,25 +369,69 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa for (unsigned i = 0; i < loc; i++) { trimmed_start.append(path_in[0] [i]); } - - - trimmed_start.append(*subdivide_at(curve_start, (attach_start - loc), true)); - curve_start = subdivide_at(curve_start, attach_start - loc, false); + + + //this is pretty annoying + //previously I wrote a function for this but it wasted a lot of time + //so I optimized it back into here. + unsigned order = Outline::bezierOrder(curve_start); + switch (order) { + case 3: { + Geom::CubicBezier *cb = static_cast(curve_start); + std::pair cb_pair = cb->subdivide((attach_start - loc)); + trimmed_start.append(cb_pair.first); curve_start = cb_pair.second.duplicate(); //goes out of scope + break; + } + case 2: { + Geom::QuadraticBezier *qb = static_cast(curve_start); + std::pair qb_pair = qb->subdivide((attach_start - loc)); + trimmed_start.append(qb_pair.first); curve_start = qb_pair.second.duplicate(); + break; + } + case 1: { + Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); + std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide((attach_start - loc)); + trimmed_start.append(lb_pair.first); curve_start = lb_pair.second.duplicate(); + break; + } + } //special case: path is one segment long //special case: what if the two knots occupy the same segment? if ((size == 1) || ( size - unsigned(attach_end) - 1 == loc )) { Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_start); + //it is just a dumb segment //we have to do some shifting here because the value changed when we reduced the length //of the previous segment. - trimmed_end.append(*subdivide_at(curve_start, t, false)); + + order = Outline::bezierOrder(curve_start); + switch (order) { + case 3: { + Geom::CubicBezier *cb = static_cast(curve_start); + std::pair cb_pair = cb->subdivide(t); + trimmed_end.append(cb_pair.second); curve_start = cb_pair.first.duplicate(); + break; + } + case 2: { + Geom::QuadraticBezier *qb = static_cast(curve_start); + std::pair qb_pair = qb->subdivide(t); + trimmed_end.append(qb_pair.second); curve_start = qb_pair.first.duplicate(); + break; + } + case 1: { + Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); + std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); + trimmed_end.append(lb_pair.second); curve_start = lb_pair.first.duplicate(); + break; + } + } + for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); } - curve_start = subdivide_at(curve_start, t, true); path_out.append(*curve_start); pathv_out.push_back(trimmed_start); pathv_out.push_back(path_out); @@ -406,9 +454,28 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa Geom::Curve * curve_end = path_in[0] [loc].duplicate(); Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); - - trimmed_end.append(*subdivide_at(curve_end, t, false)); - curve_end = subdivide_at(curve_end, t, true); + + order = Outline::bezierOrder(curve_end); + switch (order) { + case 3: { + Geom::CubicBezier *cb = static_cast(curve_end); + std::pair cb_pair = cb->subdivide(t); + trimmed_end.append(cb_pair.second); curve_end = cb_pair.first.duplicate(); + break; + } + case 2: { + Geom::QuadraticBezier *qb = static_cast(curve_end); + std::pair qb_pair = qb->subdivide(t); + trimmed_end.append(qb_pair.second); curve_end = qb_pair.first.duplicate(); + break; + } + case 1: { + Geom::BezierCurveN<1> *lb = static_cast * >(curve_end); + std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); + trimmed_end.append(lb_pair.second); curve_end = lb_pair.first.duplicate(); + break; + } + } for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); @@ -424,44 +491,6 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa return pathv_out; } -Geom::Curve * subdivide_at(const Geom::Curve* curve_in, Geom::Coord time, bool first) -{ - //the only reason for this function is the lack of a subdivide function in the Curve class. - //you have to cast to Beziers to be able to use subdivide(t) - unsigned order = Outline::bezierOrder(curve_in); - Geom::Curve* curve_out = curve_in->duplicate(); - switch (order) - { - //these need to be scoped because of the variable 'c' - case 3: - { - Geom::CubicBezier c = first ? (dynamic_cast (curve_out))->subdivide(time).first : - (dynamic_cast (curve_out))->subdivide(time).second; - if (curve_out) delete curve_out; - curve_out = c.duplicate(); - break; - } - case 2: - { - Geom::QuadraticBezier c = first ? (dynamic_cast(curve_out))->subdivide(time).first : - (dynamic_cast(curve_out))->subdivide(time).second; - if (curve_out) delete curve_out; - curve_out = c.duplicate(); - break; - } - case 1: - { - Geom::BezierCurveN<1> c = first ? (dynamic_cast* >(curve_out))->subdivide(time).first : - (dynamic_cast* >(curve_out))->subdivide(time).second; - if (curve_out) delete curve_out; - curve_out = c.duplicate(); - break; - } - } - return curve_out; -} - - //most of the below code is verbatim from Pattern Along Path. However, it needed a little //tweaking to get it to work right in this case. @@ -587,8 +616,9 @@ namespace TpS { Piecewise > pwd2; Geom::Path p_in = return_at_first_cusp(pathv[0]); pwd2.concat(p_in.toPwSb()); + std::vector > > pwd_vec = split_at_discontinuities(pwd2); - double t0 = nearest_point(s, pwd2); + double t0 = nearest_point(s, pwd_vec[0]); lpe->attach_start.param_set_value(t0); // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. @@ -607,8 +637,9 @@ namespace TpS { Piecewise > pwd2; Geom::Path p_in = return_at_first_cusp(pathv[0].reverse()); pwd2.concat(p_in.toPwSb()); + std::vector > > pwd_vec = split_at_discontinuities(pwd2); - double t0 = nearest_point(s, pwd2); + double t0 = nearest_point(s, pwd_vec[0]); lpe->attach_end.param_set_value(t0); // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. -- cgit v1.2.3 From 8a082e274bc322596c217bbe7770904a3cb50cc2 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 29 Mar 2014 15:28:44 -0400 Subject: Fix build errors and a few small bugs (bzr r13090.1.36) --- src/live_effects/lpe-taperstroke.cpp | 4 ++-- .../parameter/powerstrokepointarray.cpp | 2 +- src/live_effects/pathoutlineprovider.cpp | 25 ++++++++++++++++++---- 3 files changed, 24 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/live_effects/lpe-taperstroke.cpp (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp old mode 100644 new mode 100755 index 8e6edfa2f..0e9752d31 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -279,10 +279,10 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //don't let it be integer if (double(unsigned(attach_start)) == attach_start) { - attach_start.param_set_value(attach_start - 0.00000001); + attach_start.param_set_value(attach_start - 0.00001); } if (double(unsigned(attach_end)) == attach_end) { - attach_end.param_set_value(attach_end - 0.00000001); + attach_end.param_set_value(attach_end - 0.00001); } unsigned allowed_start = first_cusp.size(); diff --git a/src/live_effects/parameter/powerstrokepointarray.cpp b/src/live_effects/parameter/powerstrokepointarray.cpp index 7fa837689..4ed8998fa 100644 --- a/src/live_effects/parameter/powerstrokepointarray.cpp +++ b/src/live_effects/parameter/powerstrokepointarray.cpp @@ -202,7 +202,7 @@ PowerStrokePointArrayParamKnotHolderEntity::knot_get() const void PowerStrokePointArrayParamKnotHolderEntity::knot_set_offset(Geom::Point offset) { _pparam->_vector.at(_index) = Geom::Point(offset.x(), offset.y() / 2); - this->parent_holder->knot_ungrabbed_handler(this->knot); + this->parent_holder->knot_ungrabbed_handler(this->knot, 0); } void diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index a5a7a044f..2a0da05b4 100755 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -220,8 +220,8 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit, bool outside = false) { - - if ( outside ) { + bool lineProblem = (dynamic_cast *>(cbc1)) || (dynamic_cast *>(cbc2)); + if ( outside && !lineProblem ) { Geom::Path pth; pth.append(*cbc1); @@ -273,9 +273,26 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } path_builder.appendNew (endPt); } - } else { + } + if ( outside && lineProblem ) { + Geom::Path pth; + pth.append(*cbc1); + Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(pth.toPwSb()[0]), 0.); + pth = Geom::Path(); + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + boost::optional p = intersection_point (cbc1->finalPoint(), tang1, + cbc2->initialPoint(), tang2); + if (p) + { + path_builder.appendNew (*p); + } path_builder.appendNew (endPt); - } + } + if ( !outside ) { + path_builder.appendNew (endPt); + } } void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit, bool outside = false) -- cgit v1.2.3 From e667170b1473faccbeabece0cef7d24ebf15bef9 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 29 Mar 2014 20:33:36 -0400 Subject: Minor fixes (bzr r13090.1.37) --- src/live_effects/lpe-taperstroke.cpp | 4 +- src/live_effects/pathoutlineprovider.cpp | 79 +++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 0e9752d31..b4e43209d 100755 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -352,8 +352,8 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) -fabs(line_width), static_cast(join_type.get_value()), miter_limit); if (!zeroEnd) { - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); + //throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); } else { real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); } diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index 2a0da05b4..6a47285a0 100755 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -1,5 +1,5 @@ #include "pathoutlineprovider.h" - +#include "livarot/path-description.h" #include <2geom/angle.h> #include <2geom/path.h> #include <2geom/circle.h> @@ -7,6 +7,7 @@ #include <2geom/shape.h> #include <2geom/transforms.h> #include <2geom/path-sink.h> +#include namespace Geom { @@ -163,7 +164,10 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) Geom::Point end_point; //assert(cbc1.finalPoint() == cbc2.initialPoint()); + //short circuiting? if (cbc1.finalPoint() != cbc2.initialPoint()) { + printf("There was an issue when asserting that one curve's end is the start of the other. Line %d, File %s\n" + "By default we are going to say that this is an inside join, so we cannot make a line join for it.\n", __LINE__, __FILE__); return false; } switch (order) @@ -218,7 +222,8 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) return false; } -void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit, bool outside = false) +void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, + double miter_limit, double line_width, bool outside = false) { bool lineProblem = (dynamic_cast *>(cbc1)) || (dynamic_cast *>(cbc2)); if ( outside && !lineProblem ) { @@ -269,7 +274,13 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve cbc2->initialPoint(), tang2); if (p) { - path_builder.appendNew (*p); + //check size of miter + Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; + Geom::Coord len = distance(*p, point_on_path); + if (len <= miter_limit) { + // miter OK + path_builder.appendNew (*p); + } } path_builder.appendNew (endPt); } @@ -286,7 +297,13 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve cbc2->initialPoint(), tang2); if (p) { - path_builder.appendNew (*p); + //check size of miter + Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; + Geom::Coord len = distance(*p, point_on_path); + if (len <= miter_limit) { + // miter OK + path_builder.appendNew (*p); + } } path_builder.appendNew (endPt); } @@ -295,7 +312,8 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } } -void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit, bool outside = false) +void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, + double miter_limit, double line_width, bool outside = false) { //the most important work for the reflected join is done here @@ -332,7 +350,13 @@ void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cb cbc2->initialPoint(), tang2); if (p) { - path_builder.appendNew (*p); + //check size of miter + Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; + Geom::Coord len = distance(*p, point_on_path); + if (len <= miter_limit) { + // miter OK + path_builder.appendNew (*p); + } } //bevel path_builder.appendNew( endPt ); @@ -395,10 +419,10 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate(); //do the reflection/extrapolation: - if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, - outside_angle ( pv[u - 1] [pv[u - 1].size()], pv[u] [0] )); } - else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, - outside_angle ( pv[u - 1] [pv[u - 1].size()], pv[u] [0] )); } + if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, + outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); } + else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, + outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); } } path_builder.append( (*path_vec)[0] ); @@ -420,9 +444,9 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate(); //do the reflection/extrapolation: - if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, + if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); } - else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, + else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); } //Now we can store it. @@ -449,10 +473,33 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, //since you've made it this far, hopefully all this is obvious :P Geom::Path with_direction; Geom::Path against_direction; - - with_direction = Outline::doAdvHalfOutline( path_in[i], -line_width, miter_lim, extrapolate ); - against_direction = Outline::doAdvHalfOutline( path_in[i].reverse(), -line_width, extrapolate ); - + if ( !path_in[i].closed() ) { + with_direction = Outline::doAdvHalfOutline( path_in[i], -line_width, miter_lim, extrapolate ); + against_direction = Outline::doAdvHalfOutline( path_in[i].reverse(), -line_width, miter_lim, extrapolate ); + } else { + //Geom::Path absolutely refuses to do what I want with these + Geom::Path newPath = path_in[i]; + newPath.close(false); + Geom::Piecewise > pwd2 = newPath.toPwSb(); + newPath = Geom::path_from_piecewise(pwd2, 0.01)[0]; + //fuk this + with_direction = Outline::doAdvHalfOutline( newPath, -line_width, miter_lim, extrapolate ); + against_direction = Outline::doAdvHalfOutline( newPath.reverse(), -line_width, miter_lim, extrapolate ); + + /*if (dynamic_cast *>(&newPath[newPath.size()])) { + //delete the 'Z' + newPath.erase_last(); + newPath.append(path_in[i][path_in[i].size() - 1]); + newPath.appendNew(newPath.initialPoint()); + newPath.erase_last(); + } else { + //delete the 'Z' + newPath.erase_last(); + newPath.append(path_in[i][path_in[i].size() - 1]); + newPath.appendNew(newPath.initialPoint()); + newPath.erase_last(); + }*/ + } Geom::PathBuilder pb; //add in the...do I really need to say this? -- cgit v1.2.3 From 9d5889926c9752867b244e9247843dd012cefdda Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 30 Mar 2014 23:53:17 +0200 Subject: clang-format bspline lpe files (bzr r11950.1.316) --- src/live_effects/lpe-bspline.cpp | 1182 ++++++++++++++++++++------------------ src/live_effects/lpe-bspline.h | 39 +- 2 files changed, 636 insertions(+), 585 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index df98f0897..09e71d833 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -2,7 +2,7 @@ /* * Released under GNU GPL, read the file 'COPYING' for more information */ - + #include #include #include @@ -46,606 +46,658 @@ using Inkscape::DocumentUndo; namespace Inkscape { namespace LivePathEffect { - - -LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : - Effect(lpeobject), - // initialise your parameters here: - //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, Geom::Point(100,100)), - steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2), - ignoreCusp(_("Ignore cusp nodes:"), _("Change ignoring cusp nodes"), "ignoreCusp", &wr, this, true), - onlySelected(_("Change only selected nodes:"), _("Change only selected nodes"), "onlySelected", &wr, this, false), - weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, 0.3334) -{ - registerParameter( dynamic_cast(&ignoreCusp) ); - registerParameter( dynamic_cast(&onlySelected) ); - registerParameter( dynamic_cast(&weight) ); - registerParameter( dynamic_cast(&steps) ); - weight.param_set_range(0.0000, 1); - weight.param_set_increments(0.1, 0.1); - weight.param_set_digits(4); - steps.param_set_range(1, 10); - steps.param_set_increments(1, 1); - steps.param_set_digits(0); +LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + // initialise your parameters here: + //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, + //Geom::Point(100,100)), + steps(_("Steps whith CTRL:"), + _("Change number of steps whith CTRL pressed"), "steps", &wr, this, + 2), + ignoreCusp(_("Ignore cusp nodes:"), _("Change ignoring cusp nodes"), + "ignoreCusp", &wr, this, true), + onlySelected(_("Change only selected nodes:"), + _("Change only selected nodes"), "onlySelected", &wr, this, + false), + weight(_("Change weight:"), _("Change weight of the effect"), "weight", + &wr, this, 0.3334) { + registerParameter(dynamic_cast(&ignoreCusp)); + registerParameter(dynamic_cast(&onlySelected)); + registerParameter(dynamic_cast(&weight)); + registerParameter(dynamic_cast(&steps)); + weight.param_set_range(0.0000, 1); + weight.param_set_increments(0.1, 0.1); + weight.param_set_digits(4); + steps.param_set_range(1, 10); + steps.param_set_increments(1, 1); + steps.param_set_digits(0); } -LPEBSpline::~LPEBSpline() -{ -} +LPEBSpline::~LPEBSpline() {} -void -LPEBSpline::createAndApply(const char* name, SPDocument *doc, SPItem *item) -{ - if (!SP_IS_SHAPE(item)) { - g_warning("LPE BSpline can only be applied to shapes (not groups)."); - }else{ - // Path effect definition - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); - repr->setAttribute("effect", name); +void LPEBSpline::createAndApply(const char *name, SPDocument *doc, + SPItem *item) { + if (!SP_IS_SHAPE(item)) { + g_warning("LPE BSpline can only be applied to shapes (not groups)."); + } else { + // Path effect definition + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); + repr->setAttribute("effect", name); - doc->getDefs()->getRepr()->addChild(repr, NULL); // adds to and assigns the 'id' attribute - const gchar * repr_id = repr->attribute("id"); - Inkscape::GC::release(repr); + doc->getDefs()->getRepr() + ->addChild(repr, NULL); // adds to and assigns the 'id' attribute + const gchar *repr_id = repr->attribute("id"); + Inkscape::GC::release(repr); - gchar *href = g_strdup_printf("#%s", repr_id); - SP_LPE_ITEM(item)->addPathEffect( href, true); - g_free(href); - } + gchar *href = g_strdup_printf("#%s", repr_id); + SP_LPE_ITEM(item)->addPathEffect(href, true); + g_free(href); + } } -void -LPEBSpline::doEffect(SPCurve * curve) -{ - if(curve->get_segment_count() < 2) - return; - // Make copy of old path as it is changed during processing - Geom::PathVector const original_pathv = curve->get_pathvector(); - curve->reset(); +void LPEBSpline::doEffect(SPCurve *curve) { + if (curve->get_segment_count() < 2) + return; + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); + curve->reset(); - //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... - if (path_it->empty()) - continue; - //Itreadores - - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing 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 - //dichos manejadores - SPCurve *nCurve = new SPCurve(); - Geom::Point previousNode(0,0); - Geom::Point node(0,0); - Geom::Point pointAt1(0,0); - Geom::Point pointAt2(0,0); - Geom::Point nextPointAt1(0,0); - Geom::Point nextPointAt2(0,0); - Geom::Point nextPointAt3(0,0); - Geom::D2< Geom::SBasis > SBasisIn; - Geom::D2< Geom::SBasis > SBasisOut; - Geom::D2< Geom::SBasis > SBasisHelper; - Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } - //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 - nCurve->moveto(curve_it1->initialPoint()); - //Recorremos todos los segmentos menos el último - while ( curve_it2 != curve_endit ) - { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - SPCurve * in = new SPCurve(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if(cubic){ - SBasisIn = in->first_segment()->toSBasis(); - pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())); - pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment())); - }else{ - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - } - in->reset(); - delete in; - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); - SPCurve * out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - cubic = dynamic_cast(&*curve_it2); - if(cubic){ - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));; - nextPointAt3 = out->first_segment()->finalPoint(); - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - } - out->reset(); - delete out; - //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 - SPCurve *lineHelper = new SPCurve(); - lineHelper->moveto(pointAt2); - lineHelper->lineto(nextPointAt1); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - delete lineHelper; - //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); - nCurve->curveto(pointAt1, pointAt2, node); - //aumentamos los valores para el siguiente paso en el bucle - ++curve_it1; - ++curve_it2; - } - //Si está cerrada la curva, la cerramos sobre el valor guardado previamente - //Si no finalizamos en el punto final - Geom::Point startNode(0,0); - if (path_it->closed()) { - SPCurve * start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - Geom::D2< Geom::SBasis > SBasisStart = start->first_segment()->toSBasis(); - SPCurve *lineHelper = new SPCurve(); - cubic = dynamic_cast(&*path_it->begin()); - if(cubic){ - lineHelper->moveto(SBasisStart.valueAt(Geom::nearest_point((*cubic)[1],*start->first_segment()))); - }else{ - lineHelper->moveto(start->first_segment()->initialPoint()); - } - start->reset(); - delete start; + //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... + if (path_it->empty()) + continue; + //Itreadores - SPCurve * end = new SPCurve(); - end->moveto(curve_it1->initialPoint()); - end->lineto(curve_it1->finalPoint()); - Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis(); - //Geom::BezierCurve const *bezier = dynamic_cast(&*curve_endit); - cubic = dynamic_cast(&*curve_it1); - if(cubic){ - lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment()))); - }else{ - lineHelper->lineto(end->first_segment()->finalPoint()); - } - end->reset(); - delete end; - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - delete lineHelper; - startNode = SBasisHelper.valueAt(0.5); - nCurve->curveto(nextPointAt1, nextPointAt2, startNode); - nCurve->move_endpoints(startNode,startNode); - }else{ - SPCurve * start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - startNode = start->first_segment()->initialPoint(); - start->reset(); - delete start; - nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->move_endpoints(startNode,nextPointAt3); - } - //y cerramos la curva - if (path_it->closed()) { - nCurve->closepath_current(); - } - curve->append(nCurve,false); - nCurve->reset(); - delete nCurve; + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = + ++(path_it->begin()); // outgoing 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 + //dichos manejadores + SPCurve *nCurve = new SPCurve(); + Geom::Point previousNode(0, 0); + Geom::Point node(0, 0); + Geom::Point pointAt1(0, 0); + Geom::Point pointAt2(0, 0); + Geom::Point nextPointAt1(0, 0); + Geom::Point nextPointAt2(0, 0); + Geom::Point nextPointAt3(0, 0); + Geom::D2 SBasisIn; + Geom::D2 SBasisOut; + Geom::D2 SBasisHelper; + Geom::CubicBezier const *cubic = NULL; + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + //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 + nCurve->moveto(curve_it1->initialPoint()); + //Recorremos todos los segmentos menos el último + while (curve_it2 != curve_endit) { + //previousPointAt3 = pointAt3; + //Calculamos los puntos que dividirían en tres segmentos iguales el path + //recto de entrada y de salida + SPCurve *in = new SPCurve(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + SBasisIn = in->first_segment()->toSBasis(); + pointAt1 = SBasisIn.valueAt( + Geom::nearest_point((*cubic)[1], *in->first_segment())); + pointAt2 = SBasisIn.valueAt( + Geom::nearest_point((*cubic)[2], *in->first_segment())); + } else { + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } + in->reset(); + delete in; + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + SPCurve *out = new SPCurve(); + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + cubic = dynamic_cast(&*curve_it2); + if (cubic) { + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt( + Geom::nearest_point((*cubic)[1], *out->first_segment())); + nextPointAt2 = SBasisOut.valueAt( + Geom::nearest_point((*cubic)[2], *out->first_segment())); + ; + nextPointAt3 = out->first_segment()->finalPoint(); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + } + out->reset(); + delete out; + //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 + SPCurve *lineHelper = new SPCurve(); + lineHelper->moveto(pointAt2); + lineHelper->lineto(nextPointAt1); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + delete lineHelper; + //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); + nCurve->curveto(pointAt1, pointAt2, node); + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + } + //Si está cerrada la curva, la cerramos sobre el valor guardado + //previamente + //Si no finalizamos en el punto final + Geom::Point startNode(0, 0); + if (path_it->closed()) { + SPCurve *start = new SPCurve(); + start->moveto(path_it->begin()->initialPoint()); + start->lineto(path_it->begin()->finalPoint()); + Geom::D2 SBasisStart = start->first_segment()->toSBasis(); + SPCurve *lineHelper = new SPCurve(); + cubic = dynamic_cast(&*path_it->begin()); + if (cubic) { + lineHelper->moveto(SBasisStart.valueAt( + Geom::nearest_point((*cubic)[1], *start->first_segment()))); + } else { + lineHelper->moveto(start->first_segment()->initialPoint()); + } + start->reset(); + delete start; + + SPCurve *end = new SPCurve(); + end->moveto(curve_it1->initialPoint()); + end->lineto(curve_it1->finalPoint()); + Geom::D2 SBasisEnd = end->first_segment()->toSBasis(); + //Geom::BezierCurve const *bezier = dynamic_cast(&*curve_endit); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + lineHelper->lineto(SBasisEnd.valueAt( + Geom::nearest_point((*cubic)[2], *end->first_segment()))); + } else { + lineHelper->lineto(end->first_segment()->finalPoint()); + } + end->reset(); + delete end; + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + delete lineHelper; + startNode = SBasisHelper.valueAt(0.5); + nCurve->curveto(nextPointAt1, nextPointAt2, startNode); + nCurve->move_endpoints(startNode, startNode); + } else { + SPCurve *start = new SPCurve(); + start->moveto(path_it->begin()->initialPoint()); + start->lineto(path_it->begin()->finalPoint()); + startNode = start->first_segment()->initialPoint(); + start->reset(); + delete start; + nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + nCurve->move_endpoints(startNode, nextPointAt3); } + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); + } + curve->append(nCurve, false); + nCurve->reset(); + delete nCurve; + } } -Gtk::Widget * -LPEBSpline::newWidget() -{ - // use manage here, because after deletion of Effect object, others might still be pointing to this widget. - Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); +Gtk::Widget *LPEBSpline::newWidget() { + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - vbox->set_border_width(5); - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter * param = *it; - Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); - if(param->param_key == "weight"||param->param_key == "steps"){ - Inkscape::UI::Widget::Scalar * widgRegistered = Gtk::manage(dynamic_cast(widg)); - widgRegistered->signal_value_changed().connect(sigc::mem_fun (*this,&LPEBSpline::toWeight)); - widg = dynamic_cast(widgRegistered); - } - if(param->param_key == "onlySelected"){ - Gtk::CheckButton * widgRegistered = Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widgRegistered); - } - if(param->param_key == "ignoreCusp"){ - Gtk::CheckButton * widgRegistered = Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widgRegistered); - } - Glib::ustring * tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } + vbox->set_border_width(5); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "weight" || param->param_key == "steps") { + Inkscape::UI::Widget::Scalar *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_value_changed() + .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); + widg = dynamic_cast(widgRegistered); + } + if (param->param_key == "onlySelected") { + Gtk::CheckButton *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widgRegistered); + } + if (param->param_key == "ignoreCusp") { + Gtk::CheckButton *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widgRegistered); + } + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); } - - ++it; + } } - Gtk::Button* defaultWeight = Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight 0.3334")))); - defaultWeight->set_alignment(0.0, 0.5); - defaultWeight->signal_clicked().connect(sigc::mem_fun (*this,&LPEBSpline::toDefaultWeight)); - Gtk::Widget* defaultWeightWidget = dynamic_cast(defaultWeight); - vbox->pack_start(*defaultWeightWidget, true, true,2); - Gtk::Button* makeCusp = Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); - makeCusp->set_alignment(0.0, 0.5); - makeCusp->signal_clicked().connect(sigc::mem_fun (*this,&LPEBSpline::toMakeCusp)); - Gtk::Widget* makeCuspWidget = dynamic_cast(makeCusp); - vbox->pack_start(*makeCuspWidget, true, true,2); - return dynamic_cast(vbox); -} -void -LPEBSpline::toDefaultWeight(){ - changeWeight(0.3334); + ++it; + } + Gtk::Button *defaultWeight = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight 0.3334")))); + defaultWeight->set_alignment(0.0, 0.5); + defaultWeight->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); + Gtk::Widget *defaultWeightWidget = dynamic_cast(defaultWeight); + vbox->pack_start(*defaultWeightWidget, true, true, 2); + Gtk::Button *makeCusp = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); + makeCusp->set_alignment(0.0, 0.5); + makeCusp->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); + Gtk::Widget *makeCuspWidget = dynamic_cast(makeCusp); + vbox->pack_start(*makeCuspWidget, true, true, 2); + return dynamic_cast(vbox); } -void -LPEBSpline::toMakeCusp(){ - changeWeight(0.0000); -} +void LPEBSpline::toDefaultWeight() { changeWeight(0.3334); } -void -LPEBSpline::toWeight(){ - changeWeight(weight); -} +void LPEBSpline::toMakeCusp() { changeWeight(0.0000); } -void -LPEBSpline::changeWeight(double weightValue) -{ - SPDesktop *desktop = inkscape_active_desktop(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList *items = (GSList *) selection->itemList(); - SPItem *item = (SPItem *)g_slist_nth(items,0)->data; - SPPath *path = SP_PATH(item); - SPCurve *curve = path->get_curve_for_edit(); - LPEBSpline::doBSplineFromWidget(curve,weightValue); - gchar *str = sp_svg_write_path(curve->get_pathvector()); - path->getRepr()->setAttribute("inkscape:original-d", str); - if(INK_IS_NODE_TOOL(desktop->event_context)){ - Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); - nt->desktop->updateNow(); - } - g_free(str); - curve->unref(); - desktop->clearWaitingCursor(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, - _("Modified the weight of the BSpline")); +void LPEBSpline::toWeight() { changeWeight(weight); } + +void LPEBSpline::changeWeight(double weightValue) { + SPDesktop *desktop = inkscape_active_desktop(); + Inkscape::Selection *selection = sp_desktop_selection(desktop); + GSList *items = (GSList *)selection->itemList(); + SPItem *item = (SPItem *)g_slist_nth(items, 0)->data; + SPPath *path = SP_PATH(item); + SPCurve *curve = path->get_curve_for_edit(); + LPEBSpline::doBSplineFromWidget(curve, weightValue); + gchar *str = sp_svg_write_path(curve->get_pathvector()); + path->getRepr()->setAttribute("inkscape:original-d", str); + if (INK_IS_NODE_TOOL(desktop->event_context)) { + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); + nt->desktop->updateNow(); + } + g_free(str); + curve->unref(); + desktop->clearWaitingCursor(); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, + _("Modified the weight of the BSpline")); } -bool -LPEBSpline::nodeIsSelected(Geom::Point nodePoint){ - using Geom::X; - using Geom::Y; - std::cout << "\n"; - std::cout << ":: Executed -> nodeIsSelected(Geom::Point nodePoint) ::\n"; - std::cout << "Want to check the argument -nodePoint- is in points vector \n"; - std::cout << "nodePoint::X=" << nodePoint[X] << ";Y=" << nodePoint[Y] << "\n"; - std::cout << "Checking points std::vector\n"; - if(points.size() > 0){ - for(std::vector::iterator i = points.begin(); i != points.end(); ++i){ - Geom::Point p = *i; - std::cout << "p::X=" << p[X] << ";Y=" << p[Y] << "\n"; - std::cout << "Are near? "; - if(Geom::are_near(p, nodePoint)){ - std::cout << "YES\n"; - return true; - }else{ - std::cout << "NO\n"; - } - } +bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint) { + using Geom::X; + using Geom::Y; + std::cout << "\n"; + std::cout << ":: Executed -> nodeIsSelected(Geom::Point nodePoint) ::\n"; + std::cout << "Want to check the argument -nodePoint- is in points vector \n"; + std::cout << "nodePoint::X=" << nodePoint[X] << ";Y=" << nodePoint[Y] << "\n"; + std::cout << "Checking points std::vector\n"; + if (points.size() > 0) { + for (std::vector::iterator i = points.begin(); + i != points.end(); ++i) { + Geom::Point p = *i; + std::cout << "p::X=" << p[X] << ";Y=" << p[Y] << "\n"; + std::cout << "Are near? "; + if (Geom::are_near(p, nodePoint)) { + std::cout << "YES\n"; + return true; + } else { + std::cout << "NO\n"; + } } - return false; + } + return false; } -void -LPEBSpline::doBSplineFromWidget(SPCurve * curve, double weightValue) -{ - using Geom::X; - using Geom::Y; - SPDesktop *desktop = inkscape_active_desktop(); - if(INK_IS_NODE_TOOL(desktop->event_context)){ - std::cout << ":: Start -> doBSplineFromWidget(SPCurve * curve, double weightValue) ::\n"; - std::cout << "Inserting nodes selected into std::vector 'points'\n"; - Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = nt->_selected_nodes->allPoints(); - points.clear(); - std::vector::iterator pbegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i){ - if ((*i)->selected()) { - Inkscape::UI::Node *n = dynamic_cast(*i); - pbegin = points.begin(); - points.insert(pbegin,desktop->doc2dt(n->position())); - std::cout << "inserting point::X=" << desktop->doc2dt(n->position())[X] << ";Y=" << desktop->doc2dt(n->position())[Y] << "\n"; - } - } - std::cout << "End inserting selected nodes into vector\n"; +void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { + using Geom::X; + using Geom::Y; + SPDesktop *desktop = inkscape_active_desktop(); + if (INK_IS_NODE_TOOL(desktop->event_context)) { + std::cout << ":: Start -> doBSplineFromWidget(SPCurve * curve, double " + "weightValue) ::\n"; + std::cout << "Inserting nodes selected into std::vector 'points'\n"; + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::ControlPointSelection::Set &selection = + nt->_selected_nodes->allPoints(); + points.clear(); + std::vector::iterator pbegin; + for (Inkscape::UI::ControlPointSelection::Set::iterator i = + selection.begin(); + i != selection.end(); ++i) { + if ((*i)->selected()) { + Inkscape::UI::Node *n = dynamic_cast(*i); + pbegin = points.begin(); + points.insert(pbegin, desktop->doc2dt(n->position())); + std::cout << "inserting point::X=" << desktop->doc2dt(n->position())[X] + << ";Y=" << desktop->doc2dt(n->position())[Y] << "\n"; + } } - //bool hasNodesSelected = LPEBspline::hasNodesSelected(); - if(curve->get_segment_count() < 2) - return; - // Make copy of old path as it is changed during processing - Geom::PathVector const original_pathv = curve->get_pathvector(); - curve->reset(); + std::cout << "End inserting selected nodes into vector\n"; + } + //bool hasNodesSelected = LPEBspline::hasNodesSelected(); + if (curve->get_segment_count() < 2) + return; + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); + curve->reset(); + + //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... + if (path_it->empty()) + continue; + //Itreadores - //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... - if (path_it->empty()) - continue; - //Itreadores - - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing 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 - //dichos manejadores - SPCurve *nCurve = new SPCurve(); - Geom::Point pointAt0(0,0); - Geom::Point pointAt1(0,0); - Geom::Point pointAt2(0,0); - Geom::Point pointAt3(0,0); - Geom::Point nextPointAt0(0,0); - Geom::Point nextPointAt1(0,0); - Geom::Point nextPointAt2(0,0); - Geom::Point nextPointAt3(0,0); - Geom::D2< Geom::SBasis > SBasisIn; - Geom::D2< Geom::SBasis > SBasisOut; - Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength. - const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = + ++(path_it->begin()); // outgoing 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 + //dichos manejadores + SPCurve *nCurve = new SPCurve(); + Geom::Point pointAt0(0, 0); + Geom::Point pointAt1(0, 0); + Geom::Point pointAt2(0, 0); + Geom::Point pointAt3(0, 0); + Geom::Point nextPointAt0(0, 0); + Geom::Point nextPointAt1(0, 0); + Geom::Point nextPointAt2(0, 0); + Geom::Point nextPointAt3(0, 0); + Geom::D2 SBasisIn; + Geom::D2 SBasisOut; + Geom::CubicBezier const *cubic = NULL; + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + //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 + nCurve->moveto(curve_it1->initialPoint()); + //Recorremos todos los segmentos menos el último + while (curve_it2 != curve_endit) { + //previousPointAt3 = pointAt3; + //Calculamos los puntos que dividirían en tres segmentos iguales el path + //recto de entrada y de salida + SPCurve *in = new SPCurve(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + pointAt0 = in->first_segment()->initialPoint(); + pointAt3 = in->first_segment()->finalPoint(); + SBasisIn = in->first_segment()->toSBasis(); + if (!onlySelected) { + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], pointAt0)) { + pointAt1 = SBasisIn.valueAt(weightValue); + if (weightValue != 0.0000) { + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } + } else { + pointAt1 = in->first_segment()->initialPoint(); + } + if (!ignoreCusp || !Geom::are_near((*cubic)[2], pointAt3)) { + pointAt2 = SBasisIn.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } + } else { + pointAt2 = in->first_segment()->finalPoint(); + } + } else { + if (!ignoreCusp && weightValue != 0.0000) { + pointAt1 = SBasisIn.valueAt(weightValue); + if (weightValue != 0.0000) { + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } + pointAt2 = SBasisIn.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); } + } else { + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->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 - nCurve->moveto(curve_it1->initialPoint()); - //Recorremos todos los segmentos menos el último - while ( curve_it2 != curve_endit ) - { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida - SPCurve * in = new SPCurve(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - pointAt0 = in->first_segment()->initialPoint(); - pointAt3 = in->first_segment()->finalPoint(); - SBasisIn = in->first_segment()->toSBasis(); - if(!onlySelected){ - if(cubic){ - if(!ignoreCusp || !Geom::are_near((*cubic)[1],pointAt0)){ - pointAt1 = SBasisIn.valueAt(weightValue); - if(weightValue !=0.0000){ - pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); - } - }else{ - pointAt1 = in->first_segment()->initialPoint(); - } - if(!ignoreCusp || !Geom::are_near((*cubic)[2],pointAt3)){ - pointAt2 = SBasisIn.valueAt(1-weightValue); - if(weightValue !=0.0000){ - pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); - } - }else{ - pointAt2 = in->first_segment()->finalPoint(); - } - }else{ - if(!ignoreCusp && weightValue !=0.0000){ - pointAt1 = SBasisIn.valueAt(weightValue); - if(weightValue !=0.0000){ - pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); - } - pointAt2 = SBasisIn.valueAt(1-weightValue); - if(weightValue !=0.0000){ - pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); - } - }else{ - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - } - } - }else{ - if(cubic){ - if(!ignoreCusp || !Geom::are_near((*cubic)[1],pointAt0)){ - if(nodeIsSelected(pointAt0)){ - pointAt1 = SBasisIn.valueAt(weightValue); - if(weightValue !=0.0000){ - pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); - } - }else{ - pointAt1 = (*cubic)[1]; - } - }else{ - pointAt1 = in->first_segment()->initialPoint(); - } - if(!ignoreCusp || !Geom::are_near((*cubic)[2],pointAt3)){ - if(nodeIsSelected(pointAt3)){ - pointAt2 = SBasisIn.valueAt(1-weightValue); - if(weightValue !=0.0000){ - pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); - } - }else{ - pointAt2 = (*cubic)[2]; - } - }else{ - pointAt2 = in->first_segment()->finalPoint(); - } - }else{ - if(!ignoreCusp && weightValue !=0.000){ - if(nodeIsSelected(pointAt0)){ - pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = Geom::Point(pointAt1[X] + 0.0001,pointAt1[Y] + 0.0001); - }else{ - pointAt1 = in->first_segment()->initialPoint(); - } - if(nodeIsSelected(pointAt3)){ - pointAt2 = SBasisIn.valueAt(weightValue); - pointAt2 = Geom::Point(pointAt2[X] + 0.0001,pointAt2[Y] + 0.0001); - }else{ - pointAt2 = in->first_segment()->finalPoint(); - } - }else{ - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - } - } + } else { + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], pointAt0)) { + if (nodeIsSelected(pointAt0)) { + pointAt1 = SBasisIn.valueAt(weightValue); + if (weightValue != 0.0000) { + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } + } else { + pointAt1 = (*cubic)[1]; } - in->reset(); - delete in; - //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 - nCurve->curveto(pointAt1, pointAt2, pointAt3); - //aumentamos los valores para el siguiente paso en el bucle - ++curve_it1; - ++curve_it2; + } else { + pointAt1 = in->first_segment()->initialPoint(); + } + if (!ignoreCusp || !Geom::are_near((*cubic)[2], pointAt3)) { + if (nodeIsSelected(pointAt3)) { + pointAt2 = SBasisIn.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } + } else { + pointAt2 = (*cubic)[2]; + } + } else { + pointAt2 = in->first_segment()->finalPoint(); + } + } else { + if (!ignoreCusp && weightValue != 0.000) { + if (nodeIsSelected(pointAt0)) { + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } else { + pointAt1 = in->first_segment()->initialPoint(); + } + if (nodeIsSelected(pointAt3)) { + pointAt2 = SBasisIn.valueAt(weightValue); + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } else { + pointAt2 = in->first_segment()->finalPoint(); + } + } else { + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } } - SPCurve * out = new SPCurve(); - out->moveto(curve_it1->initialPoint()); - out->lineto(curve_it1->finalPoint()); - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt0 = out->first_segment()->initialPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - cubic = dynamic_cast(&*curve_it1); - if(!onlySelected){ - if(cubic){ - if(!ignoreCusp || !Geom::are_near((*cubic)[1],nextPointAt0)){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - if(weightValue !=0.0000){ - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); - } - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - } - if(!ignoreCusp || !Geom::are_near((*cubic)[2],nextPointAt3)){ - nextPointAt2 = SBasisOut.valueAt(1-weightValue); - if(weightValue !=0.0000){ - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); - } - }else{ - nextPointAt2 = out->first_segment()->finalPoint(); - } - }else{ - if(!ignoreCusp && weightValue !=0.0000){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); - nextPointAt2 = SBasisOut.valueAt(1-weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - } - } - }else{ - if(cubic){ - if(!ignoreCusp || !Geom::are_near((*cubic)[1],nextPointAt0)){ - if(nodeIsSelected(nextPointAt0)){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - if(weightValue !=0.0000){ - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); - } - }else{ - nextPointAt1 = (*cubic)[1]; - } - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - } - if(!ignoreCusp || !Geom::are_near((*cubic)[2],nextPointAt3)){ - if(nodeIsSelected(nextPointAt3)){ - nextPointAt2 = SBasisOut.valueAt(1-weightValue); - if(weightValue !=0.0000){ - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); - } - }else{ - nextPointAt2 = (*cubic)[2]; - } - }else{ - nextPointAt2 = out->first_segment()->finalPoint(); - } - }else{ - if(!ignoreCusp && weightValue !=0.0000){ - if(nodeIsSelected(nextPointAt0)){ - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,nextPointAt1[Y] + 0.0001); - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - } - if(nodeIsSelected(nextPointAt3)){ - nextPointAt2 = SBasisOut.valueAt(weightValue); - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,nextPointAt2[Y] + 0.0001); - }else{ - nextPointAt2 = out->first_segment()->finalPoint(); - } - }else{ - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - } + } + in->reset(); + delete in; + //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 + nCurve->curveto(pointAt1, pointAt2, pointAt3); + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + } + SPCurve *out = new SPCurve(); + out->moveto(curve_it1->initialPoint()); + out->lineto(curve_it1->finalPoint()); + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt0 = out->first_segment()->initialPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + cubic = dynamic_cast(&*curve_it1); + if (!onlySelected) { + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + if (weightValue != 0.0000) { + nextPointAt1 = + Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); + } + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + } + if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) { + nextPointAt2 = SBasisOut.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + nextPointAt2 = + Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); + } + } else { + nextPointAt2 = out->first_segment()->finalPoint(); + } + } else { + if (!ignoreCusp && weightValue != 0.0000) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = + Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); + nextPointAt2 = SBasisOut.valueAt(1 - weightValue); + nextPointAt2 = + Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + } + } + } else { + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) { + if (nodeIsSelected(nextPointAt0)) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + if (weightValue != 0.0000) { + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001, + nextPointAt1[Y] + 0.0001); } + } else { + nextPointAt1 = (*cubic)[1]; + } + } else { + nextPointAt1 = out->first_segment()->initialPoint(); } - out->reset(); - delete out; - //Aberiguamos la ultima parte de la curva correspondiente al último segmento - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); - if (path_it->closed()) { - nCurve->curveto(nextPointAt1, nextPointAt2, path_it->begin()->initialPoint()); - nCurve->move_endpoints(path_it->begin()->initialPoint(),path_it->begin()->initialPoint()); - }else{ - nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->move_endpoints(path_it->begin()->initialPoint(),nextPointAt3); + if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) { + if (nodeIsSelected(nextPointAt3)) { + nextPointAt2 = SBasisOut.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001, + nextPointAt2[Y] + 0.0001); + } + } else { + nextPointAt2 = (*cubic)[2]; + } + } else { + nextPointAt2 = out->first_segment()->finalPoint(); } - //y cerramos la curva - if (path_it->closed()) { - nCurve->closepath_current(); + } else { + if (!ignoreCusp && weightValue != 0.0000) { + if (nodeIsSelected(nextPointAt0)) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = + Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + } + if (nodeIsSelected(nextPointAt3)) { + nextPointAt2 = SBasisOut.valueAt(weightValue); + nextPointAt2 = + Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); + } else { + nextPointAt2 = out->first_segment()->finalPoint(); + } + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); } - curve->append(nCurve,false); - nCurve->reset(); - delete nCurve; - std::cout << ":: End ::\n"; + } + } + out->reset(); + delete out; + //Aberiguamos la ultima parte de la curva correspondiente al último + //segmento + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + if (path_it->closed()) { + nCurve->curveto(nextPointAt1, nextPointAt2, + path_it->begin()->initialPoint()); + nCurve->move_endpoints(path_it->begin()->initialPoint(), + path_it->begin()->initialPoint()); + } else { + nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + nCurve->move_endpoints(path_it->begin()->initialPoint(), nextPointAt3); + } + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); } + curve->append(nCurve, false); + nCurve->reset(); + delete nCurve; + std::cout << ":: End ::\n"; + } } }; //namespace LivePathEffect diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 510f9c989..167810c49 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -11,46 +11,45 @@ #include "live_effects/parameter/bool.h" #include - namespace Inkscape { namespace LivePathEffect { class LPEBSpline : public Effect { public: - LPEBSpline(LivePathEffectObject *lpeobject); - virtual ~LPEBSpline(); + LPEBSpline(LivePathEffectObject *lpeobject); + virtual ~LPEBSpline(); - virtual void createAndApply(const char* name, SPDocument *doc, SPItem *item); + virtual void createAndApply(const char *name, SPDocument *doc, SPItem *item); - virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } + virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } - virtual void doEffect(SPCurve * curve); + virtual void doEffect(SPCurve *curve); - virtual void doBSplineFromWidget(SPCurve * curve, double value); + virtual void doBSplineFromWidget(SPCurve *curve, double value); - virtual bool nodeIsSelected(Geom::Point nodePoint); + virtual bool nodeIsSelected(Geom::Point nodePoint); - virtual Gtk::Widget * newWidget(); + virtual Gtk::Widget *newWidget(); - virtual void changeWeight(double weightValue); + virtual void changeWeight(double weightValue); - virtual void toDefaultWeight(); + virtual void toDefaultWeight(); - virtual void toMakeCusp(); + virtual void toMakeCusp(); - virtual void toWeight(); + virtual void toWeight(); - ScalarParam steps; + ScalarParam steps; private: - std::vector points; - BoolParam ignoreCusp; - BoolParam onlySelected; - ScalarParam weight; + std::vector points; + BoolParam ignoreCusp; + BoolParam onlySelected; + ScalarParam weight; - LPEBSpline(const LPEBSpline&); - LPEBSpline& operator=(const LPEBSpline&); + LPEBSpline(const LPEBSpline &); + LPEBSpline &operator=(const LPEBSpline &); }; -- cgit v1.2.3 From 10fcc833d8d5d02bc8b77b87c812fd9e723193a0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 31 Mar 2014 14:10:57 +0200 Subject: Fixed bug in LPE Bspline widget, on apply selected nodes, because a rounding problem. Thanks very much to Johan Engelen for point me to the correct direction. maybe is better round it previously to the are_near function, not sure (bzr r11950.1.318) --- src/live_effects/lpe-bspline.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 09e71d833..8254a13b6 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -39,8 +39,6 @@ #include "inkscape.h" #include "desktop.h" -#include - using Inkscape::DocumentUndo; namespace Inkscape { @@ -367,22 +365,14 @@ void LPEBSpline::changeWeight(double weightValue) { bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint) { using Geom::X; using Geom::Y; - std::cout << "\n"; - std::cout << ":: Executed -> nodeIsSelected(Geom::Point nodePoint) ::\n"; - std::cout << "Want to check the argument -nodePoint- is in points vector \n"; - std::cout << "nodePoint::X=" << nodePoint[X] << ";Y=" << nodePoint[Y] << "\n"; - std::cout << "Checking points std::vector\n"; + if (points.size() > 0) { for (std::vector::iterator i = points.begin(); i != points.end(); ++i) { Geom::Point p = *i; - std::cout << "p::X=" << p[X] << ";Y=" << p[Y] << "\n"; - std::cout << "Are near? "; - if (Geom::are_near(p, nodePoint)) { - std::cout << "YES\n"; + if (Geom::are_near(p, nodePoint, 0.0001)) { return true; } else { - std::cout << "NO\n"; } } } @@ -394,9 +384,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { using Geom::Y; SPDesktop *desktop = inkscape_active_desktop(); if (INK_IS_NODE_TOOL(desktop->event_context)) { - std::cout << ":: Start -> doBSplineFromWidget(SPCurve * curve, double " - "weightValue) ::\n"; - std::cout << "Inserting nodes selected into std::vector 'points'\n"; Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); Inkscape::UI::ControlPointSelection::Set &selection = nt->_selected_nodes->allPoints(); @@ -409,11 +396,8 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { Inkscape::UI::Node *n = dynamic_cast(*i); pbegin = points.begin(); points.insert(pbegin, desktop->doc2dt(n->position())); - std::cout << "inserting point::X=" << desktop->doc2dt(n->position())[X] - << ";Y=" << desktop->doc2dt(n->position())[Y] << "\n"; } } - std::cout << "End inserting selected nodes into vector\n"; } //bool hasNodesSelected = LPEBspline::hasNodesSelected(); if (curve->get_segment_count() < 2) @@ -696,7 +680,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { curve->append(nCurve, false); nCurve->reset(); delete nCurve; - std::cout << ":: End ::\n"; } } -- cgit v1.2.3 From e65f0ccd07f3b1278ba389025af29df498a3b3ab Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 31 Mar 2014 16:38:26 +0200 Subject: =?UTF-8?q?clarify=20the=20'sc'=20and=20'ec'=20SPCurve,=20by=20poi?= =?UTF-8?q?nt=20of=20Vin=C3=ADcius,=20whith=20the=20result=20of=20one=20cu?= =?UTF-8?q?rve=20less=20in=20the=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.320) --- src/ui/tools/freehand-base.cpp | 20 ++++++-------------- src/ui/tools/freehand-base.h | 7 +++++-- src/ui/tools/pen-tool.cpp | 18 ++++++++---------- src/ui/tools/pencil-tool.cpp | 4 +--- 4 files changed, 20 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index ac98be2cf..04796c2a6 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -91,10 +91,9 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , white_item(NULL) , white_curves(NULL) , white_anchors(NULL) + , overwriteCurve(NULL) , sa(NULL) - , sc(NULL) , ea(NULL) - , ec(NULL) , waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE) , red_curve_is_valid(false) , anchor_statusbar(false) @@ -156,10 +155,7 @@ void FreehandBase::setup() { this->green_closed = FALSE; // Create start anchor alternative curve - this->sc = new SPCurve(); - - // Create end anchor alternative curve - this->ec = new SPCurve(); + this->overwriteCurve = new SPCurve(); this->attach = TRUE; spdc_attach_selection(this, this->selection); @@ -533,12 +529,12 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) } if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - dc->sc->append_continuous(c, 0.0625); + dc->overwriteCurve->append_continuous(c, 0.0625); c->unref(); - dc->sc->closepath_current(); + dc->overwriteCurve->closepath_current(); if(dc->sa){ dc->white_curves = g_slist_remove(dc->white_curves, dc->sa->curve); - dc->white_curves = g_slist_append(dc->white_curves, dc->sc); + dc->white_curves = g_slist_append(dc->white_curves, dc->overwriteCurve); } }else{ dc->sa->curve->append_continuous(c, 0.0625); @@ -555,7 +551,7 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) dc->white_curves = g_slist_remove(dc->white_curves, s); if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - s = dc->sc; + s = dc->overwriteCurve; } if (dc->sa->start) { s = reverse_then_unref(s); @@ -566,10 +562,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) } else /* Step D - test end */ if (dc->ea) { SPCurve *e = dc->ea->curve; dc->white_curves = g_slist_remove(dc->white_curves, e); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - e = dc->ec; - } if (!dc->ea->start) { e = reverse_then_unref(e); } diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h index 2422c3563..6e04e03b7 100644 --- a/src/ui/tools/freehand-base.h +++ b/src/ui/tools/freehand-base.h @@ -79,13 +79,16 @@ public: GSList *white_curves; GSList *white_anchors; + //ALternative curve to use on continuing exisiting curve in case of bspline or spirolive + //because usigh anchor curves give memory and random bugs, - and obscure code- in some plataform reported by su_v in mac + SPCurve *overwriteCurve; + // Start anchor SPDrawAnchor *sa; - SPCurve *sc; // End anchor SPDrawAnchor *ea; - SPCurve *ec; + /* type of the LPE that is to be applied automatically to a finished path (if any) */ Inkscape::LivePathEffect::EffectType waiting_LPE_type; diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 053f1ac3d..1c0394e15 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -378,7 +378,6 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { Geom::Point event_dt(desktop->w2d(event_w)); //Test whether we hit any anchor. SPDrawAnchor * const anchor = spdc_test_inside(this, event_w); - ToolBase *event_context = SP_EVENT_CONTEXT(this); //with this we avoid creating a new point over the existing one if(bevent.button != 3 && (this->spiro || this->bspline) && this->npoints > 0 && this->p[0] == this->p[3]){ @@ -1535,7 +1534,7 @@ void PenTool::_bspline_spiro_start_anchor_on() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc = tmpCurve; + this->overwriteCurve = tmpCurve; } void PenTool::_bspline_spiro_start_anchor_off() @@ -1560,7 +1559,7 @@ void PenTool::_bspline_spiro_start_anchor_off() if (this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc = tmpCurve; + this->overwriteCurve = tmpCurve; } } @@ -1582,7 +1581,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ }else if(!this->green_curve->is_empty()){ tmpCurve = this->green_curve->copy(); }else{ - tmpCurve = this->sc->copy(); + tmpCurve = this->overwriteCurve->copy(); if(this->sa->start) tmpCurve = tmpCurve->create_reverse(); } @@ -1694,7 +1693,7 @@ void PenTool::_bspline_spiro_end_anchor_on() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc = tmpCurve; + this->overwriteCurve = tmpCurve; } } @@ -1742,8 +1741,8 @@ void PenTool::_bspline_spiro_end_anchor_off() if (!this->sa->start) { tmpCurve = tmpCurve->create_reverse(); } - this->sc->reset(); - this->sc = tmpCurve; + this->overwriteCurve->reset(); + this->overwriteCurve = tmpCurve; } } } @@ -1758,7 +1757,7 @@ void PenTool::_bspline_spiro_build() SPCurve *curve = new SPCurve(); //If we continuate the existing curve we add it at the start if(this->sa && !this->sa->curve->is_empty()){ - curve = this->sc->copy(); + curve = this->overwriteCurve->copy(); if (this->sa->start) { curve = curve->create_reverse(); } @@ -2191,8 +2190,7 @@ void PenTool::_finish(gboolean const closed) { // cancelate line without a created segment this->red_curve->reset(); spdc_concat_colors_and_flush(this, closed); - this->sc = NULL; - this->ec = NULL; + this->overwriteCurve = NULL; this->sa = NULL; this->ea = NULL; diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 6f55d361f..0e8660248 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -200,7 +200,7 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) { } if (anchor) { p = anchor->dp; - this->sc = anchor->curve; + this->overwriteCurve = anchor->curve; desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); } else { m.setup(desktop); @@ -372,7 +372,6 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /* Finish segment now */ if (anchor) { p = anchor->dp; - this->ec = anchor->curve; } else { this->_endpointSnap(p, revent.state); } @@ -398,7 +397,6 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) { /// \todo fixme: Clean up what follows (Lauris) if (anchor) { p = anchor->dp; - this->ec = anchor->curve; } else { Geom::Point p_end = p; this->_endpointSnap(p_end, revent.state); -- cgit v1.2.3 From ac61d9ff74ea5ee53ad39e95c22348da35ef5cf0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 31 Mar 2014 16:41:27 +0200 Subject: =?UTF-8?q?use=20=20instead=20=20by=20point=20of=20?= =?UTF-8?q?Vin=C3=ADcius?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.321) --- src/ui/tool/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 4824e13fb..3be3a89a7 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -28,7 +28,7 @@ #include "ui/tool/node.h" #include "ui/tool/path-manipulator.h" #include -#include +#include namespace { -- cgit v1.2.3 From 2b19c5f6508b7a59766d89f315f9f4fbc364f288 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Apr 2014 00:48:28 +0200 Subject: Some node.cpp/h work moved to path_manipulator. Header variable bsplineWeight removed from all. Simplification of code with less functions in path_manipulator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To fix: tips stop working because is handled by two static functions and couldent call to path_manipulator from here. Vinícius, any work arround? lines 480,481,1426,1427,1462 of node.cpp. gez: ¿Puedes probar si notas algun bug o problema? principalmente con la herramienta nodo, gracias. (bzr r11950.1.322) --- src/ui/tool/curve-drag-point.cpp | 4 +- src/ui/tool/node.cpp | 166 ++++++++++++++++++++++----------------- src/ui/tool/node.h | 2 - src/ui/tool/path-manipulator.cpp | 46 ++++------- src/ui/tool/path-manipulator.h | 10 +-- 5 files changed, 118 insertions(+), 110 deletions(-) (limited to 'src') diff --git a/src/ui/tool/curve-drag-point.cpp b/src/ui/tool/curve-drag-point.cpp index ad03cf75d..013553410 100644 --- a/src/ui/tool/curve-drag-point.cpp +++ b/src/ui/tool/curve-drag-point.cpp @@ -94,8 +94,8 @@ void CurveDragPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(!_pm.isBSpline(false)){ first->front()->move(first->front()->position() + offset0); second->back()->move(second->back()->position() + offset1); - }else if(weight>=0.8 && !second->isEndNode() && held_shift(*event))second->back()->move(new_pos); - else if(weight<=0.2 && !first->isEndNode() && held_shift(*event))first->front()->move(new_pos); + }else if(weight>=0.8 && held_shift(*event))second->back()->move(new_pos); + else if(weight<=0.2 && held_shift(*event))first->front()->move(new_pos); _pm.update(); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 3be3a89a7..1eaf0afa7 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -30,6 +30,7 @@ #include #include + namespace { Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) @@ -168,9 +169,9 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); //move the handler and its oposite the same proportion - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); } return; } @@ -185,9 +186,9 @@ void Handle::move(Geom::Point const &new_pos) setRelativePos(new_delta); //move the handler and its oposite the same proportion - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); } return; @@ -211,9 +212,9 @@ void Handle::move(Geom::Point const &new_pos) setPosition(new_pos); // moves the handler and its oposite the same proportion - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); } } @@ -305,9 +306,9 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven //this function moves the handler and its oposite to the default proportion of 0.3334 void Handle::handle_2button_press(){ - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(_pm().BSplineHandleReposition(this,0.3334)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),_parent->bsplineWeight)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),0.3334)); _pm().update(); } } @@ -361,17 +362,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) new_pos = result; // moves the handler and its oposite in X fixed positions depending on parameter "steps with control" // by default in live BSpline - if(_pm().isBSpline(false)){ + if(_pm().isBSpline()){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); - _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(this)*steps)/steps; - new_pos=_pm().BSplineHandleReposition(this,_parent->bsplineWeight); + new_pos=_pm().BSplineHandleReposition(this,ceilf(_pm().BSplineHandlePosition(this)*steps)/steps); } } std::vector unselected; //if the snap adjustment is activated and it is not bspline - if (snap && !_pm().isBSpline(false)) { + if (snap && !_pm().isBSpline()) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); @@ -412,7 +412,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } } //if it is bspline but SHIFT or CONTROL are not pressed it fixes it in the original position - if(_pm().isBSpline(false) && !held_shift(*event) && !held_control(*event)){ + if(_pm().isBSpline() && !held_shift(*event) && !held_control(*event)){ new_pos=_last_drag_origin(); } move(new_pos); // needed for correct update, even though it's redundant @@ -431,10 +431,6 @@ void Handle::ungrabbed(GdkEventButton *event) Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position()); if (dist.length() <= drag_tolerance) { move(_parent->position()); - //sets the bspline strength to 0.0000 - if(_pm().isBSpline(false)){ - _parent->bsplineWeight = 0.0000; - } } } @@ -481,8 +477,8 @@ Glib::ustring Handle::_getTip(unsigned state) const // to show the appropiate messages. We cannot do it in any different way becasue the function is constant bool isBSpline = false; - if( _parent->bsplineWeight != 0.0000) - isBSpline = true; + //if( _parent->bsplineWeight != 0.0000) + // isBSpline = true; bool can_shift_rotate = _parent->type() == NODE_CUSP && !other()->isDegenerate(); if (can_shift_rotate && !isBSpline) { more = C_("Path handle tip", "more: Shift, Ctrl, Alt"); @@ -622,11 +618,21 @@ void Node::move(Geom::Point const &new_pos) Geom::Point old_pos = position(); Geom::Point delta = new_pos - position(); - // save the previous node strength to apply it again once the node is moved - double oldPos = 0.0000; + // save the previous nodes strength to apply it again once the node is moved + double nodeWeight = 0.0000; + double nextNodeWeight = 0.0000; + double prevNodeWeight = 0.0000; Node *n = this; - if(_pm().isBSpline(false)){ - oldPos = n->bsplineWeight; + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + if(_pm().isBSpline()){ + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(nextNode){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + } + if(prevNode){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } } setPosition(new_pos); @@ -639,21 +645,49 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); // move the affected handlers. First the node ones, later the adjoining ones. - if(_pm().isBSpline(false)){ - _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); - _pm().BSplineNodeHandlesReposition(this); + if(_pm().isBSpline()){ + _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); + if(prevNode){ + if(prevNode->front()->isDegenerate()){ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); + }else{ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + } + } + if(nextNode){ + if(nextNode->back()->isDegenerate()){ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); + }else{ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + } + } } } void Node::transform(Geom::Affine const &m) { - // save the previous node strength to apply it again later when the node is moved - double oldPos = 0.0000; - if(_pm().isBSpline(false)){ - oldPos = this->bsplineWeight; - } + Geom::Point old_pos = position(); + + // save the previous nodes strength to apply it again once the node is moved + double nodeWeight = 0.0000; + double nextNodeWeight = 0.0000; + double prevNodeWeight = 0.0000; + + Node *n = this; + Node * nextNode = n->nodeToward(n->front()); + Node * prevNode = n->nodeToward(n->back()); + if(_pm().isBSpline()){ + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(nextNode){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + } + if(prevNode){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } + } + setPosition(position() * m); _front.setPosition(_front.position() * m); _back.setPosition(_back.position() * m); @@ -663,10 +697,23 @@ void Node::transform(Geom::Affine const &m) _fixNeighbors(old_pos, position()); // move the involved handlers, first the node ones, later the adjoining ones - if(_pm().isBSpline(false)){ - _front.setPosition(_pm().BSplineHandleReposition(this->front(),oldPos)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),oldPos)); - _pm().BSplineNodeHandlesReposition(this); + if(_pm().isBSpline()){ + _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); + if(prevNode){ + if(prevNode->front()->isDegenerate()){ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); + }else{ + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + } + } + if(nextNode){ + if(nextNode->back()->isDegenerate()){ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); + }else{ + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + } + } } } @@ -754,19 +801,6 @@ void Node::showHandles(bool v) _back.setVisible(v); } - // define the node strength, depending on being or not bspline traced. - // every time we operate over these handlers in a trace bspline - // that strength needs to be updated. - - this->bsplineWeight = 0.0000; - if(_pm().isBSpline(false) && (!_front.isDegenerate() || !_back.isDegenerate())){ - if (!_front.isDegenerate()) { - _pm().BSplineHandlePosition(&_front); - } - if (!_back.isDegenerate()) { - _pm().BSplineHandlePosition(&_back); - } - } } void Node::updateHandles() @@ -870,10 +904,13 @@ void Node::setType(NodeType type, bool update_handles) } /* in node type changes, about bspline traces, we can mantain them with 0.0000 power in border mode, or we give them the default power in curve mode */ - if(_pm().isBSpline(false)){ - if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334; - _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); - _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); + if(_pm().isBSpline()){ + double weight = 0.0000; + if(_pm().BSplineHandlePosition(this->front()) != 0.0000){ + weight = 0.3334; + } + _front.setPosition(_pm().BSplineHandleReposition(this->front(),weight)); + _back.setPosition(_pm().BSplineHandleReposition(this->back(),weight)); } } _type = type; @@ -1123,20 +1160,9 @@ void Node::_setState(State state) mgr.setActive(_canvas_item, true); mgr.setPrelight(_canvas_item, false); //this shows the handlers when selecting the nodes - if(_pm().isBSpline(false)){ - if(!this->back()->isDegenerate()){ - _pm().BSplineHandlePosition(this->back()); - }else if (!this->front()->isDegenerate()){ - _pm().BSplineHandlePosition(this->front()); - }else{ - this->bsplineWeight = 0.0000; - } - if(!this->front()->isDegenerate()){ - this->front()->setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight)); - } - if(!this->back()->isDegenerate()){ - this->back()->setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight)); - } + if(_pm().isBSpline()){ + this->front()->setPosition(_pm().BSplineHandleReposition(this->front())); + this->back()->setPosition(_pm().BSplineHandleReposition(this->back())); } break; } @@ -1397,8 +1423,8 @@ Glib::ustring Node::_getTip(unsigned state) const to show the appropiate messages. We cannot do it in any other way, because the function is constant */ bool isBSpline = false; - if( this->bsplineWeight != 0.0000) - isBSpline = true; + //if( this->bsplineWeight != 0.0000) + // isBSpline = true; if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { @@ -1433,7 +1459,7 @@ Glib::ustring Node::_getTip(unsigned state) const "%s: drag to shape the path (more: Shift, Ctrl, Alt)"), nodetype); }else if(_selection.size() == 1){ return format_tip(C_("Path node tip", - "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),this->bsplineWeight); + "BSpline node: %g weight, drag to shape the path (more: Shift, Ctrl, Alt)"),0.0000/*this->bsplineWeight*/); } return format_tip(C_("Path node tip", "%s: drag to shape the path, click to toggle scale/rotation handles (more: Shift, Ctrl, Alt)"), nodetype); diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index fc36502a5..202dbb3cd 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -191,8 +191,6 @@ public: bool isEndNode() const; Handle *front() { return &_front; } Handle *back() { return &_back; } - //strength value for each node - double bsplineWeight; /** * Gets the handle that faces the given adjacent node. diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 841ab659a..905df61f4 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -666,14 +666,11 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite } // if we are removing, we readjust the handlers if(isBSpline()){ - double pos = 0.0000; if(start.prev()){ - pos = BSplineHandlePosition(start.prev()->back()); - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),pos)); + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),true)); } if(end){ - pos = BSplineHandlePosition(end->front()); - end->back()->setPosition(BSplineHandleReposition(end->back(),pos)); + end->back()->setPosition(BSplineHandleReposition(end->back(),true)); } } @@ -1209,31 +1206,36 @@ bool PathManipulator::isBSpline(bool recalculate){ return _is_bspline; } -// returns the corresponding strength to the position of a handler -double PathManipulator::BSplineHandlePosition(Handle *h){ +// returns the corresponding strength to the position of the handlers +double PathManipulator::BSplineHandlePosition(Handle *h, bool other){ using Geom::X; using Geom::Y; double pos = 0.0000; Node *n = h->parent(); Node * nextNode = NULL; + if(other){ + h = h->other(); + } nextNode = n->nodeToward(h); - if(nextNode && n->position() != h->position()){ + if(nextNode && !Geom::are_near(n->position(), h->position())){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } - n->bsplineWeight = pos; + if ((pos == 0.0000 || pos == 1.0000) && other == false){ + return BSplineHandlePosition(h, true); + } return pos; } -// moves the handler to the corresponding position -Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){ - double pos = this->BSplineHandlePosition(h); +// give the location for the handler in the corresponding position +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, bool other){ + double pos = this->BSplineHandlePosition(h, other); return BSplineHandleReposition(h,pos); } -// moves the handler to the specified position +// give the location for the handler to the specified position Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; @@ -1247,34 +1249,16 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); - n->bsplineWeight = pos; ret = SBasisInsideNodes.valueAt(pos); ret = Geom::Point(ret[X] + 0.005,ret[Y] + 0.005); }else{ if(pos == 0.0000){ - n->bsplineWeight = 0.0000; ret = n->position(); } } return ret; } -//moves the node handlers and its oposite handlers to the strength of its nodes -void PathManipulator::BSplineNodeHandlesReposition(Node *n){ - Node * nextNode = n->nodeToward(n->front()); - Node * prevNode = n->nodeToward(n->back()); - if(prevNode){ - if(!prevNode->isEndNode()) - prevNode->back()->setPosition(BSplineHandleReposition(prevNode->back(),prevNode->bsplineWeight)); - prevNode->front()->setPosition(BSplineHandleReposition(prevNode->front(),prevNode->bsplineWeight)); - } - if(nextNode){ - if(!nextNode->isEndNode()) - nextNode->front()->setPosition(BSplineHandleReposition(nextNode->front(),nextNode->bsplineWeight)); - nextNode->back()->setPosition(BSplineHandleReposition(nextNode->back(),nextNode->bsplineWeight)); - } -} - /** 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 diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index f15533021..cba029b68 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -106,11 +106,11 @@ private: typedef boost::shared_ptr SubpathPtr; void _createControlPointsFromGeometry(); - bool isBSpline(bool recalculate = true); - double BSplineHandlePosition(Handle *h); - Geom::Point BSplineHandleReposition(Handle *h); - Geom::Point BSplineHandleReposition(Handle *h,double pos); - void BSplineNodeHandlesReposition(Node *n); + + bool isBSpline(bool recalculate = false); + double BSplineHandlePosition(Handle *h, bool other = false); + Geom::Point BSplineHandleReposition(Handle *h, bool other = false); + Geom::Point BSplineHandleReposition(Handle *h, double pos); void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); std::string _createTypeString(); -- cgit v1.2.3 From 0f78c1425e814758c0a0d7f0c2578eae88fe3ab6 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 1 Apr 2014 14:02:22 +0200 Subject: =?UTF-8?q?A=20refactor=20for=20fixing=20some=20issues.=20Pending?= =?UTF-8?q?=20how=20to=20handle=20static=20functions=20Vin=C3=ADcius=20for?= =?UTF-8?q?=20handle=20tips=20in=20his=20static=20functions=20i=20know=20t?= =?UTF-8?q?wo=20ways:=20A:=20A=20bool=20property=20in=20node=20class=20of?= =?UTF-8?q?=20node.h=20to=20handle=20if=20curve=20is=20bspline=20B:=20Call?= =?UTF-8?q?=20another=20non=20static=20function=20from=20the=20static=20ti?= =?UTF-8?q?ps=20one=20-not=20tested-?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (bzr r11950.1.323) --- src/ui/tool/node.cpp | 61 +++++++++++++++++++++------------------- src/ui/tool/path-manipulator.cpp | 22 +++++++-------- src/ui/tool/path-manipulator.h | 4 +-- 3 files changed, 45 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1eaf0afa7..7ba69b039 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -170,8 +170,8 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm().isBSpline()){ - setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); + setPosition(_pm().BSplineHandleReposition(this,this)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this)); } return; } @@ -187,8 +187,8 @@ void Handle::move(Geom::Point const &new_pos) //move the handler and its oposite the same proportion if(_pm().isBSpline()){ - setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); + setPosition(_pm().BSplineHandleReposition(this,this)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this)); } return; @@ -213,8 +213,8 @@ void Handle::move(Geom::Point const &new_pos) // moves the handler and its oposite the same proportion if(_pm().isBSpline()){ - setPosition(_pm().BSplineHandleReposition(this)); - this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),true)); + setPosition(_pm().BSplineHandleReposition(this,this)); + this->other()->setPosition(_pm().BSplineHandleReposition(this->other(),this)); } } @@ -365,7 +365,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) if(_pm().isBSpline()){ setPosition(new_pos); int steps = _pm().BSplineGetSteps(); - new_pos=_pm().BSplineHandleReposition(this,ceilf(_pm().BSplineHandlePosition(this)*steps)/steps); + new_pos=_pm().BSplineHandleReposition(this,ceilf(_pm().BSplineHandlePosition(this,this)*steps)/steps); } } @@ -625,13 +625,15 @@ void Node::move(Geom::Point const &new_pos) Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - if(_pm().isBSpline()){ - nodeWeight = _pm().BSplineHandlePosition(n->front()); - if(nextNode){ - nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(prevNode){ + if(prevNode->isEndNode()){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front(),prevNode->front()); } - if(prevNode){ - prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } + if(nextNode){ + if(nextNode->isEndNode()){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->back(),nextNode->back()); } } @@ -649,17 +651,17 @@ void Node::move(Geom::Point const &new_pos) _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); if(prevNode){ - if(prevNode->front()->isDegenerate()){ + if(prevNode->isEndNode()){ prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); }else{ - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNode->back())); } } if(nextNode){ - if(nextNode->back()->isDegenerate()){ + if(nextNode->isEndNode()){ nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->back())); } } } @@ -674,17 +676,18 @@ void Node::transform(Geom::Affine const &m) double nodeWeight = 0.0000; double nextNodeWeight = 0.0000; double prevNodeWeight = 0.0000; - Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - if(_pm().isBSpline()){ - nodeWeight = _pm().BSplineHandlePosition(n->front()); - if(nextNode){ - nextNodeWeight = _pm().BSplineHandlePosition(nextNode->front()); + nodeWeight = _pm().BSplineHandlePosition(n->front()); + if(prevNode){ + if(prevNode->isEndNode()){ + prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front(),prevNode->front()); } - if(prevNode){ - prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front()); + } + if(nextNode){ + if(nextNode->isEndNode()){ + nextNodeWeight = _pm().BSplineHandlePosition(nextNode->back(),nextNode->back()); } } @@ -701,17 +704,17 @@ void Node::transform(Geom::Affine const &m) _front.setPosition(_pm().BSplineHandleReposition(this->front(),nodeWeight)); _back.setPosition(_pm().BSplineHandleReposition(this->back(),nodeWeight)); if(prevNode){ - if(prevNode->front()->isDegenerate()){ + if(prevNode->isEndNode()){ prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNodeWeight)); }else{ - prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),true)); + prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevNode->back())); } } if(nextNode){ - if(nextNode->back()->isDegenerate()){ + if(nextNode->isEndNode()){ nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),true)); + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->front())); } } } @@ -906,7 +909,7 @@ void Node::setType(NodeType type, bool update_handles) or we give them the default power in curve mode */ if(_pm().isBSpline()){ double weight = 0.0000; - if(_pm().BSplineHandlePosition(this->front()) != 0.0000){ + if(_pm().BSplineHandlePosition(this->front()) != 0.0000 ){ weight = 0.3334; } _front.setPosition(_pm().BSplineHandleReposition(this->front(),weight)); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 905df61f4..487c31b10 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -667,10 +667,10 @@ unsigned PathManipulator::_deleteStretch(NodeList::iterator start, NodeList::ite // if we are removing, we readjust the handlers if(isBSpline()){ if(start.prev()){ - start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),true)); + start.prev()->front()->setPosition(BSplineHandleReposition(start.prev()->front(),start.prev()->back())); } if(end){ - end->back()->setPosition(BSplineHandleReposition(end->back(),true)); + end->back()->setPosition(BSplineHandleReposition(end->back(),end->front())); } } @@ -1207,31 +1207,31 @@ bool PathManipulator::isBSpline(bool recalculate){ } // returns the corresponding strength to the position of the handlers -double PathManipulator::BSplineHandlePosition(Handle *h, bool other){ +double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ using Geom::X; using Geom::Y; + if(h2){ + h = h2; + } double pos = 0.0000; Node *n = h->parent(); Node * nextNode = NULL; - if(other){ - h = h->other(); - } nextNode = n->nodeToward(h); - if(nextNode && !Geom::are_near(n->position(), h->position())){ + if(nextNode){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); } - if ((pos == 0.0000 || pos == 1.0000) && other == false){ - return BSplineHandlePosition(h, true); + if (pos == 0.0000 && !h2){ + return BSplineHandlePosition(h, h->other()); } return pos; } // give the location for the handler in the corresponding position -Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, bool other){ - double pos = this->BSplineHandlePosition(h, other); +Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2){ + double pos = this->BSplineHandlePosition(h, h2); return BSplineHandleReposition(h,pos); } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index cba029b68..a85664ddf 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -108,8 +108,8 @@ private: void _createControlPointsFromGeometry(); bool isBSpline(bool recalculate = false); - double BSplineHandlePosition(Handle *h, bool other = false); - Geom::Point BSplineHandleReposition(Handle *h, bool other = false); + double BSplineHandlePosition(Handle *h, Handle *h2 = NULL); + Geom::Point BSplineHandleReposition(Handle *h, Handle *h2 = NULL); Geom::Point BSplineHandleReposition(Handle *h, double pos); void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); -- cgit v1.2.3 From 355bfa5bf4d51f9d8c3fddf910a73ec7958d9a8a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 1 Apr 2014 18:38:26 -0400 Subject: Fix bug 1219324 (bzr r13090.1.40) --- src/sp-lpe-item.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 666c79e49..6324af147 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -36,6 +36,10 @@ #include "desktop.h" #include "shape-editor.h" #include "sp-ellipse.h" +#include "tools-switch.h" +#include "ui/tools/node-tool.h" +#include "ui/tools/tool-base.h" +#include "ui/tool/multi-path-manipulator.h" #include @@ -416,6 +420,17 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); + + //fix bug 1219324 + Inkscape::UI::Tools::NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(SP_ACTIVE_DESKTOP, TOOLS_LPETOOL); //mhh + tools_switch(SP_ACTIVE_DESKTOP, TOOLS_NODES); + } + } } } -- cgit v1.2.3 From 064e0f756b7525d4af0b8a34b3ef6fe89c007064 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Apr 2014 01:56:31 +0200 Subject: Refactor of end anchors. (bzr r11950.1.325) --- src/ui/tools/freehand-base.cpp | 19 +++++ src/ui/tools/pen-tool.cpp | 169 ++++++++++++++++++++--------------------- 2 files changed, 101 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 04796c2a6..1c5b7b8e3 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -565,6 +565,25 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) if (!dc->ea->start) { e = reverse_then_unref(e); } + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + e = reverse_then_unref(e); + Geom::CubicBezier const * cubic = dynamic_cast(&*e->last_segment()); + SPCurve *lastSeg = new SPCurve(); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + if( e->get_segment_count() == 1){ + e = lastSeg; + }else{ + //we eliminate the last segment + e->backspace(); + //and we add it again with the recreation + e->append_continuous(lastSeg, 0.0625); + } + } + e = reverse_then_unref(e); + } c->append_continuous(e, 0.0625); e->unref(); } diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 1c0394e15..9e4df5031 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1637,62 +1637,53 @@ void PenTool::_bspline_spiro_end_anchor_on() SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); - if(!this->sa || this->sa->curve->is_empty()){ + bool reverse = false; + if( this->green_anchor && this->green_anchor->active ){ tmpCurve = this->green_curve->create_reverse(); - if(this->green_curve->get_segment_count()==0)return; - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(this->bspline){ - C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); - }else{ - C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); - } - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); - }else{ - lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); - lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + if(this->green_curve->get_segment_count()==0){ + return; } - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); + reverse = true; + } else if(this->sa){ + tmpCurve = this->overwriteCurve; + if(!this->sa->start){ + tmpCurve = tmpCurve->create_reverse(); + reverse = true; } + }else{ + return; + } + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(this->bspline){ + C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); + C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); + }else{ + C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); + } + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); + }else{ + lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); + lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + } + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (reverse) { tmpCurve = tmpCurve->create_reverse(); + } + if( this->green_anchor && this->green_anchor->active ) + { this->green_curve->reset(); this->green_curve = tmpCurve; - }else { - tmpCurve = this->sa->curve->copy(); - if(!this->sa->start) tmpCurve = tmpCurve->create_reverse(); - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(this->bspline){ - C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); - }else{ - C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); - } - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); - }else{ - lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); - lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); - } - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } - if (!this->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } + }else{ + this->overwriteCurve->reset(); this->overwriteCurve = tmpCurve; } } @@ -1702,45 +1693,43 @@ void PenTool::_bspline_spiro_end_anchor_off() SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); + bool reverse = false; this->p[2] = this->p[3]; - if(!this->sa || this->sa->curve->is_empty()){ - + if( this->green_anchor && this->green_anchor->active ){ tmpCurve = this->green_curve->create_reverse(); - if(this->green_curve->get_segment_count()==0)return; - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } + if(this->green_curve->get_segment_count()==0){ + return; + } + reverse = true; + } else if(this->sa){ + tmpCurve = this->overwriteCurve; + if(!this->sa->start){ + tmpCurve = tmpCurve->create_reverse(); + reverse = true; + } + }else{ + return; + } + Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); + if(cubic){ + lastSeg->moveto((*cubic)[0]); + lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (reverse) { tmpCurve = tmpCurve->create_reverse(); + } + if( this->green_anchor && this->green_anchor->active ) + { this->green_curve->reset(); this->green_curve = tmpCurve; - } - }else { - tmpCurve = this->sa->curve->copy(); - if(!this->sa->start) tmpCurve = tmpCurve->create_reverse(); - Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); - if(cubic){ - lastSeg->moveto((*cubic)[0]); - lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } - if (!this->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } + }else{ this->overwriteCurve->reset(); this->overwriteCurve = tmpCurve; } @@ -1750,8 +1739,9 @@ void PenTool::_bspline_spiro_end_anchor_off() //prepares the curves for its transformation into BSpline curve. void PenTool::_bspline_spiro_build() { - if(!this->spiro && !this->bspline) + if(!this->spiro && !this->bspline){ return; + } //We create the base curve SPCurve *curve = new SPCurve(); @@ -1763,14 +1753,19 @@ void PenTool::_bspline_spiro_build() } } - if (!this->green_curve->is_empty()) + if (!this->green_curve->is_empty()){ curve->append_continuous(this->green_curve, 0.0625); + } //and the red one if (!this->red_curve->is_empty()){ this->red_curve->reset(); this->red_curve->moveto(this->p[0]); - this->red_curve->curveto(this->p[1],this->p[2],this->p[3]); + if(this->anchor_statusbar && !this->sa && !(this->green_anchor && this->green_anchor->active)){ + this->red_curve->curveto(this->p[1],this->p[3],this->p[3]); + }else{ + this->red_curve->curveto(this->p[1],this->p[2],this->p[3]); + } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), this->red_curve); curve->append_continuous(this->red_curve, 0.0625); } -- cgit v1.2.3 From f3e0966f95dc4284b1fd191fb4c187c92c24aeed Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 1 Apr 2014 20:40:15 -0400 Subject: Fix some stuff (bzr r13090.1.41) --- src/live_effects/effect.cpp | 10 +++++++++- src/live_effects/effect.h | 3 +++ src/sp-lpe-item.cpp | 13 +++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 337fe631f..8bf210270 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,7 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects +//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects #ifdef HAVE_CONFIG_H # include "config.h" @@ -365,6 +365,14 @@ Effect::doBeforeEffect (SPLPEItem const*/*lpeitem*/) //Do nothing for simple effects } +void Effect::doAfterEffect (SPLPEItem const* lpeitem) +{ +} + +void Effect::doOnRemove (SPLPEItem const* lpeitem) +{ +} + /** * Effects can have a parameter path set before they are applied by accepting a nonzero number of * mouse clicks. This method activates the pen context, which waits for the specified number of diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 1da9b4cc9..85c930def 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -55,6 +55,9 @@ public: virtual void doOnApply (SPLPEItem const* lpeitem); virtual void doBeforeEffect (SPLPEItem const* lpeitem); + + virtual void doAfterEffect (SPLPEItem const* lpeitem); + virtual void doOnRemove (SPLPEItem const* lpeitem); void writeParamsToSVG(); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 6324af147..71aa9545a 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -16,6 +16,9 @@ # include "config.h" #endif +//the gtk devs are really not smart about backwards compatibility +#include "ui/tool/multi-path-manipulator.h" + #include #include "live_effects/effect.h" @@ -39,7 +42,6 @@ #include "tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/tools/tool-base.h" -#include "ui/tool/multi-path-manipulator.h" #include @@ -254,6 +256,9 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { } return false; } + if (!SP_IS_GROUP(this)) { + lpe->doAfterEffect(this); + } } } } @@ -447,11 +452,15 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) Inkscape::LivePathEffect::LPEObjectReference* lperef = this->getCurrentLPEReference(); if (!lperef) return; - + + Inkscape::LivePathEffect::Effect * lpe = this->getCurrentLPE(); + lpe->doOnRemove(this); + PathEffectList new_list = *this->path_effect_list; new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list std::string r = patheffectlist_write_svg(new_list); + if (!r.empty()) { this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); } else { -- cgit v1.2.3 From f6d88348f785616f1872b537616ae84e11d94002 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 2 Apr 2014 09:50:04 +0200 Subject: Fix for Bug #1297557 (crash if document with linked color profile uses spaces in file name). Fixed bugs: - https://launchpad.net/bugs/1297557 (bzr r13249) --- src/color-profile.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/color-profile.cpp b/src/color-profile.cpp index ed4b9029e..aa0750c00 100644 --- a/src/color-profile.cpp +++ b/src/color-profile.cpp @@ -322,17 +322,15 @@ void ColorProfile::set(unsigned key, gchar const *value) { } //# 1. Get complete URI of document gchar const *docbase = doc->getURI(); - if (!docbase) - { - // Normal for files that have not yet been saved. - docbase = ""; - } gchar* escaped = g_uri_escape_string(this->href, "!*'();:@=+$,/?#[]", TRUE); //g_message("docbase:%s\n", docbase); //org::w3c::dom::URI docUri(docbase); - Inkscape::URI docUri(docbase); + Inkscape::URI docUri(""); + if (docbase) { // The file has already been saved + docUri = Inkscape::URI::from_native_filename(docbase); + } //# 2. Get href of icc file. we don't care if it's rel or abs //org::w3c::dom::URI hrefUri(escaped); -- cgit v1.2.3 From d20b73d611b6de99e0e0697ee47a760de437ee97 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 2 Apr 2014 17:18:40 -0400 Subject: Clean up code (bzr r13090.1.42) --- src/live_effects/lpe-taperstroke.cpp | 905 ++++++++++++++++--------------- src/live_effects/lpe-taperstroke.h | 48 +- src/live_effects/pathoutlineprovider.cpp | 521 +++++++++--------- src/live_effects/pathoutlineprovider.h | 16 +- 4 files changed, 765 insertions(+), 725 deletions(-) mode change 100755 => 100644 src/live_effects/lpe-taperstroke.cpp mode change 100755 => 100644 src/live_effects/pathoutlineprovider.cpp (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp old mode 100755 new mode 100644 index b4e43209d..97ae02e3b --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -38,26 +38,27 @@ namespace Inkscape { namespace LivePathEffect { namespace TpS { - class KnotHolderEntityAttachBegin : public LPEKnotHolderEntity { - public: - KnotHolderEntityAttachBegin(LPETaperStroke * effect) : LPEKnotHolderEntity(effect) {} - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; - }; - class KnotHolderEntityAttachEnd : public LPEKnotHolderEntity { - public: - KnotHolderEntityAttachEnd(LPETaperStroke * effect) : LPEKnotHolderEntity(effect) {} - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; - }; + class KnotHolderEntityAttachBegin : public LPEKnotHolderEntity { + public: + KnotHolderEntityAttachBegin(LPETaperStroke * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; + + class KnotHolderEntityAttachEnd : public LPEKnotHolderEntity { + public: + KnotHolderEntityAttachEnd(LPETaperStroke * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; } // TpS static const Util::EnumData JoinType[] = { - {LINEJOIN_STRAIGHT, N_("Beveled"), "bevel"}, - {LINEJOIN_ROUND, N_("Rounded"), "round"}, - {LINEJOIN_REFLECTED, N_("Reflected"), "reflected"}, - {LINEJOIN_POINTY, N_("Miter"), "miter"}, - {LINEJOIN_EXTRAPOLATED, N_("Extrapolated"), "extrapolated"} + {LINEJOIN_STRAIGHT, N_("Beveled"), "bevel"}, + {LINEJOIN_ROUND, N_("Rounded"), "round"}, + {LINEJOIN_REFLECTED, N_("Reflected"), "reflected"}, + {LINEJOIN_POINTY, N_("Miter"), "miter"}, + {LINEJOIN_EXTRAPOLATED, N_("Extrapolated"), "extrapolated"} }; static const Util::EnumDataConverter JoinTypeConverter(JoinType, sizeof (JoinType)/sizeof(*JoinType)); @@ -65,31 +66,30 @@ static const Util::EnumDataConverter JoinTypeConverter(JoinType, sizeo LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), line_width(_("Stroke width"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 3), - attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), - attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), - smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), - join_type(_("Join type"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), - miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 30.) + attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), + attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), + smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), + join_type(_("Join type"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), + miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 30.) { - /* uncomment the following line to have the original path displayed while the item is selected */ show_orig_path = true; - _provides_knotholder_entities = true; - - attach_start.param_set_digits(3); - attach_end.param_set_digits(3); - - - registerParameter( dynamic_cast(&line_width) ); - registerParameter( dynamic_cast(&attach_start) ); - registerParameter( dynamic_cast(&attach_end) ); - registerParameter( dynamic_cast(&smoothing) ); - registerParameter( dynamic_cast(&join_type) ); - registerParameter( dynamic_cast(&miter_limit) ); + _provides_knotholder_entities = true; + + attach_start.param_set_digits(3); + attach_end.param_set_digits(3); + + + registerParameter( dynamic_cast(&line_width) ); + registerParameter( dynamic_cast(&attach_start) ); + registerParameter( dynamic_cast(&attach_end) ); + registerParameter( dynamic_cast(&smoothing) ); + registerParameter( dynamic_cast(&join_type) ); + registerParameter( dynamic_cast(&miter_limit) ); } LPETaperStroke::~LPETaperStroke() { - + } //from LPEPowerStroke -- sets fill if stroke color because we will @@ -97,10 +97,10 @@ LPETaperStroke::~LPETaperStroke() void LPETaperStroke::doOnApply(SPLPEItem const* lpeitem) { - if (SP_IS_SHAPE(lpeitem)) { + if (SP_IS_SHAPE(lpeitem)) { SPLPEItem* item = const_cast(lpeitem); double width = (lpeitem && lpeitem->style) ? lpeitem->style->stroke_width.computed : 1.; - + SPCSSAttr *css = sp_repr_css_attr_new (); if (lpeitem->style->stroke.isSet()) { if (lpeitem->style->stroke.isPaintserver()) { @@ -122,13 +122,13 @@ void LPETaperStroke::doOnApply(SPLPEItem const* lpeitem) } else { sp_repr_css_unset_property (css, "fill"); } - + sp_repr_css_set_property(css, "stroke", "none"); - + sp_desktop_apply_css_recursive(item, css, true); sp_repr_css_attr_unref (css); - line_width.param_set_value(width); + line_width.param_set_value(width); } else { g_warning("LPE Join Type can only be applied to paths (not groups)."); } @@ -138,8 +138,10 @@ void LPETaperStroke::doOnApply(SPLPEItem const* lpeitem) void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem) { - - if (SP_IS_SHAPE(lpeitem)) { + + if (SP_IS_SHAPE(lpeitem)) { + //TODO: make it getobjbyrepr instead of const_cast because this can cause + //undefined behavior SPLPEItem *item = const_cast(lpeitem); SPCSSAttr *css = sp_repr_css_attr_new (); @@ -164,7 +166,7 @@ void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem) sp_repr_css_unset_property (css, "stroke"); } - Inkscape::CSSOStringStream os; + Inkscape::CSSOStringStream os; os << fabs(line_width); sp_repr_css_set_property (css, "stroke-width", os.str().c_str()); @@ -173,335 +175,347 @@ void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem) sp_desktop_apply_css_recursive(item, css, true); sp_repr_css_attr_unref (css); item->updateRepr(); - } + } } //actual effect impl here Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_tolerance = 0.05) { - Geom::Path path_out = Geom::Path(); - - for (unsigned i = 0; i < path_in.size(); i++) - { - path_out.append(path_in[i]); - if (path_in.size() == 1) - break; - - //determine order of curve - int order = Outline::bezierOrder(&path_in[i]); - - Geom::Point start_point; - Geom::Point cross_point = path_in[i].finalPoint(); - Geom::Point end_point; - - g_assert(path_in[i].finalPoint() == path_in[i+1].initialPoint()); - - //can you tell that the following expressions have been shaped by - //repeated compiler errors? ;) - switch (order) - { - case 3: - start_point = (static_cast(&path_in[i]))->operator[] (2); - //major league b***f***ing - if (are_near(start_point, cross_point, 0.0000001)) { - start_point = (static_cast(&path_in[i]))->operator[] (1); - } - break; - case 2: - //this never happens - start_point = (static_cast(&path_in[i]))->operator[] (1); - break; - case 1: - default: - start_point = path_in[i].initialPoint(); - } - - order = Outline::bezierOrder(&path_in[i+1]); - - switch (order) - { - case 3: - end_point = (static_cast(&path_in[i+1]))->operator[] (1); - if (are_near(end_point, cross_point, 0.0000001)) { - end_point = (static_cast(&path_in[i+1]))->operator[] (2); - } - break; - case 2: - end_point = (static_cast(&path_in[i+1]))->operator[] (1); - break; - case 1: - default: - end_point = path_in[i+1].finalPoint(); - } - - g_assert(!are_near(start_point, cross_point, 0.0000001)); //take that motherf*ckers - g_assert(!are_near(cross_point, end_point, 0.0000001)); - g_assert(!are_near(start_point, end_point, 0.0000001)); - - if (!are_collinear(start_point, cross_point, end_point, smooth_tolerance)) - break; - } - return path_out; + Geom::Path path_out = Geom::Path(); + + for (unsigned i = 0; i < path_in.size(); i++) { + path_out.append(path_in[i]); + if (path_in.size() == 1) + break; + + //determine order of curve + int order = Outline::bezierOrder(&path_in[i]); + + Geom::Point start_point; + Geom::Point cross_point = path_in[i].finalPoint(); + Geom::Point end_point; + + g_assert(path_in[i].finalPoint() == path_in[i+1].initialPoint()); + + //can you tell that the following expressions have been shaped by + //repeated compiler errors? ;) + switch (order) { + case 3: + start_point = (static_cast(&path_in[i]))->operator[] (2); + //major league b***f***ing + if (are_near(start_point, cross_point, 0.0000001)) { + start_point = (static_cast(&path_in[i]))->operator[] (1); + } + break; + case 2: + //this never happens + start_point = (static_cast(&path_in[i]))->operator[] (1); + break; + case 1: + default: + start_point = path_in[i].initialPoint(); + } + + order = Outline::bezierOrder(&path_in[i+1]); + + switch (order) { + case 3: + end_point = (static_cast(&path_in[i+1]))->operator[] (1); + if (are_near(end_point, cross_point, 0.0000001)) { + end_point = (static_cast(&path_in[i+1]))->operator[] (2); + } + break; + case 2: + end_point = (static_cast(&path_in[i+1]))->operator[] (1); + break; + case 1: + default: + end_point = path_in[i+1].finalPoint(); + } + + //clearly it's collinear if two occupy the same point + g_assert(!are_near(start_point, cross_point, 0.0000001)); + g_assert(!are_near(cross_point, end_point, 0.0000001)); + g_assert(!are_near(start_point, end_point, 0.0000001)); + + if (!are_collinear(start_point, cross_point, end_point, smooth_tolerance)) + break; + } + return path_out; } Geom::Piecewise > stretch_along(Geom::Piecewise > pwd2_in, Geom::Path pattern, double width); +//references to pointers, because magic +void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second); Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) { - Geom::Path first_cusp = return_at_first_cusp(path_in[0]); - Geom::Path last_cusp = return_at_first_cusp(path_in[0].reverse()); - - bool zeroStart = false; - bool zeroEnd = false; - //there is a pretty good chance that people will try to drag the knots - //on top of each other, so block it - - unsigned size = path_in[0].size(); - if (size == first_cusp.size()) { - //check to see if the knots were dragged over each other - //if so, reset the end offset - if ( attach_start >= (size - attach_end) ) { - attach_end.param_set_value( size - attach_start ); - } - } - - //don't ever let it be zero - if (attach_start <= 0.00000001) { - attach_start.param_set_value( 0.00000001 ); - zeroStart = true; - } - if (attach_end <= 0.00000001) { - attach_end.param_set_value( 0.00000001 ); - zeroEnd = true; - } - - //don't let it be integer - if (double(unsigned(attach_start)) == attach_start) { - attach_start.param_set_value(attach_start - 0.00001); - } - if (double(unsigned(attach_end)) == attach_end) { - attach_end.param_set_value(attach_end - 0.00001); - } - - unsigned allowed_start = first_cusp.size(); - unsigned allowed_end = last_cusp.size(); - - //don't let the knots be farther than they are allowed to be - if ((unsigned)attach_start >= allowed_start) { - attach_start.param_set_value((double)allowed_start - 0.00000001); - } - if ((unsigned)attach_end >= allowed_end) { - attach_end.param_set_value((double)allowed_end - 0.00000001); - } - - //remember, Path::operator () means get point at time t - start_attach_point = first_cusp(attach_start); - end_attach_point = last_cusp(attach_end); - Geom::PathVector pathv_out; - - //the following function just splits it up into three pieces. - pathv_out = doEffect_simplePath(path_in); - - //now for the actual tapering. We use a Pattern Along Path method to get this done. - - Geom::PathVector real_pathv; - Geom::Path real_path; - Geom::PathVector pat_vec; - Geom::Piecewise > pwd2; - Geom::Path throwaway_path; - - if (!zeroStart) { - //Construct the pattern (pat_str stands for pattern string) (yes, this is easier, trust me) - std::stringstream pat_str; - pat_str << "M 1,0 C " << 1 - (double)smoothing << ",0 0,0.5 0,0.5 0,0.5 " << 1 - (double)smoothing << ",1 1,1"; - - pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); - pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], -fabs(line_width))); - throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; - - real_path.append(throwaway_path); - } - //append the outside outline of the path (with direction) - throwaway_path = Outline::PathOutsideOutline(pathv_out[1], - -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - - if (!zeroStart) { - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); - } else { - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); - } - - if (!zeroEnd) { - //append the ending taper - std::stringstream pat_str_1; - pat_str_1 << "M 0,0 0,1 C " << (double)smoothing << ",1 1,0.5 1,0.5 1,0.5 " << double(smoothing) << ",0 0,0"; - pat_vec = sp_svg_read_pathv(pat_str_1.str().c_str()); - - pwd2 = Geom::Piecewise > (); - pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], -fabs(line_width))); - - throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); - } - //append the inside outline of the path (against direction) - throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), - -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - - if (!zeroEnd) { - //throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); - } else { - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); - } - real_path.close(); - - real_pathv.push_back(real_path); - - return real_pathv; + Geom::Path first_cusp = return_at_first_cusp(path_in[0]); + Geom::Path last_cusp = return_at_first_cusp(path_in[0].reverse()); + + bool zeroStart = false; + bool zeroEnd = false; + //there is a pretty good chance that people will try to drag the knots + //on top of each other, so block it + + unsigned size = path_in[0].size(); + if (size == first_cusp.size()) { + //check to see if the knots were dragged over each other + //if so, reset the end offset + if ( attach_start >= (size - attach_end) ) { + attach_end.param_set_value( size - attach_start ); + } + } + + //don't ever let it be zero + if (attach_start <= 0.00000001) { + attach_start.param_set_value( 0.00000001 ); + zeroStart = true; + } + if (attach_end <= 0.00000001) { + attach_end.param_set_value( 0.00000001 ); + zeroEnd = true; + } + + //don't let it be integer + if (double(unsigned(attach_start)) == attach_start) { + attach_start.param_set_value(attach_start - 0.00001); + } + if (double(unsigned(attach_end)) == attach_end) { + attach_end.param_set_value(attach_end - 0.00001); + } + + unsigned allowed_start = first_cusp.size(); + unsigned allowed_end = last_cusp.size(); + + //don't let the knots be farther than they are allowed to be + if ((unsigned)attach_start >= allowed_start) { + attach_start.param_set_value((double)allowed_start - 0.00000001); + } + if ((unsigned)attach_end >= allowed_end) { + attach_end.param_set_value((double)allowed_end - 0.00000001); + } + + //remember, Path::operator () means get point at time t + start_attach_point = first_cusp(attach_start); + end_attach_point = last_cusp(attach_end); + Geom::PathVector pathv_out; + + //the following function just splits it up into three pieces. + pathv_out = doEffect_simplePath(path_in); + + //now for the actual tapering. We use a Pattern Along Path method to get this done. + + Geom::PathVector real_pathv; + Geom::Path real_path; + Geom::PathVector pat_vec; + Geom::Piecewise > pwd2; + Geom::Path throwaway_path; + + if (!zeroStart) { + //Construct the pattern (pat_str stands for pattern string) (yes, this is easier, trust me) + std::stringstream pat_str; + pat_str << "M 1,0 C " << 1 - (double)smoothing << ",0 0,0.5 0,0.5 0,0.5 " << 1 - (double)smoothing << ",1 1,1"; + + pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); + pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], -fabs(line_width))); + throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; + + real_path.append(throwaway_path); + } + //append the outside outline of the path (with direction) + throwaway_path = Outline::PathOutsideOutline(pathv_out[1], + -fabs(line_width), static_cast(join_type.get_value()), miter_limit); + + if (!zeroStart) { + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); + } else { + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + } + + if (!zeroEnd) { + //append the ending taper + std::stringstream pat_str_1; + pat_str_1 << "M 0,0 0,1 C " << (double)smoothing << ",1 1,0.5 1,0.5 1,0.5 " << double(smoothing) << ",0 0,0"; + pat_vec = sp_svg_read_pathv(pat_str_1.str().c_str()); + + pwd2 = Geom::Piecewise > (); + pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], -fabs(line_width))); + + throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; + throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path); + } + //append the inside outline of the path (against direction) + throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), + -fabs(line_width), static_cast(join_type.get_value()), miter_limit); + + if (!zeroEnd) { + //throwaway_path.setInitial(real_path.finalPoint()); + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + } else { + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + } + + //hmm + real_path.setFinal(real_path.initialPoint()); + + real_path.close(); + + real_pathv.push_back(real_path); + + return real_pathv; } //in all cases, this should return a PathVector with three elements. Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & path_in) { - unsigned size = path_in[0].size(); - - //do subdivision and get out - unsigned loc = (unsigned)attach_start; - Geom::Curve * curve_start = path_in[0] [loc].duplicate(); - - std::vector pathv_out; - Geom::Path path_out = Geom::Path(); - - Geom::Path trimmed_start = Geom::Path(); - Geom::Path trimmed_end = Geom::Path(); - - for (unsigned i = 0; i < loc; i++) { - trimmed_start.append(path_in[0] [i]); - } - - - //this is pretty annoying - //previously I wrote a function for this but it wasted a lot of time - //so I optimized it back into here. - unsigned order = Outline::bezierOrder(curve_start); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast(curve_start); - std::pair cb_pair = cb->subdivide((attach_start - loc)); - trimmed_start.append(cb_pair.first); curve_start = cb_pair.second.duplicate(); //goes out of scope - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast(curve_start); - std::pair qb_pair = qb->subdivide((attach_start - loc)); - trimmed_start.append(qb_pair.first); curve_start = qb_pair.second.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); - std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide((attach_start - loc)); - trimmed_start.append(lb_pair.first); curve_start = lb_pair.second.duplicate(); - break; - } - } - - //special case: path is one segment long - //special case: what if the two knots occupy the same segment? - if ((size == 1) || ( size - unsigned(attach_end) - 1 == loc )) - { - Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_start); - - //it is just a dumb segment - //we have to do some shifting here because the value changed when we reduced the length - //of the previous segment. - - order = Outline::bezierOrder(curve_start); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast(curve_start); - std::pair cb_pair = cb->subdivide(t); - trimmed_end.append(cb_pair.second); curve_start = cb_pair.first.duplicate(); - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast(curve_start); - std::pair qb_pair = qb->subdivide(t); - trimmed_end.append(qb_pair.second); curve_start = qb_pair.first.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); - std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); - trimmed_end.append(lb_pair.second); curve_start = lb_pair.first.duplicate(); - break; - } - } - - for (unsigned j = (size - attach_end) + 1; j < size; j++) { - trimmed_end.append(path_in[0] [j]); - } - - path_out.append(*curve_start); - pathv_out.push_back(trimmed_start); - pathv_out.push_back(path_out); - pathv_out.push_back(trimmed_end); - return pathv_out; - } - - pathv_out.push_back(trimmed_start); - - //append almost all of the rest of the path, ignore the curves that the knot is past (we'll get to it in a minute) - path_out.append(*curve_start); - - for (unsigned k = loc + 1; k < (size - unsigned(attach_end)) - 1; k++) { - path_out.append(path_in[0] [k]); - } - - //deal with the last segment in a very similar fashion to the first - loc = size - attach_end; - - Geom::Curve * curve_end = path_in[0] [loc].duplicate(); - - Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); - - order = Outline::bezierOrder(curve_end); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast(curve_end); - std::pair cb_pair = cb->subdivide(t); - trimmed_end.append(cb_pair.second); curve_end = cb_pair.first.duplicate(); - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast(curve_end); - std::pair qb_pair = qb->subdivide(t); - trimmed_end.append(qb_pair.second); curve_end = qb_pair.first.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast * >(curve_end); - std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); - trimmed_end.append(lb_pair.second); curve_end = lb_pair.first.duplicate(); - break; - } - } - - for (unsigned j = (size - attach_end) + 1; j < size; j++) { - trimmed_end.append(path_in[0] [j]); - } - - path_out.append(*curve_end); - pathv_out.push_back(path_out); - - pathv_out.push_back(trimmed_end); - - if (curve_end) delete curve_end; - if (curve_start) delete curve_start; - return pathv_out; + unsigned size = path_in[0].size(); + + //do subdivision and get out + unsigned loc = (unsigned)attach_start; + Geom::Curve * curve_start = path_in[0] [loc].duplicate(); + + std::vector pathv_out; + Geom::Path path_out = Geom::Path(); + + Geom::Path trimmed_start = Geom::Path(); + Geom::Path trimmed_end = Geom::Path(); + + for (unsigned i = 0; i < loc; i++) { + trimmed_start.append(path_in[0] [i]); + } + + + //this is pretty annoying + //previously I wrote a function for this but it wasted a lot of time + //so I optimized it back into here. + unsigned order = Outline::bezierOrder(curve_start); + switch (order) { + case 3: { + Geom::CubicBezier *cb = static_cast(curve_start); + std::pair cb_pair = cb->subdivide((attach_start - loc)); + trimmed_start.append(cb_pair.first); + curve_start = cb_pair.second.duplicate(); //goes out of scope + break; + } + case 2: { + Geom::QuadraticBezier *qb = static_cast(curve_start); + std::pair qb_pair = qb->subdivide((attach_start - loc)); + trimmed_start.append(qb_pair.first); + curve_start = qb_pair.second.duplicate(); + break; + } + case 1: { + Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); + std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide((attach_start - loc)); + trimmed_start.append(lb_pair.first); + curve_start = lb_pair.second.duplicate(); + break; + } + } + + //special case: path is one segment long + //special case: what if the two knots occupy the same segment? + if ((size == 1) || ( size - unsigned(attach_end) - 1 == loc )) { + Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_start); + + //it is just a dumb segment + //we have to do some shifting here because the value changed when we reduced the length + //of the previous segment. + + order = Outline::bezierOrder(curve_start); + switch (order) { + case 3: { + Geom::CubicBezier *cb = static_cast(curve_start); + std::pair cb_pair = cb->subdivide(t); + trimmed_end.append(cb_pair.second); + curve_start = cb_pair.first.duplicate(); + break; + } + case 2: { + Geom::QuadraticBezier *qb = static_cast(curve_start); + std::pair qb_pair = qb->subdivide(t); + trimmed_end.append(qb_pair.second); + curve_start = qb_pair.first.duplicate(); + break; + } + case 1: { + Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); + std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); + trimmed_end.append(lb_pair.second); + curve_start = lb_pair.first.duplicate(); + break; + } + } + + for (unsigned j = (size - attach_end) + 1; j < size; j++) { + trimmed_end.append(path_in[0] [j]); + } + + path_out.append(*curve_start); + pathv_out.push_back(trimmed_start); + pathv_out.push_back(path_out); + pathv_out.push_back(trimmed_end); + return pathv_out; + } + + pathv_out.push_back(trimmed_start); + + //append almost all of the rest of the path, ignore the curves that the knot is past (we'll get to it in a minute) + path_out.append(*curve_start); + + for (unsigned k = loc + 1; k < (size - unsigned(attach_end)) - 1; k++) { + path_out.append(path_in[0] [k]); + } + + //deal with the last segment in a very similar fashion to the first + loc = size - attach_end; + + Geom::Curve * curve_end = path_in[0] [loc].duplicate(); + + Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); + + order = Outline::bezierOrder(curve_end); + switch (order) { + case 3: { + Geom::CubicBezier *cb = static_cast(curve_end); + std::pair cb_pair = cb->subdivide(t); + trimmed_end.append(cb_pair.second); + curve_end = cb_pair.first.duplicate(); + break; + } + case 2: { + Geom::QuadraticBezier *qb = static_cast(curve_end); + std::pair qb_pair = qb->subdivide(t); + trimmed_end.append(qb_pair.second); + curve_end = qb_pair.first.duplicate(); + break; + } + case 1: { + Geom::BezierCurveN<1> *lb = static_cast * >(curve_end); + std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); + trimmed_end.append(lb_pair.second); + curve_end = lb_pair.first.duplicate(); + break; + } + } + + for (unsigned j = (size - attach_end) + 1; j < size; j++) { + trimmed_end.append(path_in[0] [j]); + } + + path_out.append(*curve_end); + pathv_out.push_back(path_out); + + pathv_out.push_back(trimmed_end); + + if (curve_end) delete curve_end; + if (curve_start) delete curve_start; + return pathv_out; } @@ -509,14 +523,14 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa //tweaking to get it to work right in this case. Geom::Piecewise > stretch_along(Geom::Piecewise > pwd2_in, Geom::Path pattern, double prop_scale) { - using namespace Geom; + using namespace Geom; // Don't allow empty path parameter: if ( pattern.empty() ) { return pwd2_in; } -/* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */ + /* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */ Piecewise > output; std::vector > > pre_output; @@ -548,7 +562,7 @@ Geom::Piecewise > stretch_along(Geom::Piecewise > > paths_in; paths_in = split_at_discontinuities(pwd2_in); - for (unsigned idx = 0; idx < paths_in.size(); idx++){ + for (unsigned idx = 0; idx < paths_in.size(); idx++) { Geom::Piecewise > path_i = paths_in[idx]; Piecewise x = x0; Piecewise y = y0; @@ -556,14 +570,14 @@ Geom::Piecewise > stretch_along(Geom::Piecewise > n = rot90(derivative(uskeleton)); n = force_continuity(remove_short_cuts(n,.1)); - + int nbCopies = 0; double scaling = 1; nbCopies = 1; scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); double pattWidth = pattBndsX->extent() * scaling; - + if (scaling != 1.0) { x*=scaling; } @@ -573,20 +587,20 @@ Geom::Piecewise > stretch_along(Geom::Piecewise > output_piece = compose(uskeleton,x+offs)+y*compose(n,x+offs); std::vector > > splited_output_piece = split_at_discontinuities(output_piece); pre_output.insert(pre_output.end(), splited_output_piece.begin(), splited_output_piece.end() ); - }else{ + } else { output.concat(compose(uskeleton,x+offs)+y*compose(n,x+offs)); } offs+=pattWidth; } } - /*if (false){ + /*if (false){ pre_output = fuse_nearby_ends(pre_output, fuse_tolerance); for (unsigned i=0; i > stretch_along(Geom::Piecewise(curve_in); + std::pair cb_pair = cb->subdivide(t); + //trimmed_start.append(cb_pair.first); + val_first = cb_pair.first.duplicate(); + val_second = cb_pair.second.duplicate(); + break; + } + case 2: { + Geom::QuadraticBezier *qb = static_cast(curve_in); + std::pair qb_pair = qb->subdivide(t); + //trimmed_start.append(qb_pair.first); + val_first = qb_pair.first.duplicate(); + val_second = qb_pair.second.duplicate(); + break; + } + case 1: { + Geom::BezierCurveN<1> *lb = static_cast * >(curve_in); + std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); + //trimmed_start.append(lb_pair.first); + val_first = lb_pair.first.duplicate(); + val_second = lb_pair.second.duplicate(); + break; + } + } +} -void LPETaperStroke::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) + +void LPETaperStroke::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { - { - KnotHolderEntity *e = new TpS::KnotHolderEntityAttachBegin(this); - e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Start point of the taper"), SP_KNOT_SHAPE_CIRCLE ); - knotholder->add(e); - } - { - KnotHolderEntity *e = new TpS::KnotHolderEntityAttachEnd(this); - e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("End point of the taper"), SP_KNOT_SHAPE_CIRCLE ); - knotholder->add(e); - } + { + KnotHolderEntity *e = new TpS::KnotHolderEntityAttachBegin(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("Start point of the taper"), SP_KNOT_SHAPE_CIRCLE ); + knotholder->add(e); + } + { + KnotHolderEntity *e = new TpS::KnotHolderEntityAttachEnd(this); + e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, + _("End point of the taper"), SP_KNOT_SHAPE_CIRCLE ); + knotholder->add(e); + } } namespace TpS { - void KnotHolderEntityAttachBegin::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) - { - using namespace Geom; - - LPETaperStroke* lpe = dynamic_cast(_effect); - - Geom::Point const s = snap_knot_position(p, state); - - SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); - Geom::PathVector pathv = curve->get_pathvector(); - Piecewise > pwd2; - Geom::Path p_in = return_at_first_cusp(pathv[0]); - pwd2.concat(p_in.toPwSb()); - std::vector > > pwd_vec = split_at_discontinuities(pwd2); - - double t0 = nearest_point(s, pwd_vec[0]); - lpe->attach_start.param_set_value(t0); - - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. - sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); - } - void KnotHolderEntityAttachEnd::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) - { - using namespace Geom; - - LPETaperStroke* lpe = dynamic_cast(_effect); - - Geom::Point const s = snap_knot_position(p, state); - - SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); - Geom::PathVector pathv = curve->get_pathvector(); - Piecewise > pwd2; - Geom::Path p_in = return_at_first_cusp(pathv[0].reverse()); - pwd2.concat(p_in.toPwSb()); - std::vector > > pwd_vec = split_at_discontinuities(pwd2); - - double t0 = nearest_point(s, pwd_vec[0]); - lpe->attach_end.param_set_value(t0); - - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. - sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); - } - Geom::Point KnotHolderEntityAttachBegin::knot_get() const - { - LPETaperStroke const * lpe = dynamic_cast (_effect); - return lpe->start_attach_point; - } - Geom::Point KnotHolderEntityAttachEnd::knot_get() const - { - LPETaperStroke const * lpe = dynamic_cast (_effect); - return lpe->end_attach_point; - } +void KnotHolderEntityAttachBegin::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +{ + using namespace Geom; + + LPETaperStroke* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); + Geom::PathVector pathv = curve->get_pathvector(); + Piecewise > pwd2; + Geom::Path p_in = return_at_first_cusp(pathv[0]); + pwd2.concat(p_in.toPwSb()); + std::vector > > pwd_vec = split_at_discontinuities(pwd2); + + double t0 = nearest_point(s, pwd_vec[0]); + lpe->attach_start.param_set_value(t0); + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} +void KnotHolderEntityAttachEnd::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) +{ + using namespace Geom; + + LPETaperStroke* lpe = dynamic_cast(_effect); + + Geom::Point const s = snap_knot_position(p, state); + + SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); + Geom::PathVector pathv = curve->get_pathvector(); + Piecewise > pwd2; + Geom::Path p_in = return_at_first_cusp(pathv[0].reverse()); + pwd2.concat(p_in.toPwSb()); + std::vector > > pwd_vec = split_at_discontinuities(pwd2); + + double t0 = nearest_point(s, pwd_vec[0]); + lpe->attach_end.param_set_value(t0); + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} +Geom::Point KnotHolderEntityAttachBegin::knot_get() const +{ + LPETaperStroke const * lpe = dynamic_cast (_effect); + return lpe->start_attach_point; +} +Geom::Point KnotHolderEntityAttachEnd::knot_get() const +{ + LPETaperStroke const * lpe = dynamic_cast (_effect); + return lpe->end_attach_point; +} } diff --git a/src/live_effects/lpe-taperstroke.h b/src/live_effects/lpe-taperstroke.h index 29a56f77c..997209543 100644 --- a/src/live_effects/lpe-taperstroke.h +++ b/src/live_effects/lpe-taperstroke.h @@ -20,39 +20,39 @@ namespace Inkscape { namespace LivePathEffect { namespace TpS { - // we need a separate namespace to avoid clashes with other LPEs - class KnotHolderEntityAttachBegin; - class KnotHolderEntityAttachEnd; +// we need a separate namespace to avoid clashes with other LPEs +class KnotHolderEntityAttachBegin; +class KnotHolderEntityAttachEnd; } class LPETaperStroke : public Effect { public: - LPETaperStroke(LivePathEffectObject *lpeobject); - virtual ~LPETaperStroke(); - - virtual void doOnApply(SPLPEItem const* lpeitem); - virtual void doOnRemove(SPLPEItem const* lpeitem); + LPETaperStroke(LivePathEffectObject *lpeobject); + virtual ~LPETaperStroke(); - virtual Geom::PathVector doEffect_path (Geom::PathVector const& path_in); - Geom::PathVector doEffect_simplePath(Geom::PathVector const& path_in); - - virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); + virtual void doOnApply(SPLPEItem const* lpeitem); + virtual void doOnRemove(SPLPEItem const* lpeitem); - friend class TpS::KnotHolderEntityAttachBegin; - friend class TpS::KnotHolderEntityAttachEnd; + virtual Geom::PathVector doEffect_path (Geom::PathVector const& path_in); + Geom::PathVector doEffect_simplePath(Geom::PathVector const& path_in); + + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); + + friend class TpS::KnotHolderEntityAttachBegin; + friend class TpS::KnotHolderEntityAttachEnd; private: - ScalarParam line_width; - ScalarParam attach_start; - ScalarParam attach_end; - ScalarParam smoothing; - EnumParam join_type; - ScalarParam miter_limit; + ScalarParam line_width; + ScalarParam attach_start; + ScalarParam attach_end; + ScalarParam smoothing; + EnumParam join_type; + ScalarParam miter_limit; - Geom::Point start_attach_point; - Geom::Point end_attach_point; + Geom::Point start_attach_point; + Geom::Point end_attach_point; - LPETaperStroke(const LPETaperStroke&); - LPETaperStroke& operator=(const LPETaperStroke&); + LPETaperStroke(const LPETaperStroke&); + LPETaperStroke& operator=(const LPETaperStroke&); }; } //namespace LivePathEffect diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp old mode 100755 new mode 100644 index 6a47285a0..ad39a7416 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -9,133 +9,128 @@ #include <2geom/path-sink.h> #include -namespace Geom +namespace Geom { +/** +* Refer to: Weisstein, Eric W. "Circle-Circle Intersection." + From MathWorld--A Wolfram Web Resource. + http://mathworld.wolfram.com/Circle-CircleIntersection.html +* +* @return 0 if no intersection +* @return 1 if one circle is contained in the other +* @return 2 if intersections are found (they are written to p0 and p1) +*/ +static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, + Point & p0, Point & p1) +{ + Point X0 = circle0.center(); + double r0 = circle0.ray(); + Point X1 = circle1.center(); + double r1 = circle1.ray(); + + /* dx and dy are the vertical and horizontal distances between + * the circle centers. + */ + Point D = X1 - X0; + + /* Determine the straight-line distance between the centers. */ + double d = L2(D); + + /* Check for solvability. */ + if (d > (r0 + r1)) { + /* no solution. circles do not intersect. */ + return 0; + } + if (d <= fabs(r0 - r1)) { + /* no solution. one circle is contained in the other */ + return 1; + } + + /* 'point 2' is the point where the line through the circle + * intersection points crosses the line between the circle + * centers. + */ + + /* Determine the distance from point 0 to point 2. */ + double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; + + /* Determine the coordinates of point 2. */ + Point p2 = X0 + D * (a/d); + + /* Determine the distance from point 2 to either of the + * intersection points. + */ + double h = std::sqrt((r0*r0) - (a*a)); + + /* Now determine the offsets of the intersection points from + * point 2. + */ + Point r = (h/d)*rot90(D); + + /* Determine the absolute intersection points. */ + p0 = p2 + r; + p1 = p2 - r; + + return 2; +} +/** +* Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t. +* Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt). +*/ +static Circle touching_circle( D2 const &curve, double t, double tol=0.01 ) { - /** - * Refer to: Weisstein, Eric W. "Circle-Circle Intersection." - From MathWorld--A Wolfram Web Resource. - http://mathworld.wolfram.com/Circle-CircleIntersection.html - * - * @return 0 if no intersection - * @return 1 if one circle is contained in the other - * @return 2 if intersections are found (they are written to p0 and p1) - */ - static int circle_circle_intersection(Circle const &circle0, Circle const &circle1, - Point & p0, Point & p1) - { - Point X0 = circle0.center(); - double r0 = circle0.ray(); - Point X1 = circle1.center(); - double r1 = circle1.ray(); - - /* dx and dy are the vertical and horizontal distances between - * the circle centers. - */ - Point D = X1 - X0; - - /* Determine the straight-line distance between the centers. */ - double d = L2(D); - - /* Check for solvability. */ - if (d > (r0 + r1)) - { - /* no solution. circles do not intersect. */ - return 0; - } - if (d <= fabs(r0 - r1)) - { - /* no solution. one circle is contained in the other */ - return 1; - } - - /* 'point 2' is the point where the line through the circle - * intersection points crosses the line between the circle - * centers. - */ - - /* Determine the distance from point 0 to point 2. */ - double a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; - - /* Determine the coordinates of point 2. */ - Point p2 = X0 + D * (a/d); - - /* Determine the distance from point 2 to either of the - * intersection points. - */ - double h = std::sqrt((r0*r0) - (a*a)); - - /* Now determine the offsets of the intersection points from - * point 2. - */ - Point r = (h/d)*rot90(D); - - /* Determine the absolute intersection points. */ - p0 = p2 + r; - p1 = p2 - r; - - return 2; - } - /** - * Find circle that touches inside of the curve, with radius matching the curvature, at time value \c t. - * Because this method internally uses unitTangentAt, t should be smaller than 1.0 (see unitTangentAt). - */ - static Circle touching_circle( D2 const &curve, double t, double tol=0.01 ) - { - D2 dM=derivative(curve); - if ( are_near(L2sq(dM(t)),0.) ) { - dM=derivative(dM); - } - if ( are_near(L2sq(dM(t)),0.) ) { // try second time - dM=derivative(dM); - } - Piecewise > unitv = unitVector(dM,tol); - Piecewise dMlength = dot(Piecewise >(dM),unitv); - Piecewise k = cross(derivative(unitv),unitv); - k = divide(k,dMlength,tol,3); - double curv = k(t); // note that this value is signed - - Geom::Point normal = unitTangentAt(curve, t).cw(); - double radius = 1/curv; - Geom::Point center = curve(t) + radius*normal; - return Geom::Circle(center, fabs(radius)); - } - - static std::vector split_at_cusps(const Geom::Path& in) - { - Geom::PathVector out = Geom::PathVector(); - Geom::Path temp = Geom::Path(); - - for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) - { - temp = Geom::Path(); - temp.append(in[path_descr]); - out.push_back(temp); - } - - return out; - } - - static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) - { - std::vector temp; - sbasis_to_bezier(temp, sbasis_in, 4); - return Geom::CubicBezier( temp ); - } - - static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, - Geom::Point const & origin_b, Geom::Point const & vector_b) - { - Geom::Coord denom = cross(vector_b, vector_a); - if (!Geom::are_near(denom,0.)){ - Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom; - return origin_a + t * vector_a; - } - return boost::none; - } + D2 dM=derivative(curve); + if ( are_near(L2sq(dM(t)),0.) ) { + dM=derivative(dM); + } + if ( are_near(L2sq(dM(t)),0.) ) { // try second time + dM=derivative(dM); + } + Piecewise > unitv = unitVector(dM,tol); + Piecewise dMlength = dot(Piecewise >(dM),unitv); + Piecewise k = cross(derivative(unitv),unitv); + k = divide(k,dMlength,tol,3); + double curv = k(t); // note that this value is signed + + Geom::Point normal = unitTangentAt(curve, t).cw(); + double radius = 1/curv; + Geom::Point center = curve(t) + radius*normal; + return Geom::Circle(center, fabs(radius)); } -namespace Outline +static std::vector split_at_cusps(const Geom::Path& in) { + Geom::PathVector out = Geom::PathVector(); + Geom::Path temp = Geom::Path(); + + for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) { + temp = Geom::Path(); + temp.append(in[path_descr]); + out.push_back(temp); + } + + return out; +} + +static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) +{ + std::vector temp; + sbasis_to_bezier(temp, sbasis_in, 4); + return Geom::CubicBezier( temp ); +} + +static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, + Geom::Point const & origin_b, Geom::Point const & vector_b) +{ + Geom::Coord denom = cross(vector_b, vector_a); + if (!Geom::are_near(denom,0.)) { + Geom::Coord t = (cross(origin_a,vector_b) + cross(vector_b,origin_b)) / denom; + return origin_a + t * vector_a; + } + return boost::none; +} +} + +namespace Outline { typedef Geom::D2 D2SB; typedef Geom::Piecewise PWD2; @@ -160,72 +155,70 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) unsigned order = bezierOrder(&cbc1); Geom::Point start_point; - Geom::Point cross_point = cbc1.finalPoint(); - Geom::Point end_point; - - //assert(cbc1.finalPoint() == cbc2.initialPoint()); - //short circuiting? - if (cbc1.finalPoint() != cbc2.initialPoint()) { - printf("There was an issue when asserting that one curve's end is the start of the other. Line %d, File %s\n" - "By default we are going to say that this is an inside join, so we cannot make a line join for it.\n", __LINE__, __FILE__); - return false; + Geom::Point cross_point = cbc1.finalPoint(); + Geom::Point end_point; + + //assert(cbc1.finalPoint() == cbc2.initialPoint()); + //short circuiting? + if (cbc1.finalPoint() != cbc2.initialPoint()) { + printf("There was an issue when asserting that one curve's end is the start of the other. Line %d, File %s\n" + "By default we are going to say that this is an inside join, so we cannot make a line join for it.\n", __LINE__, __FILE__); + return false; + } + switch (order) { + case 3: + start_point = (static_cast(&cbc1))->operator[] (2); + //major league b***f***ing + if (are_near(start_point, cross_point, 0.0000001)) { + start_point = (static_cast(&cbc1))->operator[] (1); } - switch (order) - { - case 3: - start_point = (static_cast(&cbc1))->operator[] (2); - //major league b***f***ing - if (are_near(start_point, cross_point, 0.0000001)) { - start_point = (static_cast(&cbc1))->operator[] (1); - } - break; - case 2: - //this never happens - start_point = (static_cast(&cbc1))->operator[] (1); - break; - case 1: - default: - start_point = cbc1.initialPoint(); - } - - order = Outline::bezierOrder(&cbc2); - - switch (order) - { - case 3: - end_point = (static_cast(&cbc2))->operator[] (1); - if (are_near(end_point, cross_point, 0.0000001)) { - end_point = (static_cast(&cbc2))->operator[] (2); - } - break; - case 2: - end_point = (static_cast(&cbc2))->operator[] (1); - break; - case 1: - default: - end_point = cbc2.finalPoint(); - } - //got our three points, now let's see what their clockwise angle is - - //Much credit to Wikipedia for the following ( http://en.wikipedia.org/wiki/Graham_scan ) - /******************************************************************** + break; + case 2: + //this never happens + start_point = (static_cast(&cbc1))->operator[] (1); + break; + case 1: + default: + start_point = cbc1.initialPoint(); + } + + order = Outline::bezierOrder(&cbc2); + + switch (order) { + case 3: + end_point = (static_cast(&cbc2))->operator[] (1); + if (are_near(end_point, cross_point, 0.0000001)) { + end_point = (static_cast(&cbc2))->operator[] (2); + } + break; + case 2: + end_point = (static_cast(&cbc2))->operator[] (1); + break; + case 1: + default: + end_point = cbc2.finalPoint(); + } + //got our three points, now let's see what their clockwise angle is + + //Much credit to Wikipedia for the following ( http://en.wikipedia.org/wiki/Graham_scan ) + /******************************************************************** # Three points are a counter-clockwise turn if ccw > 0, clockwise if # ccw < 0, and collinear if ccw = 0 because ccw is a determinant that # gives the signed area of the triangle formed by p1, p2 and p3. function ccw(p1, p2, p3): - return (p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x) + return (p2.x - p1.x)*(p3.y - p1.y) - (p2.y - p1.y)*(p3.x - p1.x) *********************************************************************/ - + double ccw = ( (cross_point.x() - start_point.x()) * (end_point.y() - start_point.y()) ) - ( (cross_point.y() - start_point.y()) * (end_point.x() - start_point.x()) ); if (ccw > 0) return true; return false; } -void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, +void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit, double line_width, bool outside = false) { - bool lineProblem = (dynamic_cast *>(cbc1)) || (dynamic_cast *>(cbc2)); + bool lineProblem = (dynamic_cast *>(cbc1)) || (dynamic_cast *>(cbc2)); if ( outside && !lineProblem ) { Geom::Path pth; pth.append(*cbc1); @@ -271,9 +264,8 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } } else { boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) - { + cbc2->initialPoint(), tang2); + if (p) { //check size of miter Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; Geom::Coord len = distance(*p, point_on_path); @@ -284,19 +276,18 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } path_builder.appendNew (endPt); } - } - if ( outside && lineProblem ) { - Geom::Path pth; + } + if ( outside && lineProblem ) { + Geom::Path pth; pth.append(*cbc1); - Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(pth.toPwSb()[0]), 0.); + Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(pth.toPwSb()[0]), 0.); pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); - - boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) - { + pth.append( *cbc2 ); + Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); + + boost::optional p = intersection_point (cbc1->finalPoint(), tang1, + cbc2->initialPoint(), tang2); + if (p) { //check size of miter Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; Geom::Coord len = distance(*p, point_on_path); @@ -306,13 +297,13 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } } path_builder.appendNew (endPt); - } - if ( !outside ) { - path_builder.appendNew (endPt); - } + } + if ( !outside ) { + path_builder.appendNew (endPt); + } } -void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, +void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, double miter_limit, double line_width, bool outside = false) { //the most important work for the reflected join is done here @@ -320,7 +311,7 @@ void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cb //determine where we are in the path. If we're on the inside, ignore //and just lineTo. On the outside, we'll do a little reflection magic :) Geom::Crossings cross; - + if (outside) { Geom::Path pth; pth.append(*cbc1); @@ -347,9 +338,8 @@ void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cb if ( cross.empty() ) { //curves didn't cross; default to miter boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) - { + cbc2->initialPoint(), tang2); + if (p) { //check size of miter Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; Geom::Coord len = distance(*p, point_on_path); @@ -388,27 +378,26 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double // NOTE: it is important to notice the distinction between a Geom::Path and a livarot Path here! // if you do not see "Geom::" there is a different function set! Geom::PathVector pv = split_at_cusps(path_in); - + Path to_outline; Path outlined_result; - + Geom::Path path_builder = Geom::Path(); //the path to store the result in Geom::PathVector * path_vec; //needed because livarot returns a goddamn pointer - + const unsigned k = path_in.size(); - - for (unsigned u = 0; u < k; u+=2) - { + + for (unsigned u = 0; u < k; u+=2) { to_outline = Path(); outlined_result = Path(); - + to_outline.LoadPath(pv[u], Geom::Affine(), false, false); to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10); //now a curve has been outside outlined and loaded into outlined_result - + //get the Geom::Path path_vec = outlined_result.MakePathVector(); - + //thing to do on the first run through if (u == 0) { //I could use the pv->operator[] (0) notation but that looks terrible @@ -417,58 +406,64 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double //get the curves ready for the operation Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate(); Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate(); - + //do the reflection/extrapolation: - if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); } - else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); } + if (extrapolate) { + extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, + outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); + } else { + reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, + outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); + } } - + path_builder.append( (*path_vec)[0] ); - + //outline the next segment, but don't store it yet if (path_vec) delete path_vec; - + if (u < k - 1) { outlined_result = Path(); to_outline = Path(); - + to_outline.LoadPath(pv[u+1], Geom::Affine(), false, false); to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10); - + path_vec = outlined_result.MakePathVector(); - + //get the curves ready for the operation Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate(); Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate(); - + //do the reflection/extrapolation: - if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); } - else { reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); } - + if (extrapolate) { + extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, + outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); + } else { + reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, + outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); + } + //Now we can store it. path_builder.append( (*path_vec)[0] ); - + if (cbc1) delete cbc1; if (cbc2) delete cbc2; if (path_vec) delete path_vec; } } - + return path_builder; } -Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, +Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtType butt, double miter_lim, bool extrapolate) { Geom::PathVector path_out; - + unsigned pv_size = path_in.size(); for (unsigned i = 0; i < pv_size; i++) { - + if (path_in[i].size() > 1) { //since you've made it this far, hopefully all this is obvious :P Geom::Path with_direction; @@ -484,8 +479,8 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, newPath = Geom::path_from_piecewise(pwd2, 0.01)[0]; //fuk this with_direction = Outline::doAdvHalfOutline( newPath, -line_width, miter_lim, extrapolate ); - against_direction = Outline::doAdvHalfOutline( newPath.reverse(), -line_width, miter_lim, extrapolate ); - + against_direction = Outline::doAdvHalfOutline( newPath.reverse(), -line_width, miter_lim, extrapolate ); + /*if (dynamic_cast *>(&newPath[newPath.size()])) { //delete the 'Z' newPath.erase_last(); @@ -497,54 +492,54 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, newPath.erase_last(); newPath.append(path_in[i][path_in[i].size() - 1]); newPath.appendNew(newPath.initialPoint()); - newPath.erase_last(); + newPath.erase_last(); }*/ } Geom::PathBuilder pb; - + //add in the...do I really need to say this? pb.moveTo(with_direction.initialPoint()); pb.append(with_direction); - + //add in our line caps if (!path_in[i].closed()) { switch (butt) { - case butt_straight: - pb.lineTo(against_direction.initialPoint()); - break; - case butt_round: - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, against_direction.initialPoint() ); - break; - case butt_pointy: - //I have ZERO idea what to do here. - pb.lineTo(against_direction.initialPoint()); - break; - case butt_square: - pb.lineTo(against_direction.initialPoint()); - break; + case butt_straight: + pb.lineTo(against_direction.initialPoint()); + break; + case butt_round: + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, against_direction.initialPoint() ); + break; + case butt_pointy: + //I have ZERO idea what to do here. + pb.lineTo(against_direction.initialPoint()); + break; + case butt_square: + pb.lineTo(against_direction.initialPoint()); + break; } } else { pb.moveTo(against_direction.initialPoint()); } - + pb.append(against_direction); - + //cap (if necessary) if (!path_in[i].closed()) { switch (butt) { - case butt_straight: - pb.lineTo(with_direction.initialPoint()); - break; - case butt_round: - pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, with_direction.initialPoint() ); - break; - case butt_pointy: - //I have ZERO idea what to do here. - pb.lineTo(with_direction.initialPoint()); - break; - case butt_square: - pb.lineTo(with_direction.initialPoint()); - break; + case butt_straight: + pb.lineTo(with_direction.initialPoint()); + break; + case butt_round: + pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, with_direction.initialPoint() ); + break; + case butt_pointy: + //I have ZERO idea what to do here. + pb.lineTo(with_direction.initialPoint()); + break; + case butt_square: + pb.lineTo(with_direction.initialPoint()); + break; } } pb.flush(); @@ -554,7 +549,7 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, } else { Path p = Path(); Path outlinepath = Path(); - + p.LoadPath(path_in[i], Geom::Affine(), false, false); p.Outline(&outlinepath, line_width / 2, static_cast(join), butt, miter_lim); Geom::PathVector *pv_p = outlinepath.MakePathVector(); diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h index 23cc7e2c4..27bc62d45 100644 --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -12,15 +12,15 @@ enum LineJoinType { LINEJOIN_EXTRAPOLATED }; -namespace Outline +namespace Outline { - unsigned bezierOrder (const Geom::Curve* curve_in); - std::vector PathVectorOutline(std::vector const & path_in, double line_width, ButtType linecap_type, - LineJoinType linejoin_type, double miter_limit); - - Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, - ButtType butt, double miter_lim, bool extrapolate = false); - Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit); + unsigned bezierOrder (const Geom::Curve* curve_in); + std::vector PathVectorOutline(std::vector const & path_in, double line_width, ButtType linecap_type, + LineJoinType linejoin_type, double miter_limit); + + /*Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, + ButtType butt, double miter_lim, bool extrapolate = false);*/ + Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit); } #endif // _SEEN_PATH_OUTLINE_H -- cgit v1.2.3 From b7c026006efcc5461dcef0f3c9a5e1b87d162d3d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 2 Apr 2014 17:33:37 -0400 Subject: Hopefully remove the last of the exception throwing with certain path effects (bzr r13090.1.43) --- src/live_effects/pathoutlineprovider.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index ad39a7416..56f741417 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -250,17 +250,21 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true); Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true); + try { + if (arc0) { + path_builder.append (arc0->toSBasis()); + delete arc0; + arc0 = NULL; + } - if (arc0) { - path_builder.append (arc0->toSBasis()); - delete arc0; - arc0 = NULL; - } - - if (arc1) { - path_builder.append (arc1->toSBasis()); - delete arc1; - arc1 = NULL; + if (arc1) { + path_builder.append (arc1->toSBasis()); + delete arc1; + arc1 = NULL; + } + } catch (std::exception ex) { + printf("Exception occured, probably NaN or infinite valued points: %s\n", ex.what()); + path_builder.appendNew(endPt); } } else { boost::optional p = intersection_point (cbc1->finalPoint(), tang1, -- cgit v1.2.3 From b2f138290a5dedf907fe3e67d12ab93adfd5fd50 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 2 Apr 2014 21:49:11 -0400 Subject: Fix some minor issues (bzr r13090.1.44) --- src/live_effects/lpe-taperstroke.cpp | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 97ae02e3b..c452c825c 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -248,7 +248,7 @@ Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_toler Geom::Piecewise > stretch_along(Geom::Piecewise > pwd2_in, Geom::Path pattern, double width); //references to pointers, because magic -void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second); +void subdivideCurve(const Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second); Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) { @@ -269,7 +269,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) } } - //don't ever let it be zero + //don't let it be zero if (attach_start <= 0.00000001) { attach_start.param_set_value( 0.00000001 ); zeroStart = true; @@ -329,12 +329,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) throwaway_path = Outline::PathOutsideOutline(pathv_out[1], -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - if (!zeroStart) { - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); - } else { - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); - } + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); if (!zeroEnd) { //append the ending taper @@ -346,25 +341,17 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], -fabs(line_width))); throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; - throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path); + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); } //append the inside outline of the path (against direction) throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - if (!zeroEnd) { - //throwaway_path.setInitial(real_path.finalPoint()); - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); - } else { - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); - } - - //hmm - real_path.setFinal(real_path.initialPoint()); - - real_path.close(); + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + real_path.appendNew(real_path.initialPoint()); + real_path.close(); + real_pathv.push_back(real_path); return real_pathv; -- cgit v1.2.3 From 25ff2b2a4c2808b27fa40829978c6674668f6035 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 3 Apr 2014 09:15:25 +0200 Subject: Use the save mechanism from the export instead of suplicating code to save an svg. Fixes bug #500440 also clean vacuum defs from command line which should be using extension also. Fixed bugs: - https://launchpad.net/bugs/500440 (bzr r13252) --- src/main.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 00d0fcbb6..c2377b42c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1145,7 +1145,8 @@ static int sp_process_file_list(GSList *fl) if (!sp_export_svg && (sp_vacuum_defs || has_performed_actions)) { // save under the name given in the command line - sp_repr_save_file(doc->rdoc, filename, SP_SVG_NS_URI); + Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.inkscape"), doc, filename, false, + false, false, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG); } if (sp_global_printer) { sp_print_document_to_file(doc, sp_global_printer); @@ -1177,13 +1178,8 @@ static int sp_process_file_list(GSList *fl) g_slist_free (to_select); } - Inkscape::XML::Document *rdoc; - Inkscape::XML::Node *repr; - rdoc = sp_repr_document_new("svg:svg"); - repr = rdoc->root(); - repr = doc->getRoot()->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD); - sp_repr_save_rebased_file(repr->document(), sp_export_svg, SP_SVG_NS_URI, - doc->getBase(), sp_export_svg); + Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.plain"), doc, sp_export_svg, false, + false, false, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY); } if (sp_export_ps) { retVal |= do_export_ps_pdf(doc, sp_export_ps, "image/x-postscript"); -- cgit v1.2.3 From f9733d9f72490a3d0460b92833781eb9be3a054e Mon Sep 17 00:00:00 2001 From: ryanlerch <> Date: Thu, 3 Apr 2014 13:50:22 +0200 Subject: Fix for Bug #1301869 (util/signal-blocker.h not included in tarbal) by Ryan Lerch. Fixed bugs: - https://launchpad.net/bugs/1301869 (bzr r13255) --- src/util/Makefile_insert | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/util/Makefile_insert b/src/util/Makefile_insert index 7169fa8f7..6d2e63278 100644 --- a/src/util/Makefile_insert +++ b/src/util/Makefile_insert @@ -31,6 +31,7 @@ ink_common_sources += \ util/reverse-list.h \ util/share.h \ util/share.cpp \ + util/signal-blocker.h \ util/tuple.h \ util/ucompose.hpp \ util/units.cpp \ -- cgit v1.2.3 From 1185cce53f3e490c6bb7939b1d9f42272a2e2f4f Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Thu, 3 Apr 2014 14:49:00 +0200 Subject: Try and explain what selection means when aligning. Changed Selection to Selection Area (bzr r13257) --- src/ui/dialog/align-and-distribute.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 6b4aeebb9..e02ccd3f1 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -1002,7 +1002,7 @@ AlignAndDistribute::AlignAndDistribute() _combo.append(_("Smallest object")); _combo.append(_("Page")); _combo.append(_("Drawing")); - _combo.append(_("Selection")); + _combo.append(_("Selection Area")); _combo.set_active(prefs->getInt("/dialogs/align/align-to", 6)); _combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change)); -- cgit v1.2.3 From 4007abe02509fc1e312a007fb26f31c5a595df26 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 3 Apr 2014 21:04:51 -0400 Subject: Begin first stage of resolving issue with duplicate knots (bzr r13090.1.46) --- src/knotholder.cpp | 14 ++++++++------ src/live_effects/lpe-taperstroke.cpp | 10 ++++++++++ src/live_effects/pathoutlineprovider.cpp | 4 +++- src/sp-lpe-item.cpp | 5 +++++ 4 files changed, 26 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/knotholder.cpp b/src/knotholder.cpp index cf87423d4..94a041385 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -203,14 +203,16 @@ KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/, guint) /* do cleanup tasks (e.g., for LPE items write the parameter values * that were changed by dragging the handle to SVG) */ - if (SP_IS_LPE_ITEM(object)) { + if (dynamic_cast (object)) { // This writes all parameters to SVG. Is this sufficiently efficient or should we only // write the ones that were changed? - - Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(object)->getCurrentLPE(); - if (lpe) { - LivePathEffectObject *lpeobj = lpe->getLPEObj(); - lpeobj->updateRepr(); + SPLPEItem * lpeitem = SP_LPE_ITEM(this->item); + if (lpeitem) { + Inkscape::LivePathEffect::Effect *lpe = lpeitem->getCurrentLPE(); + if (lpe) { + LivePathEffectObject *lpeobj = lpe->getLPEObj(); + lpeobj->updateRepr(); + } } } diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index c452c825c..dc70782c4 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -657,6 +657,11 @@ void KnotHolderEntityAttachBegin::knot_set(Geom::Point const &p, Geom::Point con Geom::Point const s = snap_knot_position(p, state); SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); + if (!curve) { + //oops + lpe->attach_start.param_set_value(0); + return; + } Geom::PathVector pathv = curve->get_pathvector(); Piecewise > pwd2; Geom::Path p_in = return_at_first_cusp(pathv[0]); @@ -678,6 +683,11 @@ void KnotHolderEntityAttachEnd::knot_set(Geom::Point const &p, Geom::Point const Geom::Point const s = snap_knot_position(p, state); SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); + if (!curve) { + //oops + lpe->attach_end.param_set_value(0); + return; + } Geom::PathVector pathv = curve->get_pathvector(); Piecewise > pwd2; Geom::Path p_in = return_at_first_cusp(pathv[0].reverse()); diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index 56f741417..a696728d6 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -1,3 +1,5 @@ +#include //g_critical + #include "pathoutlineprovider.h" #include "livarot/path-description.h" #include <2geom/angle.h> @@ -262,7 +264,7 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve delete arc1; arc1 = NULL; } - } catch (std::exception ex) { + } catch (std::exception & ex) { printf("Exception occured, probably NaN or infinite valued points: %s\n", ex.what()); path_builder.appendNew(endPt); } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 71aa9545a..eda34a0b5 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -553,6 +553,7 @@ bool SPLPEItem::hasBrokenPathEffect() const bool SPLPEItem::hasPathEffect() const { + if (!path_effect_list) return false; //nullptr sucks if (path_effect_list->empty()) { return false; } @@ -698,6 +699,7 @@ PathEffectList const SPLPEItem::getEffectList() const Inkscape::LivePathEffect::LPEObjectReference* SPLPEItem::getCurrentLPEReference() { + if (!this->hasPathEffect()) return NULL; if (!this->current_path_effect && !this->path_effect_list->empty()) { setCurrentPathEffect(this->path_effect_list->back()); } @@ -707,6 +709,9 @@ Inkscape::LivePathEffect::LPEObjectReference* SPLPEItem::getCurrentLPEReference( Inkscape::LivePathEffect::Effect* SPLPEItem::getCurrentLPE() { + if (path_effect_list == NULL) { + return NULL; + } Inkscape::LivePathEffect::LPEObjectReference* lperef = getCurrentLPEReference(); if (lperef && lperef->lpeobject) -- cgit v1.2.3 From 3ae99b454b4561440a18f54729826ecd429b6cfe Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 4 Apr 2014 06:39:23 +0200 Subject: Cleanup namespace removal so that it doesn't require bugs in updateRepr to work. Move to using a duplicate node-tree. Fixes bug #419266 Fixed bugs: - https://launchpad.net/bugs/419266 (bzr r13260) --- src/extension/internal/svg.cpp | 55 +++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/extension/internal/svg.cpp b/src/extension/internal/svg.cpp index 8b272af60..a94bc2141 100644 --- a/src/extension/internal/svg.cpp +++ b/src/extension/internal/svg.cpp @@ -24,6 +24,7 @@ #include "extension/output.h" #include #include "xml/attribute-record.h" +#include "xml/simple-document.h" #include "sp-root.h" #include "document.h" @@ -42,27 +43,37 @@ using Inkscape::Util::List; using Inkscape::XML::AttributeRecord; using Inkscape::XML::Node; - - -static void pruneExtendedAttributes( Inkscape::XML::Node *repr ) +/* + * Removes all sodipodi and inkscape elements and attributes from an xml tree. + * used to make plain svg output. + */ +static void pruneExtendedNamespaces( Inkscape::XML::Node *repr ) { if (repr) { if ( repr->type() == Inkscape::XML::ELEMENT_NODE ) { - std::vector toBeRemoved; + std::vector attrsRemoved; for ( List it = repr->attributeList(); it; ++it ) { const gchar* attrName = g_quark_to_string(it->key); if ((strncmp("inkscape:", attrName, 9) == 0) || (strncmp("sodipodi:", attrName, 9) == 0)) { - toBeRemoved.push_back(attrName); + attrsRemoved.push_back(attrName); } } // Can't change the set we're interating over while we are iterating. - for ( std::vector::iterator it = toBeRemoved.begin(); it != toBeRemoved.end(); ++it ) { + for ( std::vector::iterator it = attrsRemoved.begin(); it != attrsRemoved.end(); ++it ) { repr->setAttribute(*it, 0); } } + std::vector nodesRemoved; for ( Node *child = repr->firstChild(); child; child = child->next() ) { - pruneExtendedAttributes(child); + if((strncmp("inkscape:", child->name(), 9) == 0) || strncmp("sodipodi:", child->name(), 9) == 0) { + nodesRemoved.push_back(child); + } else { + pruneExtendedNamespaces(child); + } + } + for ( std::vector::iterator it = nodesRemoved.begin(); it != nodesRemoved.end(); ++it ) { + repr->removeChild(*it); } } } @@ -229,24 +240,34 @@ Svg::save(Inkscape::Extension::Output *mod, SPDocument *doc, gchar const *filena { g_return_if_fail(doc != NULL); g_return_if_fail(filename != NULL); + Inkscape::XML::Document *rdoc = doc->rdoc; bool const exportExtensions = ( !mod->get_id() || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE) || !strcmp (mod->get_id(), SP_MODULE_KEY_OUTPUT_SVGZ_INKSCAPE)); - Inkscape::XML::Document *rdoc = NULL; - Inkscape::XML::Node *repr = NULL; - if (exportExtensions) { - repr = doc->getReprRoot(); - } else { - rdoc = sp_repr_document_new ("svg:svg"); - repr = rdoc->root(); - repr = doc->getRoot()->updateRepr(rdoc, repr, SP_OBJECT_WRITE_BUILD); + if (!exportExtensions) { + // We make a duplicate document so we don't prune the in-use document + // and loose data. Perhaps the user intends to save as inkscape-svg next. + Inkscape::XML::Document *new_rdoc = new Inkscape::XML::SimpleDocument(); + + // Comments and PI nodes are not included in this duplication + // TODO: Move this code into xml/document.h and duplicate rdoc instead of root. + new_rdoc->setAttribute("version", "1.0"); + new_rdoc->setAttribute("standalone", "no"); + + // Get a new xml repr for the svg root node + Inkscape::XML::Node *root = rdoc->root()->duplicate(new_rdoc); + + // Add the duplicated svg node as the document's rdoc + new_rdoc->appendChild(root); + Inkscape::GC::release(root); - pruneExtendedAttributes(repr); + pruneExtendedNamespaces(root); + rdoc = new_rdoc; } - if (!sp_repr_save_rebased_file(repr->document(), filename, SP_SVG_NS_URI, + if (!sp_repr_save_rebased_file(rdoc, filename, SP_SVG_NS_URI, doc->getBase(), filename)) { throw Inkscape::Extension::Output::save_failed(); } -- cgit v1.2.3 From 94226a90e4ba925c940f69059249836edfcd54e8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 4 Apr 2014 15:16:22 +0200 Subject: XMLTree and InkscapePreferences are not dockable windows, don't treat them like one. (bzr r13262) --- src/ui/dialog/dialog-manager.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 47e1fdd30..4be796e67 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -96,6 +96,9 @@ DialogManager::DialogManager() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); + registerFactory("InkscapePreferences", &create); + registerFactory("XmlTree", &create); + if (dialogs_type == FLOATING) { registerFactory("AlignAndDistribute", &create); registerFactory("DocumentMetadata", &create); @@ -106,7 +109,6 @@ DialogManager::DialogManager() { registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); @@ -126,7 +128,6 @@ DialogManager::DialogManager() { registerFactory("TextFont", &create); registerFactory("SpellCheck", &create); registerFactory("Export", &create); - registerFactory("XmlTree", &create); registerFactory("CloneTiler", &create); } else { @@ -140,7 +141,6 @@ DialogManager::DialogManager() { registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); - registerFactory("InkscapePreferences", &create); registerFactory("LayersPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); @@ -160,7 +160,6 @@ DialogManager::DialogManager() { registerFactory("TextFont", &create); registerFactory("SpellCheck", &create); registerFactory("Export", &create); - registerFactory("XmlTree", &create); registerFactory("CloneTiler", &create); } -- cgit v1.2.3 From 5991c35815cd0cae8ad38d5c89d1213ca460c854 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 4 Apr 2014 15:23:06 +0200 Subject: Maximised should be the default state for new inkscape users (bzr r13263) --- src/preferences-skeleton.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 2211baddb..96629f22d 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -293,6 +293,7 @@ static char const preferences_skeleton[] = #ifdef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs " \n" #endif +" \n" " \n" " \n" " \n" -- cgit v1.2.3 From 430b4cad57740929d94d2c93041d8b63ec5fa8f9 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 4 Apr 2014 15:42:28 +0200 Subject: Only apply the offset zoom when the document units match the zoom units (bzr r13264) --- src/verbs.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index fad090852..ab6c25973 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1777,6 +1777,13 @@ void ZoomVerb::perform(SPAction *action, void *data) gdouble zoom_inc = prefs->getDoubleLimited( "/options/zoomincrement/value", 1.414213562, 1.01, 10 ); + double zcorr = 1.0; + Glib::ustring abbr = prefs->getString("/options/zoomcorrection/unit"); + if (dt->namedview->doc_units && dt->namedview->doc_units->abbr == abbr) + zcorr = prefs->getDouble("/options/zoomcorrection/value", 1.0); + + Geom::Rect const d = dt->get_display_area(); + switch (reinterpret_cast(data)) { case SP_VERB_ZOOM_IN: { @@ -1792,7 +1799,6 @@ void ZoomVerb::perform(SPAction *action, void *data) } } - Geom::Rect const d = dt->get_display_area(); dt->zoom_relative( d.midpoint()[Geom::X], d.midpoint()[Geom::Y], mul*zoom_inc); break; } @@ -1810,31 +1816,18 @@ void ZoomVerb::perform(SPAction *action, void *data) } } - Geom::Rect const d = dt->get_display_area(); dt->zoom_relative( d.midpoint()[Geom::X], d.midpoint()[Geom::Y], 1 / (mul*zoom_inc) ); break; } case SP_VERB_ZOOM_1_1: - { - double zcorr = prefs->getDouble("/options/zoomcorrection/value", 1.0); - Geom::Rect const d = dt->get_display_area(); dt->zoom_absolute( d.midpoint()[Geom::X], d.midpoint()[Geom::Y], 1.0 * zcorr ); break; - } case SP_VERB_ZOOM_1_2: - { - double zcorr = prefs->getDouble("/options/zoomcorrection/value", 1.0); - Geom::Rect const d = dt->get_display_area(); dt->zoom_absolute( d.midpoint()[Geom::X], d.midpoint()[Geom::Y], 0.5 * zcorr ); break; - } case SP_VERB_ZOOM_2_1: - { - double zcorr = prefs->getDouble("/options/zoomcorrection/value", 1.0); - Geom::Rect const d = dt->get_display_area(); dt->zoom_absolute( d.midpoint()[Geom::X], d.midpoint()[Geom::Y], 2.0 * zcorr ); break; - } case SP_VERB_ZOOM_PAGE: dt->zoom_page(); break; -- cgit v1.2.3 From f337f7705f290ecef1790c75f8f94c85e13777b2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 4 Apr 2014 20:12:04 +0200 Subject: fix crash. Iterating through a list to find an object is not necessary, SPDoc provides method for obtaining SPObj from idstring. The crash probably happened because deleting the object invalidated the list iterated (partly). Fixed bugs: - https://launchpad.net/bugs/1302079 (bzr r13265) --- src/ui/dialog/document-properties.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 67e788e21..2674efc1e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1236,23 +1236,16 @@ void DocumentProperties::removeEmbeddedScript(){ } } - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); - while ( current ) { - if (current->data && SP_IS_OBJECT(current->data)) { - SPObject* obj = SP_OBJECT(current->data); - if (id == obj->getId()){ - - //XML Tree being used directly here while it shouldn't be. - Inkscape::XML::Node *repr = obj->getRepr(); - if (repr){ - sp_repr_unparent(repr); - - // inform the document, so we can undo - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); - } - } + SPObject* obj = SP_ACTIVE_DOCUMENT->getObjectById(id); + if (obj) { + //XML Tree being used directly here while it shouldn't be. + Inkscape::XML::Node *repr = obj->getRepr(); + if (repr){ + sp_repr_unparent(repr); + + // inform the document, so we can undo + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); } - current = g_slist_next(current); } populate_script_lists(); -- cgit v1.2.3 From dfc3d059f6a909f0a564665e6403552ba7209cd6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 4 Apr 2014 20:35:16 +0200 Subject: fix crash. If there are more crashes/issues related to references to undefined filters we should fix this in a more general way (e.g. not setting filter.set if invalid href) Note that the file is still in a weird state, the stylesheet is not altered... Fixed bugs: - https://launchpad.net/bugs/1301076 (bzr r13266) --- src/filter-chemistry.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index 0f9138560..151480177 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -378,6 +378,11 @@ SPFilter *modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *it } SPFilter *filter = SP_FILTER(item->style->getFilter()); + if (!filter) { + // We reach here when filter.set is true, but the href is not found in the document + return new_filter_simple_from_item(document, item, "normal", radius); + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); // If there are more users for this filter, duplicate it -- cgit v1.2.3 From 09ab1cca2d7fb8cdbb252feb4d1ef7945249c051 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 4 Apr 2014 15:37:48 -0400 Subject: Prevent crash on "three knot" issue (bzr r13090.1.47) --- src/knotholder.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/knotholder.cpp b/src/knotholder.cpp index 94a041385..30a7e58d5 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -234,9 +234,14 @@ KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/, guint) else object_verb = SP_VERB_SELECTION_DYNAMIC_OFFSET; } - - DocumentUndo::done(object->document, object_verb, - _("Move handle")); + if (object) { //increasingly aggressive sanity checks + if (object->document) { + if (object_verb <= SP_VERB_LAST && object_verb >= SP_VERB_INVALID) { + DocumentUndo::done(object->document, object_verb, + _("Move handle")); + } + } + } //else { abort(); } } } -- cgit v1.2.3 From 40c62107849b6eb5e66dd0b1f7fe2a7d29cc83a6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 5 Apr 2014 00:24:46 +0200 Subject: fix cmake build errors for changes in 2geom Fixed bugs: - https://launchpad.net/bugs/1283174 (bzr r13267) --- src/2geom/CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 -- src/util/CMakeLists.txt | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/2geom/CMakeLists.txt b/src/2geom/CMakeLists.txt index b1c30f678..3d516dc18 100644 --- a/src/2geom/CMakeLists.txt +++ b/src/2geom/CMakeLists.txt @@ -21,6 +21,7 @@ set(2geom_SRC nearest-point.cpp numeric/matrix.cpp path-intersection.cpp + path-sink.cpp path.cpp pathvector.cpp piecewise.cpp @@ -43,7 +44,6 @@ set(2geom_SRC solve-bezier-parametric.cpp svg-elliptical-arc.cpp svg-path-parser.cpp - svg-path.cpp sweep.cpp toposweep.cpp transforms.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1e0afa79..8408d6270 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -485,7 +485,6 @@ list(APPEND inkscape_SRC add_subdirectory(debug) add_subdirectory(dialogs) add_subdirectory(display) -add_subdirectory(dom) add_subdirectory(extension) add_subdirectory(filters) add_subdirectory(helper) @@ -539,7 +538,6 @@ target_link_libraries(inkscape #sp_LIB # annoying, we need both! nrtype_LIB # annoying, we need both! - dom_LIB croco_LIB avoid_LIB gdl_LIB diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index cfccfa94d..924cab355 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -5,6 +5,7 @@ set(util_SRC expression-evaluator.cpp share.cpp units.cpp + ziptool.cpp # ------- -- cgit v1.2.3 From a303321365bf5ae640715eb9e033f6f01cb085c8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 5 Apr 2014 08:15:20 +0200 Subject: Allow command line options -i and -j to effect plain-svg output, this involves cropping and reducing. (bzr r13268) --- src/main.cpp | 16 ++++++++++++++++ src/sp-object.cpp | 17 +++++++++++++++++ src/sp-object.h | 5 +++++ 3 files changed, 38 insertions(+) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index c2377b42c..6f4add4b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1177,6 +1177,22 @@ static int sp_process_file_list(GSList *fl) g_slist_free (selected); g_slist_free (to_select); } + if(sp_export_id) { + doc->ensureUpToDate(); + + // "crop" the document to the specified object, cleaning as we go. + SPObject *obj = doc->getObjectById(sp_export_id); + Geom::OptRect const bbox(SP_ITEM(obj)->visualBounds()); + + if (bbox) { + doc->fitToRect(*bbox, false); + } + + if (sp_export_id_only) { + // If -j then remove all other objects to complete the "crop" + doc->getRoot()->cropToObject(obj); + } + } Inkscape::Extension::save(Inkscape::Extension::db.get("org.inkscape.output.svg.plain"), doc, sp_export_svg, false, false, false, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY); diff --git a/src/sp-object.cpp b/src/sp-object.cpp index be3a1ab9d..c904705fb 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -460,6 +460,23 @@ void SPObject::deleteObject(bool propagate, bool propagate_descendants) sp_object_unref(this, NULL); } +void SPObject::cropToObject(SPObject *except) +{ + GSList *toDelete = NULL; + for ( SPObject *child = this->firstChild(); child; child = child->getNext() ) { + if (SP_IS_ITEM(child)) { + if (child->isAncestorOf(except)) { + child->cropToObject(except); + } else if(child != except) { + toDelete = g_slist_append(toDelete, child); + } + } + } + for (GSList *item = toDelete; item; item = item->next) { + SP_OBJECT(item->data)->deleteObject(true, true); + } +} + void SPObject::attach(SPObject *object, SPObject *prev) { //g_return_if_fail(parent != NULL); diff --git a/src/sp-object.h b/src/sp-object.h index cf18d4523..9ce5629e6 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -464,6 +464,11 @@ public: deleteObject(propagate, propagate); } + /** + * Removes all children except for the given object, it's children and it's ancesstors. + */ + void cropToObject(SPObject *except); + /** * Connects a slot to be called when an object is deleted. * -- cgit v1.2.3 From 749e8b0ee6b95f7c704fd326ebe948f9f4a076d2 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 5 Apr 2014 09:22:29 +0200 Subject: Revert the xml editor to it's dockable behaviour and add a comment for the preferences. (bzr r13269) --- src/ui/dialog/dialog-manager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 4be796e67..d427e3590 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -96,8 +96,8 @@ DialogManager::DialogManager() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); + // The preferences dialog is broken, the DockBehavior code resizes it's floating window to the smallest size registerFactory("InkscapePreferences", &create); - registerFactory("XmlTree", &create); if (dialogs_type == FLOATING) { registerFactory("AlignAndDistribute", &create); @@ -129,6 +129,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("CloneTiler", &create); + registerFactory("XmlTree", &create); } else { @@ -161,6 +162,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("CloneTiler", &create); + registerFactory("XmlTree", &create); } } -- cgit v1.2.3 From 6f5f995b17f8eefd630c748f0fa57599830c1608 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 5 Apr 2014 11:26:51 +0200 Subject: Prevent segfault when style string is null. (bzr r13270) --- src/text-editing.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/text-editing.cpp b/src/text-editing.cpp index cae123616..47964880c 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -776,7 +776,7 @@ sp_te_delete (SPItem *item, Inkscape::Text::Layout::iterator const &start, bool has_text_decoration = false; gchar const *root_style = (item)->getRepr()->attribute("style"); - if(strstr(root_style,"text-decoration"))has_text_decoration = true; + if(root_style && strstr(root_style,"text-decoration"))has_text_decoration = true; if (start_item == end_item) { // the quick case where we're deleting stuff all from the same string @@ -2035,7 +2035,7 @@ void sp_te_apply_style(SPItem *text, Inkscape::Text::Layout::iterator const &sta roundtrippability. */ bool has_text_decoration = false; gchar const *root_style = (text)->getRepr()->attribute("style"); - if(strstr(root_style,"text-decoration"))has_text_decoration = true; + if(root_style && strstr(root_style,"text-decoration")) has_text_decoration = true; while (tidy_xml_tree_recursively(common_ancestor, has_text_decoration)){}; // if we only modified subobjects this won't have been automatically sent -- cgit v1.2.3 From 77ba51de31dadeed7d4496a01824238320887dc8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 5 Apr 2014 15:11:12 +0200 Subject: Commit patch from Johan to remove GSList and replace with vector. (bzr r13271) --- src/sp-object.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/sp-object.cpp b/src/sp-object.cpp index c904705fb..65228ec0a 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -462,18 +462,18 @@ void SPObject::deleteObject(bool propagate, bool propagate_descendants) void SPObject::cropToObject(SPObject *except) { - GSList *toDelete = NULL; + std::vector toDelete; for ( SPObject *child = this->firstChild(); child; child = child->getNext() ) { if (SP_IS_ITEM(child)) { if (child->isAncestorOf(except)) { child->cropToObject(except); } else if(child != except) { - toDelete = g_slist_append(toDelete, child); + toDelete.push_back(child); } } } - for (GSList *item = toDelete; item; item = item->next) { - SP_OBJECT(item->data)->deleteObject(true, true); + for (std::size_t i = 0; i < toDelete.size(); ++i) { + (toDelete[i])->deleteObject(true, true); } } -- cgit v1.2.3 From 87e777b212130a79f0a17e879393127739636f2c Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 6 Apr 2014 00:49:23 +0200 Subject: noop: improve code style in sp-lpe-item.cpp (bzr r13272) --- src/sp-lpe-item.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 666c79e49..7dd14f5d9 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -50,20 +50,21 @@ typedef std::list HRefList; static std::string patheffectlist_write_svg(PathEffectList const & list); static std::string hreflist_write_svg(HRefList const & list); -SPLPEItem::SPLPEItem() : SPItem() { - this->path_effects_enabled = 1; - - this->path_effect_list = new PathEffectList(); - this->current_path_effect = NULL; - - this->lpe_modified_connection_list = new std::list(); +SPLPEItem::SPLPEItem() + : SPItem() + , path_effects_enabled(1) + , path_effect_list(new PathEffectList()) + , lpe_modified_connection_list(new std::list()) + , current_path_effect(NULL) + , lpe_helperpaths() +{ } SPLPEItem::~SPLPEItem() { } void SPLPEItem::build(SPDocument *document, Inkscape::XML::Node *repr) { - this->readAttr( "inkscape:path-effect" ); + this->readAttr( "inkscape:path-effect" ); SPItem::build(document, repr); } @@ -166,9 +167,9 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { } void SPLPEItem::update(SPCtx* ctx, unsigned int flags) { - SPItem::update(ctx, flags); + SPItem::update(ctx, flags); - // update the helperpaths of all LPEs applied to the item + // update the helperpaths of all LPEs applied to the item // TODO: re-add for the new node tool } @@ -200,11 +201,11 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape */ bool SPLPEItem::performPathEffect(SPCurve *curve) { if (!this) { - return false; + return false; } if (!curve) { - return false; + return false; } if (this->hasPathEffect() && this->pathEffectsEnabled()) { @@ -259,7 +260,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { // CPPIFY: make pure virtual void SPLPEItem::update_patheffect(bool /*write*/) { - //throw; + //throw; } /** -- cgit v1.2.3 From 6f10c7f675fae8c20f24f01b7cffb861f3726e9d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 6 Apr 2014 17:38:30 -0400 Subject: Properly allow effect stacking with knotholders (and add extra LPE functionality) (bzr r13090.1.48) --- src/live_effects/effect.cpp | 18 +++++++++ src/live_effects/effect.h | 8 ++++ src/live_effects/lpe-attach-path.cpp | 11 ++---- src/live_effects/lpe-attach-path.h | 2 - src/live_effects/lpe-knot.cpp | 4 ++ src/live_effects/lpe-knot.h | 3 +- src/live_effects/lpe-tangent_to_curve.cpp | 19 ++++------ src/live_effects/lpe-tangent_to_curve.h | 1 - src/live_effects/lpe-taperstroke.cpp | 62 +++++++++++++++---------------- src/snap.cpp | 2 +- src/sp-lpe-item.cpp | 4 +- 11 files changed, 77 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 8bf210270..99282a312 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -373,6 +373,24 @@ void Effect::doOnRemove (SPLPEItem const* lpeitem) { } +//secret impl methods (shhhh!) +void Effect::doOnApply_impl(SPLPEItem const* lpeitem) +{ + sp_lpe_item = const_cast(lpeitem); + sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector(); + doOnApply(lpeitem); +} + +void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) +{ + sp_lpe_item = const_cast(lpeitem); + sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector(); + + doBeforeEffect(lpeitem); +} + /** * Effects can have a parameter path set before they are applied by accepting a nonzero number of * mouse clicks. This method activates the pen context, which waits for the specified number of diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 85c930def..d2d9f3b63 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -53,6 +53,11 @@ public: EffectType effectType() const; + //basically, to get this method called before the derived classes, a bit + //of indirection is needed. We first call these methods, then the below. + void doOnApply_impl(SPLPEItem const* lpeitem); + void doBeforeEffect_impl(SPLPEItem const* lpeitem); + virtual void doOnApply (SPLPEItem const* lpeitem); virtual void doBeforeEffect (SPLPEItem const* lpeitem); @@ -149,6 +154,9 @@ protected: // instead of normally 'splitting' the path into continuous pwd2 paths and calling doEffect_pwd2 for each. bool concatenate_before_pwd2; + SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. + SPCurve * sp_curve; + std::vector pathvector_before_effect; private: bool provides_own_flash_paths; // if true, the standard flash path is suppressed diff --git a/src/live_effects/lpe-attach-path.cpp b/src/live_effects/lpe-attach-path.cpp index 0cceb1cb7..96372892e 100644 --- a/src/live_effects/lpe-attach-path.cpp +++ b/src/live_effects/lpe-attach-path.cpp @@ -62,15 +62,10 @@ void LPEAttachPath::resetDefaults(SPItem const * item) curve_end_previous_origin = end_path_curve_end.getOrigin(); } -void LPEAttachPath::doBeforeEffect(SPLPEItem const *lpeitem) -{ - lpe_effect = const_cast (lpeitem); -} - void LPEAttachPath::doEffect (SPCurve * curve) { std::vector this_pathv = curve->get_pathvector(); - if (lpe_effect && !this_pathv.empty()) { + if (sp_lpe_item && !this_pathv.empty()) { Geom::Path p = Geom::Path(this_pathv.front().initialPoint()); bool set_start_end = start_path_curve_end.getOrigin() != curve_start_previous_origin; @@ -79,7 +74,7 @@ void LPEAttachPath::doEffect (SPCurve * curve) if (start_path.linksToPath()) { std::vector linked_pathv = start_path.get_pathvector(); - Geom::Affine linkedtransform = start_path.getObject()->getRelativeTransform(lpe_effect); + Geom::Affine linkedtransform = start_path.getObject()->getRelativeTransform(sp_lpe_item); if ( !linked_pathv.empty() ) { @@ -132,7 +127,7 @@ void LPEAttachPath::doEffect (SPCurve * curve) if (end_path.linksToPath()) { std::vector linked_pathv = end_path.get_pathvector(); - Geom::Affine linkedtransform = end_path.getObject()->getRelativeTransform(lpe_effect); + Geom::Affine linkedtransform = end_path.getObject()->getRelativeTransform(sp_lpe_item); if ( !linked_pathv.empty() ) { diff --git a/src/live_effects/lpe-attach-path.h b/src/live_effects/lpe-attach-path.h index 390282f90..1d6c590d1 100644 --- a/src/live_effects/lpe-attach-path.h +++ b/src/live_effects/lpe-attach-path.h @@ -25,7 +25,6 @@ public: LPEAttachPath(LivePathEffectObject *lpeobject); virtual ~LPEAttachPath(); - virtual void doBeforeEffect(const SPLPEItem *lpeitem); virtual void doEffect (SPCurve * curve); virtual void resetDefaults(SPItem const * item); @@ -45,7 +44,6 @@ private: ScalarParam end_path_position; TransformedPointParam end_path_curve_start; VectorParam end_path_curve_end; - SPLPEItem * lpe_effect; }; }; //namespace LivePathEffect diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 581c632f5..05b6ed795 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -538,6 +538,10 @@ LPEKnot::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem); + + if (SP_IS_PATH(lpeitem)) { + supplied_path = SP_PATH(lpeitem)->getCurve()->get_pathvector(); + } gpaths = std::vector(); gstroke_widths = std::vector(); diff --git a/src/live_effects/lpe-knot.h b/src/live_effects/lpe-knot.h index b937f9021..12ab32e5b 100644 --- a/src/live_effects/lpe-knot.h +++ b/src/live_effects/lpe-knot.h @@ -64,7 +64,8 @@ public: void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: - virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); + virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector &hp_vec); + std::vector supplied_path; //for knotholder business private: void updateSwitcher(); diff --git a/src/live_effects/lpe-tangent_to_curve.cpp b/src/live_effects/lpe-tangent_to_curve.cpp index dbebdf7fb..bce4876af 100644 --- a/src/live_effects/lpe-tangent_to_curve.cpp +++ b/src/live_effects/lpe-tangent_to_curve.cpp @@ -16,8 +16,6 @@ #include #include "live_effects/lpe-tangent_to_curve.h" -// FIXME: The following are only needed to convert the path's SPCurve* to pwd2. -// There must be a more convenient way to achieve this. #include "sp-path.h" #include "display/curve.h" @@ -108,13 +106,13 @@ LPETangentToCurve::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desk { KnotHolderEntity *e = new TtC::KnotHolderEntityLeftEnd(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the \"left\" end of the tangent") ); + _("Adjust the left end of the tangent") ); knotholder->add(e); } { KnotHolderEntity *e = new TtC::KnotHolderEntityRightEnd(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the \"right\" end of the tangent") ); + _("Adjust the right end of the tangent") ); knotholder->add(e); } }; @@ -130,14 +128,13 @@ KnotHolderEntityAttachPt::knot_set(Geom::Point const &p, Geom::Point const &/*or Geom::Point const s = snap_knot_position(p, state); - // FIXME: There must be a better way of converting the path's SPCurve* to pwd2. - SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); - Geom::PathVector pathv = curve->get_pathvector(); - Piecewise > pwd2; - for (unsigned int i=0; i < pathv.size(); i++) { - pwd2.concat(pathv[i].toPwSb()); + if ( !SP_IS_SHAPE(lpe->sp_lpe_item) ) { + //lpe->t_attach.param_set_value(0); + g_warning("LPEItem is not a path! %s:%d\n", __FILE__, __LINE__); + return; } - + Piecewise > pwd2 = paths_to_pw( lpe->pathvector_before_effect ); + double t0 = nearest_point(s, pwd2); lpe->t_attach.param_set_value(t0); diff --git a/src/live_effects/lpe-tangent_to_curve.h b/src/live_effects/lpe-tangent_to_curve.h index 309afc14b..8e44c01d1 100644 --- a/src/live_effects/lpe-tangent_to_curve.h +++ b/src/live_effects/lpe-tangent_to_curve.h @@ -34,7 +34,6 @@ class LPETangentToCurve : public Effect { public: LPETangentToCurve(LivePathEffectObject *lpeobject); virtual ~LPETangentToCurve(); - virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index dc70782c4..901abff70 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -235,9 +235,11 @@ Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_toler } //clearly it's collinear if two occupy the same point - g_assert(!are_near(start_point, cross_point, 0.0000001)); - g_assert(!are_near(cross_point, end_point, 0.0000001)); - g_assert(!are_near(start_point, end_point, 0.0000001)); + if (are_near(start_point, cross_point, 0.0000001) || + are_near(cross_point, end_point, 0.0000001) || + are_near(start_point, end_point, 0.0000001) ) { + g_critical("Holy crap, something went wrong! %s:%d\n", __FILE__, __LINE__); + } if (!are_collinear(start_point, cross_point, end_point, smooth_tolerance)) break; @@ -533,12 +535,6 @@ Geom::Piecewise > stretch_along(Geom::Piecewiseextent(); - noffset *= pattBndsY->extent(); - toffset *= pattBndsX->extent(); - }*/ - //Prevent more than 90% overlap... if (xspace < -pattBndsX->extent()*.9) { xspace = -pattBndsX->extent()*.9; @@ -587,12 +583,6 @@ Geom::Piecewise > stretch_along(Geom::Piecewiseget_curve_for_edit(); - if (!curve) { + if (!SP_IS_SHAPE(lpe->sp_lpe_item) ) { + g_warning("LPEItem is not a path! %s:%d\n", __FILE__, __LINE__); + return; + } + + SPCurve* curve; + if ( !(curve = SP_SHAPE(lpe->sp_lpe_item)->getCurve()) ) { //oops - lpe->attach_start.param_set_value(0); + //lpe->attach_start.param_set_value(0); return; } - Geom::PathVector pathv = curve->get_pathvector(); + //in case you are wondering, the above are simply sanity checks. we never want to actually + //use that object. + + Geom::PathVector pathv = lpe->pathvector_before_effect; + Piecewise > pwd2; Geom::Path p_in = return_at_first_cusp(pathv[0]); pwd2.concat(p_in.toPwSb()); - std::vector > > pwd_vec = split_at_discontinuities(pwd2); - double t0 = nearest_point(s, pwd_vec[0]); + double t0 = nearest_point(s, pwd2); lpe->attach_start.param_set_value(t0); // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. @@ -682,22 +680,24 @@ void KnotHolderEntityAttachEnd::knot_set(Geom::Point const &p, Geom::Point const Geom::Point const s = snap_knot_position(p, state); - SPCurve *curve = SP_PATH(item)->get_curve_for_edit(); - if (!curve) { + if (!SP_IS_SHAPE(lpe->sp_lpe_item) ) { + g_warning("LPEItem is not a path! %s:%d\n", __FILE__, __LINE__); + return; + } + + SPCurve* curve; + if ( !(curve = SP_SHAPE(lpe->sp_lpe_item)->getCurve()) ) { //oops - lpe->attach_end.param_set_value(0); + //lpe->attach_end.param_set_value(0); return; } - Geom::PathVector pathv = curve->get_pathvector(); - Piecewise > pwd2; + Geom::PathVector pathv = lpe->pathvector_before_effect; Geom::Path p_in = return_at_first_cusp(pathv[0].reverse()); - pwd2.concat(p_in.toPwSb()); - std::vector > > pwd_vec = split_at_discontinuities(pwd2); - - double t0 = nearest_point(s, pwd_vec[0]); + Piecewise > pwd2 = p_in.toPwSb(); + + double t0 = nearest_point(s, pwd2); lpe->attach_end.param_set_value(t0); - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); } Geom::Point KnotHolderEntityAttachBegin::knot_get() const diff --git a/src/snap.cpp b/src/snap.cpp index ecf799cdc..c3891baea 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -116,7 +116,7 @@ void SnapManager::freeSnapReturnByRef(Geom::Point &p, Inkscape::SnapSourceType const source_type, Geom::OptRect const &bbox_to_snap) const { - Inkscape::SnappedPoint const s = freeSnap(Inkscape::SnapCandidatePoint(p, source_type), bbox_to_snap); + Inkscape::SnappedPoint const s = freeSnap(Inkscape::SnapCandidatePoint(p, source_type, Inkscape::SNAPTARGET_PATH), bbox_to_snap); s.getPointIfSnapped(p); } diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index eda34a0b5..712a0d579 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -242,7 +242,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { - lpe->doBeforeEffect(this); + lpe->doBeforeEffect_impl(this); } try { @@ -414,7 +414,7 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) } // perform this once when the effect is applied - lpe->doOnApply(this); + lpe->doOnApply_impl(this); // indicate that all necessary preparations are done and the effect can be performed lpe->setReady(); -- cgit v1.2.3 From aa5ee7d5a885df6cb4a31b1edaf1a35cf32b686e Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 6 Apr 2014 23:54:56 +0200 Subject: temporary fix for bug in 2geom, the bug manifests itself in LPE Construct grid (bzr r13273) --- src/2geom/path.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp index 5797f475c..fc4d72028 100644 --- a/src/2geom/path.cpp +++ b/src/2geom/path.cpp @@ -104,12 +104,14 @@ Path &Path::operator*=(Affine const &m) { } Path &Path::operator*=(Translate const &m) { +/* Somehow there is something wrong here, LPE Construct grid fails with this code unshare(); Sequence::iterator last = get_curves().end() - 1; Sequence::iterator it; Point prev; for (it = get_curves().begin() ; it != last ; ++it) { - *(const_cast(&**it)) *= m; + //*(const_cast(&**it)) *= m; + const_cast(it->get())->operator*=(m); if ( it != get_curves().begin() && (*it)->initialPoint() != prev ) { THROW_CONTINUITYERROR(); } @@ -124,6 +126,8 @@ Path &Path::operator*=(Translate const &m) { } } return *this; +*/ + return this->operator*=(static_cast(m)); } std::vector -- cgit v1.2.3 From bbb268a4e678aa5caa932a1bea115c31097973eb Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 8 Apr 2014 22:18:19 +0200 Subject: Make extension tests compatible with VPATH builds. Fixes distcheck not being able to find the test script. (bzr r13276) --- src/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index d3f8794ee..d5439f0ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -250,7 +250,9 @@ check_PROGRAMS = cxxtests # "make distcheck". # List of all tests to be run. -TESTS = $(check_PROGRAMS) ../share/extensions/test/run-all-extension-tests +TESTS = $(check_PROGRAMS) +check-local: + $(top_srcdir)/share/extensions/test/run-all-extension-tests # FIXME: Currently, a number of cxxtest tests fail. These should be fixed and # the XFAIL_TESTS build target should be removed. -- cgit v1.2.3 From 2b1a0283357fec95109b67f9379ebec4bf56338e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 10 Apr 2014 07:43:01 +0200 Subject: Fix for Bug #1302987 (Importing a PNG image with unittype field undefined fails). Fixed bugs: - https://launchpad.net/bugs/1302987 (bzr r13279) --- src/extension/internal/image-resolution.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/extension/internal/image-resolution.cpp b/src/extension/internal/image-resolution.cpp index 18eb97f80..f092b21ef 100644 --- a/src/extension/internal/image-resolution.cpp +++ b/src/extension/internal/image-resolution.cpp @@ -353,18 +353,13 @@ void ImageResolution::readmagick(char const *fn) { g_warning("ImageResolution::readmagick: Unknown error"); return; } - Magick::Geometry geo = image.density(); - std::string type = image.magick(); - - if (type == "PNG") { // PNG only supports pixelspercentimeter - x_ = Inkscape::Util::Quantity::convert((double)geo.width(), "in", "cm"); - y_ = Inkscape::Util::Quantity::convert((double)geo.height(), "in", "cm"); - } else { - x_ = (double)geo.width(); - y_ = (double)geo.height(); - } - ok_ = true; + x_ = image.xResolution(); + y_ = image.yResolution(); + + if (x_ != 0 && y_ != 0) { + ok_ = true; + } } #else -- cgit v1.2.3 From a354238633c206078acc11a60d02382cee572740 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 12 Apr 2014 00:52:48 -0400 Subject: Wonderful code optimizations (bzr r13090.1.50) --- src/live_effects/lpe-taperstroke.cpp | 153 +++---------------------------- src/live_effects/pathoutlineprovider.cpp | 79 ++++++---------- src/live_effects/pathoutlineprovider.h | 6 ++ 3 files changed, 46 insertions(+), 192 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 901abff70..ce07ed962 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -180,77 +180,15 @@ void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem) //actual effect impl here -Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_tolerance = 0.05) +Geom::Path return_at_first_cusp (Geom::Path const & path_in, double /*smooth_tolerance*/ = 0.05) { - Geom::Path path_out = Geom::Path(); - - for (unsigned i = 0; i < path_in.size(); i++) { - path_out.append(path_in[i]); - if (path_in.size() == 1) - break; - - //determine order of curve - int order = Outline::bezierOrder(&path_in[i]); - - Geom::Point start_point; - Geom::Point cross_point = path_in[i].finalPoint(); - Geom::Point end_point; - - g_assert(path_in[i].finalPoint() == path_in[i+1].initialPoint()); - - //can you tell that the following expressions have been shaped by - //repeated compiler errors? ;) - switch (order) { - case 3: - start_point = (static_cast(&path_in[i]))->operator[] (2); - //major league b***f***ing - if (are_near(start_point, cross_point, 0.0000001)) { - start_point = (static_cast(&path_in[i]))->operator[] (1); - } - break; - case 2: - //this never happens - start_point = (static_cast(&path_in[i]))->operator[] (1); - break; - case 1: - default: - start_point = path_in[i].initialPoint(); - } - - order = Outline::bezierOrder(&path_in[i+1]); - - switch (order) { - case 3: - end_point = (static_cast(&path_in[i+1]))->operator[] (1); - if (are_near(end_point, cross_point, 0.0000001)) { - end_point = (static_cast(&path_in[i+1]))->operator[] (2); - } - break; - case 2: - end_point = (static_cast(&path_in[i+1]))->operator[] (1); - break; - case 1: - default: - end_point = path_in[i+1].finalPoint(); - } - - //clearly it's collinear if two occupy the same point - if (are_near(start_point, cross_point, 0.0000001) || - are_near(cross_point, end_point, 0.0000001) || - are_near(start_point, end_point, 0.0000001) ) { - g_critical("Holy crap, something went wrong! %s:%d\n", __FILE__, __LINE__); - } - - if (!are_collinear(start_point, cross_point, end_point, smooth_tolerance)) - break; - } - return path_out; + return Geom::split_at_cusps(path_in)[0]; } Geom::Piecewise > stretch_along(Geom::Piecewise > pwd2_in, Geom::Path pattern, double width); //references to pointers, because magic -void subdivideCurve(const Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second); +void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second); Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) { @@ -378,34 +316,9 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa trimmed_start.append(path_in[0] [i]); } - - //this is pretty annoying - //previously I wrote a function for this but it wasted a lot of time - //so I optimized it back into here. - unsigned order = Outline::bezierOrder(curve_start); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast(curve_start); - std::pair cb_pair = cb->subdivide((attach_start - loc)); - trimmed_start.append(cb_pair.first); - curve_start = cb_pair.second.duplicate(); //goes out of scope - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast(curve_start); - std::pair qb_pair = qb->subdivide((attach_start - loc)); - trimmed_start.append(qb_pair.first); - curve_start = qb_pair.second.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); - std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide((attach_start - loc)); - trimmed_start.append(lb_pair.first); - curve_start = lb_pair.second.duplicate(); - break; - } - } + Geom::Curve * temp; + subdivideCurve(curve_start, attach_start - loc, temp, curve_start); + trimmed_start.append(*temp); //special case: path is one segment long //special case: what if the two knots occupy the same segment? @@ -416,31 +329,9 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa //we have to do some shifting here because the value changed when we reduced the length //of the previous segment. - order = Outline::bezierOrder(curve_start); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast(curve_start); - std::pair cb_pair = cb->subdivide(t); - trimmed_end.append(cb_pair.second); - curve_start = cb_pair.first.duplicate(); - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast(curve_start); - std::pair qb_pair = qb->subdivide(t); - trimmed_end.append(qb_pair.second); - curve_start = qb_pair.first.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast * >(curve_start); - std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); - trimmed_end.append(lb_pair.second); - curve_start = lb_pair.first.duplicate(); - break; - } - } - + subdivideCurve(curve_start, t, curve_start, temp); + trimmed_end.append(*temp); + for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); } @@ -468,30 +359,8 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); - order = Outline::bezierOrder(curve_end); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast(curve_end); - std::pair cb_pair = cb->subdivide(t); - trimmed_end.append(cb_pair.second); - curve_end = cb_pair.first.duplicate(); - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast(curve_end); - std::pair qb_pair = qb->subdivide(t); - trimmed_end.append(qb_pair.second); - curve_end = qb_pair.first.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast * >(curve_end); - std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); - trimmed_end.append(lb_pair.second); - curve_end = lb_pair.first.duplicate(); - break; - } - } + subdivideCurve(curve_end, t, curve_end, temp); + trimmed_end.append(*temp); for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index a696728d6..5a95da75d 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -9,6 +9,7 @@ #include <2geom/shape.h> #include <2geom/transforms.h> #include <2geom/path-sink.h> +#include "helper/geom-nodetype.h" #include namespace Geom { @@ -99,21 +100,25 @@ static Circle touching_circle( D2 const &curve, double t, double tol=0.0 return Geom::Circle(center, fabs(radius)); } -static std::vector split_at_cusps(const Geom::Path& in) +std::vector split_at_cusps(const Geom::Path& in) { - Geom::PathVector out = Geom::PathVector(); - Geom::Path temp = Geom::Path(); - - for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) { - temp = Geom::Path(); - temp.append(in[path_descr]); + PathVector out = PathVector(); + Path temp = Path(); + + for (unsigned i = 0; i < in.size(); i++) { + temp.append(in[i]); + if ( get_nodetype(in[i], in[i + 1]) != Geom::NODE_SMOOTH ) { + out.push_back(temp); + temp = Path(); + } + } + if (temp.size() > 0) { out.push_back(temp); } - return out; } -static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) +Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) { std::vector temp; sbasis_to_bezier(temp, sbasis_in, 4); @@ -140,13 +145,9 @@ typedef Geom::Piecewise PWD2; unsigned bezierOrder (const Geom::Curve* curve_in) { using namespace Geom; - //cast it - const CubicBezier *cbc = dynamic_cast(curve_in); - if (cbc) return 3; - const QuadraticBezier * qbc = dynamic_cast(curve_in); - if (qbc) return 2; - const BezierCurveN<1U> * lbc = dynamic_cast *>(curve_in); - if (lbc) return 1; + if ( const BezierCurve* bz = dynamic_cast(curve_in) ) { + return bz->order(); + } return 0; } @@ -154,8 +155,6 @@ unsigned bezierOrder (const Geom::Curve* curve_in) //is >180 clockwise, otherwise false. bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) { - unsigned order = bezierOrder(&cbc1); - Geom::Point start_point; Geom::Point cross_point = cbc1.finalPoint(); Geom::Point end_point; @@ -167,38 +166,18 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) "By default we are going to say that this is an inside join, so we cannot make a line join for it.\n", __LINE__, __FILE__); return false; } - switch (order) { - case 3: - start_point = (static_cast(&cbc1))->operator[] (2); - //major league b***f***ing - if (are_near(start_point, cross_point, 0.0000001)) { - start_point = (static_cast(&cbc1))->operator[] (1); - } - break; - case 2: - //this never happens - start_point = (static_cast(&cbc1))->operator[] (1); - break; - case 1: - default: - start_point = cbc1.initialPoint(); + + //let's try: + Geom::CubicBezier cubicBezier = Geom::sbasis_to_cubicbezier(cbc1.toSBasis()); + start_point = cubicBezier [2]; + //stupid thing Inkscape does: + if (are_near(start_point, cross_point, 0.0000001)) { + start_point = cubicBezier [1]; } - - order = Outline::bezierOrder(&cbc2); - - switch (order) { - case 3: - end_point = (static_cast(&cbc2))->operator[] (1); - if (are_near(end_point, cross_point, 0.0000001)) { - end_point = (static_cast(&cbc2))->operator[] (2); - } - break; - case 2: - end_point = (static_cast(&cbc2))->operator[] (1); - break; - case 1: - default: - end_point = cbc2.finalPoint(); + cubicBezier = Geom::sbasis_to_cubicbezier(cbc2.toSBasis()); + end_point = cubicBezier [1]; + if (are_near(end_point, cross_point, 0.0000001)) { + end_point = cubicBezier [2]; } //got our three points, now let's see what their clockwise angle is @@ -391,7 +370,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double Geom::Path path_builder = Geom::Path(); //the path to store the result in Geom::PathVector * path_vec; //needed because livarot returns a goddamn pointer - const unsigned k = path_in.size(); + const unsigned k = pv.size(); for (unsigned u = 0; u < k; u+=2) { to_outline = Path(); diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h index 27bc62d45..0ee0f261e 100644 --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -12,6 +12,12 @@ enum LineJoinType { LINEJOIN_EXTRAPOLATED }; +namespace Geom +{ + Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in); + std::vector split_at_cusps(const Geom::Path& in); +} + namespace Outline { unsigned bezierOrder (const Geom::Curve* curve_in); -- cgit v1.2.3 From 727826e1fdd2c4142b1687e50c174ed14c178427 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 12 Apr 2014 14:18:31 -0400 Subject: Fix triangles in joins (bzr r13090.1.52) --- src/live_effects/lpe-taperstroke.cpp | 58 ++++++++++++++------------------ src/live_effects/pathoutlineprovider.cpp | 45 +++++++++++++++++++++---- 2 files changed, 65 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index ce07ed962..2400b3e37 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -197,6 +197,8 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) bool zeroStart = false; bool zeroEnd = false; + bool metInMiddle = false; + //there is a pretty good chance that people will try to drag the knots //on top of each other, so block it @@ -208,6 +210,10 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) attach_end.param_set_value( size - attach_start ); } } + + if (attach_start == size - attach_end) { + metInMiddle = true; + } //don't let it be zero if (attach_start <= 0.00000001) { @@ -232,10 +238,10 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //don't let the knots be farther than they are allowed to be if ((unsigned)attach_start >= allowed_start) { - attach_start.param_set_value((double)allowed_start - 0.00000001); + attach_start.param_set_value((double)allowed_start - 0.00001); } if ((unsigned)attach_end >= allowed_end) { - attach_end.param_set_value((double)allowed_end - 0.00000001); + attach_end.param_set_value((double)allowed_end - 0.00001); } //remember, Path::operator () means get point at time t @@ -265,11 +271,14 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) real_path.append(throwaway_path); } - //append the outside outline of the path (with direction) - throwaway_path = Outline::PathOutsideOutline(pathv_out[1], - -fabs(line_width), static_cast(join_type.get_value()), miter_limit); + + if (!metInMiddle) { + //append the outside outline of the path (with direction) + throwaway_path = Outline::PathOutsideOutline(pathv_out[1], + -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + } if (!zeroEnd) { //append the ending taper @@ -460,32 +469,17 @@ Geom::Piecewise > stretch_along(Geom::Piecewise(curve_in); - std::pair cb_pair = cb->subdivide(t); - //trimmed_start.append(cb_pair.first); - val_first = cb_pair.first.duplicate(); - val_second = cb_pair.second.duplicate(); - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast(curve_in); - std::pair qb_pair = qb->subdivide(t); - //trimmed_start.append(qb_pair.first); - val_first = qb_pair.first.duplicate(); - val_second = qb_pair.second.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast * >(curve_in); - std::pair, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); - //trimmed_start.append(lb_pair.first); - val_first = lb_pair.first.duplicate(); - val_second = lb_pair.second.duplicate(); - break; - } + if (Geom::LineSegment* linear = dynamic_cast(curve_in)) { + //special case for line segments + std::pair seg_pair = linear->subdivide(t); + val_first = seg_pair.first.duplicate(); + val_second = seg_pair.second.duplicate(); + } else { + //all other cases: + Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(curve_in->toSBasis()); + std::pair cubic_pair = cubic.subdivide(t); + val_first = cubic_pair.first.duplicate(); + val_second = cubic_pair.second.duplicate(); } } diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index 5a95da75d..080f42c08 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -261,6 +261,7 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } path_builder.appendNew (endPt); } + path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); } if ( outside && lineProblem ) { Geom::Path pth; @@ -282,9 +283,22 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } } path_builder.appendNew (endPt); + path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); } if ( !outside ) { - path_builder.appendNew (endPt); + /*path_builder.appendNew (endPt);*/ + Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); + if (!cross.empty()) { + path_builder.erase_last(); + Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(cbc1->toSBasis()); + cubic = cubic.subdivide(cross[0].ta).first; + path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); + cubic = Geom::sbasis_to_cubicbezier(cbc2->toSBasis()); + cubic = cubic.subdivide(cross[0].tb).second; + path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); + } else { + path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); + } } } @@ -346,9 +360,22 @@ void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cb path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); } - } else { // cross.empty() + path_builder.append(*cbc2); + } else { //probably on the inside of the corner - path_builder.appendNew ( endPt ); + /*path_builder.appendNew ( endPt );*/ + cross = Geom::crossings(*cbc1, *cbc2); + if (!cross.empty()) { + path_builder.erase_last(); + Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(cbc1->toSBasis()); + cubic = cubic.subdivide(cross[0].ta).first; + path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); + cubic = Geom::sbasis_to_cubicbezier(cbc2->toSBasis()); + cubic = cubic.subdivide(cross[0].tb).second; + path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); + } else { + path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); + } } } @@ -387,6 +414,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double if (u == 0) { //I could use the pv->operator[] (0) notation but that looks terrible path_builder.start( (*path_vec)[0].initialPoint() ); + path_builder.append( (*path_vec)[0] ); } else { //get the curves ready for the operation Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate(); @@ -400,10 +428,12 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); } + Geom::Path temp_path = (*path_vec)[0]; + temp_path.erase(temp_path.begin()); + + path_builder.append( temp_path ); } - path_builder.append( (*path_vec)[0] ); - //outline the next segment, but don't store it yet if (path_vec) delete path_vec; @@ -430,7 +460,10 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double } //Now we can store it. - path_builder.append( (*path_vec)[0] ); + Geom::Path temp_path = (*path_vec)[0]; + temp_path.erase(temp_path.begin()); + + path_builder.append( temp_path ); if (cbc1) delete cbc1; if (cbc2) delete cbc2; -- cgit v1.2.3 From e36987cea4199ec3e51becad59b88e36c75e0955 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 12 Apr 2014 14:38:11 -0400 Subject: Fix memory leak (bzr r13090.1.53) --- src/live_effects/lpe-taperstroke.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 2400b3e37..8316daf71 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -328,6 +328,7 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa Geom::Curve * temp; subdivideCurve(curve_start, attach_start - loc, temp, curve_start); trimmed_start.append(*temp); + if (temp) delete temp; temp = 0; //special case: path is one segment long //special case: what if the two knots occupy the same segment? @@ -340,6 +341,7 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa subdivideCurve(curve_start, t, curve_start, temp); trimmed_end.append(*temp); + if (temp) delete temp; temp = 0; for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); @@ -370,6 +372,7 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa subdivideCurve(curve_end, t, curve_end, temp); trimmed_end.append(*temp); + if (temp) delete temp; temp = 0; for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); -- cgit v1.2.3 From 3a4844ef32ce02cbcb9f1102f61d60914bb48d72 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 12 Apr 2014 18:58:48 -0400 Subject: Enable line caps (bzr r13090.1.54) --- src/live_effects/pathoutlineprovider.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index 080f42c08..d7f5362aa 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -528,14 +528,23 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, case butt_round: pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, against_direction.initialPoint() ); break; - case butt_pointy: - //I have ZERO idea what to do here. + case butt_pointy: { + Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.); + double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint()); + Geom::Point midpoint = 0.5 * (with_direction.finalPoint() + against_direction.initialPoint()) + radius*end_deriv; + pb.lineTo(midpoint); pb.lineTo(against_direction.initialPoint()); break; - case butt_square: + } + case butt_square: { + Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.); + double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint()); + pb.lineTo(with_direction.finalPoint() + radius*end_deriv); + pb.lineTo(against_direction.initialPoint() + radius*end_deriv); pb.lineTo(against_direction.initialPoint()); break; } + } } else { pb.moveTo(against_direction.initialPoint()); } @@ -551,14 +560,23 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, case butt_round: pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, with_direction.initialPoint() ); break; - case butt_pointy: - //I have ZERO idea what to do here. + case butt_pointy: { + Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.); + double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint()); + Geom::Point midpoint = 0.5 * (against_direction.finalPoint() + with_direction.initialPoint()) + radius*end_deriv; + pb.lineTo(midpoint); pb.lineTo(with_direction.initialPoint()); break; - case butt_square: + } + case butt_square: { + Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.); + double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint()); + pb.lineTo(against_direction.finalPoint() + radius*end_deriv); + pb.lineTo(with_direction.initialPoint() + radius*end_deriv); pb.lineTo(with_direction.initialPoint()); break; } + } } pb.flush(); for (unsigned m = 0; i < pb.peek().size(); i++) { -- cgit v1.2.3 From fd29d6366fe47e17b732ec4cc40d40ae1f272e35 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 13 Apr 2014 12:49:05 -0400 Subject: Nothing special (bzr r13090.1.55) --- src/live_effects/pathoutlineprovider.cpp | 49 ++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index d7f5362aa..d8e416fea 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -389,7 +389,13 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double { // NOTE: it is important to notice the distinction between a Geom::Path and a livarot Path here! // if you do not see "Geom::" there is a different function set! - Geom::PathVector pv = split_at_cusps(path_in); + Geom::Path temporary(path_in); + if (path_in.closed()) { + //this is a terrible solution + temporary.erase_last(); + temporary.close(false); + } + Geom::PathVector pv = split_at_cusps(temporary); Path to_outline; Path outlined_result; @@ -469,6 +475,12 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double if (cbc2) delete cbc2; if (path_vec) delete path_vec; } + if (path_in.closed()) { + temporary = Geom::Path(); + temporary.append(*path_in.end()); + Geom::Path temporary2 = doAdvHalfOutline(temporary, line_width, miter_limit, extrapolate); + path_builder.append(temporary2/*, Geom::Path::STITCH_DISCONTINUOUS*/); + } } return path_builder; @@ -492,25 +504,19 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, } else { //Geom::Path absolutely refuses to do what I want with these Geom::Path newPath = path_in[i]; - newPath.close(false); - Geom::Piecewise > pwd2 = newPath.toPwSb(); - newPath = Geom::path_from_piecewise(pwd2, 0.01)[0]; - //fuk this + if (Geom::distance(newPath.finalPoint(), newPath.initialPoint()) == newPath[newPath.size()].length()) { + Geom::LineSegment linear(newPath.finalPoint(), newPath.initialPoint()); + Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(linear.toSBasis()); + newPath.appendNew(cubic[1], cubic[2], cubic[3]); + } + //newPath.close(false); with_direction = Outline::doAdvHalfOutline( newPath, -line_width, miter_lim, extrapolate ); against_direction = Outline::doAdvHalfOutline( newPath.reverse(), -line_width, miter_lim, extrapolate ); - - /*if (dynamic_cast *>(&newPath[newPath.size()])) { - //delete the 'Z' - newPath.erase_last(); - newPath.append(path_in[i][path_in[i].size() - 1]); - newPath.appendNew(newPath.initialPoint()); - newPath.erase_last(); - } else { - //delete the 'Z' - newPath.erase_last(); - newPath.append(path_in[i][path_in[i].size() - 1]); - newPath.appendNew(newPath.initialPoint()); - newPath.erase_last(); + /*if (Geom::distance(newPath.finalPoint(), newPath.initialPoint()) != newPath[newPath.size()].length()) { + with_direction.erase_last(); + with_direction.erase_last(); + against_direction.erase(against_direction.begin()); + against_direction.erase(against_direction.begin()); }*/ } Geom::PathBuilder pb; @@ -579,8 +585,9 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, } } pb.flush(); - for (unsigned m = 0; i < pb.peek().size(); i++) { - path_out.push_back(pb.peek()[m]); + path_out.push_back(pb.peek()[0]); + if (path_in[i].closed()) { + path_out.push_back(pb.peek()[1]); } } else { Path p = Path(); @@ -658,8 +665,6 @@ Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, Lin return path_out; } else if (linejoin_type == LINEJOIN_REFLECTED) { //reflected half outline - Geom::PathVector pathvec; - pathvec.push_back(path_in); path_out = doAdvHalfOutline(path_in, line_width, miter_lim, false); return path_out; } else if (linejoin_type == LINEJOIN_EXTRAPOLATED) { -- cgit v1.2.3 From 671a7cc69e564a5cc343cfc802750e7c46bf19df Mon Sep 17 00:00:00 2001 From: Adib Taraben Date: Sun, 13 Apr 2014 18:52:12 +0200 Subject: pdf import via poppler-cairo, bug:1017123:handling stroke width < 1 Fixed bugs: - https://launchpad.net/bugs/1017123 (bzr r13283) --- src/extension/internal/pdf-input-cairo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/internal/pdf-input-cairo.cpp b/src/extension/internal/pdf-input-cairo.cpp index c45367c08..9ce73c260 100644 --- a/src/extension/internal/pdf-input-cairo.cpp +++ b/src/extension/internal/pdf-input-cairo.cpp @@ -616,7 +616,7 @@ PdfInputCairo::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { output, width, height); cairo_t* cr = cairo_create(surface); - poppler_page_render(page, cr); + poppler_page_render_for_printing(page, cr); cairo_show_page(cr); cairo_destroy(cr); -- cgit v1.2.3 From 677385b07c489ace6b7057a95a3260a341edfdff Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 14 Apr 2014 22:38:32 +0200 Subject: patch by Gellule, fixes wrong parsing of style, work-around for bug in libc++ Fixed bugs: - https://launchpad.net/bugs/1300271 (bzr r13285) --- src/xml/repr-css.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 24e2db9e1..32a1e7f5d 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -382,7 +382,10 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con std::string characters; std::string temp; bool number_valid = !(ss >> number).fail(); - if( !number_valid ) ss.clear(); + if (!number_valid) { + ss.clear(); + ss.seekg(0); // work-around for a bug in libc++ (see lp:1300271) + } while( !(ss >> temp).eof() ) { characters += temp; characters += " "; -- cgit v1.2.3 From 646534345d309233570969f98fcf9495c19d45ae Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 14 Apr 2014 22:48:12 +0200 Subject: Improve calculation precision of stroke-to-path, for very large user units that make the stroke width a very small number. Fixed bugs: - https://launchpad.net/bugs/1244861 (bzr r13286) --- src/splivarot.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 6aec42c5b..40f3f174a 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -960,16 +960,17 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) Geom::Affine const transform(item->transform); float const scale = transform.descrim(); - float o_width, o_miter; + float o_width = i_style->stroke_width.computed; + if (o_width < Geom::EPSILON) { + // This may result in rounding errors for very small stroke widths (happens e.g. when user unit is large). + // See bug lp:1244861 + o_width = Geom::EPSILON; + } + float o_miter = i_style->stroke_miterlimit.value * o_width; + JoinType o_join; ButtType o_butt; { - o_width = i_style->stroke_width.computed; - if (o_width < 0.01) { - o_width = 0.01; - } - o_miter = i_style->stroke_miterlimit.value * o_width; - switch (i_style->stroke_linejoin.computed) { case SP_STROKE_LINEJOIN_MITER: o_join = join_pointy; -- cgit v1.2.3 From 204b9726e63765daac179c9c7972e08c5b62a1c1 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 14 Apr 2014 22:55:29 +0200 Subject: remove debug messages in desktop.cpp (bzr r13287) --- src/desktop.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 22c00d4f1..b61f6867f 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -1699,7 +1699,6 @@ _layer_hierarchy_changed(SPObject */*top*/, SPObject *bottom, /// Called when document is starting to be rebuilt. static void _reconstruction_start(SPDesktop * desktop) { - g_debug("Desktop, starting reconstruction\n"); desktop->_reconstruction_old_layer_id = desktop->currentLayer()->getId() ? desktop->currentLayer()->getId() : ""; desktop->layers->reset(); @@ -1710,8 +1709,6 @@ static void _reconstruction_start(SPDesktop * desktop) } */ desktop->selection->clear(); - - g_debug("Desktop, starting reconstruction end\n"); } /// Called when document rebuild is finished. -- cgit v1.2.3 From 6f508cfcaa161695711309d3413b90d2b3f44ea0 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 14 Apr 2014 21:50:06 -0400 Subject: Minor things (bzr r13090.1.58) --- src/knotholder.cpp | 11 +++++++++-- src/live_effects/Makefile_insert | 3 ++- src/sp-lpe-item.cpp | 8 ++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/knotholder.cpp b/src/knotholder.cpp index 30a7e58d5..aea983cbb 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -154,8 +154,15 @@ KnotHolder::knot_clicked_handler(SPKnot *knot, guint state) } // for drag, this is done by ungrabbed_handler, but for click we must do it here - DocumentUndo::done(saved_item->document, object_verb, - _("Change handle")); + + if (saved_item) { //increasingly aggressive sanity checks + if (saved_item->document) { + if (object_verb <= SP_VERB_LAST && object_verb >= SP_VERB_INVALID) { + DocumentUndo::done(saved_item->document, object_verb, + _("Change handle")); + } + } + } // else { abort(); } } void diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index ac7c33e2f..e2c35c3bd 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -88,12 +88,13 @@ ink_common_sources += \ live_effects/lpe-attach-path.cpp \ live_effects/lpe-attach-path.h \ live_effects/lpe-fill-between-strokes.cpp \ - live_effects/lpe-fill-between-stroke.h \ + live_effects/lpe-fill-between-strokes.h \ live_effects/lpe-fill-between-many.cpp \ live_effects/lpe-fill-between-many.h \ live_effects/lpe-ellipse_5pts.cpp \ live_effects/lpe-ellipse_5pts.h \ live_effects/pathoutlineprovider.cpp \ + live_effects/pathoutlineprovider.h \ live_effects/lpe-jointype.cpp \ live_effects/lpe-jointype.h \ live_effects/lpe-taperstroke.cpp \ diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 07fa6147b..ae5763e67 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -689,12 +689,20 @@ static std::string hreflist_write_svg(HRefList const & list) // Return a copy of the effect list PathEffectList SPLPEItem::getEffectList() { + if (!path_effect_list) { + g_critical("Broken path effect list in %s\n", __FILE__); + return PathEffectList(); + } return *path_effect_list; } // Return a copy of the effect list PathEffectList const SPLPEItem::getEffectList() const { + if (!path_effect_list) { + g_critical("Broken path effect list in %s\n", __FILE__); + return PathEffectList(); + } return *path_effect_list; } -- cgit v1.2.3 From c95ccf684a7de367bd7024acf2610a15d20efe75 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Wed, 16 Apr 2014 08:50:06 -0400 Subject: Commit suv's patch for quartz default window size. See bug #1302627 Fixed bugs: - https://launchpad.net/bugs/1302627 (bzr r13289) --- src/preferences-skeleton.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 96629f22d..734e8a582 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -293,7 +293,9 @@ static char const preferences_skeleton[] = #ifdef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs " \n" #endif -" \n" +#if !defined(GDK_WINDOWING_QUARTZ) // No maximise for Quartz, see lp:1302627 + " \n" +#endif " \n" " \n" " \n" -- cgit v1.2.3 From 7a86aa06d93a5cdec9cc55b514bd7ac7079fe50e Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Wed, 16 Apr 2014 20:35:41 +0100 Subject: workaround build failure on Ubuntu 14.04 with dbus ext and clang (bzr r13290) --- src/display/sp-canvas.cpp | 2 ++ src/extension/dbus/Makefile_insert | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 6d903867b..3dc4a7504 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -2153,6 +2153,8 @@ gboolean SPCanvasImpl::handleDraw(GtkWidget *widget, cairo_t *cr) { canvas->requestRedraw(r.left(), r.top(), r.right(), r.bottom()); } + cairo_rectangle_list_destroy(rects); + return FALSE; } #else diff --git a/src/extension/dbus/Makefile_insert b/src/extension/dbus/Makefile_insert index 7d851715e..192651d87 100644 --- a/src/extension/dbus/Makefile_insert +++ b/src/extension/dbus/Makefile_insert @@ -78,7 +78,7 @@ libinkdbus_la_CFLAGS = \ $(DBUS_CFLAGS) \ $(INKSCAPE_CFLAGS) \ -I$(builddir)/extension/dbus \ - -Wall -Werror + -Wall libinkdbus_la_LIBADD = \ $(DBUS_LIBS) \ -- cgit v1.2.3 From 313863173f0d2f406dd3c36aea90099f22a04531 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 17 Apr 2014 13:58:57 -0400 Subject: Semi-fix for Join type on closed paths (bzr r13090.1.59) --- src/live_effects/pathoutlineprovider.cpp | 78 ++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index d8e416fea..4836b0d98 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -389,13 +389,8 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double { // NOTE: it is important to notice the distinction between a Geom::Path and a livarot Path here! // if you do not see "Geom::" there is a different function set! - Geom::Path temporary(path_in); - if (path_in.closed()) { - //this is a terrible solution - temporary.erase_last(); - temporary.close(false); - } - Geom::PathVector pv = split_at_cusps(temporary); + + Geom::PathVector pv = split_at_cusps(path_in); Path to_outline; Path outlined_result; @@ -434,6 +429,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); } + //store it Geom::Path temp_path = (*path_vec)[0]; temp_path.erase(temp_path.begin()); @@ -475,11 +471,44 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double if (cbc2) delete cbc2; if (path_vec) delete path_vec; } - if (path_in.closed()) { - temporary = Geom::Path(); - temporary.append(*path_in.end()); - Geom::Path temporary2 = doAdvHalfOutline(temporary, line_width, miter_limit, extrapolate); - path_builder.append(temporary2/*, Geom::Path::STITCH_DISCONTINUOUS*/); + } + + if (path_in.closed()) { + if ( path_in[path_in.size() - 1].length() != Geom::distance(path_in[path_in.size() - 1].finalPoint(), path_in.initialPoint())) { + //handle case for last segment curved + outlined_result = Path(); + to_outline = Path(); + + Geom::Path oneCurve; oneCurve.append(path_in[0]); + + to_outline.LoadPath(oneCurve, Geom::Affine(), false, false); + to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10); + + path_vec = outlined_result.MakePathVector(); + + Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate();//(*path_vec)[0] [0].duplicate(); + Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate();//path_builder[path_builder.size() - 1].duplicate(); + + Geom::Path temporary; //why do we need this? you'll see in a bit + temporary.append(*cbc1); + + if (extrapolate) { + extrapolate_curves(temporary, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, + outside_angle ( path_in[path_in.size() - 1], path_in [0] )); + } else { + reflect_curves (temporary, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, + outside_angle ( path_in[path_in.size() - 1], path_in [0] )); + } + //extract the appended curves + if (temporary[0].finalPoint() != path_builder[path_builder.size() - 1].finalPoint()) { + path_builder.erase(path_builder.begin()); + } else { + temporary.erase_last(); + } + path_builder.erase_last(); + + path_builder.append(temporary, Geom::Path::STITCH_DISCONTINUOUS); + path_builder.close(); } } @@ -498,27 +527,10 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, //since you've made it this far, hopefully all this is obvious :P Geom::Path with_direction; Geom::Path against_direction; - if ( !path_in[i].closed() ) { - with_direction = Outline::doAdvHalfOutline( path_in[i], -line_width, miter_lim, extrapolate ); - against_direction = Outline::doAdvHalfOutline( path_in[i].reverse(), -line_width, miter_lim, extrapolate ); - } else { - //Geom::Path absolutely refuses to do what I want with these - Geom::Path newPath = path_in[i]; - if (Geom::distance(newPath.finalPoint(), newPath.initialPoint()) == newPath[newPath.size()].length()) { - Geom::LineSegment linear(newPath.finalPoint(), newPath.initialPoint()); - Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(linear.toSBasis()); - newPath.appendNew(cubic[1], cubic[2], cubic[3]); - } - //newPath.close(false); - with_direction = Outline::doAdvHalfOutline( newPath, -line_width, miter_lim, extrapolate ); - against_direction = Outline::doAdvHalfOutline( newPath.reverse(), -line_width, miter_lim, extrapolate ); - /*if (Geom::distance(newPath.finalPoint(), newPath.initialPoint()) != newPath[newPath.size()].length()) { - with_direction.erase_last(); - with_direction.erase_last(); - against_direction.erase(against_direction.begin()); - against_direction.erase(against_direction.begin()); - }*/ - } + + with_direction = Outline::doAdvHalfOutline( path_in[i], -line_width, miter_lim, extrapolate ); + against_direction = Outline::doAdvHalfOutline( path_in[i].reverse(), -line_width, miter_lim, extrapolate ); + Geom::PathBuilder pb; //add in the...do I really need to say this? -- cgit v1.2.3 From d7d371a372254ac945dac7f5f6ac17ff1d96298f Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 18 Apr 2014 14:36:25 -0400 Subject: Move my path effects outside test effects (stable) (bzr r13090.1.61) --- src/live_effects/effect.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 99282a312..3787dd849 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -110,8 +110,6 @@ const Util::EnumData LPETypeData[] = { {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, {TEXT_LABEL, N_("Text label"), "text_label"}, - {JOIN_TYPE, N_("Join type"), "join_type"}, - {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, #endif /* 0.46 */ {BEND_PATH, N_("Bend"), "bend_path"}, @@ -137,6 +135,9 @@ const Util::EnumData LPETypeData[] = { {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"}, +/* lp:~inkscapebrony/inkscape/inkscape */ + {JOIN_TYPE, N_("Join type"), "join_type"}, + {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); -- cgit v1.2.3 From 7744bd7a4bdfedd8d0d04b647fd6c0e80a603cb7 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Fri, 18 Apr 2014 19:08:21 -0400 Subject: Add image rendering option for outlines. Setup desktop preferences observer. (bzr r13291.1.1) --- src/desktop.cpp | 12 +++++++++--- src/desktop.h | 27 ++++++++++++++++++++++++++- src/display/drawing-image.cpp | 7 +++++-- src/ui/dialog/inkscape-preferences.cpp | 5 +++++ src/ui/dialog/inkscape-preferences.h | 1 + 5 files changed, 46 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index b61f6867f..35ee22448 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -138,6 +138,8 @@ SPDesktop::SPDesktop() : _w2d(), _d2w(), _doc2dt( Geom::Scale(1, -1) ), + // This doesn't work I don't know why. + // _image_render_observer(*this, "/options/rendering/imageinoutlinemode"), grids_visible( false ) { _d2w.setIdentity(); @@ -499,11 +501,15 @@ SPDesktop::remove_temporary_canvasitem (Inkscape::Display::TemporaryItem * tempi } } +void SPDesktop::redrawDesktop() { + sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw +} + void SPDesktop::_setDisplayMode(Inkscape::RenderMode mode) { SP_CANVAS_ARENA (drawing)->drawing.setRenderMode(mode); canvas->rendermode = mode; _display_mode = mode; - sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw + redrawDesktop(); _widget->setTitle( sp_desktop_document(this)->getName() ); } void SPDesktop::_setDisplayColorMode(Inkscape::ColorMode mode) { @@ -524,7 +530,7 @@ void SPDesktop::_setDisplayColorMode(Inkscape::ColorMode mode) { SP_CANVAS_ARENA (drawing)->drawing.setColorMode(mode); canvas->colorrendermode = mode; _display_color_mode = mode; - sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw + redrawDesktop(); _widget->setTitle( sp_desktop_document(this)->getName() ); } @@ -819,7 +825,7 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double // zoom changed - set new zoom factors _d2w = Geom::Scale(newscale, -newscale); _w2d = Geom::Scale(1/newscale, 1/-newscale); - sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w); + redrawDesktop(); clear = TRUE; zoomChanged = true; } diff --git a/src/desktop.h b/src/desktop.h index 2f47dc2dd..ccc45904d 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -35,12 +35,14 @@ #include "display/rendermode.h" #include +#include "preferences.h" #include "sp-gradient.h" // TODO refactor enums out to their own .h file class SPCSSAttr; struct SPCanvas; struct SPCanvasItem; struct SPCanvasGroup; +struct DesktopPrefObserver; namespace Inkscape { namespace UI { @@ -206,7 +208,7 @@ public: /// Emitted when the zoom factor changes (not emitted when scrolling). /// The parameter is the new zoom factor sigc::signal signal_zoom_changed; - + sigc::connection connectDestroy(const sigc::slot &slot) { return _destroy_signal.connect(slot); @@ -256,6 +258,8 @@ public: Inkscape::Display::TemporaryItem * add_temporary_canvasitem (SPCanvasItem *item, guint lifetime, bool move_to_bottom = true); void remove_temporary_canvasitem (Inkscape::Display::TemporaryItem * tempitem); + void redrawDesktop(); + void _setDisplayMode(Inkscape::RenderMode mode); void setDisplayModeNormal() { _setDisplayMode(Inkscape::RENDERMODE_NORMAL); @@ -426,6 +430,27 @@ private: Geom::Affine _d2w; Geom::Affine _doc2dt; + /* + * Allow redrawing or refreshing if preferences change + */ + class DesktopPrefObserver : public Inkscape::Preferences::Observer { + public: + DesktopPrefObserver(SPDesktop *desktop, Glib::ustring const &path) + : Inkscape::Preferences::Observer(path) + , _desktop(desktop) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->addObserver(*this); + } + private: + void notify(Inkscape::Preferences::Entry const &val) { + _desktop->redrawDesktop(); + } + SPDesktop *_desktop; + }; + + // Disabled while stupid init call doesn't work + //DesktopPrefObserver _image_render_observer; + bool grids_visible; /* don't set this variable directly, use the method below */ void set_grids_visible(bool visible); diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 5844c8b08..bec59384c 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -106,7 +106,10 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar { bool outline = _drawing.outline(); - if (!outline) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool imgoutline = prefs->getBool("/options/rendering/imageinoutlinemode", true); + + if (!outline || imgoutline) { if (!_pixbuf) return RENDER_OK; Inkscape::DrawingContext::Save save(dc); @@ -141,7 +144,7 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar dc.paint(_opacity); } else { // outline; draw a rect instead - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff); { Inkscape::DrawingContext::Save save(dc); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index d826ece09..940f105d0 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1463,6 +1463,11 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_line( false, "", _importexport_import_res_override, "", _("Use default bitmap resolution in favor of information from file")); + _page_bitmaps.add_group_header( _("Render")); + // rendering outlines for pixmap image tags + _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", true); + _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); + this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index da85b805d..1c2151605 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -292,6 +292,7 @@ protected: UI::Widget::PrefCheckButton _show_filters_info_box; UI::Widget::PrefCombo _dockbar_style; UI::Widget::PrefCombo _switcher_style; + UI::Widget::PrefCheckButton _rendering_image_outline; UI::Widget::PrefSpinButton _rendering_cache_size; UI::Widget::PrefSpinButton _filter_multi_threaded; -- cgit v1.2.3 From 47abc2d2947692786bb402cedc107e40b9cd21e5 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 19 Apr 2014 00:52:30 -0400 Subject: Fix remaining issue with prefs updating (bzr r13291.1.2) --- src/desktop.cpp | 2 +- src/desktop.h | 3 +-- src/display/drawing-image.cpp | 2 +- src/ui/dialog/inkscape-preferences.cpp | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 35ee22448..3ed6d9ef3 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -139,7 +139,7 @@ SPDesktop::SPDesktop() : _d2w(), _doc2dt( Geom::Scale(1, -1) ), // This doesn't work I don't know why. - // _image_render_observer(*this, "/options/rendering/imageinoutlinemode"), + _image_render_observer(this, "/options/rendering/imageinoutlinemode"), grids_visible( false ) { _d2w.setIdentity(); diff --git a/src/desktop.h b/src/desktop.h index ccc45904d..fec6249e9 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -448,8 +448,7 @@ private: SPDesktop *_desktop; }; - // Disabled while stupid init call doesn't work - //DesktopPrefObserver _image_render_observer; + DesktopPrefObserver _image_render_observer; bool grids_visible; /* don't set this variable directly, use the method below */ void set_grids_visible(bool visible); diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index bec59384c..00caef525 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -107,7 +107,7 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar bool outline = _drawing.outline(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool imgoutline = prefs->getBool("/options/rendering/imageinoutlinemode", true); + bool imgoutline = prefs->getBool("/options/rendering/imageinoutlinemode", false); if (!outline || imgoutline) { if (!_pixbuf) return RENDER_OK; diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 940f105d0..559398a84 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1465,7 +1465,7 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_group_header( _("Render")); // rendering outlines for pixmap image tags - _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", true); + _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", false); _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); -- cgit v1.2.3 From 77b3c4eb00a8f297449deb5af29f566a12c03b2e Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 19 Apr 2014 20:36:33 -0400 Subject: Stop observer from crashing when it doesn't exist in preferences.xml (bzr r13293) --- src/desktop.cpp | 1 - src/preferences.cpp | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/desktop.cpp b/src/desktop.cpp index 3ed6d9ef3..f14a314b9 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -138,7 +138,6 @@ SPDesktop::SPDesktop() : _w2d(), _d2w(), _doc2dt( Geom::Scale(1, -1) ), - // This doesn't work I don't know why. _image_render_observer(this, "/options/rendering/imageinoutlinemode"), grids_visible( false ) { diff --git a/src/preferences.cpp b/src/preferences.cpp index 2fec3b307..d0c3783b5 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -581,6 +581,8 @@ XML::Node *Preferences::_findObserverNode(Glib::ustring const &pref_path, Glib:: // find the node corresponding to the "directory". Inkscape::XML::Node *node = _getNode(node_key, create), *child; + if (!node) return node; + for (child = node->firstChild(); child; child = child->next()) { // If there is a node with id corresponding to the attr key, // this means that the last part of the path is actually a key (folder). @@ -601,7 +603,7 @@ void Preferences::addObserver(Observer &o) if ( _observer_map.find(&o) == _observer_map.end() ) { Glib::ustring node_key, attr_key; Inkscape::XML::Node *node; - node = _findObserverNode(o.observed_path, node_key, attr_key, false); + node = _findObserverNode(o.observed_path, node_key, attr_key, true); if (node) { // set additional data if (o._data) { -- cgit v1.2.3 From 6cf3f3c4fa0309fbe2af3849cbb0c1f3e9d2b2e7 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 19 Apr 2014 21:14:39 -0400 Subject: remove easter eggs (bzr r13090.1.62) --- src/live_effects/lpe-jointype.cpp | 7 +- src/live_effects/lpe-powerstroke.cpp | 3 + src/live_effects/lpe-taperstroke.cpp | 108 ++++++++++++++++++++----------- src/live_effects/pathoutlineprovider.cpp | 58 ++++++++++++----- 4 files changed, 119 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index 3b2887bb5..f3ec02530 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -52,9 +52,9 @@ static const Util::EnumDataConverter JoinTypeConverter(JoinTypeData, s LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) : Effect(lpeobject), - line_width(_("Line width"), _("Thickness of the stroke"), "line_width", &wr, this, 10.), + line_width(_("Line width"), _("Thickness of the stroke"), "line_width", &wr, this, 1.), linecap_type(_("Line cap"), _("The end shape of the stroke"), "linecap_type", CapTypeConverter, &wr, this, butt_straight), - linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", JoinTypeConverter, &wr, this, join_pointy), + linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), miter_limit(_("Miter limit:"), _("Maximum length of the miter join (in units of stroke width)"), "miter_limit", &wr, this, 100.), attempt_force_join(_("Force miter"), _("Overrides the miter limit and forces a join."), "attempt_force_join", &wr, this, true) { @@ -164,7 +164,8 @@ void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem) std::vector LPEJoinType::doEffect_path(std::vector const & path_in) { return Outline::PathVectorOutline(path_in, line_width, static_cast(linecap_type.get_value()), - static_cast(linejoin_type.get_value()), miter_limit); + static_cast(linejoin_type.get_value()), + (attempt_force_join ? std::numeric_limits::max() : miter_limit)); } } //namespace LivePathEffect diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index d17def471..b63a2bf01 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -662,6 +662,9 @@ LPEPowerStroke::doEffect_path (std::vector const & path_in) if (Geom::Interpolate::CubicBezierJohan *johan = dynamic_cast(interpolator)) { johan->setBeta(interpolator_beta); } + if (Geom::Interpolate::CubicBezierSmooth *smooth = dynamic_cast(interpolator)) { + smooth->setBeta(interpolator_beta); + } Geom::Path strokepath = interpolator->interpolateToPath(ts); delete interpolator; diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 8316daf71..c29690d4f 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -34,6 +34,11 @@ #include "knot-holder-entity.h" #include "knotholder.h" +template +inline bool withinRange(T value, T low, T high) { + return (value > low && value < high); +} + namespace Inkscape { namespace LivePathEffect { @@ -65,12 +70,12 @@ static const Util::EnumDataConverter JoinTypeConverter(JoinType, sizeo LPETaperStroke::LPETaperStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), - line_width(_("Stroke width"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 3), + line_width(_("Stroke width"), _("The (non-tapered) width of the path"), "stroke_width", &wr, this, 1.), attach_start(_("Start offset"), _("Taper distance from path start"), "attach_start", &wr, this, 0.2), attach_end(_("End offset"), _("The ending position of the taper"), "end_offset", &wr, this, 0.2), smoothing(_("Taper smoothing"), _("Amount of smoothing to apply to the tapers"), "smoothing", &wr, this, 0.5), join_type(_("Join type"), _("Join type for non-smooth nodes"), "jointype", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), - miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 30.) + miter_limit(_("Miter limit"), _("Limit for miter joins"), "miter_limit", &wr, this, 100.) { show_orig_path = true; _provides_knotholder_entities = true; @@ -205,43 +210,47 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) unsigned size = path_in[0].size(); if (size == first_cusp.size()) { //check to see if the knots were dragged over each other - //if so, reset the end offset + //if so, reset the end offset, but still allow the start offset. if ( attach_start >= (size - attach_end) ) { attach_end.param_set_value( size - attach_start ); } } - if (attach_start == size - attach_end) { + if (attach_end == size - attach_start) { metInMiddle = true; } - //don't let it be zero - if (attach_start <= 0.00000001) { - attach_start.param_set_value( 0.00000001 ); - zeroStart = true; - } - if (attach_end <= 0.00000001) { - attach_end.param_set_value( 0.00000001 ); - zeroEnd = true; - } - //don't let it be integer - if (double(unsigned(attach_start)) == attach_start) { - attach_start.param_set_value(attach_start - 0.00001); - } - if (double(unsigned(attach_end)) == attach_end) { - attach_end.param_set_value(attach_end - 0.00001); + { + if (double(unsigned(attach_start)) == attach_start) { + attach_start.param_set_value(attach_start - 0.00001); + } + if (double(unsigned(attach_end)) == attach_end) { + attach_end.param_set_value(attach_end - 0.00001); + } } unsigned allowed_start = first_cusp.size(); unsigned allowed_end = last_cusp.size(); //don't let the knots be farther than they are allowed to be - if ((unsigned)attach_start >= allowed_start) { - attach_start.param_set_value((double)allowed_start - 0.00001); + { + if ((unsigned)attach_start >= allowed_start) { + attach_start.param_set_value((double)allowed_start - 0.00001); + } + if ((unsigned)attach_end >= allowed_end) { + attach_end.param_set_value((double)allowed_end - 0.00001); + } + } + + //don't let it be zero + if (attach_start < 0.0000001 || withinRange(double(attach_start), 0.00000001, 0.000001)) { + attach_start.param_set_value( 0.0000001 ); + zeroStart = true; } - if ((unsigned)attach_end >= allowed_end) { - attach_end.param_set_value((double)allowed_end - 0.00001); + if (attach_end < 0.0000001 || withinRange(double(attach_end), 0.00000001, 0.000001)) { + attach_end.param_set_value( 0.0000001 ); + zeroEnd = true; } //remember, Path::operator () means get point at time t @@ -252,7 +261,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //the following function just splits it up into three pieces. pathv_out = doEffect_simplePath(path_in); - //now for the actual tapering. We use a Pattern Along Path method to get this done. + //now for the actual tapering. We use the stretch_along method to get this done. Geom::PathVector real_pathv; Geom::Path real_path; @@ -261,13 +270,13 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) Geom::Path throwaway_path; if (!zeroStart) { - //Construct the pattern (pat_str stands for pattern string) (yes, this is easier, trust me) + //Construct the pattern (pat_str stands for pattern string) (and yes, this is easier, trust me) std::stringstream pat_str; pat_str << "M 1,0 C " << 1 - (double)smoothing << ",0 0,0.5 0,0.5 0,0.5 " << 1 - (double)smoothing << ",1 1,1"; pat_vec = sp_svg_read_pathv(pat_str.str().c_str()); pwd2.concat(stretch_along(pathv_out[0].toPwSb(), pat_vec[0], -fabs(line_width))); - throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; + throwaway_path = Geom::path_from_piecewise(pwd2, LPE_CONVERSION_TOLERANCE)[0]; real_path.append(throwaway_path); } @@ -276,29 +285,52 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //append the outside outline of the path (with direction) throwaway_path = Outline::PathOutsideOutline(pathv_out[1], -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + if (!zeroStart) { + if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001) { + real_path.appendNew(throwaway_path.initialPoint()); + } else { + real_path.setFinal(throwaway_path.initialPoint()); + } + } + real_path.append(throwaway_path); } if (!zeroEnd) { //append the ending taper std::stringstream pat_str_1; - pat_str_1 << "M 0,0 0,1 C " << (double)smoothing << ",1 1,0.5 1,0.5 1,0.5 " << double(smoothing) << ",0 0,0"; + pat_str_1 << "M 0,1 C " << (double)smoothing << ",1 1,0.5 1,0.5 1,0.5 " << double(smoothing) << ",0 0,0"; pat_vec = sp_svg_read_pathv(pat_str_1.str().c_str()); pwd2 = Geom::Piecewise > (); pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], -fabs(line_width))); - throwaway_path = Geom::path_from_piecewise(pwd2, 0.001)[0]; - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); + throwaway_path = Geom::path_from_piecewise(pwd2, LPE_CONVERSION_TOLERANCE)[0]; + if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001) { + real_path.appendNew(throwaway_path.initialPoint()); + } else { + real_path.setFinal(throwaway_path.initialPoint()); + } + real_path.append(throwaway_path); + } + + if (!metInMiddle) { + //append the inside outline of the path (against direction) + throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), + -fabs(line_width), static_cast(join_type.get_value()), miter_limit); + + if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001) { + real_path.appendNew(throwaway_path.initialPoint()); + } else { + real_path.setFinal(throwaway_path.initialPoint()); + } + real_path.append(throwaway_path); + } + + if (Geom::distance(real_path.finalPoint(), real_path.initialPoint()) > 0.0000001) { + real_path.appendNew(real_path.initialPoint()); + } else { + real_path.setFinal(real_path.initialPoint()); } - //append the inside outline of the path (against direction) - throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), - -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - - real_path.append(throwaway_path, Geom::Path::STITCH_DISCONTINUOUS); - real_path.appendNew(real_path.initialPoint()); - real_path.close(); real_pathv.push_back(real_path); diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index b5a3258fa..9ff896f84 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -162,8 +162,7 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) //assert(cbc1.finalPoint() == cbc2.initialPoint()); //short circuiting? if (cbc1.finalPoint() != cbc2.initialPoint()) { - printf("There was an issue when asserting that one curve's end is the start of the other. Line %d, File %s\n" - "By default we are going to say that this is an inside join, so we cannot make a line join for it.\n", __LINE__, __FILE__); + printf("erk! Line %d, File %s\n", __LINE__, __FILE__); return false; } @@ -261,7 +260,10 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } path_builder.appendNew (endPt); } - path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); + if (cbc1->finalPoint() != cbc2->initialPoint()) { + path_builder.appendNew(cbc2->initialPoint()); + } + path_builder.append(*cbc2); } if ( outside && lineProblem ) { Geom::Path pth; @@ -283,7 +285,10 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve } } path_builder.appendNew (endPt); - path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); + if (cbc1->finalPoint() != cbc2->initialPoint()) { + path_builder.appendNew(cbc2->initialPoint()); + } + path_builder.append(*cbc2); } if ( !outside ) { /*path_builder.appendNew (endPt);*/ @@ -297,7 +302,12 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve cubic = cubic.subdivide(cross[0].tb).second; path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); } else { - path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); + if (Geom::distance(path_builder.finalPoint(), cbc2->initialPoint()) > 0.0000001) { + path_builder.appendNew(cbc2->initialPoint()); + } else { + path_builder.setFinal(cbc2->initialPoint()); + } + path_builder.append(*cbc2); } } } @@ -360,6 +370,9 @@ void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cb path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); } + if (cbc1->finalPoint() != cbc2->initialPoint()) { + path_builder.appendNew(cbc2->initialPoint()); + } path_builder.append(*cbc2); } else { //probably on the inside of the corner @@ -374,7 +387,12 @@ void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cb cubic = cubic.subdivide(cross[0].tb).second; path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); } else { - path_builder.append(*cbc2, Geom::Path::STITCH_DISCONTINUOUS); + if (Geom::distance(path_builder.finalPoint(), cbc2->initialPoint()) > 0.0000001) { + path_builder.appendNew(cbc2->initialPoint()); + } else { + path_builder.setFinal(cbc2->initialPoint()); + } + path_builder.append(*cbc2); } } } @@ -431,6 +449,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double } //store it Geom::Path temp_path = (*path_vec)[0]; + //erase the first segment since the join code already appended it temp_path.erase(temp_path.begin()); path_builder.append( temp_path ); @@ -477,7 +496,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double Geom::Curve * cbc1; Geom::Curve * cbc2; - if ( path_in[path_in.size() - 1].length() != Geom::distance(path_in[path_in.size() - 1].finalPoint(), path_in.initialPoint())) { + if ( path_in[path_in.size()].isDegenerate() ) { //handle case for last segment curved outlined_result = Path(); to_outline = Path(); @@ -512,10 +531,10 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double if (extrapolate) { extrapolate_curves(path_builder, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( path_in[path_in.size() - 1], path_in [0] )); + outside_angle ( path_in[path_in.size() - 1], oneCurve [0] )); } else { reflect_curves (path_builder, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( path_in[path_in.size() - 1], path_in [0] )); + outside_angle ( path_in[path_in.size() - 1], oneCurve [0] )); } delete cbc1; cbc1 = cbc2->duplicate(); @@ -534,22 +553,29 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double Geom::Path temporary; //just an accessory path, we won't need it for long temporary.append(*cbc1); + const Geom::Curve& prev_curve = path_in[path_in.size()].isDegenerate() ? path_in[path_in.size() - 1] : + path_in[path_in.size()]; + if (extrapolate) { extrapolate_curves(temporary, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( path_in[path_in.size() - 1], path_in [0] )); + outside_angle ( prev_curve, path_in [0] )); } else { reflect_curves (temporary, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( path_in[path_in.size() - 1], path_in [0] )); + outside_angle ( prev_curve, path_in [0] )); } //extract the appended curves - if (temporary[0].finalPoint() != path_builder[path_builder.size() - 1].finalPoint()) { + //if (temporary[temporary.size()].initialPoint() != path_builder[0].initialPoint()) { path_builder.erase(path_builder.begin()); - } else { + /*} else { temporary.erase_last(); - } + }*/ path_builder.erase_last(); - - path_builder.append(temporary, Geom::Path::STITCH_DISCONTINUOUS); + if (Geom::distance(path_builder.finalPoint(), temporary.initialPoint()) > 0.0000001) { + path_builder.appendNew(temporary.initialPoint()); + } else { + path_builder.setFinal(temporary.initialPoint()); + } + path_builder.append(temporary); path_builder.close(); if (cbc1) delete cbc1; -- cgit v1.2.3 From 44dbc123e17a639c9a8dc7c2a2bd3d36a444823c Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 19 Apr 2014 23:12:30 -0400 Subject: Bug fixes (bzr r13090.1.63) --- src/live_effects/effect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 3787dd849..4b48ce68c 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -378,8 +378,8 @@ void Effect::doOnRemove (SPLPEItem const* lpeitem) void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); - sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); - pathvector_before_effect = sp_curve->get_pathvector(); + /*sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); + pathvector_before_effect = sp_curve->get_pathvector();*/ doOnApply(lpeitem); } -- cgit v1.2.3 From 2f628e571a3817765392479766418add4bbdaa20 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 20 Apr 2014 11:03:23 -0400 Subject: minor bugfix (bzr r13090.1.64) --- src/live_effects/lpe-taperstroke.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index c29690d4f..7aa896ade 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -216,7 +216,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) } } - if (attach_end == size - attach_start) { + if (attach_start == size - attach_end) { metInMiddle = true; } -- cgit v1.2.3 From 3c99062c5bc3c28b9c2b05de0ee3e9c2725a55b6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 20 Apr 2014 13:05:53 -0400 Subject: correcting previous revision (bzr r13090.1.65) --- src/live_effects/lpe-taperstroke.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 7aa896ade..8ddaa4087 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -213,12 +213,16 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //if so, reset the end offset, but still allow the start offset. if ( attach_start >= (size - attach_end) ) { attach_end.param_set_value( size - attach_start ); + metInMiddle = true; } } if (attach_start == size - attach_end) { metInMiddle = true; } + if (attach_end == size - attach_start) { + metInMiddle = true; + } //don't let it be integer { @@ -285,7 +289,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) //append the outside outline of the path (with direction) throwaway_path = Outline::PathOutsideOutline(pathv_out[1], -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - if (!zeroStart) { + if (!zeroStart && real_path.size() >= 1 && throwaway_path.size() >= 1) { if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001) { real_path.appendNew(throwaway_path.initialPoint()); } else { @@ -305,7 +309,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) pwd2.concat(stretch_along(pathv_out[2].toPwSb(), pat_vec[0], -fabs(line_width))); throwaway_path = Geom::path_from_piecewise(pwd2, LPE_CONVERSION_TOLERANCE)[0]; - if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001) { + if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001 && real_path.size() >= 1) { real_path.appendNew(throwaway_path.initialPoint()); } else { real_path.setFinal(throwaway_path.initialPoint()); @@ -318,7 +322,7 @@ Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) throwaway_path = Outline::PathOutsideOutline(pathv_out[1].reverse(), -fabs(line_width), static_cast(join_type.get_value()), miter_limit); - if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001) { + if (Geom::distance(real_path.finalPoint(), throwaway_path.initialPoint()) > 0.0000001 && real_path.size() >= 1) { real_path.appendNew(throwaway_path.initialPoint()); } else { real_path.setFinal(throwaway_path.initialPoint()); -- cgit v1.2.3 From cd13c979453864482930c496f7c4c4d2da891a7a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 22 Apr 2014 16:37:22 +0200 Subject: Restore ability to insert a font-family that is not on system or a font-fallback list. (bzr r13296) --- src/libnrtype/font-lister.cpp | 28 ++++++++++++++++++++++++++++ src/libnrtype/font-lister.h | 6 ++++++ src/widgets/text-toolbar.cpp | 7 +++++++ 3 files changed, 41 insertions(+) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 89d0cb037..dde0ee4a9 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -97,6 +97,34 @@ namespace Inkscape // } // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); + + /* Used to insert a font that was not in the document and not on the system into the font list. */ + void + FontLister::insert_font_family( Glib::ustring new_family ) { + + GList *styles = default_styles; + + /* In case this is a fallback list, check if first font-family on system. */ + std::vector tokens = Glib::Regex::split_simple(",", new_family ); + if( !tokens.empty() && !tokens[0].empty() ) { + + Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); + while( iter2 != font_list_store->children().end() ) { + Gtk::TreeModel::Row row = *iter2; + if( row[FontList.onSystem] && tokens[0].compare( row[FontList.family] ) == 0 ) { + styles = row[FontList.styles]; + break; + } + ++iter2; + } + } + + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup(new_family.c_str())); + (*treeModelIter)[FontList.styles] = styles; + (*treeModelIter)[FontList.onSystem] = false; + } + void FontLister::update_font_list( SPDocument* document ) { diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index 5a8f578d9..c42bf98fd 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -127,6 +127,12 @@ namespace Inkscape const Glib::RefPtr get_style_list () const; + /** Inserts a font family or font-fallback list (for use when not + * already in document or on system). + */ + void + insert_font_family ( Glib::ustring new_family ); + /** Updates font list to include fonts in document * */ diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 349fefa12..7b59fa633 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -146,6 +146,13 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb std::cout << " New active: " << act->active << std::endl; #endif if( new_family.compare( fontlister->get_font_family() ) != 0 ) { + // Changed font-family + + if( act->active == -1 ) { + // New font-family, not in document, not on system (could be fallback list) + fontlister->insert_font_family( new_family ); + act->active = 0; // New family is always at top of list. + } std::pair ui = fontlister->set_font_family( act->active ); // active text set in sp_text_toolbox_selection_changed() -- cgit v1.2.3 From 94553ec1515b41791125ca2382419e989d54f77f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 22 Apr 2014 16:39:13 +0200 Subject: Parse xml:lang, required for SVG (CSS uses lang) (bzr r13297) --- src/libcroco/cr-sel-eng.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libcroco/cr-sel-eng.c b/src/libcroco/cr-sel-eng.c index 0eba2b403..4f501ee05 100644 --- a/src/libcroco/cr-sel-eng.c +++ b/src/libcroco/cr-sel-eng.c @@ -136,8 +136,9 @@ lang_pseudo_class_handler (CRSelEng *const a_this, node_iface = PRIVATE(a_this)->node_iface; - if (strqcmp (a_sel->content.pseudo->name->stryng->str, - "lang", 4) + /* "xml:lang" needed for SVG */ + if ( (strqcmp (a_sel->content.pseudo->name->stryng->str, "lang", 4 ) && + (strqcmp (a_sel->content.pseudo->name->stryng->str, "xml:lang", 8 ) ) ) || !a_sel->content.pseudo->type == FUNCTION_PSEUDO) { cr_utils_trace_info ("This handler is for :lang only"); return FALSE; @@ -149,6 +150,7 @@ lang_pseudo_class_handler (CRSelEng *const a_this, return FALSE; for (; node; node = get_next_parent_element_node (node_iface, node)) { char *val = node_iface->getProp (node, "lang"); + if (!val) val = node_iface->getProp (node, "xml:lang"); if (val) { if (!strcasecmp(val, a_sel->content.pseudo->extra->stryng->str)) { result = TRUE; -- cgit v1.2.3 From 0f91c5cd6a3a8a07185e107da881ff4da71f7081 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 22 Apr 2014 19:03:36 +0200 Subject: align two buttons in LPE widget (bzr r11950.1.334) --- src/live_effects/lpe-bspline.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 8254a13b6..00ebcd9ba 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -318,20 +318,18 @@ Gtk::Widget *LPEBSpline::newWidget() { ++it; } + Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); Gtk::Button *defaultWeight = Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight 0.3334")))); - defaultWeight->set_alignment(0.0, 0.5); defaultWeight->signal_clicked() .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); - Gtk::Widget *defaultWeightWidget = dynamic_cast(defaultWeight); - vbox->pack_start(*defaultWeightWidget, true, true, 2); + buttons->pack_start(*defaultWeight, true, true, 2); Gtk::Button *makeCusp = Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); - makeCusp->set_alignment(0.0, 0.5); makeCusp->signal_clicked() .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); - Gtk::Widget *makeCuspWidget = dynamic_cast(makeCusp); - vbox->pack_start(*makeCuspWidget, true, true, 2); + buttons->pack_start(*makeCusp, true, true, 2); + vbox->pack_start(*buttons, true, true, 2); return dynamic_cast(vbox); } -- cgit v1.2.3 From bb9297f7e0a297c85b5d40eab49677293effc88f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 22 Apr 2014 21:44:02 +0200 Subject: Redesign of the BSpline LPE widgets (bzr r11950.1.335) --- src/live_effects/lpe-bspline.cpp | 57 ++++++++++++++++++++++++++++------------ src/live_effects/lpe-bspline.h | 4 +-- 2 files changed, 42 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 00ebcd9ba..edf19d1e5 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -2,7 +2,8 @@ /* * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include +#include #include #include #include @@ -59,10 +60,10 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) false), weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, 0.3334) { - registerParameter(dynamic_cast(&ignoreCusp)); - registerParameter(dynamic_cast(&onlySelected)); registerParameter(dynamic_cast(&weight)); registerParameter(dynamic_cast(&steps)); + registerParameter(dynamic_cast(&ignoreCusp)); + registerParameter(dynamic_cast(&onlySelected)); weight.param_set_range(0.0000, 1); weight.param_set_increments(0.1, 0.1); weight.param_set_digits(4); @@ -287,12 +288,32 @@ Gtk::Widget *LPEBSpline::newWidget() { if ((*it)->widget_is_visible) { Parameter *param = *it; Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "weight"){ + Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::Button *defaultWeight = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); + defaultWeight->signal_clicked() + .connect(sigc::bind(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight), widg)); + buttons->pack_start(*defaultWeight, true, true, 2); + Gtk::Button *makeCusp = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); + makeCusp->signal_clicked() + .connect(sigc::bind(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp), widg)); + buttons->pack_start(*makeCusp, true, true, 2); + vbox->pack_start(*buttons, true, true, 2); + } if (param->param_key == "weight" || param->param_key == "steps") { Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast(widg)); widgRegistered->signal_value_changed() .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); widg = dynamic_cast(widgRegistered); + if (widg){ + Gtk::HBox * scalarParameter = dynamic_cast(widg); + std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); + Gtk::Entry* entryWidg = dynamic_cast(childList[1]); + entryWidg->set_width_chars(6); + } } if (param->param_key == "onlySelected") { Gtk::CheckButton *widgRegistered = @@ -318,24 +339,26 @@ Gtk::Widget *LPEBSpline::newWidget() { ++it; } - Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); - Gtk::Button *defaultWeight = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight 0.3334")))); - defaultWeight->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); - buttons->pack_start(*defaultWeight, true, true, 2); - Gtk::Button *makeCusp = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); - makeCusp->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); - buttons->pack_start(*makeCusp, true, true, 2); - vbox->pack_start(*buttons, true, true, 2); return dynamic_cast(vbox); } -void LPEBSpline::toDefaultWeight() { changeWeight(0.3334); } +void LPEBSpline::toDefaultWeight(Gtk::Widget *widgWeight) { + weight.param_set_value(0.3334); + changeWeight(0.3334); + Gtk::HBox * scalarParameter = dynamic_cast(widgWeight); + std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); + Gtk::Entry* entryWidg = dynamic_cast(childList[1]); + entryWidg->set_text("0.3334"); +} -void LPEBSpline::toMakeCusp() { changeWeight(0.0000); } +void LPEBSpline::toMakeCusp(Gtk::Widget *widgWeight) { + weight.param_set_value(0.0000); + changeWeight(0.0000); + Gtk::HBox * scalarParameter = dynamic_cast(widgWeight); + std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); + Gtk::Entry* entryWidg = dynamic_cast(childList[1]); + entryWidg->set_text("0.0000"); +} void LPEBSpline::toWeight() { changeWeight(weight); } diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index 167810c49..aff4ce812 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -34,9 +34,9 @@ public: virtual void changeWeight(double weightValue); - virtual void toDefaultWeight(); + virtual void toDefaultWeight(Gtk::Widget *widgWeight); - virtual void toMakeCusp(); + virtual void toMakeCusp(Gtk::Widget *widgWeight); virtual void toWeight(); -- cgit v1.2.3 From 9abc39c892a58a6cff52000ae3671e50bae8a1a9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 23 Apr 2014 20:46:06 +0200 Subject: Clean up of style code, converting structures to C++ classes. Step 1. (bzr r13298) --- src/CMakeLists.txt | 1 + src/Makefile_insert | 3 +- src/color.h | 1 + src/display/nr-style.cpp | 3 +- src/id-clash.cpp | 2 +- src/style-enums.h | 265 ++- src/style-internal.h | 826 ++++++- src/style-test.h | 330 ++- src/style.cpp | 5373 +++++++++------------------------------------- src/style.h | 162 +- 10 files changed, 2411 insertions(+), 4555 deletions(-) (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8408d6270..fae4c484c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -259,6 +259,7 @@ set(inkscape_SRC snapped-point.cpp snapper.cpp style.cpp + style-internal.cpp svg-view-widget.cpp svg-view.cpp text-chemistry.cpp diff --git a/src/Makefile_insert b/src/Makefile_insert index 8872b045d..6d0d6b08c 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -210,7 +210,8 @@ ink_common_sources += \ streq.h \ strneq.h \ style.cpp style.h \ - style-enums.h style-internal.h \ + style-enums.h \ + style-internal.cpp style-internal.h \ svg-profile.h \ svg-view.cpp svg-view.h \ svg-view-widget.cpp svg-view-widget.h \ diff --git a/src/color.h b/src/color.h index 746ecebbf..604dff0e3 100644 --- a/src/color.h +++ b/src/color.h @@ -46,6 +46,7 @@ struct SPColor { SPColor& operator= (SPColor const& other); bool operator == ( SPColor const& other ) const; + bool operator != ( SPColor const& other ) const { return !(*this == other); }; bool isClose( SPColor const& other, float epsilon ) const; void set( float r, float g, float b ); diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 125d0c6d6..3d2d36483 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -201,8 +201,7 @@ void NRStyle::set(SPStyle *style) if( style->text_decoration_color.set || style->text_decoration_color.inherit || - style->text_decoration_color.currentcolor || - style->text_decoration_color.colorSet){ + style->text_decoration_color.currentcolor ){ text_decoration_color.set(style->text_decoration_color.value.color); text_decoration_useColor = true; } diff --git a/src/id-clash.cpp b/src/id-clash.cpp index f59b3b920..7a0bb9c4a 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -53,7 +53,7 @@ const char *href_like_attributes[] = { #define NUM_HREF_LIKE_ATTRIBUTES (sizeof(href_like_attributes) / sizeof(*href_like_attributes)) const SPIPaint SPStyle::* SPIPaint_members[] = { - &SPStyle::color, + //&SPStyle::color, &SPStyle::fill, &SPStyle::stroke, }; diff --git a/src/style-enums.h b/src/style-enums.h index c6f9a1ea1..356029a40 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -15,7 +15,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -/* SPTextStyle */ +/* SPFontStyle */ + +#include "display/canvas-bpath.h" enum SPCSSFontSize { SP_CSS_FONT_SIZE_XX_SMALL, @@ -215,6 +217,267 @@ enum SPTextRendering { SP_CSS_TEXT_RENDERING_GEOMETRICPRECISION }; + +struct SPStyleEnum { + gchar const *key; + gint value; +}; + +static SPStyleEnum const enum_fill_rule[] = { + {"nonzero", SP_WIND_RULE_NONZERO}, + {"evenodd", SP_WIND_RULE_EVENODD}, + {NULL, -1} +}; + +static SPStyleEnum const enum_stroke_linecap[] = { + {"butt", SP_STROKE_LINECAP_BUTT}, + {"round", SP_STROKE_LINECAP_ROUND}, + {"square", SP_STROKE_LINECAP_SQUARE}, + {NULL, -1} +}; + +static SPStyleEnum const enum_stroke_linejoin[] = { + {"miter", SP_STROKE_LINEJOIN_MITER}, + {"round", SP_STROKE_LINEJOIN_ROUND}, + {"bevel", SP_STROKE_LINEJOIN_BEVEL}, + {NULL, -1} +}; + +static SPStyleEnum const enum_font_style[] = { + {"normal", SP_CSS_FONT_STYLE_NORMAL}, + {"italic", SP_CSS_FONT_STYLE_ITALIC}, + {"oblique", SP_CSS_FONT_STYLE_OBLIQUE}, + {NULL, -1} +}; + +static SPStyleEnum const enum_font_size[] = { + {"xx-small", SP_CSS_FONT_SIZE_XX_SMALL}, + {"x-small", SP_CSS_FONT_SIZE_X_SMALL}, + {"small", SP_CSS_FONT_SIZE_SMALL}, + {"medium", SP_CSS_FONT_SIZE_MEDIUM}, + {"large", SP_CSS_FONT_SIZE_LARGE}, + {"x-large", SP_CSS_FONT_SIZE_X_LARGE}, + {"xx-large", SP_CSS_FONT_SIZE_XX_LARGE}, + {"smaller", SP_CSS_FONT_SIZE_SMALLER}, + {"larger", SP_CSS_FONT_SIZE_LARGER}, + {NULL, -1} +}; + +static SPStyleEnum const enum_font_variant[] = { + {"normal", SP_CSS_FONT_VARIANT_NORMAL}, + {"small-caps", SP_CSS_FONT_VARIANT_SMALL_CAPS}, + {NULL, -1} +}; + +static SPStyleEnum const enum_font_weight[] = { + {"100", SP_CSS_FONT_WEIGHT_100}, + {"200", SP_CSS_FONT_WEIGHT_200}, + {"300", SP_CSS_FONT_WEIGHT_300}, + {"400", SP_CSS_FONT_WEIGHT_400}, + {"500", SP_CSS_FONT_WEIGHT_500}, + {"600", SP_CSS_FONT_WEIGHT_600}, + {"700", SP_CSS_FONT_WEIGHT_700}, + {"800", SP_CSS_FONT_WEIGHT_800}, + {"900", SP_CSS_FONT_WEIGHT_900}, + {"normal", SP_CSS_FONT_WEIGHT_NORMAL}, + {"bold", SP_CSS_FONT_WEIGHT_BOLD}, + {"lighter", SP_CSS_FONT_WEIGHT_LIGHTER}, + {"bolder", SP_CSS_FONT_WEIGHT_BOLDER}, + {NULL, -1} +}; + +static SPStyleEnum const enum_font_stretch[] = { + {"ultra-condensed", SP_CSS_FONT_STRETCH_ULTRA_CONDENSED}, + {"extra-condensed", SP_CSS_FONT_STRETCH_EXTRA_CONDENSED}, + {"condensed", SP_CSS_FONT_STRETCH_CONDENSED}, + {"semi-condensed", SP_CSS_FONT_STRETCH_SEMI_CONDENSED}, + {"normal", SP_CSS_FONT_STRETCH_NORMAL}, + {"semi-expanded", SP_CSS_FONT_STRETCH_SEMI_EXPANDED}, + {"expanded", SP_CSS_FONT_STRETCH_EXPANDED}, + {"extra-expanded", SP_CSS_FONT_STRETCH_EXTRA_EXPANDED}, + {"ultra-expanded", SP_CSS_FONT_STRETCH_ULTRA_EXPANDED}, + {"narrower", SP_CSS_FONT_STRETCH_NARROWER}, + {"wider", SP_CSS_FONT_STRETCH_WIDER}, + {NULL, -1} +}; + +static SPStyleEnum const enum_text_align[] = { + {"start", SP_CSS_TEXT_ALIGN_START}, + {"end", SP_CSS_TEXT_ALIGN_END}, + {"left", SP_CSS_TEXT_ALIGN_LEFT}, + {"right", SP_CSS_TEXT_ALIGN_RIGHT}, + {"center", SP_CSS_TEXT_ALIGN_CENTER}, + {"justify", SP_CSS_TEXT_ALIGN_JUSTIFY}, + {NULL, -1} +}; + +static SPStyleEnum const enum_text_transform[] = { + {"capitalize", SP_CSS_TEXT_TRANSFORM_CAPITALIZE}, + {"uppercase", SP_CSS_TEXT_TRANSFORM_UPPERCASE}, + {"lowercase", SP_CSS_TEXT_TRANSFORM_LOWERCASE}, + {"none", SP_CSS_TEXT_TRANSFORM_NONE}, + {NULL, -1} +}; + +static SPStyleEnum const enum_text_anchor[] = { + {"start", SP_CSS_TEXT_ANCHOR_START}, + {"middle", SP_CSS_TEXT_ANCHOR_MIDDLE}, + {"end", SP_CSS_TEXT_ANCHOR_END}, + {NULL, -1} +}; + +static SPStyleEnum const enum_direction[] = { + {"ltr", SP_CSS_DIRECTION_LTR}, + {"rtl", SP_CSS_DIRECTION_RTL}, + {NULL, -1} +}; + +static SPStyleEnum const enum_block_progression[] = { + {"tb", SP_CSS_BLOCK_PROGRESSION_TB}, + {"rl", SP_CSS_BLOCK_PROGRESSION_RL}, + {"lr", SP_CSS_BLOCK_PROGRESSION_LR}, + {NULL, -1} +}; + +static SPStyleEnum const enum_writing_mode[] = { + /* Note that using the same enumerator for lr as lr-tb means we write as lr-tb even if the + * input file said lr. We prefer writing lr-tb on the grounds that the spec says the initial + * value is lr-tb rather than lr. + * + * ECMA scripts may be surprised to find tb-rl in DOM if they set the attribute to rl, so + * sharing enumerators for different strings may be a bug (once we support ecma script). + */ + {"lr-tb", SP_CSS_WRITING_MODE_LR_TB}, + {"rl-tb", SP_CSS_WRITING_MODE_RL_TB}, + {"tb-rl", SP_CSS_WRITING_MODE_TB_RL}, + {"lr", SP_CSS_WRITING_MODE_LR_TB}, + {"rl", SP_CSS_WRITING_MODE_RL_TB}, + {"tb", SP_CSS_WRITING_MODE_TB_RL}, + {NULL, -1} +}; + +static SPStyleEnum const enum_baseline_shift[] = { + {"baseline", SP_CSS_BASELINE_SHIFT_BASELINE}, + {"sub", SP_CSS_BASELINE_SHIFT_SUB}, + {"super", SP_CSS_BASELINE_SHIFT_SUPER}, + {NULL, -1} +}; + +static SPStyleEnum const enum_visibility[] = { + {"hidden", SP_CSS_VISIBILITY_HIDDEN}, + {"collapse", SP_CSS_VISIBILITY_COLLAPSE}, + {"visible", SP_CSS_VISIBILITY_VISIBLE}, + {NULL, -1} +}; + +static SPStyleEnum const enum_overflow[] = { + {"visible", SP_CSS_OVERFLOW_VISIBLE}, + {"hidden", SP_CSS_OVERFLOW_HIDDEN}, + {"scroll", SP_CSS_OVERFLOW_SCROLL}, + {"auto", SP_CSS_OVERFLOW_AUTO}, + {NULL, -1} +}; + +// CSS Compositing and Blending Level 1 +static SPStyleEnum const enum_isolation[] = { + {"auto", SP_CSS_ISOLATION_AUTO}, + {"isolate", SP_CSS_ISOLATION_ISOLATE}, + {NULL, -1} +}; + +static SPStyleEnum const enum_blend_mode[] = { + {"normal", SP_CSS_BLEND_NORMAL}, + {"multiply", SP_CSS_BLEND_MULTIPLY}, + {"screen", SP_CSS_BLEND_SCREEN}, + {"darken", SP_CSS_BLEND_DARKEN}, + {"lighten", SP_CSS_BLEND_LIGHTEN}, + {"overlay", SP_CSS_BLEND_OVERLAY}, + {"color-dodge", SP_CSS_BLEND_COLORDODGE}, + {"color-burn", SP_CSS_BLEND_COLORBURN}, + {"hard-light", SP_CSS_BLEND_HARDLIGHT}, + {"soft-light", SP_CSS_BLEND_SOFTLIGHT}, + {"difference", SP_CSS_BLEND_DIFFERENCE}, + {"exclusion", SP_CSS_BLEND_EXCLUSION}, + {"hue", SP_CSS_BLEND_HUE}, + {"saturation", SP_CSS_BLEND_SATURATION}, + {"color", SP_CSS_BLEND_COLOR}, + {"luminosity", SP_CSS_BLEND_LUMINOSITY}, + {NULL, -1} +}; + +static SPStyleEnum const enum_display[] = { + {"none", SP_CSS_DISPLAY_NONE}, + {"inline", SP_CSS_DISPLAY_INLINE}, + {"block", SP_CSS_DISPLAY_BLOCK}, + {"list-item", SP_CSS_DISPLAY_LIST_ITEM}, + {"run-in", SP_CSS_DISPLAY_RUN_IN}, + {"compact", SP_CSS_DISPLAY_COMPACT}, + {"marker", SP_CSS_DISPLAY_MARKER}, + {"table", SP_CSS_DISPLAY_TABLE}, + {"inline-table", SP_CSS_DISPLAY_INLINE_TABLE}, + {"table-row-group", SP_CSS_DISPLAY_TABLE_ROW_GROUP}, + {"table-header-group", SP_CSS_DISPLAY_TABLE_HEADER_GROUP}, + {"table-footer-group", SP_CSS_DISPLAY_TABLE_FOOTER_GROUP}, + {"table-row", SP_CSS_DISPLAY_TABLE_ROW}, + {"table-column-group", SP_CSS_DISPLAY_TABLE_COLUMN_GROUP}, + {"table-column", SP_CSS_DISPLAY_TABLE_COLUMN}, + {"table-cell", SP_CSS_DISPLAY_TABLE_CELL}, + {"table-caption", SP_CSS_DISPLAY_TABLE_CAPTION}, + {NULL, -1} +}; + +static SPStyleEnum const enum_shape_rendering[] = { + {"auto", SP_CSS_SHAPE_RENDERING_AUTO}, + {"optimizeSpeed", SP_CSS_SHAPE_RENDERING_OPTIMIZESPEED}, + {"crispEdges", SP_CSS_SHAPE_RENDERING_CRISPEDGES}, + {"geometricPrecision", SP_CSS_SHAPE_RENDERING_GEOMETRICPRECISION}, + {NULL, -1} +}; + +static SPStyleEnum const enum_color_rendering[] = { + {"auto", SP_CSS_COLOR_RENDERING_AUTO}, + {"optimizeSpeed", SP_CSS_COLOR_RENDERING_OPTIMIZESPEED}, + {"optimizeQuality", SP_CSS_COLOR_RENDERING_OPTIMIZEQUALITY}, + {NULL, -1} +}; + +static SPStyleEnum const enum_image_rendering[] = { + {"auto", SP_CSS_IMAGE_RENDERING_AUTO}, + {"optimizeSpeed", SP_CSS_IMAGE_RENDERING_OPTIMIZESPEED}, + {"optimizeQuality", SP_CSS_IMAGE_RENDERING_OPTIMIZEQUALITY}, + {"-inkscape-crisp-edges", SP_CSS_IMAGE_RENDERING_CRISPEDGES}, + {"-inkscape-pixelated", SP_CSS_IMAGE_RENDERING_PIXELATED}, + {NULL, -1} +}; + +static SPStyleEnum const enum_text_rendering[] = { + {"auto", SP_CSS_TEXT_RENDERING_AUTO}, + {"optimizeSpeed", SP_CSS_TEXT_RENDERING_OPTIMIZESPEED}, + {"optimizeLegibility", SP_CSS_TEXT_RENDERING_OPTIMIZELEGIBILITY}, + {"geometricPrecision", SP_CSS_TEXT_RENDERING_GEOMETRICPRECISION}, + {NULL, -1} +}; + +static SPStyleEnum const enum_enable_background[] = { + {"accumulate", SP_CSS_BACKGROUND_ACCUMULATE}, + {"new", SP_CSS_BACKGROUND_NEW}, + {NULL, -1} +}; + +static SPStyleEnum const enum_clip_rule[] = { + {"nonzero", SP_WIND_RULE_NONZERO}, + {"evenodd", SP_WIND_RULE_EVENODD}, + {NULL, -1} +}; + +static SPStyleEnum const enum_color_interpolation[] = { + {"auto", SP_CSS_COLOR_INTERPOLATION_AUTO}, + {"sRGB", SP_CSS_COLOR_INTERPOLATION_SRGB}, + {"linearRGB", SP_CSS_COLOR_INTERPOLATION_LINEARRGB}, + {NULL, -1} +}; + + #endif // SEEN_SP_STYLE_ENUMS_H diff --git a/src/style-internal.h b/src/style-internal.h index 7d45f96f8..e5ef72c76 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -7,7 +7,9 @@ /* Authors: * Lauris Kaplinski * Jon A. Cruz + * Tavmjong Bah * + * Copyright (C) 2014 Tavmjong Bah * Copyright (C) 2010 Jon A. Cruz * Copyright (C) 2001-2002 Lauris Kaplinski * Copyright (C) 2001 Ximian, Inc. @@ -15,21 +17,168 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "style-enums.h" + #include "color.h" +#include "svg/svg-icc-color.h" #include "sp-marker-loc.h" #include "sp-filter.h" #include "sp-filter-reference.h" #include "sp-paint-server-reference.h" #include "uri.h" +#include "xml/repr.h" #include -/// Float type internal to SPStyle. -struct SPIFloat { - unsigned set : 1; - unsigned inherit : 1; - unsigned data : 30; +struct SPStyleEnum; + +static const unsigned SP_STYLE_FLAG_ALWAYS (1 << 2); +static const unsigned SP_STYLE_FLAG_IFSET (1 << 0); +static const unsigned SP_STYLE_FLAG_IFDIFF (1 << 1); + + +/* General comments: + * + * This code is derived from the original C style code in style.cpp. + * + * Overview: + * Style can be obtained (in order of precidence) [CHECK] + * 1. "style" property in an element (style="fill:red"). + * 2. Style sheet, internal or external (). + * 3. Attributes in an element (fill="red"). + * 4. Parent's style. + * A later property overrides an earlier property. This is implemented by + * reading in the properties backwards. If a property is already set, it + * prevents an earlier property from being read. + * + * In order for cascading to work, each element in the tree must be read in from top to bottom + * (parent before child). At each step, if a style property is not explicitly set, the property + * value is taken from the parent. Some properties have "computed" values that depend on: + * the parent's value (e.g. "font-size:larger"), + * another property value ("stroke-width":1em"), or + * an external value ("stroke-width:5%"). + * + * To summarize: + * + * An explicitly set value (including 'inherit') has a 'true' "set" flag. + * The "value" is either explicitly set or inherited. + * The "computed" value (if present) is calculated from "value" and some other input. + * + * Functions: + * write(): Write a property and its value to a string. + * Flags: + * ALWAYS: Always write out property. + * IFSET: Write a property if 'set' flag is true, otherwise return empty string. + * IFDIFF: Write a property if computed values are different, otherwise return empty string, + * This is only used for text!! + * + * read(): Set a property value from a string. + * clear(): Set a property to its default value and set the 'set' flag to false. + * cascade(): Cascade the parent's property values to the child if the child's property + * is unset (and it allows inheriting) or the value is 'inherit'. + * Calculate computed values that depend on parent. + * This requires that the parent already be updated. + * merge(): Merge the property values of a child and a parent that is being deleted, + * attempting to preserve the style of the child. + * operator=: Assignment operator required due to use of templates (in original C code). + * operator==: True if computed values are equal. TO DO: DEFINE EXACTLY WHAT THIS MEANS + * operator!=: Inverse of operator==. + * + * + * Outside dependencies: + * + * The C structures that these classes are evolved from were designed to be embedded in to the + * style structure (i.e they are "internal" and thus have an "I" in the SPI prefix). However, + * they should be reasonably stand-alone and can provide some functionality outside of the style + * stucture (i.e. reading and writing style strings). Some properties do need access to other + * properties from the same object (e.g. SPILength sometimes needs to know font size) to + * calculate 'computed' values. Inheritence, of course, requires access to the parent object's + * style class. + * + * The only real outside dependancy is SPObject... which is needed in the cases of SPIPaint and + * SPIFilter for setting up the "href". (Currently, SPDocument is needed but this dependency + * should be removed as an "href" only needs the SPDocument for attaching an external document to + * the XML tree [see uri-references.cpp]. If SPDocument is really needed, it can be obtained from + * SPObject.) + * + */ + +/// Virtual base class for all SPStyle interal classes +class SPIBase { + + public: + SPIBase( Glib::ustring const &name, bool inherits = true ) + : name(name), inherits(inherits), set(false), inherit(false), style_att(false), style(NULL) {}; + virtual ~SPIBase() {}; + virtual void read( gchar const *str ) = 0; + virtual void readIfUnset( gchar const *str ) { if( !set ) read( str ); } + virtual void readAttribute( Inkscape::XML::Node *repr ) { readIfUnset( repr->attribute( name.c_str() ) ); } + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const = 0; + virtual void clear() { set = false, inherit = false; }; + virtual void cascade( const SPIBase* const parent ) {}; + virtual void merge( const SPIBase* const parent ) {}; // To do: Set to 0 + + virtual void setStylePointer( SPStyle *style_in ) { style = style_in; }; + + // Explicit assignment operator required due to templates. + SPIBase& operator=(const SPIBase& rhs) { + name = rhs.name; + inherits = rhs.inherits; + set = rhs.set; + inherit = rhs.inherit; + style_att = rhs.style_att; + return *this; + } + + // Check apples being compared to apples + virtual bool operator==(const SPIBase& rhs) { return (name == rhs.name); }; + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: + Glib::ustring name; // Make const when we switch to C++11 and change marker[] initializer + unsigned inherits : 1; // Property inherits by default from parent. + unsigned set : 1; // Property has been explicitly set (vs. inherited). + unsigned inherit : 1; // Property value set to 'inherit'. + unsigned style_att : 2; // Source (attribute, style attribute, style-sheet). NOT USED YET FIX ME + + // To do: make private after g_asserts removed + public: + SPStyle* style; // Used by SPIPaint, SPIFilter... to find values of other properties +}; + +/// Float type internal to SPStyle. (Only 'stroke-miterlimit') +class SPIFloat : public SPIBase { + + public: + SPIFloat() : SPIBase( "anonymous_float" ), value(0.0) {}; + SPIFloat( Glib::ustring name, float value_default = 0.0 ) + : SPIBase( name ), value(value_default), value_default(value_default) {}; + virtual ~SPIFloat() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); value = value_default; }; + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIFloat& operator=(const SPIFloat& rhs) { + SPIBase::operator=(rhs); + value = rhs.value; + value_default = value_default; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: float value; + + private: + float value_default; }; /* @@ -60,44 +209,42 @@ static const unsigned SP_SCALE24_MAX = 0xff0000; /** Returns a scale24 for the product of two scale24 values. */ #define SP_SCALE24_MUL(_v1, _v2) unsigned((double)(_v1) * (_v2) / SP_SCALE24_MAX + .5) + /// 24 bit data type internal to SPStyle. -struct SPIScale24 { - unsigned set : 1; - unsigned inherit : 1; +// Used only for opacity, fill-opacity, stroke-opacity. +// Opacity does not inherit but stroke-opacity and fill-opacity do. +class SPIScale24 : public SPIBase { + + public: + SPIScale24() : SPIBase( "anonymous_scale24" ), value(0) {}; + SPIScale24( Glib::ustring name, unsigned value = 0, bool inherits = true ) + : SPIBase( name, inherits ), value(value), value_default(value) {}; + virtual ~SPIScale24() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); value = value_default; }; + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIScale24& operator=(const SPIScale24& rhs) { + SPIBase::operator=(rhs); + value = rhs.value; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + + // To do: make private + public: unsigned value : 24; -}; - -/// Int type internal to SPStyle. -struct SPIInt { - unsigned set : 1; - unsigned inherit : 1; - unsigned data : 30; - int value; -}; -/// Short type internal to SPStyle. -struct SPIShort { - unsigned set : 1; - unsigned inherit : 1; - unsigned data : 14; - int value : 16; + private: + unsigned value_default : 24; }; -/// Enum type internal to SPStyle. -struct SPIEnum { - unsigned set : 1; - unsigned inherit : 1; - unsigned value : 8; - unsigned computed : 8; -}; - -/// String type internal to SPStyle. -struct SPIString { - unsigned set : 1; - unsigned inherit : 1; - unsigned data : 30; - gchar *value; -}; enum SPCSSUnit { SP_CSS_UNIT_NONE, @@ -112,33 +259,232 @@ enum SPCSSUnit { SP_CSS_UNIT_PERCENT }; + /// Length type internal to SPStyle. -struct SPILength { - unsigned set : 1; - unsigned inherit : 1; +// Needs access to 'font-size' and 'font-family' for computed values. +// Used for 'stroke-width' 'stroke-dash-offset' ('none' not handled), text-indent +class SPILength : public SPIBase { + + public: + SPILength() : SPIBase( "anonymous_length" ), unit(SP_CSS_UNIT_NONE), value(0), computed(0) {}; + SPILength( Glib::ustring name, unsigned value = 0 ) + : SPIBase( name ), unit(SP_CSS_UNIT_NONE), value(value), computed(value), value_default(value) {}; + virtual ~SPILength() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); unit = SP_CSS_UNIT_NONE, value = value_default; computed = value_default; }; + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPILength& operator=(const SPILength& rhs) { + SPIBase::operator=(rhs); + unit = rhs.unit; + value = rhs.value; + computed = rhs.computed; + value_default = rhs.value_default; + return *this; + }; + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: unsigned unit : 4; float value; float computed; + + private: + float value_default; }; -#define SP_STYLE_FILL_SERVER(s) ((const_cast (s))->getFillPaintServer()) -#define SP_STYLE_STROKE_SERVER(s) ((const_cast (s))->getStrokePaintServer()) -/// Paint type internal to SPStyle. -struct SPIPaint { - unsigned int set : 1; //c++ bitfields are used here as opposed to bools to reduce memory consumption, see http://tinyurl.com/cswh6mq - unsigned int inherit : 1; - unsigned int currentcolor : 1; - unsigned int colorSet : 1; - unsigned int noneSet : 1; +/// Extended length type internal to SPStyle. +// Used for: line-height, letter-spacing, word-spacing +class SPILengthOrNormal : public SPILength { + + public: + SPILengthOrNormal() : SPILength( "anonymous_length" ), normal(true) {}; + SPILengthOrNormal( Glib::ustring name, unsigned value = 0 ) + : SPILength( name, value ), normal(true) {}; + virtual ~SPILengthOrNormal() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPILength::clear(); normal = true; }; + // virtual void cascade( const SPIBase* const parent ); // Use SPILength::cascade + virtual void merge( const SPIBase* const parent ); + + SPILengthOrNormal& operator=(const SPILengthOrNormal& rhs) { + SPILength::operator=(rhs); + normal = rhs.normal; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: + bool normal : 1; +}; + + +/// Enum type internal to SPStyle. +// Used for many properties. 'font-stretch' and 'font-weight' must be special cased. +class SPIEnum : public SPIBase { + + public: + SPIEnum() : + SPIBase( "anonymous_enum" ), enums( NULL ), value(0), computed(0) {}; + SPIEnum( Glib::ustring name, SPStyleEnum const *enums, unsigned value = 0, bool inherits = true ) : + SPIBase( name, inherits ), enums( enums ), value(value), computed(value), + value_default(value), computed_default(value) {}; + // Following is needed for font-weight + SPIEnum( Glib::ustring name, SPStyleEnum const *enums, SPCSSFontWeight value, SPCSSFontWeight computed ) : + SPIBase( name ), enums( enums ), value(value), computed(computed), + value_default(value), computed_default(computed) {}; + virtual ~SPIEnum() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); value = value_default, computed = computed_default; }; + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIEnum& operator=(const SPIEnum& rhs) { + SPIBase::operator=(rhs); + value = rhs.value; + computed = rhs.computed; + value_default = rhs.value_default; + computed_default = rhs.computed_default; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: + SPStyleEnum const *enums; + + unsigned value : 8; + unsigned computed: 8; + + private: + unsigned value_default : 8; + unsigned computed_default: 8; // for font-weight +}; + + +/// String type internal to SPStyle. +// Used for 'marker', ..., 'font', 'font-family', 'inkscape-font-specification' +class SPIString : public SPIBase { + + public: + SPIString() : + SPIBase( "anonymous_string" ), value(NULL) {}; + SPIString( Glib::ustring name ) : + SPIBase( name ) , value(NULL) {}; + virtual ~SPIString() { g_free(value); }; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); g_free( value ); value = NULL; }; + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIString& operator=(const SPIString& rhs) { + SPIBase::operator=(rhs); + value = rhs.value?g_strdup(rhs.value):NULL; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private, convert value to Glib::ustring + public: + gchar *value; +}; + +/// Color type interal to SPStyle, FIXME Add string value to store SVG named color. +class SPIColor : public SPIBase { + + public: + SPIColor() : SPIBase( "anonymous_color" ), currentcolor(false) { value.color.set(0); } + SPIColor( Glib::ustring name ) : SPIBase( name ), currentcolor(false) { value.color.set(0); } + virtual ~SPIColor() {} + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); value.color.set(0); } + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIColor& operator=(const SPIColor& rhs) { + SPIBase::operator=(rhs); + value.color = rhs.value.color; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); } + + void setColor( float r, float g, float b ) { value.color.set( r, g, b ); } + void setColor( guint32 val ) { value.color.set( val ); } + void setColor( SPColor const& color ) { value.color = color; } + + public: + bool currentcolor : 1; + // FIXME: remove structure and derive SPIPaint from this class. struct { - SPPaintServerReference *href; SPColor color; } value; +}; + - SPIPaint(); - bool isSet() const { return true; /* set || colorSet*/} +#define SP_STYLE_FILL_SERVER(s) ((const_cast (s))->getFillPaintServer()) +#define SP_STYLE_STROKE_SERVER(s) ((const_cast (s))->getStrokePaintServer()) + +/// Paint type internal to SPStyle. +class SPIPaint : public SPIBase { + + public: + SPIPaint() : SPIBase( "anonymous_paint" ), currentcolor(false), colorSet(false), noneSet(false) { + value.href = NULL; + clear(); + }; + SPIPaint( Glib::ustring name ) + : SPIBase( name ), currentcolor(false), colorSet(false), noneSet(false) { + value.href = NULL; + clear(); // Sets defaults + }; + virtual ~SPIPaint(); // Clear and delete href. + virtual void read( gchar const *str ); + virtual void read( gchar const *str, SPStyle &style, SPDocument *document = 0); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear(); + virtual void reset( bool init ); // Used internally when reading or cascading + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIPaint& operator=(const SPIPaint& rhs) { + SPIBase::operator=(rhs); + currentcolor = rhs.currentcolor; + colorSet = rhs.colorSet; + noneSet = rhs.noneSet; + value.color = rhs.value.color; + value.href = rhs.value.href; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + bool isSameType( SPIPaint const & other ) const {return (isPaintserver() == other.isPaintserver()) && (colorSet == other.colorSet) && (currentcolor == other.currentcolor);} bool isNoneSet() const {return noneSet;} @@ -147,22 +493,24 @@ struct SPIPaint { bool isColor() const {return colorSet && !isPaintserver();} bool isPaintserver() const {return (value.href) ? value.href->getObject():0;} - void clear(); - void setColor( float r, float g, float b ) {value.color.set( r, g, b ); colorSet = true;} void setColor( guint32 val ) {value.color.set( val ); colorSet = true;} void setColor( SPColor const& color ) {value.color = color; colorSet = true;} - void read( gchar const *str, SPStyle &tyle, SPDocument *document = 0); -}; -class SPIDashArray { - public: - unsigned set : 1; - unsigned inherit : 1; - std::vector values; + + // To do: make private + public: + bool currentcolor : 1; + bool colorSet : 1; + bool noneSet : 1; + struct { + SPPaintServerReference *href; + SPColor color; + } value; }; + // SVG 2 enum SPPaintOrderLayer { SP_CSS_PAINT_ORDER_NORMAL, @@ -171,54 +519,225 @@ enum SPPaintOrderLayer { SP_CSS_PAINT_ORDER_MARKER }; +// Normal maybe should be moved out as is done in other classes. +// This could be replaced by a generic enum class where multiple keywords are allowed and +// where order matters (in contrast to 'text-decoration-line' where order does not matter). + +// Each layer represents a layer of paint which can be a fill, a stroke, or markers. const size_t PAINT_ORDER_LAYERS = 3; -struct SPIPaintOrder { - unsigned set : 1; - unsigned inherit : 1; + +/// Paint order type internal to SPStyle +class SPIPaintOrder : public SPIBase { + + public: + SPIPaintOrder() : SPIBase( "paint-order" ), value(NULL) { this->clear(); }; + virtual ~SPIPaintOrder() { g_free( value ); }; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { + SPIBase::clear(); + for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) { + layer[i] = SP_CSS_PAINT_ORDER_NORMAL; + layer_set[i] = false; + } + g_free(value); + value = NULL; + } + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIPaintOrder& operator=(const SPIPaintOrder& rhs) { + SPIBase::operator=(rhs); + for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) { + layer[i] = rhs.layer[i]; + layer_set[i] = rhs.layer_set[i]; + } + value = g_strdup(rhs.value); + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + + // To do: make private + public: SPPaintOrderLayer layer[PAINT_ORDER_LAYERS]; bool layer_set[PAINT_ORDER_LAYERS]; gchar *value; // Raw string }; + +/// Filter type internal to SPStyle +class SPIDashArray : public SPIBase { + + public: + SPIDashArray() : SPIBase( "stroke-dasharray" ) {}; // Only one instance of SPIDashArray + virtual ~SPIDashArray() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); values.clear(); }; + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIDashArray& operator=(const SPIDashArray& rhs) { + SPIBase::operator=(rhs); + values = rhs.values; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + + // To do: make private, change double to SVGLength + public: + std::vector values; +}; + /// Filter type internal to SPStyle -struct SPIFilter { - unsigned set : 1; - unsigned inherit : 1; +class SPIFilter : public SPIBase { + + public: + SPIFilter() : SPIBase( "filter", false ), href(NULL) {}; + virtual ~SPIFilter(); + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear(); + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIFilter& operator=(const SPIFilter& rhs) { + SPIBase::operator=(rhs); + href = rhs.href; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: SPFilterReference *href; }; + + enum { SP_FONT_SIZE_LITERAL, SP_FONT_SIZE_LENGTH, SP_FONT_SIZE_PERCENTAGE }; -enum { - SP_BASELINE_SHIFT_LITERAL, - SP_BASELINE_SHIFT_LENGTH, - SP_BASELINE_SHIFT_PERCENTAGE -}; - - -#define SP_STYLE_FLAG_IFSET (1 << 0) -#define SP_STYLE_FLAG_IFDIFF (1 << 1) -#define SP_STYLE_FLAG_ALWAYS (1 << 2) - /// Fontsize type internal to SPStyle (also used by libnrtype/Layout-TNG-Input.cpp). -struct SPIFontSize { - unsigned set : 1; - unsigned inherit : 1; +class SPIFontSize : public SPIBase { + + public: + SPIFontSize() : SPIBase( "font-size" ) { this->clear(); }; + virtual ~SPIFontSize() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); type = SP_FONT_SIZE_LITERAL, unit = SP_CSS_UNIT_NONE, + literal = SP_CSS_FONT_SIZE_MEDIUM, value = 12.0, computed = 12.0; } + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIFontSize& operator=(const SPIFontSize& rhs) { + SPIBase::operator=(rhs); + type = rhs.type; + unit = rhs.unit; + literal = rhs.literal; + value = rhs.value; + computed = rhs.computed; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + public: + static float const font_size_default; + + // To do: make private + public: unsigned type : 2; unsigned unit : 4; - unsigned literal: 4; + unsigned literal : 4; float value; float computed; + + private: + double relative_fraction() const; + static float const font_size_table[]; +}; + + +/// Font type internal to SPStyle ('font' shorthand) +class SPIFont : public SPIBase { + + public: + SPIFont() : SPIBase( "font" ) {}; + virtual ~SPIFont() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { + SPIBase::clear(); + }; + virtual void cascade( const SPIBase* const parent ) {}; // Done in dependent properties + virtual void merge( const SPIBase* const parent ) {}; + + SPIFont& operator=(const SPIFont& rhs) { + SPIBase::operator=(rhs); + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; +}; + + +enum { + SP_BASELINE_SHIFT_LITERAL, + SP_BASELINE_SHIFT_LENGTH, + SP_BASELINE_SHIFT_PERCENTAGE }; -/// Baseline shift type internal to SPStyle. -struct SPIBaselineShift { - unsigned set : 1; - unsigned inherit : 1; +/// Baseline shift type internal to SPStyle. (This is actually just like SPIFontSize) +class SPIBaselineShift : public SPIBase { + + public: + SPIBaselineShift() : SPIBase( "baseline-shift", false ) { this->clear(); }; + virtual ~SPIBaselineShift() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); type=SP_BASELINE_SHIFT_LITERAL, unit=SP_CSS_UNIT_NONE, + literal = SP_CSS_BASELINE_SHIFT_BASELINE, value = 0.0, computed = 0.0; } + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPIBaselineShift& operator=(const SPIBaselineShift& rhs) { + SPIBase::operator=(rhs); + type = rhs.type; + unit = rhs.unit; + literal = rhs.literal; + value = rhs.value; + computed = rhs.computed; + return *this; + } + + // This is not used but we have it for completeness, it has not been tested. + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + bool isZero() const; + + // To do: make private + public: unsigned type : 2; unsigned unit : 4; unsigned literal: 2; @@ -227,38 +746,112 @@ struct SPIBaselineShift { }; // CSS 2. Changes in CSS 3, where description is for TextDecorationLine, NOT TextDecoration -/// Text decoration type internal to SPStyle. -struct SPITextDecorationLine { - unsigned set : 1; - unsigned inherit : 1; - unsigned underline : 1; - unsigned overline : 1; - unsigned line_through : 1; - unsigned blink : 1; // "Conforming user agents are not required to support this value." yay! +// See http://www.w3.org/TR/css-text-decor-3/ + +// CSS3 2.2 +/// Text decoration line type internal to SPStyle. THIS SHOULD BE A GENERIC CLASS +class SPITextDecorationLine : public SPIBase { + + public: + SPITextDecorationLine() : SPIBase( "text-decoration-line" ) { this->clear(); }; + virtual ~SPITextDecorationLine() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); underline = false, overline = false, line_through = false, blink = false; } + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPITextDecorationLine& operator=(const SPITextDecorationLine& rhs) { + SPIBase::operator=(rhs); + underline = rhs.underline; + overline = rhs.overline; + line_through = rhs.line_through; + blink = rhs.blink; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: + bool underline : 1; + bool overline : 1; + bool line_through : 1; + bool blink : 1; // "Conforming user agents are not required to support this value." yay! }; // CSS3 2.2 -/// Text decoration style type internal to SPStyle. -struct SPITextDecorationStyle { - unsigned set : 1; - unsigned inherit : 1; - unsigned solid : 1; - unsigned isdouble : 1; // cannot use "double" as it is a reserved keyword - unsigned dotted : 1; - unsigned dashed : 1; - unsigned wavy : 1; +/// Text decoration style type internal to SPStyle. THIS SHOULD JUST BE SPIEnum! +class SPITextDecorationStyle : public SPIBase { + + public: + SPITextDecorationStyle() : SPIBase( "text-decoration-style" ) { this->clear(); }; + virtual ~SPITextDecorationStyle() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { SPIBase::clear(); solid = true, isdouble = false, dotted = false, dashed = false, wavy = false; } + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ); + + SPITextDecorationStyle& operator=(const SPITextDecorationStyle& rhs) { + SPIBase::operator=(rhs); + solid = rhs.solid; + isdouble = rhs.isdouble; + dotted = rhs.dotted; + dashed = rhs.dashed; + wavy = rhs.wavy; + return *this; + } + + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + // To do: make private + public: + bool solid : 1; + bool isdouble : 1; // cannot use "double" as it is a reserved keyword + bool dotted : 1; + bool dashed : 1; + bool wavy : 1; }; -/// Extended length type internal to SPStyle. -struct SPILengthOrNormal { - unsigned set : 1; - unsigned inherit : 1; - unsigned normal : 1; - unsigned unit : 4; - float value; - float computed; + + +// This class reads in both CSS2 and CSS3 'text-decoration' property. It passes the line, style, +// and color parts to the appropriate CSS3 long-hand classes for reading and storing values. When +// writing out data, we write all four properties, with 'text-decoration' being written out with +// the CSS2 format. This allows CSS1/CSS2 renderers to at least render lines, even if they are not +// the right style. (See http://www.w3.org/TR/css-text-decor-3/#text-decoration-property ) + +/// Text decoration type internal to SPStyle. +class SPITextDecoration: public SPIBase { + + public: + SPITextDecoration() : SPIBase( "text-decoration" ) {}; + virtual ~SPITextDecoration() {}; + virtual void read( gchar const *str ); + virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, + SPIBase const *const base = NULL ) const; + virtual void clear() { + SPIBase::clear(); + }; + virtual void cascade( const SPIBase* const parent ) {}; // Done in SPITextDecorationLine + virtual void merge( const SPIBase* const parent ) {}; // Done in SPITextDecorationLine + + SPITextDecoration& operator=(const SPITextDecoration& rhs) { + SPIBase::operator=(rhs); + return *this; + } + + // Use CSS2 value + virtual bool operator==(const SPIBase& rhs); + virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; }; + // These are used to implement text_decoration. The values are not saved to or read from SVG file struct SPITextDecorationData { float phase_length; // length along text line,used for phase for dot/dash/wavy @@ -274,12 +867,9 @@ struct SPITextDecorationData { float line_through_position; }; -struct SPTextStyle; - -/// An SPTextStyle has a refcount, a font family, and a font name. -struct SPTextStyle { - int refcount; +/// An SPFontStyle has a 'font', 'font-family', and font_specification (ala Pango). +struct SPFontStyle { /* CSS font properties */ SPIString font_family; @@ -287,7 +877,7 @@ struct SPTextStyle { SPIString font_specification; /** \todo fixme: The 'font' property is ugly, and not working (lauris) */ - SPIString font; +// SPIString font; }; #endif // SEEN_SP_STYLE_INTERNAL_H diff --git a/src/style-test.h b/src/style-test.h index c88c1c30a..2fe270336 100644 --- a/src/style-test.h +++ b/src/style-test.h @@ -48,6 +48,7 @@ public: // --------------------------------------------------------------- // --------------------------------------------------------------- + // Reading and writing style string void testOne() { struct TestCase { @@ -95,15 +96,33 @@ public: TestCase("overflow:visible"), // SPIEnum TestCase("overflow:auto"), // SPIEnum - // Not directly read + TestCase("color:#ff0000"), + TestCase("color:blue", "color:#0000ff"), + // TestCase("color:currentColor"), SVG 1.1 does not allow color value 'currentColor' + + // Font shorthand TestCase("font:bold 12px Arial", - "font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-family:Arial"), - // line-height not read in - //TestCase("font:bold 12px/24px 'Times New Roman'", - // "font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;line-height:24px;font-family:Times New Roman"), + "font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:normal;font-family:Arial"), + TestCase("font:bold 12px/24px 'Times New Roman'", + "font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12px;line-height:24px;font-family:\'\"Times New Roman\"\'"), + // From CSS 3 Fonts (examples): + TestCase("font: 12pt/14pt sans-serif", + "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:14pt;font-family:sans-serif"), + TestCase("font: 80% sans-serif", + "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:80.00000119%;line-height:normal;font-family:sans-serif"), + TestCase("font: x-large/110% 'new century schoolbook', serif", + "font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:x-large;line-height:110.00000238%;font-family:\'\"new century schoolbook\", serif\'"), + TestCase("font: bold italic large Palatino, serif", + "font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:large;line-height:normal;font-family:\'Palatino, serif\'"), + TestCase("font: normal small-caps 120%/120% fantasy", + "font-style:normal;font-variant:small-caps;font-weight:normal;font-stretch:normal;font-size:120.00000477%;line-height:120.00000477%;font-family:fantasy"), + TestCase("font: condensed oblique 12pt 'Helvetica Neue', serif;", + "font-style:oblique;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:15px;line-height:normal;font-family:\'\"Helvetica Neue\", serif\'"), + TestCase("font-family:sans-serif"), // SPIString, text_private TestCase("font-family:Arial"), TestCase("font-variant:normal;font-stretch:normal;-inkscape-font-specification:Nimbus Roman No9 L Bold Italic"), + // Needs to be fixed (quotes should be around each font-family): TestCase("font-family:Georgia, 'Minion Web'","font-family:'Georgia, \"Minion Web\"'"), TestCase("font-size:12", "font-size:12px"), // SPIFontSize @@ -121,9 +140,31 @@ public: // Should be moved down TestCase("text-indent:12em"), // SPILength? TestCase("text-align:center"), // SPIEnum - TestCase("text-decoration: underline"), // SPITextDecoration - TestCase("text-decoration: underline wavy #0000ff"), // SPITextDecoration CSS3 - TestCase("text-decoration: overline double #ff0000"), + + // SPITextDecoration + // The default value for 'text-decoration-color' is 'currentColor', but + // we cannot set the default to that value yet. (We need to switch + // SPIPaint to SPIColor and then add the ability to set default.) + TestCase("text-decoration: underline", + "text-decoration: underline;text-decoration-line: underline;text-decoration-color:currentColor"), + TestCase("text-decoration: overline underline", + "text-decoration: underline overline;text-decoration-line: underline overline;text-decoration-color:currentColor"), + + TestCase("text-decoration: underline wavy #0000ff", + "text-decoration: underline;text-decoration-line: underline;text-decoration-style:wavy;text-decoration-color:#0000ff"), + TestCase("text-decoration: double overline underline #ff0000", + "text-decoration: underline overline;text-decoration-line: underline overline;text-decoration-style:double;text-decoration-color:#ff0000"), + + // SPITextDecorationLine + TestCase("text-decoration-line: underline", + "text-decoration: underline;text-decoration-line: underline"), + + // SPITextDecorationStyle + TestCase("text-decoration-style:solid"), + TestCase("text-decoration-style:dotted"), + + // SPITextDecorationColor + TestCase("text-decoration-color:#ff00ff"), // Should be moved up TestCase("line-height:24px"), // SPILengthOrNormal @@ -166,11 +207,13 @@ public: TestCase("paint-order:stroke"), // SPIPaintOrder TestCase("paint-order:normal"), TestCase("paint-order: markers stroke fill", "paint-order:markers stroke fill"), + #endif TestCase(0) }; for ( gint i = 0; cases[i].src; i++ ) { + // std::cout << "Test one: " << i << std::endl; SPStyle *style = sp_style_new(_doc); TS_ASSERT(style); if ( style ) { @@ -188,10 +231,10 @@ public: gchar *str0_set = sp_style_write_string( style, SP_STYLE_FLAG_IFSET ); //printf("<<%s>>\n", str0_set); if ( cases[i].dst ) { - //std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].dst) << std::endl; + // std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].dst) << std::endl; TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].dst) ); } else { - //std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].src) << std::endl; + // std::cout << " " << std::string(str0_set) << " " << std::string(cases[i].src) << std::endl; TS_ASSERT_EQUALS( std::string(str0_set), std::string(cases[i].src) ); } @@ -201,6 +244,273 @@ public: } } + // Testing operator== + void testTwo() + { + struct TestCase { + TestCase(gchar const* src, gchar const* dst, bool match) : + src(src), dst(dst), match(match) {} + gchar const* src; + gchar const* dst; + bool match; + }; + + TestCase cases[] = { + + // SPIFloat + TestCase("stroke-miterlimit:4", "stroke-miterlimit:4", true ), + TestCase("stroke-miterlimit:4", "stroke-miterlimit:2", false), + TestCase("stroke-miterlimit:4", "", true ), // Default + + // SPIScale24 + TestCase("opacity:0.3", "opacity:0.3", true ), + TestCase("opacity:0.3", "opacity:0.6", false), + TestCase("opacity:1.0", "", true ), // Default + + // SPILength + TestCase("text-indent:3", "text-indent:3", true ), + TestCase("text-indent:6", "text-indent:3", false), + TestCase("text-indent:6px", "text-indent:3", false), + TestCase("text-indent:1px", "text-indent:12pc", false), + TestCase("text-indent:2ex", "text-indent:2ex", false), + + // SPILengthOrNormal + TestCase("letter-spacing:normal", "letter-spacing:normal", true ), + TestCase("letter-spacing:2", "letter-spacing:normal", false), + TestCase("letter-spacing:normal", "letter-spacing:2", false), + TestCase("letter-spacing:5px", "letter-spacing:5px", true ), + TestCase("letter-spacing:10px", "letter-spacing:5px", false), + TestCase("letter-spacing:10em", "letter-spacing:10em", false), + + // SPIEnum + TestCase("text-anchor:start", "text-anchor:start", true ), + TestCase("text-anchor:start", "text-anchor:middle", false), + TestCase("text-anchor:start", "", true ), // Default + TestCase("text-anchor:start", "text-anchor:junk", true ), // Bad value + + TestCase("font-weight:normal", "font-weight:400", true ), + TestCase("font-weight:bold", "font-weight:700", true ), + + + // SPIString and SPIFontString + TestCase("font-family:Arial", "font-family:Arial", true ), + TestCase("font-family:A B", "font-family:A B", true ), + TestCase("font-family:A B", "font-family:A C", false), + // Default is not set by class... value is NULL which cannot be compared + // TestCase("font-family:sans-serif", "", true ), // Default + + // SPIColor + TestCase("color:blue", "color:blue", true ), + TestCase("color:blue", "color:red", false), + TestCase("color:red", "color:#ff0000", true ), + + // SPIPaint + TestCase("fill:blue", "fill:blue", true ), + TestCase("fill:blue", "fill:red", false), + TestCase("fill:currentColor", "fill:currentColor", true ), + TestCase("fill:url(#xxx)", "fill:url(#xxx)", true ), + // Needs URL defined as in test 1 + //TestCase("fill:url(#xxx)", "fill:url(#yyy)", false), + + // SPIPaintOrder + TestCase("paint-order:markers", "paint-order:markers", true ), + TestCase("paint-order:markers", "paint-order:stroke", false), + //TestCase("paint-order:fill stroke markers", "", true ), // Default + TestCase("paint-order:normal", "paint-order:normal", true ), + //TestCase("paint-order:fill stroke markers", "paint-order:normal", true ), + + // SPIDashArray + TestCase("stroke-dasharray:0 1 2 3","stroke-dasharray:0 1 2 3",true ), + TestCase("stroke-dasharray:0 1", "stroke-dasharray:0 2", false), + + // SPIFilter + + // SPIFontSize + TestCase("font-size:12px", "font-size:12px", true ), + TestCase("font-size:12px", "font-size:24px", false), + TestCase("font-size:12ex", "font-size:24ex", false), + TestCase("font-size:medium", "font-size:medium", true ), + TestCase("font-size:medium", "font-size:large", false), + + // SPIBaselineShift + TestCase("baseline-shift:baseline", "baseline-shift:baseline", true ), + TestCase("baseline-shift:sub", "baseline-shift:sub", true ), + TestCase("baseline-shift:sub", "baseline-shift:super", false), + TestCase("baseline-shift:baseline", "baseline-shift:sub", false), + TestCase("baseline-shift:10px", "baseline-shift:10px", true ), + TestCase("baseline-shift:10px", "baseline-shift:12px", false), + + + // SPITextDecorationLine + TestCase("text-decoration-line:underline", "text-decoration-line:underline", true ), + TestCase("text-decoration-line:underline", "text-decoration-line:overline", false), + TestCase("text-decoration-line:underline overline", "text-decoration-line:underline overline", true ), + TestCase("text-decoration-line:none", "", true ), // Default + + + // SPITextDecorationStyle + TestCase("text-decoration-style:solid", "text-decoration-style:solid", true ), + TestCase("text-decoration-style:dotted", "text-decoration-style:solid", false), + TestCase("text-decoration-style:solid", "", true ), // Default + + // SPITextDecoration + TestCase("text-decoration:underline", "text-decoration:underline", true ), + TestCase("text-decoration:underline", "text-decoration:overline", false), + TestCase("text-decoration:underline overline","text-decoration:underline overline",true ), + TestCase("text-decoration:overline underline","text-decoration:underline overline",true ), + TestCase("text-decoration:none", "text-decoration-color:currentColor", true ), // Default + + + // Terminate + TestCase(0,0,0) + }; + for ( gint i = 0; cases[i].src; i++ ) { + // std::cout << "Test two: " << i << std::endl; + SPStyle *style_src = sp_style_new(_doc); + TS_ASSERT(style_src); + SPStyle *style_dst = sp_style_new(_doc); + TS_ASSERT(style_dst); + + if ( style_src && style_dst ) { + sp_style_merge_from_style_string( style_src, cases[i].src ); + sp_style_merge_from_style_string( style_dst, cases[i].dst ); + // std::cout << "Test:" << std::endl; + // std::cout << " C: |" << cases[i].src << "| |" << cases[i].dst << "|" << std::endl; + // std::cout << " S: |" << style_src->write( SP_STYLE_FLAG_IFSET, NULL ) << "| |" + // << style_dst->write( SP_STYLE_FLAG_IFSET, NULL ) << "|" <write( SP_STYLE_FLAG_IFSET ) + // << " Child: " << style_child->write( SP_STYLE_FLAG_IFSET ) + // << " Result: " << style_result->write( SP_STYLE_FLAG_IFSET ) << std::endl; + + //sp_style_merge_from_parent( style_child, style_parent ); + style_child->cascade( style_parent ); + + TS_ASSERT(*style_child == *style_result ); + + sp_style_unref(style_child); + sp_style_unref(style_parent); + sp_style_unref(style_result); + // std::cout << "End Test: *************\n" << std::endl; + } + } + } + }; diff --git a/src/style.cpp b/src/style.cpp index bc869b127..97d9c811c 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -14,6 +14,7 @@ * Copyright (C) 2001 Ximian, Inc. * Copyright (C) 2005 Monash University * Copyright (C) 2012 Kris De Gussem + * Copyright (C) 2014 Tavmjong Bah * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -24,6 +25,7 @@ #include #include +#include #include "libcroco/cr-sel-eng.h" #include "xml/croco-node-iface.h" @@ -65,925 +67,540 @@ using std::vector; struct SPStyleEnum; +int SPStyle::_count = 0; + /*######################### ## FORWARD DECLARATIONS #########################*/ -static void sp_style_clear(SPStyle *style); - -static void sp_style_merge_property(SPStyle *style, gint id, gchar const *val); - -static void sp_style_merge_ipaint(SPStyle *style, SPIPaint *paint, SPIPaint const *parent); -static void sp_style_merge_ifilter(SPStyle *style, SPIFilter const *parent); -static void sp_style_read_dash(SPStyle *style, gchar const *str); - -static SPTextStyle *sp_text_style_new(void); -static void sp_text_style_clear(SPTextStyle *ts); -static SPTextStyle *sp_text_style_unref(SPTextStyle *st); -static SPTextStyle *sp_text_style_duplicate_unset(SPTextStyle *st); -static guint sp_text_style_write(gchar *p, guint len, SPTextStyle const *st, guint flags = SP_STYLE_FLAG_IFSET); -static void sp_style_privatize_text(SPStyle *style); - -static void sp_style_read_ifloat(SPIFloat *val, gchar const *str); -static void sp_style_read_iscale24(SPIScale24 *val, gchar const *str); -static void sp_style_read_ienum(SPIEnum *val, gchar const *str, SPStyleEnum const *dict, bool can_explicitly_inherit); -static void sp_style_read_istring(SPIString *val, gchar const *str); -static void sp_style_read_ilength(SPILength *val, gchar const *str); -static void sp_style_read_ilengthornormal(SPILengthOrNormal *val, gchar const *str); - -static void sp_style_read_ipaintorder(SPIPaintOrder *val, gchar const *str); - -static void sp_style_read_itextdecoration(SPITextDecorationLine *line, SPITextDecorationStyle *style, SPIPaint *color, gchar const *str); -static void sp_style_read_itextdecorationLine(SPITextDecorationLine *line, gchar const *str); -static void sp_style_read_itextdecorationStyle(SPITextDecorationStyle *style, gchar const *str); -static void sp_style_read_itextdecorationColor(SPIPaint *color, gchar const *str); - -static void sp_style_read_icolor(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocument *document); -static void sp_style_read_ifontsize(SPIFontSize *val, gchar const *str); -static void sp_style_read_ibaselineshift(SPIBaselineShift *val, gchar const *str); -static void sp_style_read_ifilter(gchar const *str, SPStyle *style, SPDocument *document); - -static void sp_style_read_penum(SPIEnum *val, Inkscape::XML::Node *repr, gchar const *key, SPStyleEnum const *dict, bool can_explicitly_inherit); -static void sp_style_read_plength(SPILength *val, Inkscape::XML::Node *repr, gchar const *key); -static void sp_style_read_pfontsize(SPIFontSize *val, Inkscape::XML::Node *repr, gchar const *key); -static void sp_style_read_pbaselineshift(SPIBaselineShift *val, Inkscape::XML::Node *repr, gchar const *key); -static void sp_style_read_pfloat(SPIFloat *val, Inkscape::XML::Node *repr, gchar const *key); - -static gint sp_style_write_ifloat(gchar *p, gint len, gchar const *key, SPIFloat const *val, SPIFloat const *base, guint flags); -static gint sp_style_write_iscale24(gchar *p, gint len, gchar const *key, SPIScale24 const *val, SPIScale24 const *base, guint flags); -static gint sp_style_write_ienum(gchar *p, gint len, gchar const *key, SPStyleEnum const *dict, SPIEnum const *val, SPIEnum const *base, guint flags); -static gint sp_style_write_istring(gchar *p, gint len, gchar const *key, SPIString const *val, SPIString const *base, guint flags); -static gint sp_style_write_ilength(gchar *p, gint len, gchar const *key, SPILength const *val, SPILength const *base, guint flags); -static gint sp_style_write_ipaint(gchar *b, gint len, gchar const *key, SPIPaint const *paint, SPIPaint const *base, guint flags); -static gint sp_style_write_ipaintorder(gchar *p, gint len, gchar const *key, SPIPaintOrder const *paint_order, SPIPaintOrder const *base, guint flags); -static gint sp_style_write_idasharray(gchar *p, gint const len, gchar const *const key, SPIDashArray const *const val, SPIDashArray const *const base, guint const flags); - -static gint sp_style_write_ifontsize(gchar *p, gint len, gchar const *key, SPIFontSize const *val, SPIFontSize const *base, guint flags); -static gint sp_style_write_ibaselineshift(gchar *p, gint len, gchar const *key, SPIBaselineShift const *val, SPIBaselineShift const *base, guint flags); -static gint sp_style_write_ilengthornormal(gchar *p, gint const len, gchar const *const key, SPILengthOrNormal const *const val, SPILengthOrNormal const *const base, guint const flags); -static gint sp_style_write_itextdecoration(gchar *p, gint const len, gchar const *const key, - SPITextDecorationLine const *const line, - SPITextDecorationStyle const *const style, - SPIPaint const *const color, - SPITextDecorationLine const *const baseLine, - SPITextDecorationStyle const *const baseStyle, - SPIPaint const *const baseColor, - guint const flags); -static gint sp_style_write_ifilter(gchar *b, gint len, gchar const *key, SPIFilter const *filter, SPIFilter const *base, guint flags); - -static void sp_style_filter_clear(SPStyle *style); - -#define SPS_READ_IENUM_IF_UNSET(v,s,d,i) if (!(v)->set) {sp_style_read_ienum((v), (s), (d), (i));} -#define SPS_READ_PENUM_IF_UNSET(v,r,k,d,i) if (!(v)->set) {sp_style_read_penum((v), (r), (k), (d), (i));} - -#define SPS_READ_ILENGTH_IF_UNSET(v,s) if (!(v)->set) {sp_style_read_ilength((v), (s));} -#define SPS_READ_PLENGTH_IF_UNSET(v,r,k) if (!(v)->set) {sp_style_read_plength((v), (r), (k));} - -#define SPS_READ_PFLOAT_IF_UNSET(v,r,k) if (!(v)->set) {sp_style_read_pfloat((v), (r), (k));} - -#define SPS_READ_IFONTSIZE_IF_UNSET(v,s) if (!(v)->set) {sp_style_read_ifontsize((v), (s));} -#define SPS_READ_PFONTSIZE_IF_UNSET(v,r,k) if (!(v)->set) {sp_style_read_pfontsize((v), (r), (k));} - -#define SPS_READ_IBASELINE_SHIFT_IF_UNSET(v,s) if (!(v)->set) {sp_style_read_ibaselineshift((v), (s));} -#define SPS_READ_PBASELINE_SHIFT_IF_UNSET(v,r,k) if (!(v)->set) {sp_style_read_pbaselineshift((v), (r), (k));} - -static void sp_style_merge_from_object_stylesheet(SPStyle *, SPObject const *); - -struct SPStyleEnum { - gchar const *key; - gint value; -}; - -static SPStyleEnum const enum_fill_rule[] = { - {"nonzero", SP_WIND_RULE_NONZERO}, - {"evenodd", SP_WIND_RULE_EVENODD}, - {NULL, -1} -}; - -static SPStyleEnum const enum_stroke_linecap[] = { - {"butt", SP_STROKE_LINECAP_BUTT}, - {"round", SP_STROKE_LINECAP_ROUND}, - {"square", SP_STROKE_LINECAP_SQUARE}, - {NULL, -1} -}; - -static SPStyleEnum const enum_stroke_linejoin[] = { - {"miter", SP_STROKE_LINEJOIN_MITER}, - {"round", SP_STROKE_LINEJOIN_ROUND}, - {"bevel", SP_STROKE_LINEJOIN_BEVEL}, - {NULL, -1} -}; - -static SPStyleEnum const enum_font_style[] = { - {"normal", SP_CSS_FONT_STYLE_NORMAL}, - {"italic", SP_CSS_FONT_STYLE_ITALIC}, - {"oblique", SP_CSS_FONT_STYLE_OBLIQUE}, - {NULL, -1} -}; - -static SPStyleEnum const enum_font_size[] = { - {"xx-small", SP_CSS_FONT_SIZE_XX_SMALL}, - {"x-small", SP_CSS_FONT_SIZE_X_SMALL}, - {"small", SP_CSS_FONT_SIZE_SMALL}, - {"medium", SP_CSS_FONT_SIZE_MEDIUM}, - {"large", SP_CSS_FONT_SIZE_LARGE}, - {"x-large", SP_CSS_FONT_SIZE_X_LARGE}, - {"xx-large", SP_CSS_FONT_SIZE_XX_LARGE}, - {"smaller", SP_CSS_FONT_SIZE_SMALLER}, - {"larger", SP_CSS_FONT_SIZE_LARGER}, - {NULL, -1} -}; - -static SPStyleEnum const enum_font_variant[] = { - {"normal", SP_CSS_FONT_VARIANT_NORMAL}, - {"small-caps", SP_CSS_FONT_VARIANT_SMALL_CAPS}, - {NULL, -1} -}; - -static SPStyleEnum const enum_font_weight[] = { - {"100", SP_CSS_FONT_WEIGHT_100}, - {"200", SP_CSS_FONT_WEIGHT_200}, - {"300", SP_CSS_FONT_WEIGHT_300}, - {"400", SP_CSS_FONT_WEIGHT_400}, - {"500", SP_CSS_FONT_WEIGHT_500}, - {"600", SP_CSS_FONT_WEIGHT_600}, - {"700", SP_CSS_FONT_WEIGHT_700}, - {"800", SP_CSS_FONT_WEIGHT_800}, - {"900", SP_CSS_FONT_WEIGHT_900}, - {"normal", SP_CSS_FONT_WEIGHT_NORMAL}, - {"bold", SP_CSS_FONT_WEIGHT_BOLD}, - {"lighter", SP_CSS_FONT_WEIGHT_LIGHTER}, - {"bolder", SP_CSS_FONT_WEIGHT_BOLDER}, - {NULL, -1} -}; - -static SPStyleEnum const enum_font_stretch[] = { - {"ultra-condensed", SP_CSS_FONT_STRETCH_ULTRA_CONDENSED}, - {"extra-condensed", SP_CSS_FONT_STRETCH_EXTRA_CONDENSED}, - {"condensed", SP_CSS_FONT_STRETCH_CONDENSED}, - {"semi-condensed", SP_CSS_FONT_STRETCH_SEMI_CONDENSED}, - {"normal", SP_CSS_FONT_STRETCH_NORMAL}, - {"semi-expanded", SP_CSS_FONT_STRETCH_SEMI_EXPANDED}, - {"expanded", SP_CSS_FONT_STRETCH_EXPANDED}, - {"extra-expanded", SP_CSS_FONT_STRETCH_EXTRA_EXPANDED}, - {"ultra-expanded", SP_CSS_FONT_STRETCH_ULTRA_EXPANDED}, - {"narrower", SP_CSS_FONT_STRETCH_NARROWER}, - {"wider", SP_CSS_FONT_STRETCH_WIDER}, - {NULL, -1} -}; - -static SPStyleEnum const enum_text_align[] = { - {"start", SP_CSS_TEXT_ALIGN_START}, - {"end", SP_CSS_TEXT_ALIGN_END}, - {"left", SP_CSS_TEXT_ALIGN_LEFT}, - {"right", SP_CSS_TEXT_ALIGN_RIGHT}, - {"center", SP_CSS_TEXT_ALIGN_CENTER}, - {"justify", SP_CSS_TEXT_ALIGN_JUSTIFY}, - {NULL, -1} -}; - -static SPStyleEnum const enum_text_transform[] = { - {"capitalize", SP_CSS_TEXT_TRANSFORM_CAPITALIZE}, - {"uppercase", SP_CSS_TEXT_TRANSFORM_UPPERCASE}, - {"lowercase", SP_CSS_TEXT_TRANSFORM_LOWERCASE}, - {"none", SP_CSS_TEXT_TRANSFORM_NONE}, - {NULL, -1} -}; - -static SPStyleEnum const enum_text_anchor[] = { - {"start", SP_CSS_TEXT_ANCHOR_START}, - {"middle", SP_CSS_TEXT_ANCHOR_MIDDLE}, - {"end", SP_CSS_TEXT_ANCHOR_END}, - {NULL, -1} -}; - -static SPStyleEnum const enum_direction[] = { - {"ltr", SP_CSS_DIRECTION_LTR}, - {"rtl", SP_CSS_DIRECTION_RTL}, - {NULL, -1} -}; - -static SPStyleEnum const enum_block_progression[] = { - {"tb", SP_CSS_BLOCK_PROGRESSION_TB}, - {"rl", SP_CSS_BLOCK_PROGRESSION_RL}, - {"lr", SP_CSS_BLOCK_PROGRESSION_LR}, - {NULL, -1} -}; - -static SPStyleEnum const enum_writing_mode[] = { - /* Note that using the same enumerator for lr as lr-tb means we write as lr-tb even if the - * input file said lr. We prefer writing lr-tb on the grounds that the spec says the initial - * value is lr-tb rather than lr. - * - * ECMA scripts may be surprised to find tb-rl in DOM if they set the attribute to rl, so - * sharing enumerators for different strings may be a bug (once we support ecma script). - */ - {"lr-tb", SP_CSS_WRITING_MODE_LR_TB}, - {"rl-tb", SP_CSS_WRITING_MODE_RL_TB}, - {"tb-rl", SP_CSS_WRITING_MODE_TB_RL}, - {"lr", SP_CSS_WRITING_MODE_LR_TB}, - {"rl", SP_CSS_WRITING_MODE_RL_TB}, - {"tb", SP_CSS_WRITING_MODE_TB_RL}, - {NULL, -1} -}; - -static SPStyleEnum const enum_baseline_shift[] = { - {"baseline", SP_CSS_BASELINE_SHIFT_BASELINE}, - {"sub", SP_CSS_BASELINE_SHIFT_SUB}, - {"super", SP_CSS_BASELINE_SHIFT_SUPER}, - {NULL, -1} -}; - -static SPStyleEnum const enum_visibility[] = { - {"hidden", SP_CSS_VISIBILITY_HIDDEN}, - {"collapse", SP_CSS_VISIBILITY_COLLAPSE}, - {"visible", SP_CSS_VISIBILITY_VISIBLE}, - {NULL, -1} -}; - -static SPStyleEnum const enum_overflow[] = { - {"visible", SP_CSS_OVERFLOW_VISIBLE}, - {"hidden", SP_CSS_OVERFLOW_HIDDEN}, - {"scroll", SP_CSS_OVERFLOW_SCROLL}, - {"auto", SP_CSS_OVERFLOW_AUTO}, - {NULL, -1} -}; - -// CSS Compositing and Blending Level 1 -static SPStyleEnum const enum_isolation[] = { - {"auto", SP_CSS_ISOLATION_AUTO}, - {"isolate", SP_CSS_ISOLATION_ISOLATE}, - {NULL, -1} -}; - -static SPStyleEnum const enum_blend_mode[] = { - {"normal", SP_CSS_BLEND_NORMAL}, - {"multiply", SP_CSS_BLEND_MULTIPLY}, - {"screen", SP_CSS_BLEND_SCREEN}, - {"darken", SP_CSS_BLEND_DARKEN}, - {"lighten", SP_CSS_BLEND_LIGHTEN}, - {"overlay", SP_CSS_BLEND_OVERLAY}, - {"color-dodge", SP_CSS_BLEND_COLORDODGE}, - {"color-burn", SP_CSS_BLEND_COLORBURN}, - {"hard-light", SP_CSS_BLEND_HARDLIGHT}, - {"soft-light", SP_CSS_BLEND_SOFTLIGHT}, - {"difference", SP_CSS_BLEND_DIFFERENCE}, - {"exclusion", SP_CSS_BLEND_EXCLUSION}, - {"hue", SP_CSS_BLEND_HUE}, - {"saturation", SP_CSS_BLEND_SATURATION}, - {"color", SP_CSS_BLEND_COLOR}, - {"luminosity", SP_CSS_BLEND_LUMINOSITY}, - {NULL, -1} -}; - -static SPStyleEnum const enum_display[] = { - {"none", SP_CSS_DISPLAY_NONE}, - {"inline", SP_CSS_DISPLAY_INLINE}, - {"block", SP_CSS_DISPLAY_BLOCK}, - {"list-item", SP_CSS_DISPLAY_LIST_ITEM}, - {"run-in", SP_CSS_DISPLAY_RUN_IN}, - {"compact", SP_CSS_DISPLAY_COMPACT}, - {"marker", SP_CSS_DISPLAY_MARKER}, - {"table", SP_CSS_DISPLAY_TABLE}, - {"inline-table", SP_CSS_DISPLAY_INLINE_TABLE}, - {"table-row-group", SP_CSS_DISPLAY_TABLE_ROW_GROUP}, - {"table-header-group", SP_CSS_DISPLAY_TABLE_HEADER_GROUP}, - {"table-footer-group", SP_CSS_DISPLAY_TABLE_FOOTER_GROUP}, - {"table-row", SP_CSS_DISPLAY_TABLE_ROW}, - {"table-column-group", SP_CSS_DISPLAY_TABLE_COLUMN_GROUP}, - {"table-column", SP_CSS_DISPLAY_TABLE_COLUMN}, - {"table-cell", SP_CSS_DISPLAY_TABLE_CELL}, - {"table-caption", SP_CSS_DISPLAY_TABLE_CAPTION}, - {NULL, -1} -}; - -static SPStyleEnum const enum_shape_rendering[] = { - {"auto", SP_CSS_SHAPE_RENDERING_AUTO}, - {"optimizeSpeed", SP_CSS_SHAPE_RENDERING_OPTIMIZESPEED}, - {"crispEdges", SP_CSS_SHAPE_RENDERING_CRISPEDGES}, - {"geometricPrecision", SP_CSS_SHAPE_RENDERING_GEOMETRICPRECISION}, - {NULL, -1} -}; - -static SPStyleEnum const enum_color_rendering[] = { - {"auto", SP_CSS_COLOR_RENDERING_AUTO}, - {"optimizeSpeed", SP_CSS_COLOR_RENDERING_OPTIMIZESPEED}, - {"optimizeQuality", SP_CSS_COLOR_RENDERING_OPTIMIZEQUALITY}, - {NULL, -1} -}; - -static SPStyleEnum const enum_image_rendering[] = { - {"auto", SP_CSS_IMAGE_RENDERING_AUTO}, - {"optimizeSpeed", SP_CSS_IMAGE_RENDERING_OPTIMIZESPEED}, - {"optimizeQuality", SP_CSS_IMAGE_RENDERING_OPTIMIZEQUALITY}, - {"-inkscape-crisp-edges", SP_CSS_IMAGE_RENDERING_CRISPEDGES}, - {"-inkscape-pixelated", SP_CSS_IMAGE_RENDERING_PIXELATED}, - {NULL, -1} -}; - -static SPStyleEnum const enum_text_rendering[] = { - {"auto", SP_CSS_TEXT_RENDERING_AUTO}, - {"optimizeSpeed", SP_CSS_TEXT_RENDERING_OPTIMIZESPEED}, - {"optimizeLegibility", SP_CSS_TEXT_RENDERING_OPTIMIZELEGIBILITY}, - {"geometricPrecision", SP_CSS_TEXT_RENDERING_GEOMETRICPRECISION}, - {NULL, -1} -}; - -static SPStyleEnum const enum_enable_background[] = { - {"accumulate", SP_CSS_BACKGROUND_ACCUMULATE}, - {"new", SP_CSS_BACKGROUND_NEW}, - {NULL, -1} -}; - -static SPStyleEnum const enum_clip_rule[] = { - {"nonzero", SP_WIND_RULE_NONZERO}, - {"evenodd", SP_WIND_RULE_EVENODD}, - {NULL, -1} -}; - -static SPStyleEnum const enum_color_interpolation[] = { - {"auto", SP_CSS_COLOR_INTERPOLATION_AUTO}, - {"sRGB", SP_CSS_COLOR_INTERPOLATION_SRGB}, - {"linearRGB", SP_CSS_COLOR_INTERPOLATION_LINEARRGB}, - {NULL, -1} -}; +void sp_style_filter_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style); +void sp_style_fill_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style); +void sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style); + +static void sp_style_object_release(SPObject *object, SPStyle *style); +static CRSelEng *sp_repr_sel_eng(); + + +//SPPropMap SPStyle::_propmap; + +// C++11 allows one constructor to call another... might be useful. The original C code +// had separate calls to create SPStyle, one with only SPDocument and the other with only +// SPObject as parameters. +SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : + + // Unimplemented SVG 1.1: alignment-baseline, clip, clip-path, color-profile, cursor, + // dominant-baseline, flood-color, flood-opacity, font-size-adjust, + // glyph-orientation-horizontal, glyph-orientation-vertical, kerning, lighting-color, + // pointer-events, stop-color, stop-opacity, unicode-bidi + + // For enums: property( name, enumeration, default value , inherits = true ); + // For scale24: property( name, default value = 0, inherits = true ); + + // 'font', 'font-size', and 'font-family' must come first as other properties depend on them + // for calculated values (through 'em' and 'ex'). ('ex' is currently not read.) + // The following properties can depend on 'em' and 'ex': + // baseline-shift, kerning, letter-spacing, stroke-dash-offset, stroke-width, word-spacing, + // Non-SVG 1.1: text-indent, line-spacing + + // Hidden in SPIFontStyle: (to be refactored) + // font-family + // font-specification + + // Font related properties and 'font' shorthand + font_style( "font-style", enum_font_style, SP_CSS_FONT_STYLE_NORMAL ), + font_variant( "font-variant", enum_font_variant, SP_CSS_FONT_VARIANT_NORMAL ), + font_weight( "font-weight", enum_font_weight, SP_CSS_FONT_WEIGHT_NORMAL, SP_CSS_FONT_WEIGHT_400 ), + font_stretch( "font-stretch", enum_font_stretch, SP_CSS_FONT_STRETCH_NORMAL ), + font_size(), + line_height( "line-height", 1.0 ), // SPILengthOrNormal + font(), // SPIFont + + // Text related properties + text_indent( "text-indent", 0.0 ), // SPILength + text_align( "text-align", enum_text_align, SP_CSS_TEXT_ALIGN_START ), + text_decoration(), + text_decoration_line(), + text_decoration_style(), + text_decoration_color( "text-decoration-color" ), // SPIColor + + letter_spacing( "letter-spacing", 0.0 ), // SPILengthOrNormal + word_spacing( "word-spacing", 0.0 ), // SPILengthOrNormal + text_transform( "text-transform", enum_text_transform, SP_CSS_TEXT_TRANSFORM_NONE ), + + direction( "direction", enum_direction, SP_CSS_DIRECTION_LTR ), + block_progression("block-progression", enum_block_progression, SP_CSS_BLOCK_PROGRESSION_TB), + writing_mode( "writing-mode", enum_writing_mode, SP_CSS_WRITING_MODE_LR_TB ), + baseline_shift(), + text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), + + // General visual properties + clip_rule( "clip-rule", enum_clip_rule, SP_WIND_RULE_NONZERO ), + display( "display", enum_display, SP_CSS_DISPLAY_INLINE, false ), + overflow( "overflow", enum_overflow, SP_CSS_OVERFLOW_VISIBLE, false ), + visibility( "visibility", enum_visibility, SP_CSS_VISIBILITY_VISIBLE ), + opacity( "opacity", SP_SCALE24_MAX, false ), + + isolation( "isolation", enum_isolation, SP_CSS_ISOLATION_AUTO ), + blend_mode( "blend_mode", enum_blend_mode, SP_CSS_BLEND_NORMAL ), + + paint_order(), // SPIPaintOrder + + // Color properties + color( "color" ), // SPIColor + color_interpolation( "color-interpolation", enum_color_interpolation, SP_CSS_COLOR_INTERPOLATION_SRGB), + color_interpolation_filters("color-interpolation-filters", enum_color_interpolation, SP_CSS_COLOR_INTERPOLATION_LINEARRGB), + + // Fill properties + fill( "fill" ), // SPIPaint + fill_opacity( "fill-opacity", SP_SCALE24_MAX ), + fill_rule( "fill-rule", enum_fill_rule, SP_WIND_RULE_NONZERO ), + + // Stroke properites + stroke( "stroke" ), // SPIPaint + stroke_width( "stroke-width", 1.0 ), // SPILength + stroke_linecap( "stroke-linecap", enum_stroke_linecap, SP_STROKE_LINECAP_BUTT ), + stroke_linejoin( "stroke-linejoin", enum_stroke_linejoin, SP_STROKE_LINEJOIN_MITER ), + stroke_miterlimit("stroke-miterlimit", 4 ), // SPIFloat (only use of float!) + stroke_dasharray(), // SPIDashArray + stroke_dashoffset("stroke-dashoffset", 0.0 ), // SPILength for now + + stroke_opacity( "stroke-opacity", SP_SCALE24_MAX), + +// marker({ "marker", "marker-start", "marker-mid", "marker-end" }), C++11 + + // Filter properties + filter(), + filter_blend_mode("filter-blend-mode", enum_blend_mode, SP_CSS_BLEND_NORMAL), + filter_gaussianBlur_deviation( "filter-gaussianBlur-deviation", 0.0 ), // SPILength + enable_background("enable-background", enum_enable_background, SP_CSS_BACKGROUND_ACCUMULATE, false), + + // Rendering hint properties + color_rendering( "color-rendering", enum_color_rendering, SP_CSS_COLOR_RENDERING_AUTO), + image_rendering( "image-rendering", enum_image_rendering, SP_CSS_IMAGE_RENDERING_AUTO), + shape_rendering( "shape-rendering", enum_shape_rendering, SP_CSS_SHAPE_RENDERING_AUTO), + text_rendering( "text-rendering", enum_text_rendering, SP_CSS_TEXT_RENDERING_AUTO ) + +{ + // std::cout << "SPStyle::SPStyle( SPDocument ): Entrance: (" << _count << ")" << std::endl; + // std::cout << " Document: " << (document_in?"present":"null") << std::endl; + // std::cout << " Object: " + // << (object_in?(object_in->getId()?object_in->getId():"id null"):"object null") << std::endl; + + // static bool first = true; + // if( first ) { + // std::cout << "Size of SPStyle: " << sizeof(SPStyle) << std::endl; + // std::cout << " SPIBase: " << sizeof(SPIBase) << std::endl; + // std::cout << " SPIFloat: " << sizeof(SPIFloat) << std::endl; + // std::cout << " SPIScale24: " << sizeof(SPIScale24) << std::endl; + // std::cout << " SPILength: " << sizeof(SPILength) << std::endl; + // std::cout << " SPILengthOrNormal: " << sizeof(SPILengthOrNormal) << std::endl; + // std::cout << " SPIColor: " << sizeof(SPIColor) << std::endl; + // std::cout << " SPIPaint: " << sizeof(SPIPaint) << std::endl; + // std::cout << " SPITextDecorationLine" << sizeof(SPITextDecorationLine) << std::endl; + // std::cout << " Glib::ustring:" << sizeof(Glib::ustring) << std::endl; + // std::cout << " SPColor: " << sizeof(SPColor) << std::endl; + // first = false; + // } + + ++_count; // Poor man's memory leak detector + + _refcount = 1; + + cloned = false; + + object = object_in; + if( object ) { + g_assert( SP_IS_OBJECT(object) ); + document = object->document; + release_connection = + object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_object_release), this)); + + cloned = object->cloned; -/** - * Release callback. - */ -static void -sp_style_object_release(SPObject *object, SPStyle *style) -{ - (void)object; // TODO - style->object = NULL; -} + } else { + document = document_in; + } + + new (&release_connection) sigc::connection(); + new (&filter_modified_connection) sigc::connection(); + new (&fill_ps_modified_connection) sigc::connection(); + new (&stroke_ps_modified_connection) sigc::connection(); + + + // FIX-ME Remove SPFontStyle + text = new SPFontStyle(); + text->font_family = SPIString( "font-family" ); + text->font_specification = SPIString( "-inkscape-font-specification" ); + // 'font' shorthand requires access to included properties. + font.setStylePointer( this ); + + // Properties that depend on 'font-size' for calculating lengths. + baseline_shift.setStylePointer( this ); + text_indent.setStylePointer( this ); + line_height.setStylePointer( this ); + letter_spacing.setStylePointer( this ); + word_spacing.setStylePointer( this ); + stroke_width.setStylePointer( this ); + stroke_dashoffset.setStylePointer( this ); + + // Properties that depend on 'color' + text_decoration_color.setStylePointer( this ); + fill.setStylePointer( this ); + stroke.setStylePointer( this ); + // color.setStylePointer( this ); // Doen't need reference to self -/** - * Emit style modified signal on style's object if the filter changed. - */ -static void -sp_style_filter_ref_modified(SPObject *obj, guint flags, SPStyle *style) -{ - (void)flags; // TODO - SPFilter *filter=static_cast(obj); - if (style->getFilter() == filter) - { - if (style->object) { - style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - } - } -} + // 'text_decoration' shorthand requires access to included properties. + text_decoration.setStylePointer( this ); + + // SPIPaint, SPIFilter needs access to 'this' (SPStyle) + // for setting up signals... 'fill', 'stroke' already done + filter.setStylePointer( this ); + + marker[SP_MARKER_LOC] = SPIString( "marker" ); + marker[SP_MARKER_LOC_START] = SPIString( "marker-start" ); + marker[SP_MARKER_LOC_MID] = SPIString( "marker-mid" ); + marker[SP_MARKER_LOC_END] = SPIString( "marker-end" ); + + + // This might be too resource hungary... but for now it possible to loop over properties + + // 'color' must be before 'fill', 'stroke', 'text-decoration-color', ... + _properties.push_back( &color ); + + // 'font-size'/'font' must be before properties that need to know em, ex size (SPILength, + // SPILenghtOrNormal) + _properties.push_back( &font_style ); + _properties.push_back( &font_variant ); + _properties.push_back( &font_weight ); + _properties.push_back( &font_stretch ); + _properties.push_back( &font_size ); + _properties.push_back( &line_height ); + _properties.push_back( &font ); + + _properties.push_back( &text_indent ); + _properties.push_back( &text_align ); + + _properties.push_back( &text_decoration ); + _properties.push_back( &text_decoration_line ); + _properties.push_back( &text_decoration_style ); + _properties.push_back( &text_decoration_color ); + + _properties.push_back( &letter_spacing ); + _properties.push_back( &word_spacing ); + _properties.push_back( &text_transform ); + + _properties.push_back( &direction ); + _properties.push_back( &block_progression ); + _properties.push_back( &writing_mode ); + _properties.push_back( &baseline_shift ); + _properties.push_back( &text_anchor ); + + _properties.push_back( &clip_rule ); + _properties.push_back( &display ); + _properties.push_back( &overflow ); + _properties.push_back( &visibility ); + _properties.push_back( &opacity ); + + _properties.push_back( &isolation ); + _properties.push_back( &blend_mode ); + + _properties.push_back( &color_interpolation ); + _properties.push_back( &color_interpolation_filters ); + + _properties.push_back( &fill ); + _properties.push_back( &fill_opacity ); + _properties.push_back( &fill_rule ); + + _properties.push_back( &stroke ); + _properties.push_back( &stroke_width ); + _properties.push_back( &stroke_linecap ); + _properties.push_back( &stroke_linejoin ); + _properties.push_back( &stroke_miterlimit ); + _properties.push_back( &stroke_dasharray ); + _properties.push_back( &stroke_dashoffset ); + _properties.push_back( &stroke_opacity ); + + _properties.push_back( &marker[SP_MARKER_LOC] ); + _properties.push_back( &marker[SP_MARKER_LOC_START] ); + _properties.push_back( &marker[SP_MARKER_LOC_MID] ); + _properties.push_back( &marker[SP_MARKER_LOC_END] ); + + _properties.push_back( &paint_order ); + + _properties.push_back( &filter ); + _properties.push_back( &filter_blend_mode ); + _properties.push_back( &filter_gaussianBlur_deviation ); + + _properties.push_back( &color_rendering ); + _properties.push_back( &image_rendering ); + _properties.push_back( &shape_rendering ); + _properties.push_back( &text_rendering ); + + _properties.push_back( &enable_background ); -/** - * Gets called when the filter is (re)attached to the style - */ -static void -sp_style_filter_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style) -{ - if (old_ref) { - style->filter_modified_connection.disconnect(); - } - if ( SP_IS_FILTER(ref)) - { - style->filter_modified_connection = - ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_filter_ref_modified), style)); - } + _properties.push_back( &text->font_family ); // Must be first as other values depend on it ('ex') + _properties.push_back( &text->font_specification ); - sp_style_filter_ref_modified(ref, 0, style); -} + // MAP ------------------------------------------- -/** - * Emit style modified signal on style's object if server is style's fill - * or stroke paint server. - */ -static void -sp_style_paint_server_ref_modified(SPObject *obj, guint flags, SPStyle *style) -{ - (void)flags; // TODO - SPPaintServer *server = static_cast(obj); + // if( _propmap.size() == 0 ) { - if ((style->fill.isPaintserver()) - && style->getFillPaintServer() == server) - { - if (style->object) { - /** \todo - * fixme: I do not know, whether it is optimal - we are - * forcing reread of everything (Lauris) - */ - /** \todo - * fixme: We have to use object_modified flag, because parent - * flag is only available downstreams. - */ - style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - } - } else if ((style->stroke.isPaintserver()) - && style->getStrokePaintServer() == server) - { - if (style->object) { - /// \todo fixme: - style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - } - } else if (server) { - g_assert_not_reached(); - } -} + // // 'color' must be before 'fill', 'stroke', 'text-decoration-color', ... + // _propmap.insert( std::make_pair( color.name, reinterpret_cast(&SPStyle::color ) ) ); -/** - * Gets called when the paintserver is (re)attached to the style - */ -static void -sp_style_fill_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style) -{ - if (old_ref) { - style->fill_ps_modified_connection.disconnect(); - } - if (SP_IS_PAINT_SERVER(ref)) { - style->fill_ps_modified_connection = - ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_paint_server_ref_modified), style)); - } + // // 'font-size' must be before properties that need to know em, ex size (SPILength, SPILenghtOrNormal) + // _propmap.insert( std::make_pair( font.name, reinterpret_cast(&SPStyle::font ) ) ); + // _propmap.insert( std::make_pair( font_style.name, reinterpret_cast(&SPStyle::font_style ) ) ); + // _propmap.insert( std::make_pair( font_variant.name, reinterpret_cast(&SPStyle::font_variant ) ) ); + // _propmap.insert( std::make_pair( font_weight.name, reinterpret_cast(&SPStyle::font_weight ) ) ); + // _propmap.insert( std::make_pair( font_stretch.name, reinterpret_cast(&SPStyle::font_stretch ) ) ); + // _propmap.insert( std::make_pair( font_size.name, reinterpret_cast(&SPStyle::font_size ) ) ); + // _propmap.insert( std::make_pair( line_height.name, reinterpret_cast(&SPStyle::line_height ) ) ); - sp_style_paint_server_ref_modified(ref, 0, style); -} + // _propmap.insert( std::make_pair( text_indent.name, reinterpret_cast(&SPStyle::text_indent ) ) ); + // _propmap.insert( std::make_pair( text_align.name, reinterpret_cast(&SPStyle::text_align ) ) ); -/** - * Gets called when the paintserver is (re)attached to the style - */ -static void -sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style) -{ - if (old_ref) { - style->stroke_ps_modified_connection.disconnect(); - } - if (SP_IS_PAINT_SERVER(ref)) { - style->stroke_ps_modified_connection = - ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_paint_server_ref_modified), style)); - } + // _propmap.insert( std::make_pair( text_decoration.name, reinterpret_cast(&SPStyle::text_decoration ) ) ); + // _propmap.insert( std::make_pair( text_decoration_line.name, reinterpret_cast(&SPStyle::text_decoration_line ) ) ); + // _propmap.insert( std::make_pair( text_decoration_style.name, reinterpret_cast(&SPStyle::text_decoration_style ) ) ); + // _propmap.insert( std::make_pair( text_decoration_color.name, reinterpret_cast(&SPStyle::text_decoration_color ) ) ); - sp_style_paint_server_ref_modified(ref, 0, style); -} + // _propmap.insert( std::make_pair( letter_spacing.name, reinterpret_cast(&SPStyle::letter_spacing ) ) ); + // _propmap.insert( std::make_pair( word_spacing.name, reinterpret_cast(&SPStyle::word_spacing ) ) ); + // _propmap.insert( std::make_pair( text_transform.name, reinterpret_cast(&SPStyle::text_transform ) ) ); -/** - * Returns a new SPStyle object with settings as per sp_style_clear(). - */ -SPStyle * -sp_style_new(SPDocument *document) -{ - SPStyle *const style = g_new0(SPStyle, 1); + // _propmap.insert( std::make_pair( direction.name, reinterpret_cast(&SPStyle::direction ) ) ); + // _propmap.insert( std::make_pair( block_progression.name, reinterpret_cast(&SPStyle::block_progression ) ) ); + // _propmap.insert( std::make_pair( writing_mode.name, reinterpret_cast(&SPStyle::writing_mode ) ) ); + // _propmap.insert( std::make_pair( baseline_shift.name, reinterpret_cast(&SPStyle::baseline_shift ) ) ); + // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast(&SPStyle::text_anchor ) ) ); - style->refcount = 1; - style->object = NULL; - style->document = document; - style->text = sp_text_style_new(); - style->text_private = TRUE; + // _propmap.insert( std::make_pair( clip_rule.name, reinterpret_cast(&SPStyle::clip_rule ) ) ); + // _propmap.insert( std::make_pair( display.name, reinterpret_cast(&SPStyle::display ) ) ); + // _propmap.insert( std::make_pair( overflow.name, reinterpret_cast(&SPStyle::overflow ) ) ); + // _propmap.insert( std::make_pair( visibility.name, reinterpret_cast(&SPStyle::visibility ) ) ); + // _propmap.insert( std::make_pair( opacity.name, reinterpret_cast(&SPStyle::opacity ) ) ); - sp_style_clear(style); + // _propmap.insert( std::make_pair( isolation.name, reinterpret_cast(&SPStyle::isolation ) ) ); + // _propmap.insert( std::make_pair( blend_mode.name, reinterpret_cast(&SPStyle::blend_mode ) ) ); - style->cloned = false; + // _propmap.insert( std::make_pair( color_interpolation.name, reinterpret_cast(&SPStyle::color_interpolation ) ) ); + // _propmap.insert( std::make_pair( color_interpolation_filters.name, reinterpret_cast(&SPStyle::color_interpolation_filters ) ) ); - new (&style->release_connection) sigc::connection(); - new (&style->filter_modified_connection) sigc::connection(); - new (&style->fill_ps_modified_connection) sigc::connection(); - new (&style->stroke_ps_modified_connection) sigc::connection(); + // _propmap.insert( std::make_pair( fill.name, reinterpret_cast(&SPStyle::fill ) ) ); + // _propmap.insert( std::make_pair( fill_opacity.name, reinterpret_cast(&SPStyle::fill_opacity ) ) ); + // _propmap.insert( std::make_pair( fill_rule.name, reinterpret_cast(&SPStyle::fill_rule ) ) ); - return style; + // _propmap.insert( std::make_pair( stroke.name, reinterpret_cast(&SPStyle::stroke ) ) ); + // _propmap.insert( std::make_pair( stroke_width.name, reinterpret_cast(&SPStyle::stroke_width ) ) ); + // _propmap.insert( std::make_pair( stroke_linecap.name, reinterpret_cast(&SPStyle::stroke_linecap ) ) ); + // _propmap.insert( std::make_pair( stroke_linejoin.name, reinterpret_cast(&SPStyle::stroke_linejoin ) ) ); + // _propmap.insert( std::make_pair( stroke_miterlimit.name, reinterpret_cast(&SPStyle::stroke_miterlimit ) ) ); + // _propmap.insert( std::make_pair( stroke_dasharray.name, reinterpret_cast(&SPStyle::stroke_dasharray ) ) ); + // _propmap.insert( std::make_pair( stroke_dashoffset.name, reinterpret_cast(&SPStyle::stroke_dashoffset ) ) ); + // _propmap.insert( std::make_pair( stroke_opacity.name, reinterpret_cast(&SPStyle::stroke_opacity ) ) ); + + // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC] ) ) ); + // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC_START].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC_START] ) ) ); + // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC_MID].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC_MID] ) ) ); + // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC_END].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC_END] ) ) ); + + // _propmap.insert( std::make_pair( paint_order.name, reinterpret_cast(&SPStyle::paint_order ) ) ); + + // _propmap.insert( std::make_pair( filter.name, reinterpret_cast(&SPStyle::filter ) ) ); + // _propmap.insert( std::make_pair( filter_blend_mode.name, reinterpret_cast(&SPStyle::filter_blend_mode ) ) ); + // _propmap.insert( std::make_pair( filter_gaussianBlur_deviation.name, reinterpret_cast(&SPStyle::filter_gaussianBlur_deviation ) ) ); + + // _propmap.insert( std::make_pair( color_rendering.name, reinterpret_cast(&SPStyle::color_rendering ) ) ); + // _propmap.insert( std::make_pair( image_rendering.name, reinterpret_cast(&SPStyle::image_rendering ) ) ); + // _propmap.insert( std::make_pair( shape_rendering.name, reinterpret_cast(&SPStyle::shape_rendering ) ) ); + // _propmap.insert( std::make_pair( text_rendering.name, reinterpret_cast(&SPStyle::text_rendering ) ) ); + + // _propmap.insert( std::make_pair( enable_background.name, reinterpret_cast(&SPStyle::enable_background ) ) ); + + // } } +SPStyle::~SPStyle() { -/** - * Creates a new SPStyle object, and attaches it to the specified SPObject. - */ -SPStyle * -sp_style_new_from_object(SPObject *object) -{ - g_return_val_if_fail(object != NULL, NULL); - g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + // std::cout << "SPStyle::~SPStyle" << std::endl; + --_count; // Poor man's memory leak detector. - SPStyle *style = sp_style_new( object->document ); - style->object = object; - style->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_object_release), style)); + // Remove connections + release_connection.disconnect(); + release_connection.~connection(); - if (object->cloned) { - style->cloned = true; + // The following shoud be moved into SPIPaint and SPIFilter + if (fill.value.href) { + fill_ps_modified_connection.disconnect(); } - return style; -} + if (stroke.value.href) { + stroke_ps_modified_connection.disconnect(); + } + if (filter.href) { + filter_modified_connection.disconnect(); + } -/** - * Increase refcount of style. - */ -SPStyle * -sp_style_ref(SPStyle *style) -{ - g_return_val_if_fail(style != NULL, NULL); - g_return_val_if_fail(style->refcount > 0, NULL); + filter_modified_connection.~connection(); + fill_ps_modified_connection.~connection(); + stroke_ps_modified_connection.~connection(); - style->refcount += 1; + _properties.clear(); + //_propmap.clear(); + delete text; - return style; + // std::cout << "SPStyle::~SPstyle(): Exit\n" << std::endl; } +// Used in SPStyle::clear() +void clear_property( SPIBase* p ) { + p->clear(); +} -/** - * Decrease refcount of style with possible destruction. - */ -SPStyle * -sp_style_unref(SPStyle *style) -{ - g_return_val_if_fail(style != NULL, NULL); - g_return_val_if_fail(style->refcount > 0, NULL); - - style->refcount -= 1; - - if (style->refcount < 1) { - style->release_connection.disconnect(); - style->release_connection.~connection(); - if (style->text) sp_text_style_unref(style->text); - - if (style->fill.value.href) { - style->fill_ps_modified_connection.disconnect(); - delete style->fill.value.href; - style->fill.value.href = NULL; - } - if (style->stroke.value.href) { - style->stroke_ps_modified_connection.disconnect(); - delete style->stroke.value.href; - style->stroke.value.href = NULL; - } - if (style->filter.href) { - style->filter_modified_connection.disconnect(); - delete style->filter.href; - style->filter.href = NULL; - } - - style->filter_modified_connection.~connection(); - style->fill_ps_modified_connection.~connection(); - style->stroke_ps_modified_connection.~connection(); - - style->fill.clear(); - style->stroke.clear(); - sp_style_filter_clear(style); - - style->stroke_dasharray.values.clear(); - - for (unsigned i = SP_MARKER_LOC; i < SP_MARKER_LOC_QTY; i++) { - if (style->marker[i].value) { - g_free(style->marker[i].value); - style->marker[i].value = NULL; - } - } - g_free(style); - return NULL; +// Matches void sp_style_clear(); +void +SPStyle::clear() { + + for_each( _properties.begin(), _properties.end(), clear_property ); + // for(SPPropMap::iterator i = _propmap.begin(); i != _propmap.end(); ++i ) { + // (this->*(i->second)).clear(); + // } + + // Release connection to object, created in sp_style_new_from_object() + release_connection.disconnect(); + + // href->detach() called in fill->clear()... + fill_ps_modified_connection.disconnect(); + if (fill.value.href) { + delete fill.value.href; + fill.value.href = NULL; } - return style; + stroke_ps_modified_connection.disconnect(); + if (stroke.value.href) { + delete stroke.value.href; + stroke.value.href = NULL; + } + filter_modified_connection.disconnect(); + if (filter.href) { + delete filter.href; + filter.href = NULL; + } + + if (document) { + filter.href = new SPFilterReference(document); + filter.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), this)); + + fill.value.href = new SPPaintServerReference(document); + fill.value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_fill_paint_server_ref_changed), this)); + + stroke.value.href = new SPPaintServerReference(document); + stroke.value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_stroke_paint_server_ref_changed), this)); + } + + cloned = false; + } -/** - * Reads the various style parameters for an object from repr. - */ -static void -sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr) -{ - g_assert(style != NULL); +// Matches void sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr) +void +SPStyle::read( SPObject *object, Inkscape::XML::Node *repr ) { + + // std::cout << "SPstyle::read( SPObject, Inkscape::XML::Node ): Entrance: " + // << (object?(object->getId()?object->getId():"id null"):"object null") << " " + // << (repr?(repr->name()?repr->name():"no name"):"repr null") + // << std::endl; g_assert(repr != NULL); g_assert(!object || (object->getRepr() == repr)); - sp_style_clear(style); + // // Uncomment to verify that we don't need to call clear. + // std::cout << " Creating temp style for testing" << std::endl; + // SPStyle *temp = new SPStyle(); + // if( !(*temp == *this ) ) std::cout << "SPStyle::read: Need to clear" << std::endl; + // delete temp; + + clear(); // FIXME, If this isn't here, gradient editing stops working. Why? if (object && object->cloned) { - style->cloned = true; + cloned = true; } /* 1. Style attribute */ + // std::cout << " MERGING STYLE ATTRIBUTE" << std::endl; gchar const *val = repr->attribute("style"); - if (val != NULL && *val) { - sp_style_merge_from_style_string(style, val); + if( val != NULL && *val ) { + _mergeString( val ); } + /* 2 Style sheet */ + // std::cout << " MERGING OBJECT STYLESHEET" << std::endl; if (object) { - sp_style_merge_from_object_stylesheet(style, object); + _mergeObjectStylesheet( object ); } else { - /** \todo No stylesheet information. Find out under what circumstances - * this occurs, and handle accordingly. (If we really wanted to, we - * could probably get stylesheets by going through repr->doc.) - */ - } - - /* 2. Presentation attributes */ - /* Attributes are only read in if not already set in a style sheet or style attribute above. */ - - /* CSS2 */ - SPS_READ_PENUM_IF_UNSET(&style->visibility, repr, "visibility", enum_visibility, true); - SPS_READ_PENUM_IF_UNSET(&style->display, repr, "display", enum_display, true); - SPS_READ_PENUM_IF_UNSET(&style->overflow, repr, "overflow", enum_overflow, true); - - /* CSS Compositing and Blending Level 1 */ - SPS_READ_PENUM_IF_UNSET(&style->isolation, repr, "isolation", enum_isolation, true); - SPS_READ_PENUM_IF_UNSET(&style->blend_mode, repr, "mix_blend_mode", enum_blend_mode, true); - - /* Font */ - SPS_READ_PFONTSIZE_IF_UNSET(&style->font_size, repr, "font-size"); - SPS_READ_PENUM_IF_UNSET(&style->font_style, repr, "font-style", enum_font_style, true); - SPS_READ_PENUM_IF_UNSET(&style->font_variant, repr, "font-variant", enum_font_variant, true); - SPS_READ_PENUM_IF_UNSET(&style->font_weight, repr, "font-weight", enum_font_weight, true); - SPS_READ_PENUM_IF_UNSET(&style->font_stretch, repr, "font-stretch", enum_font_stretch, true); - /* Text (css2 chapter 16) */ - SPS_READ_PLENGTH_IF_UNSET(&style->text_indent, repr, "text-indent"); - SPS_READ_PENUM_IF_UNSET(&style->text_align, repr, "text-align", enum_text_align, true); - if (!style->text_decoration_line.set) { - // assume it uses either text-decoration or text-decoration-line, but not both - if ((val = repr->attribute("text-decoration")) || (val = repr->attribute("text-decoration-line"))) { - sp_style_read_itextdecoration(&style->text_decoration_line, &style->text_decoration_style, &style->text_decoration_color, val); - } - } - if (!style->line_height.set) { - val = repr->attribute("line-height"); - if (val) { - sp_style_read_ilengthornormal(&style->line_height, val); - } - } - if (!style->letter_spacing.set) { - val = repr->attribute("letter-spacing"); - if (val) { - sp_style_read_ilengthornormal(&style->letter_spacing, val); - } - } - if (!style->word_spacing.set) { - val = repr->attribute("word-spacing"); - if (val) { - sp_style_read_ilengthornormal(&style->word_spacing, val); - } - } - SPS_READ_PENUM_IF_UNSET(&style->text_transform, repr, "text-transform", enum_text_transform, true); - SPS_READ_PENUM_IF_UNSET(&style->direction, repr, "direction", enum_direction, true); - SPS_READ_PENUM_IF_UNSET(&style->block_progression, repr, "block_progression", enum_block_progression, true); - - /* SVG */ - SPS_READ_PENUM_IF_UNSET(&style->writing_mode, repr, "writing-mode", - enum_writing_mode, true); - SPS_READ_PENUM_IF_UNSET(&style->text_anchor, repr, "text-anchor", - enum_text_anchor, true); - SPS_READ_PBASELINE_SHIFT_IF_UNSET(&style->baseline_shift, repr, "baseline-shift"); - - /* opacity */ - if (!style->opacity.set) { - val = repr->attribute("opacity"); - if (val) { - sp_style_read_iscale24(&style->opacity, val); - } - } - /* color */ - if (!style->color.set) { - val = repr->attribute("color"); - if (val) { - sp_style_read_icolor(&style->color, val, style, ( object - ? object->document - : NULL )); - } - } - /* color interpolation */ - SPS_READ_PENUM_IF_UNSET(&style->color_interpolation, repr, "color-interpolation", enum_color_interpolation, true); - /* color interpolation filters*/ - SPS_READ_PENUM_IF_UNSET(&style->color_interpolation_filters, repr, "color-interpolation-filters", enum_color_interpolation, true); - /* fill */ - if (!style->fill.set) { - val = repr->attribute("fill"); - if (val) { - style->fill.read( val, *style, (object) ? object->document : NULL ); - } - } - /* fill-opacity */ - if (!style->fill_opacity.set) { - val = repr->attribute("fill-opacity"); - if (val) { - sp_style_read_iscale24(&style->fill_opacity, val); - } - } - /* fill-rule */ - SPS_READ_PENUM_IF_UNSET(&style->fill_rule, repr, "fill-rule", enum_fill_rule, true); - /* stroke */ - if (!style->stroke.set) { - val = repr->attribute("stroke"); - if (val) { - style->stroke.read( val, *style, (object) ? object->document : NULL ); - } - } - SPS_READ_PLENGTH_IF_UNSET(&style->stroke_width, repr, "stroke-width"); - SPS_READ_PENUM_IF_UNSET(&style->stroke_linecap, repr, "stroke-linecap", enum_stroke_linecap, true); - SPS_READ_PENUM_IF_UNSET(&style->stroke_linejoin, repr, "stroke-linejoin", enum_stroke_linejoin, true); - SPS_READ_PFLOAT_IF_UNSET(&style->stroke_miterlimit, repr, "stroke-miterlimit"); - - /* markers */ - if (!style->marker[SP_MARKER_LOC].set) { - val = repr->attribute("marker"); - if (val) { - sp_style_read_istring(&style->marker[SP_MARKER_LOC], val); - } - } - if (!style->marker[SP_MARKER_LOC_START].set) { - val = repr->attribute("marker-start"); - if (val) { - sp_style_read_istring(&style->marker[SP_MARKER_LOC_START], val); - } - } - if (!style->marker[SP_MARKER_LOC_MID].set) { - val = repr->attribute("marker-mid"); - if (val) { - sp_style_read_istring(&style->marker[SP_MARKER_LOC_MID], val); - } - } - if (!style->marker[SP_MARKER_LOC_END].set) { - val = repr->attribute("marker-end"); - if (val) { - sp_style_read_istring(&style->marker[SP_MARKER_LOC_END], val); - } - } - - /* stroke-opacity */ - if (!style->stroke_opacity.set) { - val = repr->attribute("stroke-opacity"); - if (val) { - sp_style_read_iscale24(&style->stroke_opacity, val); - } - } - if (!style->stroke_dasharray.set) { - val = repr->attribute("stroke-dasharray"); - if (val) { - sp_style_read_dash(style, val); - } - } - SPS_READ_PLENGTH_IF_UNSET(&style->stroke_width, repr, "stroke-dashoffset"); - - /* paint-order */ - if (!style->paint_order.set) { - val = repr->attribute("paint-order"); - if (val) { - sp_style_read_ipaintorder(&style->paint_order, val); - } else { - style->paint_order.layer[0] = SP_CSS_PAINT_ORDER_NORMAL; - } - } - - /* -inkscape-font-specification */ - if (!style->text_private || !style->text->font_specification.set) { - val = repr->attribute("-inkscape-font-specification"); - if (val) { - if (!style->text_private) sp_style_privatize_text(style); - gchar *val_unquoted = attribute_unquote(val); - sp_style_read_istring(&style->text->font_specification, val_unquoted); - if (val_unquoted) g_free (val_unquoted); - } - } - - /* font-family */ - if (!style->text_private || !style->text->font_family.set) { - val = repr->attribute("font-family"); - if (val) { - if (!style->text_private) sp_style_privatize_text(style); - gchar *val_unquoted = attribute_unquote(val); - sp_style_read_istring(&style->text->font_family, val_unquoted); - if (val_unquoted) g_free (val_unquoted); - } + // std::cerr << "SPStyle::read: No object! Can not read style sheet" << std::endl; } - /* filter effects */ - if (!style->filter.set) { - val = repr->attribute("filter"); - if (val) { - sp_style_read_ifilter(val, style, (object) ? object->document : NULL); - } + /* 3 Presentation attributes */ + // std::cout << " MERGING PRESENTATION ATTRIBUTES" << std::endl; + for(std::vector::size_type i = 0; i != _properties.size(); ++i) { + _properties[i]->readAttribute( repr ); } - SPS_READ_PENUM_IF_UNSET(&style->enable_background, repr, - "enable-background", enum_enable_background, true); - - /* clip-rule */ - SPS_READ_PENUM_IF_UNSET(&style->clip_rule, repr, "clip-rule", enum_clip_rule, true); + // for(SPPropMap::iterator i = _propmap.begin(); i != _propmap.end(); ++i ) { + // (this->*(i->second)).readAttribute( repr ); + // } - /* color_rendering, image_rendering, shape_rendering, text_rendering */ - SPS_READ_PENUM_IF_UNSET(&style->color_rendering, repr, "color-rendering", enum_color_rendering, true); - SPS_READ_PENUM_IF_UNSET(&style->image_rendering, repr, "image-rendering", enum_image_rendering, true); - SPS_READ_PENUM_IF_UNSET(&style->shape_rendering, repr, "shape-rendering", enum_shape_rendering, true); - SPS_READ_PENUM_IF_UNSET(&style->text_rendering, repr, "text-rendering", enum_text_rendering, true); - - /* 3. Merge from parent */ - if (object) { - if (object->parent) { - sp_style_merge_from_parent(style, object->parent->style); + /* 4 Cascade from parent */ + // std::cout << " CASCADING FROM PARENT" << std::endl; + if( object ) { + if( object->parent ) { + cascade( object->parent->style ); } } else { - if (repr->parent()) { - /// \todo fixme: This is not the prettiest thing (Lauris) - SPStyle *parent = sp_style_new(NULL); - sp_style_read(parent, NULL, repr->parent()); - sp_style_merge_from_parent(style, parent); - sp_style_unref(parent); + // When does this happen? + // std::cout << "SPStyle::read(): reading via repr->parent()" << std::endl; + if( repr->parent() ) { + SPStyle *parent = new SPStyle(); + parent->read( NULL, repr->parent() ); + cascade( parent ); + delete parent; } } } - -/** - * Read style properties from object's repr. - * - * 1. Reset existing object style - * 2. Load current effective object style - * 3. Load i attributes from immediate parent (which has to be up-to-date) - */ +// Matches void sp_style_read_from_object(SPStyle *style, SPObject *object); void -sp_style_read_from_object(SPStyle *style, SPObject *object) -{ - g_return_if_fail(style != NULL); +SPStyle::readFromObject( SPObject *object ) { + + // std::cout << "SPStyle::readFromObject: "<< (object->getId()?object->getId():"null")<< std::endl; + g_return_if_fail(object != NULL); g_return_if_fail(SP_IS_OBJECT(object)); Inkscape::XML::Node *repr = object->getRepr(); g_return_if_fail(repr != NULL); - sp_style_read(style, object, repr); + read( object, repr ); } - -/** - * Read style properties from preferences. - * @param style The style to write to - * @param path Preferences directory from which the style should be read - */ +// Matches sp_style_merge_property(SPStyle *style, gint id, gchar const *val) void -sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path) -{ - g_return_if_fail(style != NULL); - g_return_if_fail(path != ""); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // not optimal: we reconstruct the node based on the prefs, then pass it to - // sp_style_read for actual processing. - Inkscape::XML::SimpleDocument *tempdoc = new Inkscape::XML::SimpleDocument; - Inkscape::XML::Node *tempnode = tempdoc->createElement("temp"); - - std::vector attrs = prefs->getAllEntries(path); - for (std::vector::iterator i = attrs.begin(); i != attrs.end(); ++i) { - tempnode->setAttribute(i->getEntryName().data(), i->getString().data()); - } +SPStyle::readIfUnset( gint id, gchar const *val ) { - sp_style_read(style, NULL, tempnode); - - Inkscape::GC::release(tempnode); - Inkscape::GC::release(tempdoc); - delete tempdoc; -} - - - -/** - * - */ -static void -sp_style_privatize_text(SPStyle *style) -{ - SPTextStyle *text = style->text; - style->text = sp_text_style_duplicate_unset(style->text); - sp_text_style_unref(text); - style->text_private = TRUE; -} - - -/** - * Merge property into style. - * - * Should be called in order of highest to lowest precedence. - * E.g. for a single style string, call from the last declaration to the first, - * as CSS says that later declarations override earlier ones. - * - * \pre val != NULL. - */ -static void -sp_style_merge_property(SPStyle *style, gint id, gchar const *val) -{ - g_return_if_fail(val != NULL); + // std::cout << "SPStyle::readIfUnset: Entrance: " << (val?val:"null") << std::endl; + // To Do: If it is not too slow, use std::map instead of std::vector inorder to remove switch() + // (looking up SP_PROP_xxxx already uses a hash). + g_return_if_fail(val != NULL); switch (id) { case SP_PROP_INKSCAPE_FONT_SPEC: - if (!style->text_private) sp_style_privatize_text(style); - if (!style->text->font_specification.set) { - gchar *val_unquoted = attribute_unquote(val); - sp_style_read_istring(&style->text->font_specification, val_unquoted); - if (val_unquoted) g_free (val_unquoted); - } + text->font_specification.readIfUnset( val ); break; - /* CSS2 */ - /* Font */ case SP_PROP_FONT_FAMILY: - if (!style->text_private) sp_style_privatize_text(style); - if (!style->text->font_family.set) { - gchar *val_unquoted = attribute_unquote(val); - sp_style_read_istring(&style->text->font_family, val_unquoted); - if (val_unquoted) g_free (val_unquoted); - } + text->font_family.readIfUnset( val ); break; case SP_PROP_FONT_SIZE: - SPS_READ_IFONTSIZE_IF_UNSET(&style->font_size, val); + font_size.readIfUnset( val ); break; case SP_PROP_FONT_SIZE_ADJUST: if (strcmp(val, "none") != 0) { @@ -991,220 +608,71 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) } break; case SP_PROP_FONT_STYLE: - SPS_READ_IENUM_IF_UNSET(&style->font_style, val, enum_font_style, true); + font_style.readIfUnset( val ); break; case SP_PROP_FONT_VARIANT: - SPS_READ_IENUM_IF_UNSET(&style->font_variant, val, enum_font_variant, true); + font_variant.readIfUnset( val ); break; case SP_PROP_FONT_WEIGHT: - SPS_READ_IENUM_IF_UNSET(&style->font_weight, val, enum_font_weight, true); + font_weight.readIfUnset( val ); break; case SP_PROP_FONT_STRETCH: - SPS_READ_IENUM_IF_UNSET(&style->font_stretch, val, enum_font_stretch, true); + font_stretch.readIfUnset( val ); break; case SP_PROP_FONT: - if (!style->text_private) sp_style_privatize_text(style); - if (!style->text->font.set) { - g_free(style->text->font.value); - style->text->font.value = g_strdup(val); - style->text->font.set = TRUE; - style->text->font.inherit = (val && !strcmp(val, "inherit")); - - // Break string into white space separated tokens - std::stringstream os( val ); - Glib::ustring param; - - while (os >> param) { - - // CSS is case insensitive but we're comparing against lowercase strings - Glib::ustring lparam = param.lowercase(); - - if (lparam == "/") { - - os >> param; - // Eat the line-height for the moment as it is not an SVG property. - // lparam = param.lowercase(); - // sp_style_read_ilengthornormal(&style->line_height, lparam); - - } else { - - // Skip if "normal" as that is the default (and we don't know which attribute it applies to). - if (lparam == "normal") continue; - - // Check each property in turn - - // font-style - SPIEnum test_style; - test_style.set = FALSE; - - // Read once to see if param is valid style. If valid, .set will be TRUE. - sp_style_read_ienum(&test_style, lparam.c_str(), enum_font_style, true); - - // If valid style parameter - if (test_style.set) { - - // If not previously set - if (!style->font_style.set) { - style->font_style.set = TRUE; - style->font_style.inherit = test_style.inherit; - style->font_style.value = test_style.value; - style->font_style.computed = test_style.computed; - } - continue; // Next parameter. - } - - // font-variant (small-caps) - SPIEnum test_variant; - test_variant.set = FALSE; - sp_style_read_ienum(&test_variant, lparam.c_str(), enum_font_variant, true); - - // If valid variant parameter - if (test_variant.set) { - - // If not previously set - if (!style->font_variant.set) { - style->font_variant.set = TRUE; - style->font_variant.inherit = test_variant.inherit; - style->font_variant.value = test_variant.value; - style->font_variant.computed = test_variant.computed; - } - continue; // Next parameter. - } - - // font-weight - SPIEnum test_weight; - test_weight.set = FALSE; - sp_style_read_ienum(&test_weight, lparam.c_str(), enum_font_weight, true); - - // If valid weight parameter - if (test_weight.set) { - - // If not previously set - if (!style->font_weight.set) { - style->font_weight.set = TRUE; - style->font_weight.inherit = test_weight.inherit; - style->font_weight.value = test_weight.value; - style->font_weight.computed = test_weight.computed; - } - continue; // Next parameter - } - - // Font-size - SPIFontSize test_size; - test_size.set = FALSE; - - // Read once to see if param is valid size. - sp_style_read_ifontsize( &test_size, lparam.c_str() ); - - // If valid size parameter - if (test_size.set) { - - // If not previously set - if (!style->font_size.set) { - style->font_size.set = TRUE; - style->font_size.inherit = test_size.inherit; - style->font_size.unit = test_size.unit; - style->font_size.value = test_size.value; - style->font_size.computed = test_size.computed; - style->font_size.type = test_size.type; - style->font_size.literal = test_size.literal; - } - continue; - } - - // No valid property value found. - break; - } - } // params - - // The rest must be font-family... - std::string val_s = val; - std::string family = val_s.substr( val_s.find( param ) ); - - if (!style->text_private) sp_style_privatize_text(style); - if (!style->text->font_family.set) { - gchar *val_unquoted = attribute_unquote( family.c_str() ); - sp_style_read_istring(&style->text->font_family, val_unquoted); - if (val_unquoted) g_free (val_unquoted); - } - - // Set all properties to their default values per CSS 2.1 spec if not already set - SPS_READ_IFONTSIZE_IF_UNSET(&style->font_size, "medium" ); - SPS_READ_IENUM_IF_UNSET(&style->font_style, "normal", enum_font_style, true); - SPS_READ_IENUM_IF_UNSET(&style->font_variant, "normal", enum_font_variant, true); - SPS_READ_IENUM_IF_UNSET(&style->font_weight, "normal", enum_font_weight, true); - // Line height is not an SVG property but Inkscape uses it for multi-line text. - // sp_style_read_ilengthornormal(&style->line_height, "normal"); - - } - + font.readIfUnset( val ); break; /* Text */ case SP_PROP_TEXT_INDENT: - SPS_READ_ILENGTH_IF_UNSET(&style->text_indent, val); + text_indent.readIfUnset( val ); break; case SP_PROP_TEXT_ALIGN: - SPS_READ_IENUM_IF_UNSET(&style->text_align, val, enum_text_align, true); + text_align.readIfUnset( val ); break; case SP_PROP_TEXT_DECORATION: - if (!style->text_decoration_line.set) { - sp_style_read_itextdecoration(&style->text_decoration_line, &style->text_decoration_style, &style->text_decoration_color, val); - } + text_decoration.readIfUnset( val ); break; case SP_PROP_TEXT_DECORATION_LINE: - if (!style->text_decoration_line.set) { - sp_style_read_itextdecorationLine(&style->text_decoration_line, val); - } + text_decoration_line.readIfUnset( val ); break; case SP_PROP_TEXT_DECORATION_STYLE: - if (!style->text_decoration_style.set) { - sp_style_read_itextdecorationStyle(&style->text_decoration_style, val); - } + text_decoration_style.readIfUnset( val ); break; case SP_PROP_TEXT_DECORATION_COLOR: - if (!style->text_decoration_color.set) { - sp_style_read_itextdecorationColor(&style->text_decoration_color, val); - } + text_decoration_color.readIfUnset( val ); break; case SP_PROP_LINE_HEIGHT: - if (!style->line_height.set) { - sp_style_read_ilengthornormal(&style->line_height, val); - } + line_height.readIfUnset( val ); break; case SP_PROP_LETTER_SPACING: - if (!style->letter_spacing.set) { - sp_style_read_ilengthornormal(&style->letter_spacing, val); - } + letter_spacing.readIfUnset( val ); break; case SP_PROP_WORD_SPACING: - if (!style->word_spacing.set) { - sp_style_read_ilengthornormal(&style->word_spacing, val); - } + word_spacing.readIfUnset( val ); break; case SP_PROP_TEXT_TRANSFORM: - SPS_READ_IENUM_IF_UNSET(&style->text_transform, val, enum_text_transform, true); + text_transform.readIfUnset( val ); break; /* Text (css3) */ case SP_PROP_DIRECTION: - SPS_READ_IENUM_IF_UNSET(&style->direction, val, enum_direction, true); + direction.readIfUnset( val ); break; case SP_PROP_BLOCK_PROGRESSION: - SPS_READ_IENUM_IF_UNSET(&style->block_progression, val, enum_block_progression, true); + block_progression.readIfUnset( val ); break; case SP_PROP_WRITING_MODE: - SPS_READ_IENUM_IF_UNSET(&style->writing_mode, val, enum_writing_mode, true); + writing_mode.readIfUnset( val ); break; case SP_PROP_TEXT_ANCHOR: - SPS_READ_IENUM_IF_UNSET(&style->text_anchor, val, enum_text_anchor, true); + text_anchor.readIfUnset( val ); break; case SP_PROP_BASELINE_SHIFT: - SPS_READ_IBASELINE_SHIFT_IF_UNSET(&style->baseline_shift, val); + baseline_shift.readIfUnset( val ); break; - case SP_PROP_TEXT_RENDERING: { - SPS_READ_IENUM_IF_UNSET(&style->text_rendering, val, enum_text_rendering, true); + case SP_PROP_TEXT_RENDERING: + text_rendering.readIfUnset( val ); break; - } case SP_PROP_ALIGNMENT_BASELINE: g_warning("Unimplemented style property SP_PROP_ALIGNMENT_BASELINE: value: %s", val); break; @@ -1225,31 +693,25 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) g_warning("Unimplemented style property SP_PROP_CLIP: value: %s", val); break; case SP_PROP_COLOR: - if (!style->color.set) { - sp_style_read_icolor(&style->color, val, style, (style->object) ? style->object->document : NULL); - } + color.readIfUnset( val ); break; case SP_PROP_CURSOR: g_warning("Unimplemented style property SP_PROP_CURSOR: value: %s", val); break; case SP_PROP_DISPLAY: - SPS_READ_IENUM_IF_UNSET(&style->display, val, enum_display, true); + display.readIfUnset( val ); break; case SP_PROP_OVERFLOW: - /** \todo - * FIXME: not supported properly yet, we just read and write it, - * but act as if it is always "display". - */ - SPS_READ_IENUM_IF_UNSET(&style->overflow, val, enum_overflow, true); + overflow.readIfUnset( val ); break; case SP_PROP_VISIBILITY: - SPS_READ_IENUM_IF_UNSET(&style->visibility, val, enum_visibility, true); + visibility.readIfUnset( val ); break; case SP_PROP_ISOLATION: - SPS_READ_IENUM_IF_UNSET(&style->isolation, val, enum_isolation, true); + isolation.readIfUnset( val ); break; case SP_PROP_BLEND_MODE: - SPS_READ_IENUM_IF_UNSET(&style->blend_mode, val, enum_blend_mode, true); + blend_mode.readIfUnset( val ); break; /* SVG */ @@ -1264,12 +726,10 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) g_warning("attribute 'clip-path' given as CSS"); //XML Tree being directly used here. - style->object->getRepr()->setAttribute("clip-path", val); + this->object->getRepr()->setAttribute("clip-path", val); break; case SP_PROP_CLIP_RULE: - if (!style->clip_rule.set) { - sp_style_read_ienum(&style->clip_rule, val, enum_clip_rule, true); - } + clip_rule.readIfUnset( val ); break; case SP_PROP_MASK: /** \todo @@ -1278,22 +738,17 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) g_warning("attribute 'mask' given as CSS"); //XML Tree being directly used here. - style->object->getRepr()->setAttribute("mask", val); + this->object->getRepr()->setAttribute("mask", val); break; case SP_PROP_OPACITY: - if (!style->opacity.set) { - sp_style_read_iscale24(&style->opacity, val); - } + opacity.readIfUnset( val ); break; case SP_PROP_ENABLE_BACKGROUND: - SPS_READ_IENUM_IF_UNSET(&style->enable_background, val, - enum_enable_background, true); + enable_background.readIfUnset( val ); break; /* Filter */ case SP_PROP_FILTER: - if (!style->filter.set && !style->filter.inherit) { - sp_style_read_ifilter(val, style, (style->object) ? style->object->document : NULL); - } + if( !filter.inherit ) filter.readIfUnset( val ); break; case SP_PROP_FLOOD_COLOR: g_warning("Unimplemented style property SP_PROP_FLOOD_COLOR: value: %s", val); @@ -1318,3553 +773,725 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val) /* Paint */ case SP_PROP_COLOR_INTERPOLATION: // We read it but issue warning - SPS_READ_IENUM_IF_UNSET(&style->color_interpolation, val, enum_color_interpolation, true); - if( style->color_interpolation.value != SP_CSS_COLOR_INTERPOLATION_SRGB ) { + color_interpolation.readIfUnset( val ); + if( color_interpolation.value != SP_CSS_COLOR_INTERPOLATION_SRGB ) { g_warning("Inkscape currently only supports color-interpolation = sRGB"); } break; case SP_PROP_COLOR_INTERPOLATION_FILTERS: - SPS_READ_IENUM_IF_UNSET(&style->color_interpolation_filters, val, enum_color_interpolation, true); + color_interpolation_filters.readIfUnset( val ); break; case SP_PROP_COLOR_PROFILE: g_warning("Unimplemented style property SP_PROP_COLOR_PROFILE: value: %s", val); break; - case SP_PROP_COLOR_RENDERING: { - SPS_READ_IENUM_IF_UNSET(&style->color_rendering, val, enum_color_rendering, true); + case SP_PROP_COLOR_RENDERING: + color_rendering.readIfUnset( val ); break; - } case SP_PROP_FILL: - if (!style->fill.set) { - style->fill.read( val, *style, (style->object) ? style->object->document : NULL ); - } + fill.readIfUnset( val ); break; case SP_PROP_FILL_OPACITY: - if (!style->fill_opacity.set) { - sp_style_read_iscale24(&style->fill_opacity, val); - } + fill_opacity.readIfUnset( val ); break; case SP_PROP_FILL_RULE: - if (!style->fill_rule.set) { - sp_style_read_ienum(&style->fill_rule, val, enum_fill_rule, true); - } + fill_rule.readIfUnset( val ); break; - case SP_PROP_IMAGE_RENDERING: { - SPS_READ_IENUM_IF_UNSET(&style->image_rendering, val, enum_image_rendering, true); + case SP_PROP_IMAGE_RENDERING: + image_rendering.readIfUnset( val ); break; - } case SP_PROP_MARKER: - /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - /* style->marker[SP_MARKER_LOC] = g_quark_from_string(val); */ - if (!style->marker[SP_MARKER_LOC].set) { - g_free(style->marker[SP_MARKER_LOC].value); - style->marker[SP_MARKER_LOC].value = g_strdup(val); - style->marker[SP_MARKER_LOC].set = TRUE; - style->marker[SP_MARKER_LOC].inherit = (val && !strcmp(val, "inherit")); - } + /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ + marker[SP_MARKER_LOC].readIfUnset( val ); break; - case SP_PROP_MARKER_START: /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - if (!style->marker[SP_MARKER_LOC_START].set) { - g_free(style->marker[SP_MARKER_LOC_START].value); - style->marker[SP_MARKER_LOC_START].value = g_strdup(val); - style->marker[SP_MARKER_LOC_START].set = TRUE; - style->marker[SP_MARKER_LOC_START].inherit = (val && !strcmp(val, "inherit")); - } + marker[SP_MARKER_LOC_START].readIfUnset( val ); break; case SP_PROP_MARKER_MID: /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - if (!style->marker[SP_MARKER_LOC_MID].set) { - g_free(style->marker[SP_MARKER_LOC_MID].value); - style->marker[SP_MARKER_LOC_MID].value = g_strdup(val); - style->marker[SP_MARKER_LOC_MID].set = TRUE; - style->marker[SP_MARKER_LOC_MID].inherit = (val && !strcmp(val, "inherit")); - } + marker[SP_MARKER_LOC_MID].readIfUnset( val ); break; case SP_PROP_MARKER_END: /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - if (!style->marker[SP_MARKER_LOC_END].set) { - g_free(style->marker[SP_MARKER_LOC_END].value); - style->marker[SP_MARKER_LOC_END].value = g_strdup(val); - style->marker[SP_MARKER_LOC_END].set = TRUE; - style->marker[SP_MARKER_LOC_END].inherit = (val && !strcmp(val, "inherit")); - } + marker[SP_MARKER_LOC_END].readIfUnset( val ); break; - - case SP_PROP_SHAPE_RENDERING: { - SPS_READ_IENUM_IF_UNSET(&style->shape_rendering, val, enum_shape_rendering, true); + case SP_PROP_SHAPE_RENDERING: + shape_rendering.readIfUnset( val ); break; - } - case SP_PROP_STROKE: - if (!style->stroke.set) { - style->stroke.read( val, *style, (style->object) ? style->object->document : NULL ); - } + stroke.readIfUnset( val ); break; case SP_PROP_STROKE_WIDTH: - SPS_READ_ILENGTH_IF_UNSET(&style->stroke_width, val); + stroke_width.readIfUnset( val ); break; case SP_PROP_STROKE_DASHARRAY: - if (!style->stroke_dasharray.set) { - sp_style_read_dash(style, val); - } + stroke_dasharray.readIfUnset( val ); break; case SP_PROP_STROKE_DASHOFFSET: - SPS_READ_ILENGTH_IF_UNSET(&style->stroke_dashoffset, val); + stroke_dashoffset.readIfUnset( val ); break; case SP_PROP_STROKE_LINECAP: - if (!style->stroke_linecap.set) { - sp_style_read_ienum(&style->stroke_linecap, val, enum_stroke_linecap, true); - } + stroke_linecap.readIfUnset( val ); break; case SP_PROP_STROKE_LINEJOIN: - if (!style->stroke_linejoin.set) { - sp_style_read_ienum(&style->stroke_linejoin, val, enum_stroke_linejoin, true); - } + stroke_linejoin.readIfUnset( val ); break; case SP_PROP_STROKE_MITERLIMIT: - if (!style->stroke_miterlimit.set) { - sp_style_read_ifloat(&style->stroke_miterlimit, val); - } + stroke_miterlimit.readIfUnset( val ); break; case SP_PROP_STROKE_OPACITY: - if (!style->stroke_opacity.set) { - sp_style_read_iscale24(&style->stroke_opacity, val); - } + stroke_opacity.readIfUnset( val ); break; case SP_PROP_PAINT_ORDER: - if (!style->paint_order.set) { - sp_style_read_ipaintorder(&style->paint_order, val); - } + paint_order.readIfUnset( val ); break; - default: - g_warning("Invalid style property id: %d value: %s", id, val); + g_warning("SPIStyle::readIfUnset(): Invalid style property id: %d value: %s", id, val); break; } } -static void -sp_style_merge_style_from_decl(SPStyle *const style, CRDeclaration const *const decl) -{ - /** \todo Ensure that property is lcased, as per - * http://www.w3.org/TR/REC-CSS2/syndata.html#q4. - * Should probably be done in libcroco. - */ - unsigned const prop_idx = sp_attribute_lookup(decl->property->stryng->str); - if (prop_idx != SP_ATTR_INVALID) { - /** \todo - * effic: Test whether the property is already set before trying to - * convert to string. Alternatively, set from CRTerm directly rather - * than converting to string. - */ - guchar *const str_value_unsigned = cr_term_to_string(decl->value); - gchar *const str_value = reinterpret_cast(str_value_unsigned); - sp_style_merge_property(style, prop_idx, str_value); - g_free(str_value); - } -} - -static void -sp_style_merge_from_props(SPStyle *const style, CRPropList *const props) -{ -#if 0 /* forwards */ - for (CRPropList const *cur = props; cur; cur = cr_prop_list_get_next(cur)) { - CRDeclaration *decl = NULL; - cr_prop_list_get_decl(cur, &decl); - sp_style_merge_style_from_decl(style, decl); - } -#else /* in reverse order, as we need later declarations to take precedence over earlier ones. */ - if (props) { - sp_style_merge_from_props(style, cr_prop_list_get_next(props)); - CRDeclaration *decl = NULL; - cr_prop_list_get_decl(props, &decl); - sp_style_merge_style_from_decl(style, decl); - } -#endif -} - -/** - * \pre decl_list != NULL - */ -static void -sp_style_merge_from_decl_list(SPStyle *const style, CRDeclaration const *const decl_list) -{ - // read the decls from end to start, using head recursion, so that latter declarations override - // (Ref: http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order point 4.) - // because sp_style_merge_style_from_decl only sets properties that are unset - if (decl_list->next) { - sp_style_merge_from_decl_list(style, decl_list->next); - } - sp_style_merge_style_from_decl(style, decl_list); -} - -static CRSelEng * -sp_repr_sel_eng() -{ - CRSelEng *const ret = cr_sel_eng_new(); - cr_sel_eng_set_node_iface(ret, &Inkscape::XML::croco_node_iface); - - /** \todo - * Check whether we need to register any pseudo-class handlers. - * libcroco has its own default handlers for first-child and lang. - * - * We probably want handlers for link and arguably visited (though - * inkscape can't visit links at the time of writing). hover etc. - * more useful in inkview than the editor inkscape. - * - * http://www.w3.org/TR/SVG11/styling.html#StylingWithCSS says that - * the following should be honoured, at least by inkview: - * :hover, :active, :focus, :visited, :link. - */ - - g_assert(ret); - return ret; -} - -static void -sp_style_merge_from_object_stylesheet(SPStyle *const style, SPObject const *const object) -{ - static CRSelEng *sel_eng = NULL; - if (!sel_eng) { - sel_eng = sp_repr_sel_eng(); - } - - CRPropList *props = NULL; - - //XML Tree being directly used here while it shouldn't be. - CRStatus status = cr_sel_eng_get_matched_properties_from_cascade(sel_eng, - object->document->style_cascade, - object->getRepr(), - &props); - g_return_if_fail(status == CR_OK); - /// \todo Check what errors can occur, and handle them properly. - if (props) { - sp_style_merge_from_props(style, props); - cr_prop_list_destroy(props); - } -} - -/** - * Parses a style="..." string and merges it with an existing SPStyle. - */ -void -sp_style_merge_from_style_string(SPStyle *const style, gchar const *const p) -{ - /* - * Reference: http://www.w3.org/TR/SVG11/styling.html#StyleAttribute: - * ``When CSS styling is used, CSS inline style is specified by including - * semicolon-separated property declarations of the form "name : value" - * within the style attribute''. - * - * That's fairly ambiguous. Is a `value' allowed to contain semicolons? - * Why does it say "including", what else is allowed in the style - * attribute value? - */ - - CRDeclaration *const decl_list - = cr_declaration_parse_list_from_buf(reinterpret_cast(p), CR_UTF_8); - if (decl_list) { - sp_style_merge_from_decl_list(style, decl_list); - cr_declaration_destroy(decl_list); - } -} - -/** Indexed by SP_CSS_FONT_SIZE_blah. */ -static float const font_size_table[] = {6.0, 8.0, 10.0, 12.0, 14.0, 18.0, 24.0}; - -static void -sp_style_merge_font_size_from_parent(SPIFontSize &child, SPIFontSize const &parent) -{ - /* 'font-size' */ - if (!child.set || child.inherit) { - /* Inherit the computed value. Reference: http://www.w3.org/TR/SVG11/styling.html#Inheritance */ - child.computed = parent.computed; - } else if (child.type == SP_FONT_SIZE_LITERAL) { - /** \todo - * fixme: SVG and CSS do not specify clearly, whether we should use - * user or screen coordinates (Lauris) - */ - if (child.literal < SP_CSS_FONT_SIZE_SMALLER) { - child.computed = font_size_table[child.literal]; - } else if (child.literal == SP_CSS_FONT_SIZE_SMALLER) { - child.computed = parent.computed / 1.2; - } else if (child.literal == SP_CSS_FONT_SIZE_LARGER) { - child.computed = parent.computed * 1.2; - } else { - /* Illegal value */ - } - } else if (child.type == SP_FONT_SIZE_PERCENTAGE) { - /* Unlike most other lengths, percentage for font size is relative to parent computed value - * rather than viewport. */ - child.computed = parent.computed * child.value; - } else if (child.type == SP_FONT_SIZE_LENGTH) { - switch (child.unit) { - case SP_CSS_UNIT_EM: - /* Relative to parent font size */ - child.computed = parent.computed * child.value; - break; - case SP_CSS_UNIT_EX: - /* Relative to parent font size */ - child.computed = parent.computed * child.value * 0.5; /* Hack */ - break; - default: - /* No change */ - break; - } - } -} - -// Some shifts are defined relative to parent. -static void -sp_style_merge_baseline_shift_from_parent(SPIBaselineShift &child, SPIBaselineShift const &parent, - SPIFontSize const &pfont_size) -{ - /* 'baseline-shift' */ - if (!child.set || child.inherit) { - /* Inherit the computed value. Reference: http://www.w3.org/TR/SVG11/styling.html#Inheritance */ - child.computed = parent.computed; // Does this make sense (applying a shift a second time)? - } else if (child.type == SP_BASELINE_SHIFT_LITERAL) { - if( child.literal == SP_CSS_BASELINE_SHIFT_BASELINE ) { - child.computed = 0; // No change - } else if (child.literal == SP_CSS_BASELINE_SHIFT_SUB ) { - // Should use subscript position from font relative to alphabetic baseline - // OpenOffice, Adobe: -0.33, Word -0.14, LaTex about -0.2. - child.computed = -0.2 * pfont_size.computed; - } else if (child.literal == SP_CSS_BASELINE_SHIFT_SUPER ) { - // Should use superscript position from font relative to alphabetic baseline - // OpenOffice, Adobe: 0.33, Word 0.35, LaTex about 0.45. - child.computed = 0.4 * pfont_size.computed; - } else { - /* Illegal value */ - } - } else if (child.type == SP_BASELINE_SHIFT_PERCENTAGE) { - // Percentage for baseline shift is relative to computed "line-height" - // which is just font-size (see SVG1.1 'font'). - child.computed = pfont_size.computed * child.value; - } else if (child.type == SP_BASELINE_SHIFT_LENGTH) { - switch (child.unit) { - case SP_CSS_UNIT_EM: - child.computed = child.value * pfont_size.computed; - break; - case SP_CSS_UNIT_EX: - child.computed = child.value * 0.5 * pfont_size.computed; - break; - default: - /* No change */ - break; - } - } - // baseline-shifts are relative to parent baseline - child.computed += parent.computed; -} - -/** - * Sets computed values in \a style, which may involve inheriting from (or in some other way - * calculating from) corresponding computed values of \a parent. - * - * References: http://www.w3.org/TR/SVG11/propidx.html shows what properties inherit by default. - * http://www.w3.org/TR/SVG11/styling.html#Inheritance gives general rules as to what it means to - * inherit a value. http://www.w3.org/TR/REC-CSS2/cascade.html#computed-value is more precise - * about what the computed value is (not obvious for lengths). - * - * \pre \a parent's computed values are already up-to-date. - */ -void -sp_style_merge_from_parent(SPStyle *const style, SPStyle const *const parent) -{ - g_return_if_fail(style != NULL); - - /** \todo - * fixme: Check for existing callers that might pass null parent. - * This should probably be g_return_if_fail, or else we should make a - * best attempt to set computed values correctly without having a parent - * (i.e., by assuming parent has initial values). - */ - if (!parent) - return; - - /* CSS2 */ - /* Font */ - sp_style_merge_font_size_from_parent(style->font_size, parent->font_size); - - /* 'font-style' */ - if (!style->font_style.set || style->font_style.inherit) { - style->font_style.computed = parent->font_style.computed; - } - - /* 'font-variant' */ - if (!style->font_variant.set || style->font_variant.inherit) { - style->font_variant.computed = parent->font_variant.computed; - } - - /* 'font-weight' */ - if (!style->font_weight.set || style->font_weight.inherit) { - style->font_weight.computed = parent->font_weight.computed; - } else if (style->font_weight.value == SP_CSS_FONT_WEIGHT_NORMAL) { - /** \todo - * fixme: This is unconditional, i.e., happens even if parent not - * present. - */ - style->font_weight.computed = SP_CSS_FONT_WEIGHT_400; - } else if (style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLD) { - style->font_weight.computed = SP_CSS_FONT_WEIGHT_700; - } else if (style->font_weight.value == SP_CSS_FONT_WEIGHT_LIGHTER) { - unsigned const parent_val = parent->font_weight.computed; - g_assert(SP_CSS_FONT_WEIGHT_100 == 0); - // strictly, 'bolder' and 'lighter' should go to the next weight - // expressible in the current font family, but that's difficult to - // find out, so jumping by 3 seems an appropriate approximation - style->font_weight.computed = (parent_val <= SP_CSS_FONT_WEIGHT_100 + 3 - ? (unsigned)SP_CSS_FONT_WEIGHT_100 - : parent_val - 3); - g_assert(style->font_weight.computed <= (unsigned) SP_CSS_FONT_WEIGHT_900); - } else if (style->font_weight.value == SP_CSS_FONT_WEIGHT_BOLDER) { - unsigned const parent_val = parent->font_weight.computed; - g_assert(parent_val <= SP_CSS_FONT_WEIGHT_900); - style->font_weight.computed = (parent_val >= SP_CSS_FONT_WEIGHT_900 - 3 - ? (unsigned)SP_CSS_FONT_WEIGHT_900 - : parent_val + 3); - g_assert(style->font_weight.computed <= (unsigned) SP_CSS_FONT_WEIGHT_900); - } - - /* 'font-stretch' */ - if (!style->font_stretch.set || style->font_stretch.inherit) { - style->font_stretch.computed = parent->font_stretch.computed; - } else if (style->font_stretch.value == SP_CSS_FONT_STRETCH_NARROWER) { - unsigned const parent_val = parent->font_stretch.computed; - style->font_stretch.computed = (parent_val == SP_CSS_FONT_STRETCH_ULTRA_CONDENSED - ? parent_val - : parent_val - 1); - g_assert(style->font_stretch.computed <= (unsigned) SP_CSS_FONT_STRETCH_ULTRA_EXPANDED); - } else if (style->font_stretch.value == SP_CSS_FONT_STRETCH_WIDER) { - unsigned const parent_val = parent->font_stretch.computed; - g_assert(parent_val <= SP_CSS_FONT_STRETCH_ULTRA_EXPANDED); - style->font_stretch.computed = (parent_val == SP_CSS_FONT_STRETCH_ULTRA_EXPANDED - ? parent_val - : parent_val + 1); - g_assert(style->font_stretch.computed <= (unsigned) SP_CSS_FONT_STRETCH_ULTRA_EXPANDED); - } - - /* text (css2) */ - if (!style->text_indent.set || style->text_indent.inherit) { - style->text_indent.computed = parent->text_indent.computed; - } - - if (!style->text_align.set || style->text_align.inherit) { - style->text_align.computed = parent->text_align.computed; - } - - if (!style->text_decoration_line.set || style->text_decoration_line.inherit) { - style->text_decoration_line.underline = parent->text_decoration_line.underline; - style->text_decoration_line.overline = parent->text_decoration_line.overline; - style->text_decoration_line.line_through = parent->text_decoration_line.line_through; - style->text_decoration_line.blink = parent->text_decoration_line.blink; - } - - if (!style->text_decoration_style.set || style->text_decoration_style.inherit) { - style->text_decoration_style.solid = parent->text_decoration_style.solid; - style->text_decoration_style.isdouble = parent->text_decoration_style.isdouble; - style->text_decoration_style.dotted = parent->text_decoration_style.dotted; - style->text_decoration_style.dashed = parent->text_decoration_style.dashed; - style->text_decoration_style.wavy = parent->text_decoration_style.wavy; - } - - if (!style->text_decoration_color.set || style->text_decoration_color.inherit) { - sp_style_merge_ipaint(style, &style->text_decoration_color, &parent->text_decoration_color); - } - - if (!style->line_height.set || style->line_height.inherit) { - style->line_height.value = parent->line_height.value; - style->line_height.computed = parent->line_height.computed; - style->line_height.normal = parent->line_height.normal; - } - - if (!style->letter_spacing.set || style->letter_spacing.inherit) { - style->letter_spacing.value = parent->letter_spacing.value; - style->letter_spacing.computed = parent->letter_spacing.computed; - style->letter_spacing.normal = parent->letter_spacing.normal; - } - - if (!style->word_spacing.set || style->word_spacing.inherit) { - style->word_spacing.value = parent->word_spacing.value; - style->word_spacing.computed = parent->word_spacing.computed; - style->word_spacing.normal = parent->word_spacing.normal; - } - - if (!style->text_transform.set || style->text_transform.inherit) { - style->text_transform.computed = parent->text_transform.computed; - } - - if (!style->direction.set || style->direction.inherit) { - style->direction.computed = parent->direction.computed; - } - - if (!style->block_progression.set || style->block_progression.inherit) { - style->block_progression.computed = parent->block_progression.computed; - } - - if (!style->writing_mode.set || style->writing_mode.inherit) { - style->writing_mode.computed = parent->writing_mode.computed; - } - - if (!style->text_anchor.set || style->text_anchor.inherit) { - style->text_anchor.computed = parent->text_anchor.computed; - } - - /* Baseline Shift... Some shifts are relative to parent. */ - sp_style_merge_baseline_shift_from_parent(style->baseline_shift, parent->baseline_shift, - parent->font_size); +Glib::ustring +SPStyle::write( guint const flags, SPStyle const *const base ) const { - if (style->opacity.inherit) { - style->opacity.value = parent->opacity.value; - } - - /* Color */ - if (!style->color.set || style->color.inherit) { - sp_style_merge_ipaint(style, &style->color, &parent->color); - } - if (!style->color_interpolation.set || style->color_interpolation.inherit) { - style->color_interpolation.computed = parent->color_interpolation.computed; - } - if (!style->color_interpolation_filters.set || style->color_interpolation_filters.inherit) { - style->color_interpolation_filters.computed = parent->color_interpolation_filters.computed; - } - - - /* Fill */ - if (!style->fill.set || style->fill.inherit || style->fill.currentcolor) { - sp_style_merge_ipaint(style, &style->fill, &parent->fill); - } - - if (!style->fill_opacity.set || style->fill_opacity.inherit) { - style->fill_opacity.value = parent->fill_opacity.value; - } - - if (!style->fill_rule.set || style->fill_rule.inherit) { - style->fill_rule.computed = parent->fill_rule.computed; - } - - /* Stroke */ - if (!style->stroke.set || style->stroke.inherit || style->stroke.currentcolor) { - sp_style_merge_ipaint(style, &style->stroke, &parent->stroke); - } - - if (!style->stroke_width.set || style->stroke_width.inherit) { - style->stroke_width.computed = parent->stroke_width.computed; - } else { - /* Update computed value for any change in font inherited from parent. */ - double const em = style->font_size.computed; - if (style->stroke_width.unit == SP_CSS_UNIT_EM) { - style->stroke_width.computed = style->stroke_width.value * em; - } else if (style->stroke_width.unit == SP_CSS_UNIT_EX) { - double const ex = em * 0.5; // fixme: Get x height from libnrtype or pango. - style->stroke_width.computed = style->stroke_width.value * ex; - } - } - - if (!style->stroke_linecap.set || style->stroke_linecap.inherit) { - style->stroke_linecap.computed = parent->stroke_linecap.computed; - } - - if (!style->stroke_linejoin.set || style->stroke_linejoin.inherit) { - style->stroke_linejoin.computed = parent->stroke_linejoin.computed; - } - - if (!style->stroke_miterlimit.set || style->stroke_miterlimit.inherit) { - style->stroke_miterlimit.value = parent->stroke_miterlimit.value; - } - - if (!style->stroke_dasharray.set || style->stroke_dasharray.inherit) { - style->stroke_dasharray.values = parent->stroke_dasharray.values; - } - - if (!style->stroke_dashoffset.set || style->stroke_dashoffset.inherit) { - style->stroke_dashoffset.value = parent->stroke_dashoffset.value; - } - - if (!style->stroke_opacity.set || style->stroke_opacity.inherit) { - style->stroke_opacity.value = parent->stroke_opacity.value; - } - - if (!style->paint_order.set || style->paint_order.inherit) { - g_free(style->paint_order.value); - style->paint_order.value = g_strdup(parent->paint_order.value); - for (unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i) { - style->paint_order.layer[i] = parent->paint_order.layer[i]; - style->paint_order.layer_set[i] = parent->paint_order.layer_set[i]; - } - } - - if (style->text && parent->text) { - if (!style->text->font_family.set || style->text->font_family.inherit) { - g_free(style->text->font_family.value); - style->text->font_family.value = g_strdup(parent->text->font_family.value); - } - } - - if (style->text && parent->text) { - if (!style->text->font_specification.set || style->text->font_specification.inherit) { - g_free(style->text->font_specification.value); - style->text->font_specification.value = g_strdup(parent->text->font_specification.value); - } - } - - /* Markers - Free the old value and make copy of the new */ - for (unsigned i = SP_MARKER_LOC; i < SP_MARKER_LOC_QTY; i++) { - if (!style->marker[i].set || style->marker[i].inherit) { - g_free(style->marker[i].value); - style->marker[i].value = g_strdup(parent->marker[i].value); - } - } - - /* Filter effects */ - if (style->filter.inherit) { - sp_style_merge_ifilter(style, &parent->filter); - } - - if(style->enable_background.inherit) { - style->enable_background.value = parent->enable_background.value; - } - - /* Clipping */ - if (!style->clip_rule.set || style->clip_rule.inherit) { - style->clip_rule.computed = parent->clip_rule.computed; - } - - /* Rendering */ - if (!style->color_rendering.set || style->color_rendering.inherit) { - style->color_rendering.computed = parent->color_rendering.computed; - } - if (!style->image_rendering.set || style->image_rendering.inherit) { - style->image_rendering.computed = parent->image_rendering.computed; - } - if (!style->shape_rendering.set || style->shape_rendering.inherit) { - style->shape_rendering.computed = parent->shape_rendering.computed; - } - if (!style->text_rendering.set || style->text_rendering.inherit) { - style->text_rendering.computed = parent->text_rendering.computed; - } -} - -template -static void -sp_style_merge_prop_from_dying_parent(T &child, T const &parent) -{ - if ( ( !(child.set) || child.inherit ) - && parent.set && !(parent.inherit) ) - { - child = parent; - } -} - -/** - * Copy SPIString from parent to child. - */ -static void -sp_style_merge_string_prop_from_dying_parent(SPIString &child, SPIString const &parent) -{ - if ( ( !(child.set) || child.inherit ) - && parent.set && !(parent.inherit) ) - { - g_free(child.value); - child.value = g_strdup(parent.value); - child.set = parent.set; - child.inherit = parent.inherit; - } -} - -static void -sp_style_merge_paint_prop_from_dying_parent(SPStyle *style, - SPIPaint &child, SPIPaint const &parent) -{ - /** \todo - * I haven't given this much attention. See comments below about - * currentColor, colorProfile, and relative URIs. - */ - if (!child.set || child.inherit) { - sp_style_merge_ipaint(style, &child, &parent); - child.set = parent.set; - child.inherit = parent.inherit; - } -} - -static void -sp_style_merge_rel_enum_prop_from_dying_parent(SPIEnum &child, SPIEnum const &parent, - unsigned const max_computed_val, - unsigned const smaller_val) -{ - /* We assume that min computed val is 0, contiguous up to max_computed_val, - then zero or more other absolute values, then smaller_val then larger_val. */ - unsigned const min_computed_val = 0; - unsigned const larger_val = smaller_val + 1; - g_return_if_fail(min_computed_val < max_computed_val); - g_return_if_fail(max_computed_val < smaller_val); - - if (parent.set && !parent.inherit) { - if (!child.set || child.inherit) { - child.value = parent.value; - child.set = parent.set; // i.e. true - child.inherit = parent.inherit; // i.e. false - } else if (child.value < smaller_val) { - /* Child has absolute value: leave as is. */ - } else if ( ( child.value == smaller_val - && parent.value == larger_val ) - || ( parent.value == smaller_val - && child.value == larger_val ) ) - { - child.set = false; - /* - * Note that this can result in a change in computed value in the - * rare case that the parent's setting was a no-op (i.e. if the - * parent's parent's computed value was already ultra-condensed or - * ultra-expanded). However, I'd guess that the change is for the - * better: I'd guess that if the properties were specified - * relatively, then the intent is to counteract parent's effect. - * I.e. I believe this is the best code even in that case. - */ - } else if (child.value == parent.value) { - /* Leave as is. */ - /** \todo - * It's unclear what to do if style and parent specify the same - * relative directive (narrower or wider). We can either convert - * to absolute specification or coalesce to a single relative - * request (of half the strength of the original pair). - * - * Converting to a single level of relative specification is a - * better choice if the newly-unlinked clone is itself cloned to - * other contexts (inheriting different font stretchiness): it - * would preserve the effect that it will be narrower than - * the inherited context in each case. The disadvantage is that - * it will ~certainly affect the computed value of the - * newly-unlinked clone. - */ - } else { - unsigned const parent_val = parent.computed; - child.value = ( child.value == smaller_val - ? ( parent_val == min_computed_val - ? parent_val - : parent_val - 1 ) - : ( parent_val == max_computed_val - ? parent_val - : parent_val + 1 ) ); - g_assert(child.value <= max_computed_val); - child.inherit = false; - g_assert(child.set); - } - } -} - -template -static void -sp_style_merge_length_prop_from_dying_parent(LengthT &child, LengthT const &parent, - double const parent_child_em_ratio) -{ - if ( ( !(child.set) || child.inherit ) - && parent.set && !(parent.inherit) ) - { - child = parent; - switch (parent.unit) { - case SP_CSS_UNIT_EM: - case SP_CSS_UNIT_EX: - child.value *= parent_child_em_ratio; - /** \todo - * fixme: Have separate ex ratio parameter. - * Get x height from libnrtype or pango. - */ - if (!IS_FINITE(child.value)) { - child.value = child.computed; - child.unit = SP_CSS_UNIT_NONE; - } - break; - - default: - break; - } - } -} - -static double -get_relative_font_size_frac(SPIFontSize const &font_size) -{ - switch (font_size.type) { - case SP_FONT_SIZE_LITERAL: { - switch (font_size.literal) { - case SP_CSS_FONT_SIZE_SMALLER: - return 5.0 / 6.0; - - case SP_CSS_FONT_SIZE_LARGER: - return 6.0 / 5.0; - - default: - g_assert_not_reached(); - } - } - - case SP_FONT_SIZE_PERCENTAGE: - return font_size.value; - - case SP_FONT_SIZE_LENGTH: { - switch (font_size.unit ) { - case SP_CSS_UNIT_EM: - return font_size.value; - - case SP_CSS_UNIT_EX: - return font_size.value * 0.5; - - default: - g_assert_not_reached(); - } - } - } - g_assert_not_reached(); -} - -/** - * Combine \a style and \a parent style specifications into a single style specification that - * preserves (as much as possible) the effect of the existing \a style being a child of \a parent. - * - * Called when the parent repr is to be removed (e.g. the parent is a \ element that is being - * unlinked), in which case we copy/adapt property values that are explicitly set in \a parent, - * trying to retain the same visual appearance once the parent is removed. Interesting cases are - * when there is unusual interaction with the parent's value (opacity, display) or when the value - * can be specified as relative to the parent computed value (font-size, font-weight etc.). - * - * Doesn't update computed values of \a style. For correctness, you should subsequently call - * sp_style_merge_from_parent against the new parent (presumably \a parent's parent) even if \a - * style was previously up-to-date wrt \a parent. - * - * \pre \a parent's computed values are already up-to-date. - * (\a style's computed values needn't be up-to-date.) - */ -void -sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const parent) -{ - /** \note - * The general rule for each property is as follows: - * - * If style is set to an absolute value, then leave it as is. - * - * Otherwise (i.e. if style has a relative value): - * - * If parent is set to an absolute value, then set style to the computed value. - * - * Otherwise, calculate the combined relative value (e.g. multiplying the two percentages). - */ - - /* We do font-size first, to ensure that em size is up-to-date. */ - /** \todo - * fixme: We'll need to have more font-related things up the top once - * we're getting x-height from pango or libnrtype. - */ - - /* Some things that allow relative specifications. */ - { - /* font-size. Note that we update the computed font-size of style, - to assist in em calculations later in this function. */ - - if (parent->font_size.set && !parent->font_size.inherit) { - /* Parent has defined font-size */ - - if (!style->font_size.set || style->font_size.inherit) { - /* font_size inherits the computed value, so we can use the parent value - * verbatim. */ - style->font_size = parent->font_size; - - } else if ( style->font_size.type == SP_FONT_SIZE_LENGTH && - style->font_size.unit != SP_CSS_UNIT_EM && - style->font_size.unit != SP_CSS_UNIT_EX ) { - - /* Child already has absolute size (stored in computed value), so do nothing. */ - - } else if ( style->font_size.type == SP_FONT_SIZE_LITERAL - && style->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) { - /* Child already has absolute size, but we ensure that the computed value - is up-to-date. */ - unsigned const ix = style->font_size.literal; - g_assert(ix < G_N_ELEMENTS(font_size_table)); - style->font_size.computed = font_size_table[ix]; - - } else { - /* Child has relative size. */ - double const child_frac(get_relative_font_size_frac(style->font_size)); - style->font_size.set = true; - style->font_size.inherit = false; - style->font_size.computed = parent->font_size.computed * child_frac; - - if ( ( parent->font_size.type == SP_FONT_SIZE_LITERAL - && parent->font_size.literal < SP_CSS_FONT_SIZE_SMALLER ) || - ( parent->font_size.type == SP_FONT_SIZE_LENGTH && - parent->font_size.unit != SP_CSS_UNIT_EM && - parent->font_size.unit != SP_CSS_UNIT_EX ) ) { - - /* Absolute value. */ - style->font_size.type = SP_FONT_SIZE_LENGTH; - /* .value is unused for non ex/em SP_FONT_SIZE_LENGTH. */ - - } else { - /* Relative value. */ - - double const parent_frac(get_relative_font_size_frac(parent->font_size)); - if( style->font_size.type == SP_FONT_SIZE_LENGTH ) { - /* Value in terms of ex/em */ - style->font_size.value *= parent_frac; - } else { - style->font_size.value = parent_frac * child_frac; - style->font_size.type = SP_FONT_SIZE_PERCENTAGE; - } - } - } - } - - /* 'font-stretch' */ - sp_style_merge_rel_enum_prop_from_dying_parent(style->font_stretch, - parent->font_stretch, - SP_CSS_FONT_STRETCH_ULTRA_EXPANDED, - SP_CSS_FONT_STRETCH_NARROWER); - - /* font-weight */ - sp_style_merge_rel_enum_prop_from_dying_parent(style->font_weight, - parent->font_weight, - SP_CSS_FONT_WEIGHT_900, - SP_CSS_FONT_WEIGHT_LIGHTER); - } - - - /* Enum values that don't have any relative settings (other than `inherit'). */ - { - SPIEnum SPStyle::*const fields[] = { - &SPStyle::blend_mode, - &SPStyle::clip_rule, - &SPStyle::color_interpolation, - &SPStyle::color_interpolation_filters, - &SPStyle::color_rendering, - &SPStyle::direction, - &SPStyle::fill_rule, - &SPStyle::font_style, - &SPStyle::font_variant, - &SPStyle::image_rendering, - &SPStyle::isolation, - //nyi: SPStyle::pointer_events, - &SPStyle::shape_rendering, - &SPStyle::stroke_linecap, - &SPStyle::stroke_linejoin, - &SPStyle::text_anchor, - &SPStyle::text_rendering, - &SPStyle::visibility, - &SPStyle::writing_mode - }; - - for (unsigned i = 0; i < G_N_ELEMENTS(fields); ++i) { - SPIEnum SPStyle::*const fld = fields[i]; - sp_style_merge_prop_from_dying_parent(style->*fld, parent->*fld); - } - } - - /* A few other simple inheritance properties. */ - { - sp_style_merge_prop_from_dying_parent(style->fill_opacity, parent->fill_opacity); - sp_style_merge_prop_from_dying_parent(style->stroke_opacity, parent->stroke_opacity); - sp_style_merge_prop_from_dying_parent(style->stroke_miterlimit, parent->stroke_miterlimit); - - /** \todo - * We currently treat text-decoration as if it were a simple inherited - * property (fixme). This code may need changing once we do the - * special fill/stroke inheritance mentioned by the spec. - */ - sp_style_merge_prop_from_dying_parent( style->text_decoration_line, parent->text_decoration_line); - sp_style_merge_prop_from_dying_parent(style->text_decoration_style, parent->text_decoration_style); - sp_style_merge_paint_prop_from_dying_parent(style,style->text_decoration_color, parent->text_decoration_color); - - //nyi: font-size-adjust, // | none | inherit - //nyi: glyph-orientation-horizontal, - //nyi: glyph-orientation-vertical, - } - - /* Properties that involve length but are easy in other respects. */ - { - /* The difficulty with lengths is that font-relative units need adjusting if the font - * varies between parent & child. - * - * Lengths specified in the existing child can stay as they are: its computed font - * specification should stay unchanged, so em & ex lengths should continue to mean the same - * size. - * - * Lengths specified in the dying parent in em or ex need to be scaled according to the - * ratio of em or ex size between parent & child. - */ - double const parent_child_em_ratio = parent->font_size.computed / style->font_size.computed; - - SPILength SPStyle::*const lfields[] = { - &SPStyle::stroke_width, - &SPStyle::text_indent - }; - for (unsigned i = 0; i < G_N_ELEMENTS(lfields); ++i) { - SPILength SPStyle::*fld = lfields[i]; - sp_style_merge_length_prop_from_dying_parent(style->*fld, - parent->*fld, - parent_child_em_ratio); - } - - SPILengthOrNormal SPStyle::*const nfields[] = { - &SPStyle::letter_spacing, - &SPStyle::line_height, - &SPStyle::word_spacing - }; - for (unsigned i = 0; i < G_N_ELEMENTS(nfields); ++i) { - SPILengthOrNormal SPStyle::*fld = nfields[i]; - sp_style_merge_length_prop_from_dying_parent(style->*fld, - parent->*fld, - parent_child_em_ratio); - } - - //nyi: &SPStyle::kerning: length or `auto' - - /* fixme: Move stroke-dash and stroke-dash-offset here once they - can accept units. */ - } - - /* Properties that involve a URI but are easy in other respects. */ - { - /** \todo - * Could cause problems if original object was in another document - * and it used a relative URL. (At the time of writing, we don't - * allow hrefs to other documents, so this isn't a problem yet.) - * Paint properties also allow URIs. - */ - //nyi: cursor, // may involve change in effect, but we can't do much better - //nyi: color-profile, - - // Markers (marker-start, marker-mid, marker-end). - for (unsigned i = SP_MARKER_LOC; i < SP_MARKER_LOC_QTY; i++) { - sp_style_merge_string_prop_from_dying_parent(style->marker[i], parent->marker[i]); - } - } - - /* CSS2 */ - /* Font */ - - if (style->text && parent->text) { - sp_style_merge_string_prop_from_dying_parent(style->text->font_specification, - parent->text->font_specification); - - sp_style_merge_string_prop_from_dying_parent(style->text->font_family, - parent->text->font_family); - } - - - /* Properties that don't inherit by default. Most of these need special handling. */ - { - /* - * opacity's effect is cumulative; we set the new value to the combined effect. The - * default value for opacity is 1.0, not inherit. (Note that stroke-opacity and - * fill-opacity are quite different from opacity, and don't need any special handling.) - * - * Cases: - * - parent & child were each previously unset, in which case the effective - * opacity value is 1.0, and style should remain unset. - * - parent was previously unset (so computed opacity value of 1.0) - * and child was set to inherit. The merged child should - * get a value of 1.0, and shouldn't inherit (lest the new parent - * has a different opacity value). Given that opacity's default - * value is 1.0 (rather than inherit), we might as well have the - * merged child's opacity be unset. - * - parent was previously unset (so opacity 1.0), and child was set to a number. - * The merged child should retain its existing settings (though it doesn't matter - * if we make it unset if that number was 1.0). - * - parent was inherit and child was unset. Merged child should be set to inherit. - * - parent was inherit and child was inherit. (We can't in general reproduce this - * effect (short of introducing a new group), but setting opacity to inherit is rare.) - * If the inherited value was strictly between 0.0 and 1.0 (exclusive) then the merged - * child's value should be set to the product of the two, i.e. the square of the - * inherited value, and should not be marked as inherit. (This decision assumes that it - * is more important to retain the effective opacity than to retain the inheriting - * effect, and assumes that the inheriting effect either isn't important enough to create - * a group or isn't common enough to bother maintaining the code to create a group.) If - * the inherited value was 0.0 or 1.0, then marking the merged child as inherit comes - * closer to maintaining the effect. - * - parent was inherit and child was set to a numerical value. If the child's value - * was 1.0, then the merged child should have the same settings as the parent. - * If the child's value was 0, then the merged child should also be set to 0. - * If the child's value was anything else, then we do the same as for the inherit/inherit - * case above: have the merged child set to the product of the two opacities and not - * marked as inherit, for the same reasons as for that case. - * - parent was set to a value, and child was unset. The merged child should have - * parent's settings. - * - parent was set to a value, and child was inherit. The merged child should - * be set to the product, i.e. the square of the parent's value. - * - parent & child are each set to a value. The merged child should be set to the - * product. - */ - if ( !style->opacity.set - || ( !style->opacity.inherit - && style->opacity.value == SP_SCALE24_MAX ) ) - { - style->opacity = parent->opacity; - } else { - /* Ensure that style's computed value is up-to-date. */ - if (style->opacity.inherit) { - style->opacity.value = parent->opacity.value; - } - - /* Multiplication of opacities occurs even if a child's opacity is set to inherit. */ - style->opacity.value = SP_SCALE24_MUL(style->opacity.value, - parent->opacity.value); - - style->opacity.inherit = (parent->opacity.inherit - && style->opacity.inherit - && (parent->opacity.value == 0 || - parent->opacity.value == SP_SCALE24_MAX)); - style->opacity.set = ( style->opacity.inherit - || style->opacity.value < SP_SCALE24_MAX ); - } - - /* display is in principle similar to opacity, but implementation is easier. */ - if ( parent->display.set && !parent->display.inherit - && parent->display.value == SP_CSS_DISPLAY_NONE ) { - style->display.value = SP_CSS_DISPLAY_NONE; - style->display.set = true; - style->display.inherit = false; - } else if (style->display.inherit) { - style->display.value = parent->display.value; - style->display.set = parent->display.set; - style->display.inherit = parent->display.inherit; - } else { - /* Leave as is. (display doesn't inherit by default.) */ - } - - /* enable-background - this is rather complicated, because - * it is valid only when applied to container elements. - * Let's check a simple case anyhow. */ - if (parent->enable_background.set - && !parent->enable_background.inherit - && style->enable_background.inherit) - { - style->enable_background.set = true; - style->enable_background.inherit = false; - style->enable_background.value = parent->enable_background.value; - } - - if (!style->filter.set || style->filter.inherit) - { - sp_style_merge_ifilter(style, &parent->filter); - -} - /** \todo - * fixme: Check that we correctly handle all properties that don't - * inherit by default (as shown in - * http://www.w3.org/TR/SVG11/propidx.html for most SVG 1.1 properties). - */ - } - - /* SPIPaint properties (including color). */ - { - /** \todo - * Think about the issues involved if specified as currentColor or - * if specified relative to colorProfile, and if the currentColor or - * colorProfile differs between parent \& child. See also comments - * elsewhere in this function about URIs. - */ - SPIPaint SPStyle::*const fields[] = { - &SPStyle::color, - &SPStyle::fill, - &SPStyle::stroke - }; - for (unsigned i = 0; i < G_N_ELEMENTS(fields); ++i) { - SPIPaint SPStyle::*const fld = fields[i]; - sp_style_merge_paint_prop_from_dying_parent(style, style->*fld, parent->*fld); - } - } - - /* Things from SVG 1.2 or CSS3. */ - { - /* Note: If we ever support setting string values for text-align then we'd need strdup - * handling here. */ - sp_style_merge_prop_from_dying_parent(style->text_align, parent->text_align); - - sp_style_merge_prop_from_dying_parent(style->text_transform, parent->text_transform); - sp_style_merge_prop_from_dying_parent(style->block_progression, parent->block_progression); - } - - /* Note: this will need length handling once dasharray supports units. */ - if ( ( !style->stroke_dasharray.set || style->stroke_dasharray.inherit ) - && parent->stroke_dasharray.set && !parent->stroke_dasharray.inherit ) - { - style->stroke_dasharray.values = parent->stroke_dasharray.values; - style->stroke_dasharray.set = parent->stroke_dasharray.set; - style->stroke_dasharray.inherit = parent->stroke_dasharray.inherit; - } - - { - sp_style_merge_prop_from_dying_parent(style->stroke_dashoffset, parent->stroke_dashoffset); - } -} - - -static void -sp_style_set_ipaint_to_uri(SPStyle *style, SPIPaint *paint, const Inkscape::URI *uri, SPDocument *document) -{ - // it may be that this style's SPIPaint has not yet created its URIReference; - // now that we have a document, we can create it here - if (!paint->value.href && document) { - paint->value.href = new SPPaintServerReference(document); - paint->value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun((paint == &style->fill)? sp_style_fill_paint_server_ref_changed : sp_style_stroke_paint_server_ref_changed), style)); - } - - if (paint->value.href){ - if (paint->value.href->getObject()){ - paint->value.href->detach(); - } - - try { - paint->value.href->attach(*uri); - } catch (Inkscape::BadURIException &e) { - g_warning("%s", e.what()); - paint->value.href->detach(); - } - } -} - -static void -sp_style_set_ipaint_to_uri_string (SPStyle *style, SPIPaint *paint, const gchar *uri) -{ - try { - const Inkscape::URI IURI(uri); - sp_style_set_ipaint_to_uri(style, paint, &IURI, style->document); - } catch (...) { - g_warning("URI failed to parse: %s", uri); - } -} - -void -sp_style_set_to_uri_string (SPStyle *style, bool isfill, const gchar *uri) -{ - sp_style_set_ipaint_to_uri_string (style, isfill? &style->fill : &style->stroke, uri); -} - -gchar const * -sp_style_get_css_unit_string(int unit) -{ - // specify px by default, see inkscape bug 1221626, mozilla bug 234789 - - switch (unit) { - - case SP_CSS_UNIT_NONE: return "px"; - case SP_CSS_UNIT_PX: return "px"; - case SP_CSS_UNIT_PT: return "pt"; - case SP_CSS_UNIT_PC: return "pc"; - case SP_CSS_UNIT_MM: return "mm"; - case SP_CSS_UNIT_CM: return "cm"; - case SP_CSS_UNIT_IN: return "in"; - case SP_CSS_UNIT_EM: return "em"; - case SP_CSS_UNIT_EX: return "ex"; - case SP_CSS_UNIT_PERCENT: return "%"; - default: return "px"; - } - return "px"; -} - -/* - * Convert a size in pixels into another CSS unit size - */ -double -sp_style_css_size_px_to_units(double size, int unit) -{ - double unit_size = size; - switch (unit) { - - case SP_CSS_UNIT_NONE: unit_size = size; break; - case SP_CSS_UNIT_PX: unit_size = size; break; - case SP_CSS_UNIT_PT: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pt"); break; - case SP_CSS_UNIT_PC: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pc"); break; - case SP_CSS_UNIT_MM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "mm"); break; - case SP_CSS_UNIT_CM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "cm"); break; - case SP_CSS_UNIT_IN: unit_size = Inkscape::Util::Quantity::convert(size, "px", "in"); break; - case SP_CSS_UNIT_EM: unit_size = size / SP_CSS_FONT_SIZE_DEFAULT; break; - case SP_CSS_UNIT_EX: unit_size = size * 2.0 / SP_CSS_FONT_SIZE_DEFAULT ; break; - case SP_CSS_UNIT_PERCENT: unit_size = size * 100.0 / SP_CSS_FONT_SIZE_DEFAULT; break; - - default: - g_warning("sp_style_get_css_font_size_units conversion to %d not implemented.", unit); - break; - } - - return unit_size; -} - -/* - * Convert a size in a CSS unit size to pixels - */ -double -sp_style_css_size_units_to_px(double size, int unit) -{ - if (unit == SP_CSS_UNIT_PX) { - return size; - } - //g_message("sp_style_css_size_units_to_px %f %d = %f px", size, unit, out); - return size * (size / sp_style_css_size_px_to_units(size, unit));; -} -/** - * - */ -static void -sp_style_merge_ipaint(SPStyle *style, SPIPaint *paint, SPIPaint const *parent) -{ - if ((paint->set && paint->currentcolor) || parent->currentcolor) { - bool isset = paint->set; - paint->clear(); - paint->set = isset; - paint->currentcolor = TRUE; - paint->setColor(style->color.value.color); - return; - } - - paint->clear(); - if ( parent->isPaintserver() ) { - if (parent->value.href) { - sp_style_set_ipaint_to_uri(style, paint, parent->value.href->getURI(), parent->value.href->getOwnerDocument()); - } else { - g_warning("Expected paint server not found."); - } - } else if ( parent->isColor() ) { - paint->setColor( parent->value.color ); - } else if ( parent->isNoneSet() ) { - paint->noneSet = TRUE; - } else if ( parent->isNone() ) { - // - } else { - g_assert_not_reached(); - } -} - - -/** - * Merge filter style from parent. - * Filter effects do not inherit by default - */ -static void -sp_style_merge_ifilter(SPStyle *style, SPIFilter const *parent) -{ - // FIXME: - // instead of just copying over, we need to _really merge_ the two filters by combining their - // filter primitives - - sp_style_filter_clear(style); - style->filter.set = parent->set; - style->filter.inherit = parent->inherit; - - if (style->filter.href){ - if (style->filter.href->getObject()){ - style->filter.href->detach(); - } - } - else{ - // it may be that this style has not yet created its SPFilterReference - if (style->object){ - if (style->object->document) { - style->filter.href = new SPFilterReference(style->object->document); - style->filter.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); - } - } - } - - if (style->filter.href && parent->href){ - if (parent->href->getObject()) { - try { - style->filter.href->attach(*parent->href->getURI()); - } catch (Inkscape::BadURIException &e) { - g_warning("%s", e.what()); - style->filter.href->detach(); - } - } - } -} - -/** - * Dumps the style to a CSS string, with either SP_STYLE_FLAG_IFSET or - * SP_STYLE_FLAG_ALWAYS flags. Used with Always for copying an object's - * complete cascaded style to style_clipboard. When you need a CSS string - * for an object in the document tree, you normally call - * sp_style_write_difference instead to take into account the object's parent. - * - * \pre style != NULL. - * \pre flags in {IFSET, ALWAYS}. - * \post ret != NULL. - */ -gchar * -sp_style_write_string(SPStyle const *const style, guint const flags) -{ - /** \todo - * Merge with write_difference, much duplicate code! - */ - g_return_val_if_fail(style != NULL, NULL); - g_return_val_if_fail(((flags == SP_STYLE_FLAG_IFSET) || - (flags == SP_STYLE_FLAG_ALWAYS) ), - NULL); - - gchar c[BMAX]; - gchar *p = c; - *p = '\0'; - - p += sp_style_write_ifontsize(p, c + BMAX - p, "font-size", &style->font_size, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "font-style", enum_font_style, &style->font_style, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "font-variant", enum_font_variant, &style->font_variant, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "font-weight", enum_font_weight, &style->font_weight, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "font-stretch", enum_font_stretch, &style->font_stretch, NULL, flags); - - /* Text */ - p += sp_style_write_ilength(p, c + BMAX - p, "text-indent", &style->text_indent, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "text-align", enum_text_align, &style->text_align, NULL, flags); - p += sp_style_write_itextdecoration(p, c + BMAX - p, "text-decoration", - &style->text_decoration_line, &style->text_decoration_style, &style->text_decoration_color, - NULL, NULL, NULL, flags); - p += sp_style_write_ilengthornormal(p, c + BMAX - p, "line-height", &style->line_height, NULL, flags); - p += sp_style_write_ilengthornormal(p, c + BMAX - p, "letter-spacing", &style->letter_spacing, NULL, flags); - p += sp_style_write_ilengthornormal(p, c + BMAX - p, "word-spacing", &style->word_spacing, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "text-transform", enum_text_transform, &style->text_transform, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "direction", enum_direction, &style->direction, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "block-progression", enum_block_progression, &style->block_progression, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "writing-mode", enum_writing_mode, &style->writing_mode, NULL, flags); - - p += sp_style_write_ienum(p, c + BMAX - p, "text-anchor", enum_text_anchor, &style->text_anchor, NULL, flags); - p += sp_style_write_ibaselineshift(p, c + BMAX - p, "baseline-shift", &style->baseline_shift, NULL, flags); - - - /// \todo fixme: Per type methods need default flag too (lauris) - - if (style->opacity.value != SP_SCALE24_MAX) { - p += sp_style_write_iscale24(p, c + BMAX - p, "opacity", &style->opacity, NULL, flags); - } - - if (!style->color.noneSet) { // CSS does not permit "none" for color - p += sp_style_write_ipaint(p, c + BMAX - p, "color", &style->color, NULL, flags); - } - p += sp_style_write_ienum(p, c + BMAX - p, "color-interpolation", enum_color_interpolation, &style->color_interpolation, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "color-interpolation-filters", enum_color_interpolation, &style->color_interpolation_filters, NULL, flags); - - - p += sp_style_write_ipaint(p, c + BMAX - p, "fill", &style->fill, NULL, flags); - // if fill:none, skip writing fill properties - if (!style->fill.noneSet) { - p += sp_style_write_iscale24(p, c + BMAX - p, "fill-opacity", &style->fill_opacity, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "fill-rule", enum_fill_rule, &style->fill_rule, NULL, flags); - } - - p += sp_style_write_ipaint(p, c + BMAX - p, "stroke", &style->stroke, NULL, flags); - - // stroke width affects markers, so write it if there's stroke OR any markers - if (!style->stroke.noneSet || - style->marker[SP_MARKER_LOC].set || - style->marker[SP_MARKER_LOC_START].set || - style->marker[SP_MARKER_LOC_MID].set || - style->marker[SP_MARKER_LOC_END].set) { - p += sp_style_write_ilength(p, c + BMAX - p, "stroke-width", &style->stroke_width, NULL, flags); - } - - // if stroke:none, skip writing stroke properties - if (!style->stroke.noneSet) { - p += sp_style_write_ienum(p, c + BMAX - p, "stroke-linecap", enum_stroke_linecap, &style->stroke_linecap, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "stroke-linejoin", enum_stroke_linejoin, &style->stroke_linejoin, NULL, flags); - p += sp_style_write_ifloat(p, c + BMAX - p, "stroke-miterlimit", &style->stroke_miterlimit, NULL, flags); - p += sp_style_write_iscale24(p, c + BMAX - p, "stroke-opacity", &style->stroke_opacity, NULL, flags); - p += sp_style_write_idasharray(p, c + BMAX - p, "stroke-dasharray", &style->stroke_dasharray, NULL, flags); - p += sp_style_write_ilength(p, c + BMAX - p, "stroke-dashoffset", &style->stroke_dashoffset, NULL, flags); - } - - if (style->paint_order.set) { - p += sp_style_write_ipaintorder(p, c + BMAX - p, "paint-order", &style->paint_order, NULL, flags); - } else if (flags == SP_STYLE_FLAG_ALWAYS) { - p += g_snprintf(p, c + BMAX - p, "paint-order:normal;"); - } - - bool marker_none = false; - gchar *master = style->marker[SP_MARKER_LOC].value; - if (style->marker[SP_MARKER_LOC].set) { - p += g_snprintf(p, c + BMAX - p, "marker:%s;", style->marker[SP_MARKER_LOC].value); - } else if (flags == SP_STYLE_FLAG_ALWAYS) { - p += g_snprintf(p, c + BMAX - p, "marker:none;"); - marker_none = true; - } - if (style->marker[SP_MARKER_LOC_START].set - && (!master || strcmp(master, style->marker[SP_MARKER_LOC_START].value))) { - p += g_snprintf(p, c + BMAX - p, "marker-start:%s;", style->marker[SP_MARKER_LOC_START].value); - } else if (flags == SP_STYLE_FLAG_ALWAYS && !marker_none) { - p += g_snprintf(p, c + BMAX - p, "marker-start:none;"); - } - if (style->marker[SP_MARKER_LOC_MID].set - && (!master || strcmp(master, style->marker[SP_MARKER_LOC_MID].value))) { - p += g_snprintf(p, c + BMAX - p, "marker-mid:%s;", style->marker[SP_MARKER_LOC_MID].value); - } else if (flags == SP_STYLE_FLAG_ALWAYS && !marker_none) { - p += g_snprintf(p, c + BMAX - p, "marker-mid:none;"); - } - if (style->marker[SP_MARKER_LOC_END].set - && (!master || strcmp(master, style->marker[SP_MARKER_LOC_END].value))) { - p += g_snprintf(p, c + BMAX - p, "marker-end:%s;", style->marker[SP_MARKER_LOC_END].value); - } else if (flags == SP_STYLE_FLAG_ALWAYS && !marker_none) { - p += g_snprintf(p, c + BMAX - p, "marker-end:none;"); - } - - p += sp_style_write_ienum(p, c + BMAX - p, "visibility", enum_visibility, &style->visibility, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "display", enum_display, &style->display, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "overflow", enum_overflow, &style->overflow, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "isolation", enum_isolation, &style->isolation, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "mix-blend-mode", enum_blend_mode, &style->blend_mode, NULL, flags); - - /* filter: */ - p += sp_style_write_ifilter(p, c + BMAX - p, "filter", &style->filter, NULL, flags); - - p += sp_style_write_ienum(p, c + BMAX - p, "enable-background", enum_enable_background, &style->enable_background, NULL, flags); - - /* clipping */ - p += sp_style_write_ienum(p, c + BMAX - p, "clip-rule", enum_clip_rule, &style->clip_rule, NULL, flags); - - /* rendering */ - p += sp_style_write_ienum(p, c + BMAX - p, "color-rendering", enum_color_rendering, &style->color_rendering, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "image-rendering", enum_image_rendering, &style->image_rendering, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "shape-rendering", enum_shape_rendering, &style->shape_rendering, NULL, flags); - p += sp_style_write_ienum(p, c + BMAX - p, "text-rendering", enum_text_rendering, &style->text_rendering, NULL, flags); - - /* fixme: */ - p += sp_text_style_write(p, c + BMAX - p, style->text, flags); - - /* Get rid of trailing `;'. */ - if (p != c) { - --p; - if (*p == ';') { - *p = '\0'; - } - } - - return g_strdup(c); -} - - -#define STYLE_BUF_MAX - - -/** - * Dumps style to CSS string, see sp_style_write_string() - * - * \pre from != NULL. - * \pre to != NULL. - * \post ret != NULL. - */ -gchar * -sp_style_write_difference(SPStyle const *const from, SPStyle const *const to) -{ - g_return_val_if_fail(from != NULL, NULL); - g_return_val_if_fail(to != NULL, NULL); - - gchar c[BMAX], *p = c; - *p = '\0'; - - p += sp_style_write_ifontsize(p, c + BMAX - p, "font-size", &from->font_size, &to->font_size, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "font-style", enum_font_style, &from->font_style, &to->font_style, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "font-variant", enum_font_variant, &from->font_variant, &to->font_variant, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "font-weight", enum_font_weight, &from->font_weight, &to->font_weight, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "font-stretch", enum_font_stretch, &from->font_stretch, &to->font_stretch, SP_STYLE_FLAG_IFDIFF); - - /* Text */ - p += sp_style_write_ilength(p, c + BMAX - p, "text-indent", &from->text_indent, &to->text_indent, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "text-align", enum_text_align, &from->text_align, &to->text_align, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_itextdecoration(p, c + BMAX - p, "text-decoration", - &from->text_decoration_line, &from->text_decoration_style, &from->text_decoration_color, - &to->text_decoration_line, &to->text_decoration_style, &to->text_decoration_color, - SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ilengthornormal(p, c + BMAX - p, "line-height", &from->line_height, &to->line_height, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ilengthornormal(p, c + BMAX - p, "letter-spacing", &from->letter_spacing, &to->letter_spacing, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ilengthornormal(p, c + BMAX - p, "word-spacing", &from->word_spacing, &to->word_spacing, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "text-transform", enum_text_transform, &from->text_transform, &to->text_transform, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "direction", enum_direction, &from->direction, &to->direction, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "block-progression", enum_block_progression, &from->block_progression, &to->block_progression, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "writing-mode", enum_writing_mode, &from->writing_mode, &to->writing_mode, SP_STYLE_FLAG_IFDIFF); - - p += sp_style_write_ienum(p, c + BMAX - p, "text-anchor", enum_text_anchor, &from->text_anchor, &to->text_anchor, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ibaselineshift(p, c + BMAX - p, "baseline-shift", &from->baseline_shift, &to->baseline_shift, SP_STYLE_FLAG_IFDIFF); - - /// \todo fixme: Per type methods need default flag too - if (from->opacity.set && from->opacity.value != SP_SCALE24_MAX) { - p += sp_style_write_iscale24(p, c + BMAX - p, "opacity", &from->opacity, &to->opacity, SP_STYLE_FLAG_IFSET); - } - - if (!from->color.noneSet) { // CSS does not permit "none" for color - p += sp_style_write_ipaint(p, c + BMAX - p, "color", &from->color, &to->color, SP_STYLE_FLAG_IFSET); - } - p += sp_style_write_ienum(p, c + BMAX - p, "color-interpolation", enum_color_interpolation, &from->color_interpolation, &to->color_interpolation, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "color-interpolation-filters", enum_color_interpolation, &from->color_interpolation_filters, &to->color_interpolation_filters, SP_STYLE_FLAG_IFDIFF); - - p += sp_style_write_ipaint(p, c + BMAX - p, "fill", &from->fill, &to->fill, SP_STYLE_FLAG_IFDIFF); - // if fill:none, skip writing fill properties - if (!from->fill.noneSet) { - p += sp_style_write_iscale24(p, c + BMAX - p, "fill-opacity", &from->fill_opacity, &to->fill_opacity, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "fill-rule", enum_fill_rule, &from->fill_rule, &to->fill_rule, SP_STYLE_FLAG_IFDIFF); - } - - p += sp_style_write_ipaint(p, c + BMAX - p, "stroke", &from->stroke, &to->stroke, SP_STYLE_FLAG_IFDIFF); - - // stroke width affects markers, so write it if there's stroke OR any markers - if (!from->stroke.noneSet || - from->marker[SP_MARKER_LOC].set || - from->marker[SP_MARKER_LOC_START].set || - from->marker[SP_MARKER_LOC_MID].set || - from->marker[SP_MARKER_LOC_END].set) { - p += sp_style_write_ilength(p, c + BMAX - p, "stroke-width", &from->stroke_width, &to->stroke_width, SP_STYLE_FLAG_IFDIFF); - } - - // if stroke:none, skip writing stroke properties - if (!from->stroke.noneSet) { - p += sp_style_write_ienum(p, c + BMAX - p, "stroke-linecap", enum_stroke_linecap, - &from->stroke_linecap, &to->stroke_linecap, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "stroke-linejoin", enum_stroke_linejoin, - &from->stroke_linejoin, &to->stroke_linejoin, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ifloat(p, c + BMAX - p, "stroke-miterlimit", - &from->stroke_miterlimit, &to->stroke_miterlimit, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_idasharray(p, c + BMAX - p, "stroke-dasharray", - &from->stroke_dasharray, &to->stroke_dasharray, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ilength(p, c + BMAX - p, "stroke-dashoffset", &from->stroke_dashoffset, &to->stroke_dashoffset, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_iscale24(p, c + BMAX - p, "stroke-opacity", &from->stroke_opacity, &to->stroke_opacity, SP_STYLE_FLAG_IFDIFF); - } - - /* paint-order */ - if( from->paint_order.set) { - p += sp_style_write_ipaintorder(p, c + BMAX - p, "paint-order", &from->paint_order, &to->paint_order, SP_STYLE_FLAG_IFDIFF); - } - - /* markers */ - gchar *master = from->marker[SP_MARKER_LOC].value; - if (master != NULL) { - p += g_snprintf(p, c + BMAX - p, "marker:%s;", master); - } - if (from->marker[SP_MARKER_LOC_START].value != NULL && (!master || strcmp(master, from->marker[SP_MARKER_LOC_START].value))) { - p += g_snprintf(p, c + BMAX - p, "marker-start:%s;", from->marker[SP_MARKER_LOC_START].value); - } - if (from->marker[SP_MARKER_LOC_MID].value != NULL && (!master || strcmp(master, from->marker[SP_MARKER_LOC_MID].value))) { - p += g_snprintf(p, c + BMAX - p, "marker-mid:%s;", from->marker[SP_MARKER_LOC_MID].value); - } - if (from->marker[SP_MARKER_LOC_END].value != NULL && (!master || strcmp(master, from->marker[SP_MARKER_LOC_END].value))) { - p += g_snprintf(p, c + BMAX - p, "marker-end:%s;", from->marker[SP_MARKER_LOC_END].value); - } - - p += sp_style_write_ienum(p, c + BMAX - p, "visibility", enum_visibility, &from->visibility, &to->visibility, SP_STYLE_FLAG_IFSET); - p += sp_style_write_ienum(p, c + BMAX - p, "display", enum_display, &from->display, &to->display, SP_STYLE_FLAG_IFSET); - p += sp_style_write_ienum(p, c + BMAX - p, "overflow", enum_overflow, &from->overflow, &to->overflow, SP_STYLE_FLAG_IFSET); - p += sp_style_write_ienum(p, c + BMAX - p, "isolation", enum_isolation, &from->isolation, &to->isolation, SP_STYLE_FLAG_IFSET); - p += sp_style_write_ienum(p, c + BMAX - p, "mix-blend-mode", enum_blend_mode, &from->blend_mode, &to->blend_mode, SP_STYLE_FLAG_IFSET); - - /* filter: */ - p += sp_style_write_ifilter(p, c + BMAX - p, "filter", &from->filter, &to->filter, SP_STYLE_FLAG_IFDIFF); - - p += sp_style_write_ienum(p, c + BMAX - p, "enable-background", enum_enable_background, &from->enable_background, &to->enable_background, SP_STYLE_FLAG_IFSET); - - p += sp_text_style_write(p, c + BMAX - p, from->text, SP_STYLE_FLAG_IFDIFF); - - p += sp_style_write_ienum(p, c + BMAX - p, "clip-rule", enum_clip_rule, &from->clip_rule, &to->clip_rule, SP_STYLE_FLAG_IFDIFF); - - /* rendering */ - p += sp_style_write_ienum(p, c + BMAX - p, "color-rendering", enum_color_rendering, &from->color_rendering, &to->color_rendering, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "image-rendering", enum_image_rendering, &from->image_rendering, &to->image_rendering, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "shape-rendering", enum_shape_rendering, &from->shape_rendering, &to->shape_rendering, SP_STYLE_FLAG_IFDIFF); - p += sp_style_write_ienum(p, c + BMAX - p, "text-rendering", enum_text_rendering, &from->text_rendering, &to->text_rendering, SP_STYLE_FLAG_IFDIFF); - - /** \todo - * The reason we use IFSET rather than IFDIFF is the belief that the IFDIFF - * flag is mainly only for attributes that don't handle explicit unset well. - * We may need to revisit the behaviour of this routine. - */ - - /* Get rid of trailing `;'. */ - if (p != c) { - --p; - if (*p == ';') { - *p = '\0'; - } - } - - return g_strdup(c); -} - - - -/** - * Reset all style properties. - */ -static void -sp_style_clear(SPStyle *style) -{ - g_return_if_fail(style != NULL); - - style->fill.clear(); - style->stroke.clear(); - sp_style_filter_clear(style); - - style->release_connection.disconnect(); - - style->fill_ps_modified_connection.disconnect(); - if (style->fill.value.href) { - delete style->fill.value.href; - style->fill.value.href = NULL; - } - style->stroke_ps_modified_connection.disconnect(); - if (style->stroke.value.href) { - delete style->stroke.value.href; - style->stroke.value.href = NULL; - } - style->filter_modified_connection.disconnect(); - if (style->filter.href) { - delete style->filter.href; - style->filter.href = NULL; - } - - style->stroke_dasharray.values.clear(); - style->stroke_dasharray.inherit = FALSE; - style->stroke_dashoffset.inherit = FALSE; - - /** \todo fixme: Do that text manipulation via parents */ - SPObject *object = style->object; - SPDocument *document = style->document; - gint const refcount = style->refcount; - SPTextStyle *text = style->text; - unsigned const text_private = style->text_private; - - - style->refcount = refcount; - style->object = object; - style->document = document; - - if (document) { - style->filter.href = new SPFilterReference(document); - style->filter.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); - - style->fill.value.href = new SPPaintServerReference(document); - style->fill.value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_fill_paint_server_ref_changed), style)); - - style->stroke.value.href = new SPPaintServerReference(document); - style->stroke.value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_stroke_paint_server_ref_changed), style)); - } - - style->text = text; - style->text_private = text_private; - - style->text->font_specification.set = FALSE; - style->text->font.set = FALSE; - style->text->font_family.set = FALSE; - - style->font_size.set = FALSE; - style->font_size.inherit = FALSE; - style->font_size.type = SP_FONT_SIZE_LITERAL; - style->font_size.unit = 0; - style->font_size.literal = SP_CSS_FONT_SIZE_MEDIUM; - style->font_size.value = 12.0; - style->font_size.computed = 12.0; - style->font_style.set = FALSE; - style->font_style.inherit = FALSE; - style->font_style.value = style->font_style.computed = SP_CSS_FONT_STYLE_NORMAL; - style->font_variant.set = FALSE; - style->font_variant.inherit = FALSE; - style->font_variant.value = style->font_variant.computed = SP_CSS_FONT_VARIANT_NORMAL; - style->font_weight.set = FALSE; - style->font_weight.inherit = FALSE; - style->font_weight.value = SP_CSS_FONT_WEIGHT_NORMAL; - style->font_weight.computed = SP_CSS_FONT_WEIGHT_400; - style->font_stretch.set = FALSE; - style->font_stretch.inherit = FALSE; - style->font_stretch.value = style->font_stretch.computed = SP_CSS_FONT_STRETCH_NORMAL; - - /* text */ - style->text_indent.set = FALSE; - style->text_indent.inherit = FALSE; - style->text_indent.unit = SP_CSS_UNIT_NONE; - style->text_indent.computed = 0.0; - - style->text_align.set = FALSE; - style->text_align.inherit = FALSE; - style->text_align.value = style->text_align.computed = SP_CSS_TEXT_ALIGN_START; - - style->text_decoration_line.set = FALSE; - style->text_decoration_line.inherit = FALSE; - style->text_decoration_line.underline = FALSE; - style->text_decoration_line.overline = FALSE; - style->text_decoration_line.line_through = FALSE; - style->text_decoration_line.blink = FALSE; - - style->text_decoration_style.set = FALSE; - style->text_decoration_style.inherit = FALSE; - style->text_decoration_style.solid = FALSE; - style->text_decoration_style.isdouble = FALSE; - style->text_decoration_style.dotted = FALSE; - style->text_decoration_style.dashed = FALSE; - style->text_decoration_style.wavy = FALSE; - - style->text_decoration_color.clear(); - - style->line_height.set = FALSE; - style->line_height.inherit = FALSE; - style->line_height.unit = SP_CSS_UNIT_PERCENT; - style->line_height.normal = TRUE; - style->line_height.value = style->line_height.computed = 1.0; - - style->letter_spacing.set = FALSE; - style->letter_spacing.inherit = FALSE; - style->letter_spacing.unit = SP_CSS_UNIT_NONE; - style->letter_spacing.normal = TRUE; - style->letter_spacing.value = style->letter_spacing.computed = 0.0; - - style->word_spacing.set = FALSE; - style->word_spacing.inherit = FALSE; - style->word_spacing.unit = SP_CSS_UNIT_NONE; - style->word_spacing.normal = TRUE; - style->word_spacing.value = style->word_spacing.computed = 0.0; - - style->baseline_shift.set = FALSE; - style->baseline_shift.inherit = FALSE; - style->baseline_shift.type = SP_BASELINE_SHIFT_LITERAL; - style->baseline_shift.unit = SP_CSS_UNIT_NONE; - style->baseline_shift.literal = SP_CSS_BASELINE_SHIFT_BASELINE; - style->baseline_shift.value = 0.0; - style->baseline_shift.computed = 0.0; - - style->text_transform.set = FALSE; - style->text_transform.inherit = FALSE; - style->text_transform.value = style->text_transform.computed = SP_CSS_TEXT_TRANSFORM_NONE; - - style->direction.set = FALSE; - style->direction.inherit = FALSE; - style->direction.value = style->direction.computed = SP_CSS_DIRECTION_LTR; - - style->block_progression.set = FALSE; - style->block_progression.inherit = FALSE; - style->block_progression.value = style->block_progression.computed = SP_CSS_BLOCK_PROGRESSION_TB; - - style->writing_mode.set = FALSE; - style->writing_mode.inherit = FALSE; - style->writing_mode.value = style->writing_mode.computed = SP_CSS_WRITING_MODE_LR_TB; - - style->text_anchor.set = FALSE; - style->text_anchor.inherit = FALSE; - style->text_anchor.value = style->text_anchor.computed = SP_CSS_TEXT_ANCHOR_START; - - style->clip_set = FALSE; - style->color_set = FALSE; - style->cursor_set = FALSE; - style->overflow_set = FALSE; - style->clip_path_set = FALSE; - style->mask_set = FALSE; - - style->clip_rule.set = FALSE; - style->clip_rule.inherit = FALSE; - style->clip_rule.value = style->clip_rule.computed = SP_WIND_RULE_NONZERO; - - style->opacity.set = FALSE; - style->opacity.inherit = FALSE; - style->opacity.value = SP_SCALE24_MAX; - style->visibility.set = FALSE; - style->visibility.inherit = FALSE; - style->visibility.value = style->visibility.computed = SP_CSS_VISIBILITY_VISIBLE; - style->display.set = FALSE; - style->display.inherit = FALSE; - style->display.value = style->display.computed = SP_CSS_DISPLAY_INLINE; - style->overflow.set = FALSE; - style->overflow.inherit = FALSE; - style->overflow.value = style->overflow.computed = SP_CSS_OVERFLOW_VISIBLE; - style->isolation.set = FALSE; - style->isolation.inherit = FALSE; - style->isolation.value = style->isolation.computed = SP_CSS_ISOLATION_AUTO; - style->blend_mode.set = FALSE; - style->blend_mode.inherit = FALSE; - style->blend_mode.value = style->blend_mode.computed = SP_CSS_BLEND_NORMAL; - - style->color.clear(); - style->color.setColor(0.0, 0.0, 0.0); - style->color_interpolation.set = FALSE; - style->color_interpolation.inherit = FALSE; - style->color_interpolation.value = style->color_interpolation.computed = SP_CSS_COLOR_INTERPOLATION_SRGB; - style->color_interpolation_filters.set = FALSE; - style->color_interpolation_filters.inherit = FALSE; - style->color_interpolation_filters.value = style->color_interpolation_filters.computed = SP_CSS_COLOR_INTERPOLATION_LINEARRGB; - - - style->fill.clear(); - style->fill.setColor(0.0, 0.0, 0.0); - style->fill_opacity.set = FALSE; - style->fill_opacity.inherit = FALSE; - style->fill_opacity.value = SP_SCALE24_MAX; - style->fill_rule.set = FALSE; - style->fill_rule.inherit = FALSE; - style->fill_rule.value = style->fill_rule.computed = SP_WIND_RULE_NONZERO; - - style->stroke.clear(); - style->stroke_opacity.set = FALSE; - style->stroke_opacity.inherit = FALSE; - style->stroke_opacity.value = SP_SCALE24_MAX; - - style->stroke_width.set = FALSE; - style->stroke_width.inherit = FALSE; - style->stroke_width.unit = SP_CSS_UNIT_NONE; - style->stroke_width.value = style->stroke_width.computed = 1.0; - - style->stroke_linecap.set = FALSE; - style->stroke_linecap.inherit = FALSE; - style->stroke_linecap.value = style->stroke_linecap.computed = SP_STROKE_LINECAP_BUTT; - style->stroke_linejoin.set = FALSE; - style->stroke_linejoin.inherit = FALSE; - style->stroke_linejoin.value = style->stroke_linejoin.computed = SP_STROKE_LINEJOIN_MITER; - - style->stroke_miterlimit.set = FALSE; - style->stroke_miterlimit.inherit = FALSE; - style->stroke_miterlimit.value = 4.0; - - style->stroke_dasharray.values.clear(); - style->stroke_dasharray.set = FALSE; - style->stroke_dasharray.inherit = FALSE; - - style->stroke_dashoffset.value = style->stroke_dashoffset.computed = 0.0; - style->stroke_dashoffset.set = FALSE; - style->stroke_dashoffset.inherit = FALSE; - - for (unsigned i = SP_MARKER_LOC; i < SP_MARKER_LOC_QTY; i++) { - g_free(style->marker[i].value); - style->marker[i].set = FALSE; - style->marker[i].inherit = FALSE; - style->marker[i].data = 0; - style->marker[i].value = NULL; - } - - /* SVG 2 */ - style->paint_order.set = FALSE; - style->paint_order.inherit = FALSE; // For now - for (unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i) { - style->paint_order.layer[i] = SP_CSS_PAINT_ORDER_NORMAL; - style->paint_order.layer_set[i] = false; - } - style->paint_order.value = NULL; - - style->filter.set = FALSE; - style->filter.inherit = FALSE; - style->filter.href = NULL; - - style->enable_background.value = SP_CSS_BACKGROUND_ACCUMULATE; - style->enable_background.set = false; - style->enable_background.inherit = false; - - style->filter_blend_mode.set = style->filter_blend_mode.inherit = false; - style->filter_blend_mode.value = style->filter_blend_mode.computed = 0; - style->filter_gaussianBlur_deviation.set = style->filter_gaussianBlur_deviation.inherit = false; - style->filter_gaussianBlur_deviation.value = style->filter_gaussianBlur_deviation.computed = 0; - - style->color_rendering.set = style->color_rendering.inherit = false; - style->color_rendering.value = style->color_rendering.computed = SP_CSS_COLOR_RENDERING_AUTO; - style->image_rendering.set = style->image_rendering.inherit = false; - style->image_rendering.value = style->image_rendering.computed = SP_CSS_IMAGE_RENDERING_AUTO; - style->shape_rendering.set = style->shape_rendering.inherit = false; - style->shape_rendering.value = style->shape_rendering.computed = SP_CSS_SHAPE_RENDERING_AUTO; - style->text_rendering.set = style->text_rendering.inherit = false; - style->text_rendering.value = style->text_rendering.computed = SP_CSS_TEXT_RENDERING_AUTO; - - style->cloned = false; -} - - - -/** - * - */ -static void -sp_style_read_dash(SPStyle *style, gchar const *str) -{ - /* Ref: http://www.w3.org/TR/SVG11/painting.html#StrokeDasharrayProperty */ - style->stroke_dasharray.set = TRUE; - - if (strcmp(str, "inherit") == 0) { - style->stroke_dasharray.inherit = true; - return; - } - style->stroke_dasharray.inherit = false; - - style->stroke_dasharray.values.clear(); - - if (strcmp(str, "none") == 0) { - return; - } - - gchar *e = NULL; - bool LineSolid = true; - while (e != str) { - /* TODO: Should allow rather than just a unitless (px) number. */ - double number = g_ascii_strtod(str, (char **) &e); - style->stroke_dasharray.values.push_back( number ); - if (number > 0.00000001) - LineSolid = false; - if (e != str) { - str = e; - } - while (str && *str && !isalnum(*str)) str += 1; - } - - if (LineSolid) { - style->stroke_dasharray.values.clear(); - } -} - - -/*######################### -## SPTextStyle operations -#########################*/ - - -/** - * Return new SPTextStyle object with default settings. - */ -static SPTextStyle * -sp_text_style_new() -{ - SPTextStyle *ts = g_new0(SPTextStyle, 1); - ts->refcount = 1; - sp_text_style_clear(ts); - - ts->font_specification.value = g_strdup("sans-serif"); - ts->font.value = g_strdup("sans-serif"); - ts->font_family.value = g_strdup("sans-serif"); - - return ts; -} - - -/** - * Clear text style settings. - */ -static void -sp_text_style_clear(SPTextStyle *ts) -{ - ts->font_specification.set = FALSE; - ts->font.set = FALSE; - ts->font_family.set = FALSE; -} - - - -/** - * Reduce refcount of text style and possibly free it. - */ -static SPTextStyle * -sp_text_style_unref(SPTextStyle *st) -{ - st->refcount -= 1; - - if (st->refcount < 1) { - g_free(st->font_specification.value); - g_free(st->font.value); - g_free(st->font_family.value); - g_free(st); - } - - return NULL; -} - - - -/** - * Return duplicate of text style. - */ -static SPTextStyle * -sp_text_style_duplicate_unset(SPTextStyle *st) -{ - SPTextStyle *nt = g_new0(SPTextStyle, 1); - nt->refcount = 1; - - nt->font_specification.value = g_strdup(st->font_specification.value); - nt->font.value = g_strdup(st->font.value); - nt->font_family.value = g_strdup(st->font_family.value); - - return nt; -} - - - -/** - * Write SPTextStyle object into string. - */ -static guint -sp_text_style_write(gchar *p, guint const len, SPTextStyle const *const st, guint flags) -{ - gint d = 0; - - // We do not do diffing for text style - if (flags == SP_STYLE_FLAG_IFDIFF) - flags = SP_STYLE_FLAG_IFSET; - - d += sp_style_write_istring(p + d, len - d, "font-family", &st->font_family, NULL, flags); - d += sp_style_write_istring(p + d, len - d, "-inkscape-font-specification", &st->font_specification, NULL, flags); - return d; -} - - - -/* The following sp_tyle_read_* functions ignore invalid values, as per - * http://www.w3.org/TR/REC-CSS2/syndata.html#parsing-errors. - * - * [However, the SVG spec is somewhat unclear as to whether the style attribute should - * be handled as per CSS2 rules or whether it must simply be a set of PROPERTY:VALUE - * pairs, in which case SVG's error-handling rules - * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing should instead be applied.] - */ - - -/** - * Set SPIFloat object from string. - */ -static void -sp_style_read_ifloat(SPIFloat *val, gchar const *str) -{ - if (!strcmp(str, "inherit")) { - val->set = TRUE; - val->inherit = TRUE; - } else { - gfloat value; - if (sp_svg_number_read_f(str, &value)) { - val->set = TRUE; - val->inherit = FALSE; - val->value = value; - } - } -} - - - -/** - * Set SPIScale24 object from string. - */ -static void -sp_style_read_iscale24(SPIScale24 *val, gchar const *str) -{ - if (!strcmp(str, "inherit")) { - val->set = TRUE; - val->inherit = TRUE; - } else { - gfloat value; - if (sp_svg_number_read_f(str, &value)) { - val->set = TRUE; - val->inherit = FALSE; - value = CLAMP(value, 0.0, 1.0); - val->value = SP_SCALE24_FROM_FLOAT(value); - } - } -} - -/** - * Reads a style value and performs lookup based on the given style value enumerations. - */ -static void -sp_style_read_ienum(SPIEnum *val, gchar const *str, SPStyleEnum const *dict, - bool const can_explicitly_inherit) -{ - if ( can_explicitly_inherit && !strcmp(str, "inherit") ) { - val->set = TRUE; - val->inherit = TRUE; - } else { - for (unsigned i = 0; dict[i].key; i++) { - if (!strcmp(str, dict[i].key)) { - val->set = TRUE; - val->inherit = FALSE; - val->value = dict[i].value; - /* Save copying for values not needing it */ - val->computed = val->value; - break; - } - } - } - return; -} - - - -/** - * Set SPIString object from string. - */ -static void -sp_style_read_istring(SPIString *val, gchar const *str) -{ - g_free(val->value); - - if (!strcmp(str, "inherit")) { - val->set = TRUE; - val->inherit = TRUE; - val->value = NULL; - } else { - val->set = TRUE; - val->inherit = FALSE; - val->value = g_strdup(str); - } -} - - - -/** - * Set SPILength object from string. - */ -static void -sp_style_read_ilength(SPILength *val, gchar const *str) -{ - if (!strcmp(str, "inherit")) { - val->set = TRUE; - val->inherit = TRUE; - } else { - gdouble value; - gchar *e; - /** \todo fixme: Move this to standard place (Lauris) */ - value = g_ascii_strtod(str, &e); - if ( !IS_FINITE(value) ) { // fix for bug lp:935157 - return; - } - if ((gchar const *) e != str) { - /** \todo - * Allow the number of px per inch to vary (document preferences, - * X server or whatever). E.g. don't fill in computed here, do - * it at the same time as percentage units are done. - */ - val->value = value; - if (!*e) { - /* Userspace */ - val->unit = SP_CSS_UNIT_NONE; - val->computed = value; - } else if (!strcmp(e, "px")) { - /* Userspace */ - val->unit = SP_CSS_UNIT_PX; - val->computed = value; - } else if (!strcmp(e, "pt")) { - /* Userspace / DEVICESCALE */ - val->unit = SP_CSS_UNIT_PT; - val->computed = Inkscape::Util::Quantity::convert(value, "pt", "px"); - } else if (!strcmp(e, "pc")) { - val->unit = SP_CSS_UNIT_PC; - val->computed = Inkscape::Util::Quantity::convert(value, "pc", "px"); - } else if (!strcmp(e, "mm")) { - val->unit = SP_CSS_UNIT_MM; - val->computed = Inkscape::Util::Quantity::convert(value, "mm", "px"); - } else if (!strcmp(e, "cm")) { - val->unit = SP_CSS_UNIT_CM; - val->computed = Inkscape::Util::Quantity::convert(value, "cm", "px"); - } else if (!strcmp(e, "in")) { - val->unit = SP_CSS_UNIT_IN; - val->computed = Inkscape::Util::Quantity::convert(value, "in", "px"); - } else if (!strcmp(e, "em")) { - /* EM square */ - val->unit = SP_CSS_UNIT_EM; - val->computed = value * SP_CSS_FONT_SIZE_DEFAULT; - } else if (!strcmp(e, "ex")) { - /* ex square */ - val->unit = SP_CSS_UNIT_EX; - val->computed = value * 0.5 * SP_CSS_FONT_SIZE_DEFAULT; - } else if (!strcmp(e, "%")) { - /* Percentage */ - val->unit = SP_CSS_UNIT_PERCENT; - val->value = value * 0.01; - } else { - /* Invalid */ - return; - } - val->set = TRUE; - val->inherit = FALSE; - } - } -} - -/** - * Set SPILengthOrNormal object from string. - */ -static void -sp_style_read_ilengthornormal(SPILengthOrNormal *val, gchar const *str) -{ - if (!strcmp(str, "normal")) { - val->set = TRUE; - val->inherit = FALSE; - val->normal = TRUE; - val->unit = SP_CSS_UNIT_NONE; - val->value = val->computed = 0.0; - } else { - SPILength length; - sp_style_read_ilength(&length, str); - val->set = length.set; - val->inherit = length.inherit; - val->normal = FALSE; - val->unit = length.unit; - val->value = length.value; - val->computed = length.computed; - } -} - -/** - * Set SPIPaintOrder object from string. - */ -static void -sp_style_read_ipaintorder(SPIPaintOrder *val, gchar const *str) -{ - g_free(val->value); - - if (!strcmp(str, "inherit")) { - // NEED TO CHECK FINAL SPEC - val->set = TRUE; - val->inherit = TRUE; - val->value = NULL; - } else { - val->set = TRUE; - val->inherit = FALSE; - val->value = g_strdup(str); - - if (!strcmp(str, "normal")) { - val->layer[0] = SP_CSS_PAINT_ORDER_NORMAL; - val->layer_set[0] = true; - } else { - // This certainly can be done more efficiently - gchar** c = g_strsplit(str, " ", PAINT_ORDER_LAYERS + 1); - bool used[3] = {false, false, false}; - unsigned int i = 0; - for( ; i < PAINT_ORDER_LAYERS; ++i ) { - if( c[i] ) { - val->layer_set[i] = false; - if( !strcmp( c[i], "fill")) { - val->layer[i] = SP_CSS_PAINT_ORDER_FILL; - val->layer_set[i] = true; - used[0] = true; - } else if( !strcmp( c[i], "stroke")) { - val->layer[i] = SP_CSS_PAINT_ORDER_STROKE; - val->layer_set[i] = true; - used[1] = true; - } else if( !strcmp( c[i], "markers")) { - val->layer[i] = SP_CSS_PAINT_ORDER_MARKER; - val->layer_set[i] = true; - used[2] = true; - } else { - break; - } - } else { - break; - } - } - g_strfreev(c); - - // Fill out rest of the layers using the default order - if( !used[0] && i < PAINT_ORDER_LAYERS ) { - val->layer[i] = SP_CSS_PAINT_ORDER_FILL; - val->layer_set[i] = false; - ++i; - } - if( !used[1] && i < PAINT_ORDER_LAYERS ) { - val->layer[i] = SP_CSS_PAINT_ORDER_STROKE; - val->layer_set[i] = false; - ++i; - } - if( !used[2] && i < PAINT_ORDER_LAYERS ) { - val->layer[i] = SP_CSS_PAINT_ORDER_MARKER; - val->layer_set[i] = false; - } - } - } -} - - - -/** - * Set SPITextDecoration object from string. - */ -static void -sp_style_read_itextdecoration(SPITextDecorationLine *line, SPITextDecorationStyle *style, SPIPaint *color, gchar const *str){ - sp_style_read_itextdecorationLine(line, str); // scans all tokens for line types - sp_style_read_itextdecorationStyle(style, str); // scans all tokens for style types - // the color routine must be fed one token at a time - if multiple colors are found the LAST one is used - const gchar *hstr = str; - while (1) { - if (*str == ' ' || *str == ',' || *str == '\0'){ - int slen = str - hstr; - gchar *frag = g_strndup(hstr,slen+1); // only send one piece at a time, since keywords may be intermixed - sp_style_read_itextdecorationColor(color, frag); - g_free(frag); - if(color->set)break; - if(*str == '\0')break; - hstr = str + 1; - } - str++; - } -} - -/** - * Set SPITextDecorationLine object from string. - * returns true if there was a match, false otherwise - */ -static void -sp_style_read_itextdecorationLine(SPITextDecorationLine *line, gchar const *str){ - if (!strcmp(str, "inherit")) { - line->set = true; - line->inherit = true; - } else if (!strcmp(str, "none")) { - line->set = true; - line->inherit = false; - line->underline = false; - line->overline = false; - line->line_through = false; - line->blink = false; - } else { - bool found_one = false; - bool hit_one = false; - - // CSS 2 keywords - bool found_underline = false; - bool found_overline = false; - bool found_line_through = false; - bool found_blink = false; - - // this method ignores inlineid keys and extra delimiters, so " ,,, blink hello" will set blink and ignore hello - const gchar *hstr = str; - while (1) { - if (*str == ' ' || *str == ',' || *str == '\0'){ - int slen = str - hstr; - // CSS 2 keywords - while(1){ // not really a loop, used to avoid a goto - hit_one = true; // most likely we will - if ((slen == 9) && strneq(hstr, "underline", slen)){ found_underline = true; break; } - if ((slen == 8) && strneq(hstr, "overline", slen)){ found_overline = true; break; } - if ((slen == 12) && strneq(hstr, "line-through", slen)){ found_line_through = true; break; } - if ((slen == 5) && strneq(hstr, "blink", slen)){ found_blink = true; break; } - if ((slen == 4) && strneq(hstr, "none", slen)){ break; } - - hit_one = false; // whatever this thing is, we do not recognize it - break; - } - found_one |= hit_one; - if(*str == '\0')break; - hstr = str + 1; - } - str++; - } - if (found_one) { - line->set = true; - line->inherit = false; - line->underline = found_underline; - line->overline = found_overline; - line->line_through = found_line_through; - line->blink = found_blink; - } - else { - line->set = false; - line->inherit = false; - } - } -} - -/** - * Set SPITextDecorationStyle object from string. - * returns true if there was a match, false otherwise -*/ -static void -sp_style_read_itextdecorationStyle(SPITextDecorationStyle *style, gchar const *str){ - if (!strcmp(str, "inherit")) { - style->set = true; - style->inherit = true; - } else if (!strcmp(str, "none")) { - style->set = true; - style->inherit = false; - style->solid = false; - style->isdouble = false; - style->dotted = false; - style->dashed = false; - style->wavy = false; - } else { - // note, these are CSS 3 keywords - bool found_solid = false; - bool found_double = false; - bool found_dotted = false; - bool found_dashed = false; - bool found_wavy = false; - bool found_one = false; - - // this method ignores inlineid keys and extra delimiters, so " ,,, style hello" will set style and ignore hello - // if more than one style is present, the first is used - const gchar *hstr = str; - while (1) { - if (*str == ' ' || *str == ',' || *str == '\0'){ - int slen = str - hstr; - if ( (slen == 5) && strneq(hstr, "solid", slen)){ found_solid = true; found_one = true; break; } - else if ((slen == 6) && strneq(hstr, "double", slen)){ found_double = true; found_one = true; break; } - else if ((slen == 6) && strneq(hstr, "dotted", slen)){ found_dotted = true; found_one = true; break; } - else if ((slen == 6) && strneq(hstr, "dashed", slen)){ found_dashed = true; found_one = true; break; } - else if ((slen == 4) && strneq(hstr, "wavy", slen)){ found_wavy = true; found_one = true; break; } - if(*str == '\0')break; // nothing more to test - hstr = str + 1; - } - str++; - } - if(found_one){ - style->set = true; - style->inherit = false; - style->solid = found_solid; - style->isdouble = found_double; - style->dotted = found_dotted; - style->dashed = found_dashed; - style->wavy = found_wavy; - } - else { - style->set = false; - style->inherit = false; - } - } -} - -/** - * Set SPIPaint object from string. - */ -static void -sp_style_read_itextdecorationColor(SPIPaint *color, gchar const *str){ - sp_style_read_icolor(color, str, NULL,NULL); -} - - -/** - * Set SPIPaint object from string containing an integer value. - * \param document Ignored - */ -static void -sp_style_read_icolor(SPIPaint *paint, gchar const *str, SPStyle *style, SPDocument *document) -{ - (void)style; // TODO - (void)document; // TODO - paint->currentcolor = FALSE; /* currentColor not a valid . */ - if (!strcmp(str, "inherit")) { - paint->set = TRUE; - paint->inherit = TRUE; - } else { - paint->inherit = FALSE; - guint32 const rgb0 = sp_svg_read_color(str, 0xff); - if (rgb0 != 0xff) { - paint->setColor(rgb0); - paint->set = TRUE; - } - } -} - - -/** - * Set SPIPaint object from string. - * - * \pre paint == \&style.fill || paint == \&style.stroke. - */ -void SPIPaint::read( gchar const *str, SPStyle &style, SPDocument *document ) -{ - while (g_ascii_isspace(*str)) { - ++str; - } - - clear(); - - if (streq(str, "inherit")) { - set = TRUE; - inherit = TRUE; - } else { - if ( strneq(str, "url", 3) ) { - gchar *uri = extract_uri( str, &str ); - while ( g_ascii_isspace(*str) ) { - ++str; - } - // TODO check on and comment the comparrison "paint != &style->color". - if ( uri && *uri && (this != &style.color) ) { - set = TRUE; - - // it may be that this style's SPIPaint has not yet created its URIReference; - // now that we have a document, we can create it here - if (!value.href && document) { - value.href = new SPPaintServerReference(document); - value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun((this == &style.fill)? sp_style_fill_paint_server_ref_changed : sp_style_stroke_paint_server_ref_changed), &style)); - } - - // TODO check what this does in light of move away from union - sp_style_set_ipaint_to_uri_string (&style, this, uri); - } - g_free( uri ); - } - - if (streq(str, "currentColor") && (this != &style.color)) { - set = TRUE; - currentcolor = TRUE; - } else if (streq(str, "none") && (this != &style.color)) { - set = TRUE; - noneSet = TRUE; - } else { - guint32 const rgb0 = sp_svg_read_color(str, &str, 0xff); - if (rgb0 != 0xff) { - setColor( rgb0 ); - set = TRUE; - - while (g_ascii_isspace(*str)) { - ++str; - } - if (strneq(str, "icc-color(", 10)) { - SVGICCColor* tmp = new SVGICCColor(); - if ( ! sp_svg_read_icc_color( str, &str, tmp ) ) { - delete tmp; - tmp = 0; - } - value.color.icc = tmp; - } - } - } - } -} - - - -/** - * Set SPIFontSize object from string. - */ -static void -sp_style_read_ifontsize(SPIFontSize *val, gchar const *str) -{ - if (!strcmp(str, "inherit")) { - val->set = TRUE; - val->inherit = TRUE; - } else if ((*str == 'x') || (*str == 's') || (*str == 'm') || (*str == 'l')) { - // xx-small, x-small, etc. - for (unsigned i = 0; enum_font_size[i].key; i++) { - if (!strcmp(str, enum_font_size[i].key)) { - val->set = TRUE; - val->inherit = FALSE; - val->type = SP_FONT_SIZE_LITERAL; - val->literal = enum_font_size[i].value; - return; - } - } - /* Invalid */ - return; - } else { - SPILength length; - length.set = FALSE; - sp_style_read_ilength(&length, str); - if( length.set ) { - val->set = TRUE; - val->inherit = length.inherit; - val->unit = length.unit; - val->value = length.value; - val->computed = length.computed; - if( val->unit == SP_CSS_UNIT_PERCENT ) { - val->type = SP_FONT_SIZE_PERCENTAGE; - } else { - val->type = SP_FONT_SIZE_LENGTH; - } - } - return; - } -} - - -/** - * Set SPIBaselineShift object from string. - */ -static void -sp_style_read_ibaselineshift(SPIBaselineShift *val, gchar const *str) -{ - if (!strcmp(str, "inherit")) { - val->set = TRUE; - val->inherit = TRUE; - } else if ((*str == 'b') || (*str == 's')) { - // baseline or sub or super - for (unsigned i = 0; enum_baseline_shift[i].key; i++) { - if (!strcmp(str, enum_baseline_shift[i].key)) { - val->set = TRUE; - val->inherit = FALSE; - val->type = SP_BASELINE_SHIFT_LITERAL; - val->literal = enum_baseline_shift[i].value; - return; - } - } - /* Invalid */ - return; - } else { - SPILength length; - sp_style_read_ilength(&length, str); - val->set = length.set; - val->inherit = length.inherit; - val->unit = length.unit; - val->value = length.value; - val->computed = length.computed; - if( val->unit == SP_CSS_UNIT_PERCENT ) { - val->type = SP_BASELINE_SHIFT_PERCENTAGE; - } else { - val->type = SP_BASELINE_SHIFT_LENGTH; - } - return; - } -} - - -/** - * Set SPIFilter object from string. - */ -static void -sp_style_read_ifilter(gchar const *str, SPStyle * style, SPDocument *document) -{ - SPIFilter *f = &(style->filter); - /* Try all possible values: inherit, none, uri */ - if (streq(str, "inherit")) { - f->set = TRUE; - f->inherit = TRUE; - if (f->href){ - if (f->href->getObject()){ - f->href->detach(); - } - } - } else if(streq(str, "none")) { - f->set = TRUE; - f->inherit = FALSE; - if (f->href){ - if (f->href->getObject()){ - f->href->detach(); - } - } - } else if (strneq(str, "url", 3)) { - char *uri = extract_uri(str); - if(uri == NULL || uri[0] == '\0') { - g_warning("Specified filter url is empty"); - f->set = TRUE; - f->inherit = FALSE; - return; - } - f->set = TRUE; - f->inherit = FALSE; - if (f->href){ - if (f->href->getObject()){ - f->href->detach(); - } - } + // std::cout << "SPStyle::write" << std::endl; - // it may be that this style has not yet created its SPFilterReference; - // now that we have a document, we can create it here - if (!f->href && document) { - f->href = new SPFilterReference(document); - f->href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); + Glib::ustring style_string; + for(std::vector::size_type i = 0; i != _properties.size(); ++i) { + if( base != NULL ) { + style_string += _properties[i]->write( flags, base->_properties[i] ); + } else { + style_string += _properties[i]->write( flags, NULL ); } + } + // for(SPPropMap::iterator i = _propmap.begin(); i != _propmap.end(); ++i ) { + // if( base != NULL ) { + // style_string += (this->*(i->second)).write( flags, &(base->*(i->second)) ); + // } else { + // style_string += (this->*(i->second)).write( flags, NULL ); + // } + // } - try { - f->href->attach(Inkscape::URI(uri)); - } catch (Inkscape::BadURIException &e) { - g_warning("%s", e.what()); - f->href->detach(); - } - g_free (uri); + // Remove trailing ';' + if( style_string.size() > 0 ) { + style_string.erase( style_string.size() - 1 ); + } + return style_string; +} - } else { - /* We shouldn't reach this if SVG input is well-formed */ - f->set = FALSE; - f->inherit = FALSE; - if (f->href){ - if (f->href->getObject()){ - f->href->detach(); - } - } +// Corresponds to sp_style_merge_from_parent() +void +SPStyle::cascade( SPStyle const *const parent ) { + // std::cout << "SPStyle::cascade" << std::endl; + for(std::vector::size_type i = 0; i != _properties.size(); ++i) { + _properties[i]->cascade( parent->_properties[i] ); } + // for(SPPropMap::iterator i = _propmap.begin(); i != _propmap.end(); ++i ) { + // (this->*(i->second)).cascade( &(parent->*(i->second)) ); + // } } -/** - * Set SPIEnum object from repr attribute. - */ -static void -sp_style_read_penum(SPIEnum *val, Inkscape::XML::Node *repr, - gchar const *key, SPStyleEnum const *dict, - bool const can_explicitly_inherit) -{ - gchar const *str = repr->attribute(key); - if (str) { - sp_style_read_ienum(val, str, dict, can_explicitly_inherit); +// Corresponds to sp_style_merge_from_dying_parent() +void +SPStyle::merge( SPStyle const *const parent ) { + // std::cout << "SPStyle::merge" << std::endl; + for(std::vector::size_type i = 0; i != _properties.size(); ++i) { + _properties[i]->merge( parent->_properties[i] ); } + // for(SPPropMap::iterator i = _propmap.begin(); i != _propmap.end(); ++i ) { + // (this->*(i->second)).cascade( &(parent->*(i->second)) ); + // } } +// Mostly for unit testing +bool +SPStyle::operator==(const SPStyle& rhs) { + // Uncomment for testing + // for(std::vector::size_type i = 0; i != _properties.size(); ++i) { + // if( *_properties[i] != *rhs._properties[i]) + // std::cout << _properties[i]->name << ": " + // << _properties[i]->write(SP_STYLE_FLAG_ALWAYS,NULL) << " " + // << rhs._properties[i]->write(SP_STYLE_FLAG_ALWAYS,NULL) + // << (*_properties[i] == *rhs._properties[i]) << std::endl; + // } -/** - * Set SPILength object from repr attribute. - */ -static void -sp_style_read_plength(SPILength *val, Inkscape::XML::Node *repr, gchar const *key) -{ - gchar const *str = repr->attribute(key); - if (str) { - sp_style_read_ilength(val, str); + for(std::vector::size_type i = 0; i != _properties.size(); ++i) { + if( *_properties[i] != *rhs._properties[i]) return false; } + return true; } -/** - * Set SPIFontSize object from repr attribute. - */ -static void -sp_style_read_pfontsize(SPIFontSize *val, Inkscape::XML::Node *repr, gchar const *key) -{ - gchar const *str = repr->attribute(key); - if (str) { - sp_style_read_ifontsize(val, str); +void +SPStyle::_mergeString( gchar const *const p ) { + + // std::cout << "SPStyle::_mergeString: " << (p?p:"null") << std::endl; + CRDeclaration *const decl_list + = cr_declaration_parse_list_from_buf(reinterpret_cast(p), CR_UTF_8); + if (decl_list) { + _mergeDeclList( decl_list ); + cr_declaration_destroy(decl_list); } } +void +SPStyle::_mergeDeclList( CRDeclaration const *const decl_list ) { -/** - * Set SPIBaselineShift object from repr attribute. - */ -static void -sp_style_read_pbaselineshift(SPIBaselineShift *val, Inkscape::XML::Node *repr, gchar const *key) -{ - gchar const *str = repr->attribute(key); - if (str) { - sp_style_read_ibaselineshift(val, str); + // std::cout << "SPStyle::_mergeDeclList" << std::endl; + + // In reverse order, as later declarations to take precedence over earlier ones. + // (Properties are only set if not previously set. See: + // Ref: http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order point 4.) + if (decl_list->next) { + _mergeDeclList( decl_list->next ); } + _mergeDecl( decl_list ); } +void +SPStyle::_mergeDecl( CRDeclaration const *const decl ) { + + // std::cout << "SPStyle::_mergeDecl" << std::endl; -/** - * Set SPIFloat object from repr attribute. - */ -static void -sp_style_read_pfloat(SPIFloat *val, Inkscape::XML::Node *repr, gchar const *key) -{ - gchar const *str = repr->attribute(key); - if (str) { - sp_style_read_ifloat(val, str); + unsigned const prop_idx = sp_attribute_lookup(decl->property->stryng->str); + if (prop_idx != SP_ATTR_INVALID) { + /** \todo + * effic: Test whether the property is already set before trying to + * convert to string. Alternatively, set from CRTerm directly rather + * than converting to string. + */ + guchar *const str_value_unsigned = cr_term_to_string(decl->value); + gchar *const str_value = reinterpret_cast(str_value_unsigned); + readIfUnset( prop_idx, str_value ); + g_free(str_value); } } +void +SPStyle::_mergeProps( CRPropList *const props ) { -/** - * Write SPIFloat object into string. - */ -static gint -sp_style_write_ifloat(gchar *p, gint const len, gchar const *const key, - SPIFloat const *const val, SPIFloat const *const base, guint const flags) -{ - Inkscape::CSSOStringStream os; + // std::cout << "SPStyle::_mergeProps" << std::endl; - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || (val->value != base->value)))) - { - if (val->inherit) { - return g_snprintf(p, len, "%s:inherit;", key); - } else { - os << key << ":" << val->value << ";"; - return g_strlcpy(p, os.str().c_str(), len); - } + // In reverse order, as later declarations to take precedence over earlier ones. + if (props) { + _mergeProps( cr_prop_list_get_next( props ) ); + CRDeclaration *decl = NULL; + cr_prop_list_get_decl(props, &decl); + _mergeDecl( decl ); } - return 0; } +void +SPStyle::_mergeObjectStylesheet( SPObject const *const object ) { -/** - * Write SPIScale24 object into string. - */ -static gint -sp_style_write_iscale24(gchar *p, gint const len, gchar const *const key, - SPIScale24 const *const val, SPIScale24 const *const base, - guint const flags) -{ - Inkscape::CSSOStringStream os; + // std::cout << "SPStyle::_mergeObjectStylesheet: " << (object->getId()?object->getId():"null") << std::endl; - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || (val->value != base->value)))) - { - if (val->inherit) { - return g_snprintf(p, len, "%s:inherit;", key); - } else { - os << key << ":" << SP_SCALE24_TO_FLOAT(val->value) << ";"; - return g_strlcpy(p, os.str().c_str(), len); - } + static CRSelEng *sel_eng = NULL; + if (!sel_eng) { + sel_eng = sp_repr_sel_eng(); } - return 0; -} + CRPropList *props = NULL; + + //XML Tree being directly used here while it shouldn't be. + CRStatus status = cr_sel_eng_get_matched_properties_from_cascade(sel_eng, + object->document->style_cascade, + object->getRepr(), + &props); + g_return_if_fail(status == CR_OK); + /// \todo Check what errors can occur, and handle them properly. + if (props) { + _mergeProps(props); + cr_prop_list_destroy(props); + } +} +// Internal /** - * Write SPIEnum object into string. + * Release callback. */ -static gint -sp_style_write_ienum(gchar *p, gint const len, gchar const *const key, - SPStyleEnum const *const dict, - SPIEnum const *const val, SPIEnum const *const base, guint const flags) +static void +sp_style_object_release(SPObject *object, SPStyle *style) { - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || (val->computed != base->computed)))) - { - if (val->inherit) { - return g_snprintf(p, len, "%s:inherit;", key); - } - for (unsigned i = 0; dict[i].key; i++) { - if (dict[i].value == static_cast< gint > (val->value) ) { - return g_snprintf(p, len, "%s:%s;", key, dict[i].key); - } - } - } - return 0; + (void)object; // TODO + style->object = NULL; } - - +// Internal /** - * Write SPIString object into string. + * Emit style modified signal on style's object if the filter changed. */ -static gint -sp_style_write_istring(gchar *p, gint const len, gchar const *const key, - SPIString const *const val, SPIString const *const base, guint const flags) +static void +sp_style_filter_ref_modified(SPObject *obj, guint flags, SPStyle *style) { - gint res = 0; - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || strcmp(val->value, base->value)))) + (void)flags; // TODO + SPFilter *filter=static_cast(obj); + if (style->getFilter() == filter) { - if (val->inherit) { - res = g_snprintf(p, len, "%s:inherit;", key); - } else { - Glib::ustring val_quoted = css2_escape_quote(val->value); - if (~val_quoted.empty()) { - res = g_snprintf(p, len, "%s:%s;", key, val_quoted.c_str()); - } + if (style->object) { + style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } } - return res; } - +// Internal /** - * + * Gets called when the filter is (re)attached to the style */ -static bool -sp_length_differ(SPILength const *const a, SPILength const *const b) +void +sp_style_filter_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style) { - if (a->unit != b->unit) { - if (a->unit == SP_CSS_UNIT_EM) return true; - if (a->unit == SP_CSS_UNIT_EX) return true; - if (a->unit == SP_CSS_UNIT_PERCENT) return true; - if (b->unit == SP_CSS_UNIT_EM) return true; - if (b->unit == SP_CSS_UNIT_EX) return true; - if (b->unit == SP_CSS_UNIT_PERCENT) return true; + if (old_ref) { + style->filter_modified_connection.disconnect(); + } + if ( SP_IS_FILTER(ref)) + { + style->filter_modified_connection = + ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_filter_ref_modified), style)); } - return (a->computed != b->computed); + sp_style_filter_ref_modified(ref, 0, style); } - - /** - * Write SPILength object into string. + * Emit style modified signal on style's object if server is style's fill + * or stroke paint server. */ -static gint -sp_style_write_ilength(gchar *p, gint const len, gchar const *const key, - SPILength const *const val, SPILength const *const base, guint const flags) +static void +sp_style_paint_server_ref_modified(SPObject *obj, guint flags, SPStyle *style) { - Inkscape::CSSOStringStream os; + (void)flags; // TODO + SPPaintServer *server = static_cast(obj); - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || sp_length_differ(val, base)))) + if ((style->fill.isPaintserver()) + && style->getFillPaintServer() == server) { - if (val->inherit) { - return g_snprintf(p, len, "%s:inherit;", key); - } else { - switch (val->unit) { - case SP_CSS_UNIT_NONE: - os << key << ":" << val->computed << ";"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_PX: - os << key << ":" << val->computed << "px;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_PT: - os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "pt") << "pt;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_PC: - os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "pc") << "pc;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_MM: - os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "mm") << "mm;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_CM: - os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "cm") << "cm;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_IN: - os << key << ":" << Inkscape::Util::Quantity::convert(val->computed, "px", "in") << "in;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_EM: - os << key << ":" << val->value << "em;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_EX: - os << key << ":" << val->value << "ex;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - case SP_CSS_UNIT_PERCENT: - os << key << ":" << (val->value * 100.0) << "%;"; - return g_strlcpy(p, os.str().c_str(), len); - break; - default: - /* Invalid */ - break; - } + if (style->object) { + /** \todo + * fixme: I do not know, whether it is optimal - we are + * forcing reread of everything (Lauris) + */ + /** \todo + * fixme: We have to use object_modified flag, because parent + * flag is only available downstreams. + */ + style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } + } else if ((style->stroke.isPaintserver()) + && style->getStrokePaintServer() == server) + { + if (style->object) { + /// \todo fixme: + style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } + } else if (server) { + g_assert_not_reached(); } - return 0; } - /** - * + * Gets called when the paintserver is (re)attached to the style */ -static bool -sp_lengthornormal_differ(SPILengthOrNormal const *const a, SPILengthOrNormal const *const b) +void +sp_style_fill_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style) { - if (a->normal != b->normal) return true; - if (a->normal) return false; - - if (a->unit != b->unit) { - if (a->unit == SP_CSS_UNIT_EM) return true; - if (a->unit == SP_CSS_UNIT_EX) return true; - if (a->unit == SP_CSS_UNIT_PERCENT) return true; - if (b->unit == SP_CSS_UNIT_EM) return true; - if (b->unit == SP_CSS_UNIT_EX) return true; - if (b->unit == SP_CSS_UNIT_PERCENT) return true; + if (old_ref) { + style->fill_ps_modified_connection.disconnect(); + } + if (SP_IS_PAINT_SERVER(ref)) { + style->fill_ps_modified_connection = + ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_paint_server_ref_modified), style)); } - return (a->computed != b->computed); + sp_style_paint_server_ref_modified(ref, 0, style); } /** - * Write SPILengthOrNormal object into string. + * Gets called when the paintserver is (re)attached to the style */ -static gint -sp_style_write_ilengthornormal(gchar *p, gint const len, gchar const *const key, - SPILengthOrNormal const *const val, - SPILengthOrNormal const *const base, - guint const flags) +void +sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style) { - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || sp_lengthornormal_differ(val, base)))) - { - if (val->normal) { - return g_snprintf(p, len, "%s:normal;", key); - } else { - SPILength length; - length.set = val->set; - length.inherit = val->inherit; - length.unit = val->unit; - length.value = val->value; - length.computed = val->computed; - return sp_style_write_ilength(p, len, key, &length, NULL, SP_STYLE_FLAG_ALWAYS); - } + if (old_ref) { + style->stroke_ps_modified_connection.disconnect(); + } + if (SP_IS_PAINT_SERVER(ref)) { + style->stroke_ps_modified_connection = + ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_paint_server_ref_modified), style)); } - return 0; + + sp_style_paint_server_ref_modified(ref, 0, style); } +// Called in: desktop-style.cpp, gradient-chemistry.cpp, sp-object.cpp, sp-stop.cpp, style.cpp +// text-editing.cpp, libnrtype/font-lister.cpp, widgets/dash-selector.cpp, widgets/fill-style.cpp, +// widgets/stroke-style.cpp, widgets/text-toolbar.cpp, ui/dialog/glyphs.cpp, ui/dialog/swatches.cpp, +// ui/dialog/swatches.cpp, ui/dialog/text-edit.cpp. ui/tools/freehand-base.cpp, +// ui/widget/object-composite-settings.cpp, ui/widget/selected-style.cpp, ui/widget/style-swatch.cpp /** - * Write SPIDashArray object into string. + * Returns a new SPStyle object with default settings. */ -static gint -sp_style_write_idasharray(gchar *p, gint const len, gchar const *const /*key*/, - SPIDashArray const *const val, SPIDashArray const *const base, guint const flags) +SPStyle * +sp_style_new(SPDocument *document) { - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || (val->values != base->values)))) - { - if (val->inherit) { - return g_snprintf(p, len, "stroke-dasharray:inherit;"); - } else if ( !val->values.empty() ) { - Inkscape::CSSOStringStream os; - os << "stroke-dasharray:"; - for (unsigned i = 0; i < val->values.size(); i++) { - if (i) { - os << ", "; - } - os << val->values[i]; - } - os << ";"; - return g_strlcpy(p, os.str().c_str(), len); - } else { - return g_snprintf(p, len, "stroke-dasharray:none;"); - } - } - return 0; + SPStyle *const style = new SPStyle( document ); + return style; } - +// Called in: sp-object.cpp /** - * + * Creates a new SPStyle object, and attaches it to the specified SPObject. */ -static bool -sp_textdecorationLine_differ(SPITextDecorationLine const *const a, SPITextDecorationLine const *const b) +SPStyle * +sp_style_new_from_object(SPObject *object) { - return( (a->underline != b->underline ) - || (a->overline != b->overline ) - || (a->line_through != b->line_through) - || (a->blink != b->blink ) - ); + g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + + SPStyle *const style = new SPStyle( NULL, object ); + return style; } +// Called in display/drawing-item.cpp, display/nr-filter-primitive.cpp, libnrtype/Layout-TNG-Input.cpp /** - * + * Increase refcount of style. */ -static bool -sp_textdecorationStyle_differ(SPITextDecorationStyle const *const a, SPITextDecorationStyle const *const b) +SPStyle * +sp_style_ref(SPStyle *style) { - return( (a->solid != b->solid ) - || (a->isdouble != b->isdouble ) - || (a->dotted != b->dotted ) - || (a->dashed != b->dashed ) - || (a->wavy != b->wavy ) - ); + g_return_val_if_fail(style != NULL, NULL); + + style->ref(); // Increase ref count + + return style; } +// Called in style.cpp, desktop-style.cpp, sp-object.cpp, sp-stop.cpp, text-editing.cpp +// display/drawing-group.cpp, ... /** - * + * Decrease refcount of style with possible destruction. */ -static bool -sp_textdecorationColor_differ(SPIPaint const *const a, SPIPaint const *const b) +SPStyle * +sp_style_unref(SPStyle *style) { - bool status = (a->isPaintserver() == b->isPaintserver()) && - (a->colorSet == b->colorSet) && - (a->currentcolor == b->currentcolor); - return(status); + g_return_val_if_fail(style != NULL, NULL); + if (style->unref() < 1) { + delete style; + return NULL; + } + return style; } + + +// Called in: sp-clippath.cpp, sp-item.cpp (suspicious), sp-object.cpp, sp-style-elem.cpp /** - * Write SPITextDecoration object into string. + * Read style properties from object's repr. + * + * 1. Reset existing object style + * 2. Load current effective object style + * 3. Load i attributes from immediate parent (which has to be up-to-date) */ -static gint -sp_style_write_itextdecoration(gchar *p, gint const len, gchar const *const key, - SPITextDecorationLine const *const line, - SPITextDecorationStyle const *const style, - SPIPaint const *const color, - SPITextDecorationLine const *const baseLine, - SPITextDecorationStyle const *const baseStyle, - SPIPaint const *const baseColor, - guint const flags) +void +sp_style_read_from_object(SPStyle *style, SPObject *object) { - Inkscape::CSSOStringStream os; - - if ( (flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && line->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && line->set - && ( !baseLine->set || sp_textdecorationLine_differ(line, baseLine))) - || ((flags & SP_STYLE_FLAG_IFSET) && style->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && style->set - && ( !baseStyle->set || sp_textdecorationStyle_differ(style, baseStyle))) - || ((flags & SP_STYLE_FLAG_IFSET) && color->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && color->set - && ( !baseColor->set || sp_textdecorationColor_differ(color, baseColor))) - ){ - os << key << ":"; - if (line->inherit || style->inherit || color->inherit) { - os << " inherit"; - } - else if (line->underline || line->overline || line->line_through || line->blink) { - if (line->underline) os << " underline"; - if (line->overline) os << " overline"; - if (line->line_through) os << " line-through"; - if (line->blink) os << " blink"; - - if ( style->solid) os << " solid"; - else if (style->isdouble) os << " double"; - else if (style->dotted) os << " dotted"; - else if (style->dashed) os << " dashed"; - else if (style->wavy) os << " wavy"; - // color, if it is set, otherwise omit it - if(color->set){ - char color_buf[8]; - sp_svg_write_color(color_buf, sizeof(color_buf), color->value.color.toRGBA32( 0 )); - os << " "; - os << color_buf; - } - } - else { - os << "none"; - } - os << ";"; - return g_strlcpy(p, os.str().c_str(), len); - } - return 0; + // std::cout << "sp_style_read_from_object: " << (object->getId()?object->getId():"null") << std::endl; + g_return_if_fail(style != NULL); + g_return_if_fail(object != NULL); + g_return_if_fail(SP_IS_OBJECT(object)); + + Inkscape::XML::Node *repr = object->getRepr(); + g_return_if_fail(repr != NULL); + + style->read( object, repr ); } +// Called in: libnrtype/font-lister.cpp, widgets/dash-selector.cpp, widgets/text-toolbar.cpp, +// ui/dialog/text-edit.cpp +// Why is this called when draging a gradient handle? /** - * + * Read style properties from preferences. + * @param style The style to write to + * @param path Preferences directory from which the style should be read */ -static bool -sp_paint_differ(SPIPaint const *const a, SPIPaint const *const b) +void +sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path) { - if ( (a->isColor() != b->isColor()) - || (a->isPaintserver() != b->isPaintserver()) - || (a->set != b->set) - || (a->currentcolor != b->currentcolor) - || (a->inherit!= b->inherit) ) { - return true; - } + g_return_if_fail(style != NULL); + g_return_if_fail(path != ""); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // TODO refactor to allow for mixed paints (rgb() *and* url(), etc) + // not optimal: we reconstruct the node based on the prefs, then pass it to + // sp_style_read for actual processing. + Inkscape::XML::SimpleDocument *tempdoc = new Inkscape::XML::SimpleDocument; + Inkscape::XML::Node *tempnode = tempdoc->createElement("prefs"); - if ( a->isPaintserver() ) { - return (a->value.href == NULL || b->value.href == NULL || a->value.href->getObject() != b->value.href->getObject()); + std::vector attrs = prefs->getAllEntries(path); + for (std::vector::iterator i = attrs.begin(); i != attrs.end(); ++i) { + tempnode->setAttribute(i->getEntryName().data(), i->getString().data()); } - if ( a->isColor() ) { - return !( (a->value.color == b->value.color) - && ((a->value.color.icc == b->value.color.icc) - || (a->value.color.icc && b->value.color.icc - && (a->value.color.icc->colorProfile == b->value.color.icc->colorProfile) - && (a->value.color.icc->colors == b->value.color.icc->colors)))); - /* todo: Allow for epsilon differences in iccColor->colors, e.g. changes small enough not to show up - * in the string representation. */ - } + style->read( NULL, tempnode ); - return false; + Inkscape::GC::release(tempnode); + Inkscape::GC::release(tempdoc); + delete tempdoc; } - -/** - * Write SPIPaint object into string. - */ -static gint -sp_style_write_ipaint(gchar *b, gint const len, gchar const *const key, - SPIPaint const *const paint, SPIPaint const *const base, guint const flags) +static CRSelEng * +sp_repr_sel_eng() { - int retval = 0; - - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && paint->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && paint->set - && (!base->set || sp_paint_differ(paint, base)))) - { - CSSOStringStream css; - - if (paint->inherit) { - css << "inherit"; - } else { - if ( paint->value.href && paint->value.href->getURI() ) { - const gchar* uri = paint->value.href->getURI()->toString(); - css << "url(" << uri << ")"; - g_free((void *)uri); - } - - if ( paint->noneSet ) { - if ( !css.str().empty() ) { - css << " "; - } - css << "none"; - } - - if ( paint->currentcolor ) { - if ( !css.str().empty() ) { - css << " "; - } - css << "currentColor"; - } + CRSelEng *const ret = cr_sel_eng_new(); + cr_sel_eng_set_node_iface(ret, &Inkscape::XML::croco_node_iface); - if ( paint->colorSet && !paint->currentcolor ) { - if ( !css.str().empty() ) { - css << " "; - } - char color_buf[8]; - sp_svg_write_color(color_buf, sizeof(color_buf), paint->value.color.toRGBA32( 0 )); - css << color_buf; - } + /** \todo + * Check whether we need to register any pseudo-class handlers. + * libcroco has its own default handlers for first-child and lang. + * + * We probably want handlers for link and arguably visited (though + * inkscape can't visit links at the time of writing). hover etc. + * more useful in inkview than the editor inkscape. + * + * http://www.w3.org/TR/SVG11/styling.html#StylingWithCSS says that + * the following should be honoured, at least by inkview: + * :hover, :active, :focus, :visited, :link. + */ - if (paint->value.color.icc && !paint->currentcolor) { - if ( !css.str().empty() ) { - css << " "; - } - css << "icc-color(" << paint->value.color.icc->colorProfile; - for (vector::const_iterator i(paint->value.color.icc->colors.begin()), - iEnd(paint->value.color.icc->colors.end()); - i != iEnd; ++i) { - css << ", " << *i; - } - css << ')'; - } - } + g_assert(ret); + return ret; +} - if ( !css.str().empty() ) { - retval = g_snprintf( b, len, "%s:%s;", key, css.str().c_str() ); - } - } - return retval; +// Called in text-editting.cpp, ui/tools/frehand-base.cpp, ui/widget/style-swatch.cpp +/** + * Parses a style="..." string and merges it with an existing SPStyle. + */ +void +sp_style_merge_from_style_string(SPStyle *const style, gchar const *const p) +{ + // std::cout << "sp_style_merge_from_style_string: " << (p?p:"null") <_mergeString( p ); } +/** Indexed by SP_CSS_FONT_SIZE_blah. These seem a bit small */ +static float const font_size_table[] = {6.0, 8.0, 10.0, 12.0, 14.0, 18.0, 24.0}; +// Called in sp-object.cpp, sp-tref.cpp, sp-use.cpp /** + * Sets computed values in \a style, which may involve inheriting from (or in some other way + * calculating from) corresponding computed values of \a parent. + * + * References: http://www.w3.org/TR/SVG11/propidx.html shows what properties inherit by default. + * http://www.w3.org/TR/SVG11/styling.html#Inheritance gives general rules as to what it means to + * inherit a value. http://www.w3.org/TR/REC-CSS2/cascade.html#computed-value is more precise + * about what the computed value is (not obvious for lengths). * + * \pre \a parent's computed values are already up-to-date. */ -static bool -sp_paint_order_differ(SPIPaintOrder const *const a, SPIPaintOrder const *const b) +void +sp_style_merge_from_parent(SPStyle *const style, SPStyle const *const parent) { - if( (a->set != b->set) || - (a->inherit!= b->inherit) ) { - return true; - } - - // Check this works when paint-order value is 'normal' - for (unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) { - if( (a->layer[i] != b->layer[i]) || - (a->layer_set[i] != b->layer_set[i]) ) { - return true; - } - } - return false; -} + // std::cout << "sp_style_merge_from_parent" << std::endl; + g_return_if_fail(style != NULL); + if (!parent) + return; + style->cascade( parent ); + return; +} +// Called in: sp-use.cpp, sp-tref.cpp, sp-item.cpp /** - * Write SPIPaintOrder object into string. + * Combine \a style and \a parent style specifications into a single style specification that + * preserves (as much as possible) the effect of the existing \a style being a child of \a parent. + * + * Called when the parent repr is to be removed (e.g. the parent is a \ element that is being + * unlinked), in which case we copy/adapt property values that are explicitly set in \a parent, + * trying to retain the same visual appearance once the parent is removed. Interesting cases are + * when there is unusual interaction with the parent's value (opacity, display) or when the value + * can be specified as relative to the parent computed value (font-size, font-weight etc.). + * + * Doesn't update computed values of \a style. For correctness, you should subsequently call + * sp_style_merge_from_parent against the new parent (presumably \a parent's parent) even if \a + * style was previously up-to-date wrt \a parent. + * + * \pre \a parent's computed values are already up-to-date. + * (\a style's computed values needn't be up-to-date.) */ -static gint -sp_style_write_ipaintorder(gchar *p, gint len, gchar const *key, SPIPaintOrder const *paint_order, SPIPaintOrder const *base, guint flags) +void +sp_style_merge_from_dying_parent(SPStyle *const style, SPStyle const *const parent) { - int retval = 0; + // std::cout << "sp_style_merge_from_dying_parent" << std::endl; + style->merge( parent ); +} - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && paint_order->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && paint_order->set - && (!base->set || sp_paint_order_differ(paint_order, base)))) - { - CSSOStringStream css; +// The following functions should be incorporated into SPIPaint. FIXME +// Called in: style.cpp, style-internal.cpp +void +sp_style_set_ipaint_to_uri(SPStyle *style, SPIPaint *paint, const Inkscape::URI *uri, SPDocument *document) +{ + // std::cout << "sp_style_set_ipaint_to_uri: Entrance: " << uri << " " << (void*)document << std::endl; + // it may be that this style's SPIPaint has not yet created its URIReference; + // now that we have a document, we can create it here + if (!paint->value.href && document) { + paint->value.href = new SPPaintServerReference(document); + paint->value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun((paint == &style->fill)? sp_style_fill_paint_server_ref_changed : sp_style_stroke_paint_server_ref_changed), style)); + } - if (paint_order->inherit) { - css << "inherit"; - } else { - for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) { - if( paint_order->layer_set[i] == true ) { - switch (paint_order->layer[i]) { - case SP_CSS_PAINT_ORDER_NORMAL: - css << "normal"; - assert( i == 0 ); - break; - case SP_CSS_PAINT_ORDER_FILL: - if (i!=0) css << " "; - css << "fill"; - break; - case SP_CSS_PAINT_ORDER_STROKE: - if (i!=0) css << " "; - css << "stroke"; - break; - case SP_CSS_PAINT_ORDER_MARKER: - if (i!=0) css << " "; - css << "markers"; - break; - } - } else { - break; - } - } + if (paint->value.href){ + if (paint->value.href->getObject()){ + paint->value.href->detach(); } - if ( !css.str().empty() ) { - retval = g_snprintf( p, len, "%s:%s;", key, css.str().c_str() ); + try { + paint->value.href->attach(*uri); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + paint->value.href->detach(); } } - - return retval; } -/** - * - */ -static bool -sp_fontsize_differ(SPIFontSize const *const a, SPIFontSize const *const b) +// Called in: style.cpp, style-internal.cpp +void +sp_style_set_ipaint_to_uri_string (SPStyle *style, SPIPaint *paint, const gchar *uri) { - if (a->type != b->type) - return true; - if (a->type == SP_FONT_SIZE_LENGTH) { - if (a->computed != b->computed) - return true; - } else { - if (a->value != b->value) - return true; + try { + const Inkscape::URI IURI(uri); + sp_style_set_ipaint_to_uri(style, paint, &IURI, style->document); + } catch (...) { + g_warning("URI failed to parse: %s", uri); } - return false; } +// Called in: desktop-style.cpp +void +sp_style_set_to_uri_string (SPStyle *style, bool isfill, const gchar *uri) +{ + sp_style_set_ipaint_to_uri_string (style, isfill? &style->fill : &style->stroke, uri); +} -/** - * Write SPIFontSize object into string. - */ -static gint -sp_style_write_ifontsize(gchar *p, gint const len, gchar const *key, - SPIFontSize const *const val, SPIFontSize const *const base, - guint const flags) +// Called in: widgets/font-selector.cpp, widgets/text-toolbar.cpp, ui/dialog/text-edit.cpp +gchar const * +sp_style_get_css_unit_string(int unit) { - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || sp_fontsize_differ(val, base)))) - { - if (val->inherit) { - return g_snprintf(p, len, "%s:inherit;", key); - } else if (val->type == SP_FONT_SIZE_LITERAL) { - for (unsigned i = 0; enum_font_size[i].key; i++) { - if (enum_font_size[i].value == static_cast< gint > (val->literal) ) { - return g_snprintf(p, len, "%s:%s;", key, enum_font_size[i].key); - } - } - } else if (val->type == SP_FONT_SIZE_LENGTH) { - Inkscape::CSSOStringStream os; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - if (prefs->getBool("/options/font/textOutputPx", true)) { - unit = SP_CSS_UNIT_PX; - } - os << key << ":" << sp_style_css_size_px_to_units(val->computed, unit) << sp_style_get_css_unit_string(unit) << ";"; - return g_strlcpy(p, os.str().c_str(), len); - } else if (val->type == SP_FONT_SIZE_PERCENTAGE) { - Inkscape::CSSOStringStream os; - os << key << ":" << (val->value * 100.0) << "%;"; - return g_strlcpy(p, os.str().c_str(), len); - } + // specify px by default, see inkscape bug 1221626, mozilla bug 234789 + + switch (unit) { + + case SP_CSS_UNIT_NONE: return "px"; + case SP_CSS_UNIT_PX: return "px"; + case SP_CSS_UNIT_PT: return "pt"; + case SP_CSS_UNIT_PC: return "pc"; + case SP_CSS_UNIT_MM: return "mm"; + case SP_CSS_UNIT_CM: return "cm"; + case SP_CSS_UNIT_IN: return "in"; + case SP_CSS_UNIT_EM: return "em"; + case SP_CSS_UNIT_EX: return "ex"; + case SP_CSS_UNIT_PERCENT: return "%"; + default: return "px"; } - return 0; + return "px"; } - +// Called in: style-internal.cpp, widgets/text-toolbar.cpp, ui/dialog/text-edit.cpp /* - * baseline-shift is relative to parent. The only time it should - * not be written out is if it is zero (or not set). + * Convert a size in pixels into another CSS unit size */ -static bool -sp_baseline_shift_notzero(SPIBaselineShift const *const a ) +double +sp_style_css_size_px_to_units(double size, int unit) { - if( a->type == SP_BASELINE_SHIFT_LITERAL ) { - if( a->literal == SP_CSS_BASELINE_SHIFT_BASELINE ) { - return false; - } - } else { - if( a->value == 0.0 ) { - return false; - } + double unit_size = size; + switch (unit) { + + case SP_CSS_UNIT_NONE: unit_size = size; break; + case SP_CSS_UNIT_PX: unit_size = size; break; + case SP_CSS_UNIT_PT: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pt"); break; + case SP_CSS_UNIT_PC: unit_size = Inkscape::Util::Quantity::convert(size, "px", "pc"); break; + case SP_CSS_UNIT_MM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "mm"); break; + case SP_CSS_UNIT_CM: unit_size = Inkscape::Util::Quantity::convert(size, "px", "cm"); break; + case SP_CSS_UNIT_IN: unit_size = Inkscape::Util::Quantity::convert(size, "px", "in"); break; + case SP_CSS_UNIT_EM: unit_size = size / SP_CSS_FONT_SIZE_DEFAULT; break; + case SP_CSS_UNIT_EX: unit_size = size * 2.0 / SP_CSS_FONT_SIZE_DEFAULT ; break; + case SP_CSS_UNIT_PERCENT: unit_size = size * 100.0 / SP_CSS_FONT_SIZE_DEFAULT; break; + + default: + g_warning("sp_style_get_css_font_size_units conversion to %d not implemented.", unit); + break; } - return true; + + return unit_size; } -/** - * Write SPIBaselineShift object into string. +// Called in: widgets/text-toolbar.cpp, ui/dialog/text-edit.cpp +/* + * Convert a size in a CSS unit size to pixels */ -static gint -sp_style_write_ibaselineshift(gchar *p, gint const len, gchar const *key, - SPIBaselineShift const *const val, SPIBaselineShift const *const base, - guint const flags) +double +sp_style_css_size_units_to_px(double size, int unit) { - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set - && (!base->set || sp_baseline_shift_notzero(val) ))) - { - if (val->inherit) { - return g_snprintf(p, len, "%s:inherit;", key); - } else if (val->type == SP_BASELINE_SHIFT_LITERAL) { - for (unsigned i = 0; enum_baseline_shift[i].key; i++) { - if (enum_baseline_shift[i].value == static_cast< gint > (val->literal) ) { - return g_snprintf(p, len, "%s:%s;", key, enum_baseline_shift[i].key); - } - } - } else if (val->type == SP_BASELINE_SHIFT_LENGTH) { - if( val->unit == SP_CSS_UNIT_EM || val->unit == SP_CSS_UNIT_EX ) { - Inkscape::CSSOStringStream os; - os << key << ":" << val->value << (val->unit == SP_CSS_UNIT_EM ? "em;" : "ex;"); - return g_strlcpy(p, os.str().c_str(), len); - } else { - Inkscape::CSSOStringStream os; - os << key << ":" << val->computed << "px;"; // must specify px, see inkscape bug 1221626, mozilla bug 234789 - return g_strlcpy(p, os.str().c_str(), len); - } - } else if (val->type == SP_BASELINE_SHIFT_PERCENTAGE) { - Inkscape::CSSOStringStream os; - os << key << ":" << (val->value * 100.0) << "%;"; - return g_strlcpy(p, os.str().c_str(), len); - } + if (unit == SP_CSS_UNIT_PX) { + return size; } - return 0; + //g_message("sp_style_css_size_units_to_px %f %d = %f px", size, unit, out); + return size * (size / sp_style_css_size_px_to_units(size, unit));; } - - +// Called in style.cpp, text-editing.cpp /** - * Write SPIFilter object into string. + * Dumps the style to a CSS string, with either SP_STYLE_FLAG_IFSET or + * SP_STYLE_FLAG_ALWAYS flags. Used with Always for copying an object's + * complete cascaded style to style_clipboard. When you need a CSS string + * for an object in the document tree, you normally call + * sp_style_write_difference instead to take into account the object's parent. + * + * \pre style != NULL. + * \pre flags in {IFSET, ALWAYS}. + * \post ret != NULL. */ -static gint -sp_style_write_ifilter(gchar *p, gint const len, gchar const *key, - SPIFilter const *const val, SPIFilter const *const base, - guint const flags) +gchar * +sp_style_write_string(SPStyle const *const style, guint const flags) { - (void)base; // TODO - if ((flags & SP_STYLE_FLAG_ALWAYS) - || ((flags & SP_STYLE_FLAG_IFSET) && val->set) - || ((flags & SP_STYLE_FLAG_IFDIFF) && val->set)) - { - if (val->inherit) { - return g_snprintf(p, len, "%s:inherit;", key); - } else if (val->href && val->href->getURI()) { - gchar *uri = val->href->getURI()->toString(); - gint ret = g_snprintf(p, len, "%s:url(%s);", key, uri); - g_free(uri); - return ret; - } - } - - - return 0; -} + /** \todo + * Merge with write_difference, much duplicate code! + */ + g_return_val_if_fail(style != NULL, NULL); + g_return_val_if_fail(((flags == SP_STYLE_FLAG_IFSET) || + (flags == SP_STYLE_FLAG_ALWAYS) ), + NULL); -SPIPaint::SPIPaint() : - set(false), - inherit(0), - currentcolor(0), - colorSet(0), - noneSet(0), - value() -{ - value.color.set( 0 ); - value.href = 0; + return g_strdup( style->write( flags ).c_str() ); } -void SPIPaint::clear() -{ - set = false; - inherit = false; - currentcolor = false; - colorSet = false; - noneSet = false; - value.color.set( 0 ); - if (value.href){ - if (value.href->getObject()){ - value.href->detach(); - } - } -} +// Called in style.cpp, path-chemistry, NOT in text-editting.cpp (because of bug) /** - * Clear filter object, and disconnect style from paintserver (if present). + * Dumps style to CSS string, see sp_style_write_string() + * + * \pre from != NULL. + * \pre to != NULL. + * \post ret != NULL. */ -static void -sp_style_filter_clear(SPStyle *style) +gchar * +sp_style_write_difference(SPStyle const *const from, SPStyle const *const to) { - if (style->filter.href){ - if (style->filter.href->getObject()){ - style->filter.href->detach(); - } - } + g_return_val_if_fail(from != NULL, NULL); + g_return_val_if_fail(to != NULL, NULL); + + return g_strdup( from->write( SP_STYLE_FLAG_IFDIFF, to ).c_str() ); } @@ -4894,7 +1521,7 @@ sp_style_set_property_url (SPObject *item, gchar const *property, SPObject *link sp_repr_css_attr_unref(css); } - +// Called in sp-object.cpp /** * Clear all style property attributes in object. */ @@ -4972,10 +1599,10 @@ sp_style_unset_property_attrs(SPObject *o) if (style->paint_order.set) { repr->setAttribute("paint-order", NULL); } - if (style->text_private && style->text->font_specification.set) { + if (style->text->font_specification.set) { repr->setAttribute("-inkscape-font-specification", NULL); } - if (style->text_private && style->text->font_family.set) { + if (style->text->font_family.set) { repr->setAttribute("font-family", NULL); } if (style->text_anchor.set) { @@ -5025,7 +1652,8 @@ sp_css_attr_from_style(SPStyle const *const style, guint const flags) return css; } - +// Called in: selection-chemistry.cpp, widgets/stroke-marker-selector.cpp, widgets/stroke-style.cpp, +// ui/tools/freehand-base.cpp /** * \pre object != NULL * \pre flags in {IFSET, ALWAYS}. @@ -5042,13 +1670,14 @@ SPCSSAttr *sp_css_attr_from_object(SPObject *object, guint const flags) return result; } +// Called in: selection-chemistry.cpp, ui/dialog/inkscape-preferences.cpp /** * Unset any text-related properties */ SPCSSAttr * sp_css_attr_unset_text(SPCSSAttr *css) { - sp_repr_css_set_property(css, "font", NULL); // not implemented yet + sp_repr_css_set_property(css, "font", NULL); sp_repr_css_set_property(css, "-inkscape-font-specification", NULL); sp_repr_css_set_property(css, "font-size", NULL); sp_repr_css_set_property(css, "font-size-adjust", NULL); // not implemented yet @@ -5076,6 +1705,7 @@ sp_css_attr_unset_text(SPCSSAttr *css) return css; } +// Called in style.cpp static bool is_url(char const *p) { @@ -5088,6 +1718,7 @@ is_url(char const *p) return (g_ascii_strncasecmp(p, "url(", 4) == 0); } +// Called in: ui/dialog/inkscape-preferences.cpp, ui/tools/tweek-tool.cpp /** * Unset any properties that contain URI values. * @@ -5113,6 +1744,7 @@ sp_css_attr_unset_uris(SPCSSAttr *css) return css; } +// Called in style.cpp /** * Scale a single-value property. */ @@ -5137,6 +1769,7 @@ sp_css_attr_scale_property_single(SPCSSAttr *css, gchar const *property, } } +// Called in style.cpp for stroke-dasharray /** * Scale a list-of-values property. */ @@ -5169,6 +1802,7 @@ sp_css_attr_scale_property_list(SPCSSAttr *css, gchar const *property, double ex } } +// Called in: text-editing.cpp, /** * Scale any properties that may hold by ex. */ @@ -5189,6 +1823,7 @@ sp_css_attr_scale(SPCSSAttr *css, double ex) } +// Called in style.cpp, xml/repr-css.cpp /** * Remove quotes and escapes from a string. Returned value must be g_free'd. * Note: in CSS (in style= and in stylesheets), unquoting and unescaping is done @@ -5215,11 +1850,15 @@ attribute_unquote(gchar const *val) return (val? g_strdup (val) : NULL); } +// Called in style.cpp, xml/repr-css.cpp /** * Quote and/or escape string for writing to CSS (style=). Returned value must be g_free'd. */ Glib::ustring css2_escape_quote(gchar const *val) { + std::cout << "css2_escape_quote: " << (val?val:"null") << std::endl; + //return val; + Glib::ustring t; bool quote = false; bool last_was_space = false; diff --git a/src/style.h b/src/style.h index 939ace0d3..76a0929cd 100644 --- a/src/style.h +++ b/src/style.h @@ -7,7 +7,9 @@ /* Authors: * Lauris Kaplinski * Jon A. Cruz + * Tavmjong Bah * + * Copyright (C) 2014 Tavmjong Bah * Copyright (C) 2010 Jon A. Cruz * Copyright (C) 2001-2002 Lauris Kaplinski * Copyright (C) 2001 Ximian, Inc. @@ -20,6 +22,15 @@ #include #include +#include +#include +// #include + +// Define SPIBasePtr, a Pointer to a data member of SPStyle of type SPIBase; +typedef SPIBase SPStyle::*SPIBasePtr; + +// Define SPPropMap, a map linking property name to property data +// typedef std::map SPPropMap; namespace Inkscape { namespace XML { @@ -27,24 +38,67 @@ class Node; } } +#include "libcroco/cr-declaration.h" +#include "libcroco/cr-prop-list.h" +//struct CRDeclaration; +//struct CRPropList; + + /// An SVG style object. -struct SPStyle { - int refcount; +class SPStyle { +public: + + SPStyle(SPDocument *document = NULL, SPObject *object = NULL);// document is ignored if valid object given + ~SPStyle(); + void clear(); + void read(SPObject *object, Inkscape::XML::Node *repr); + void readFromObject(SPObject *object); + void readFromPrefs(Glib::ustring const &path); + void readIfUnset( gint id, gchar const *val ); + Glib::ustring write( guint const flags, SPStyle const *const base = NULL ) const; + void cascade( SPStyle const *const parent ); + void merge( SPStyle const *const parent ); + bool operator==(const SPStyle& rhs); + + int ref() { ++_refcount; return _refcount; } + int unref() { --_refcount; return _refcount; } + +//FIXME: Make private +public: + void _mergeString( gchar const *const p ); // Rename to readFromString? +private: + void _mergeDeclList( CRDeclaration const *const decl_list ); + void _mergeDecl( CRDeclaration const *const decl ); + void _mergeProps( CRPropList *const props ); + void _mergeObjectStylesheet( SPObject const *const object ); + +private: + int _refcount; + static int _count; // Poor man's leak detector + +// FIXME: Make private +public: /** Object we are attached to */ SPObject *object; /** Document we are associated with */ SPDocument *document; - /** Our text style component */ - SPTextStyle *text; - unsigned text_private : 1; +private: + /// Pointers to all the properties (for looping through them) + std::vector _properties; + // static SPPropMap _propmap; + +public: + + /* ----------------------- THE PROPERTIES ------------------------- */ + + /** Our font style component */ + SPFontStyle *text; // FIXME: Break into font, font-family, ... /* CSS2 */ /* Font */ - /** Size of the font */ - SPIFontSize font_size; - /** Style of the font */ + /** Font style */ SPIEnum font_style; /** Which substyle of the font */ SPIEnum font_variant; @@ -52,26 +106,30 @@ struct SPStyle { SPIEnum font_weight; /** Stretch of the font */ SPIEnum font_stretch; + /** Size of the font */ + SPIFontSize font_size; + /** Line height (css2 10.8.1) */ + SPILengthOrNormal line_height; + /** Font shorthand */ + SPIFont font; /** First line indent of paragraphs (css2 16.1) */ SPILength text_indent; /** text alignment (css2 16.2) (not to be confused with text-anchor) */ SPIEnum text_align; - /** text decoration (css2 16.3.1) is now handled as a subset of css3 2.4 */ - // SPITextDecoration text_decoration; - + + /** text decoration (css2 16.3.1) */ + SPITextDecoration text_decoration; /** CSS 3 2.1, 2.2, 2.3 */ /** Not done yet, test_decoration3 = css3 2.4*/ SPITextDecorationLine text_decoration_line; - SPIPaint text_decoration_color; - SPITextDecorationStyle text_decoration_style; - + SPITextDecorationStyle text_decoration_style; // SPIEnum? Only one can be set at time. + SPIColor text_decoration_color; // used to implement text_decoration, not saved to or read from SVG file SPITextDecorationData text_decoration_data; // 16.3.2 is text-shadow. That's complicated. - /** Line spacing (css2 10.8.1) */ - SPILengthOrNormal line_height; + /** letter spacing (css2 16.4) */ SPILengthOrNormal letter_spacing; /** word spacing (also css2 16.4) */ @@ -93,14 +151,6 @@ struct SPStyle { /** Anchor of the text (svg1.1 10.9.1) */ SPIEnum text_anchor; - /* Misc attributes */ - unsigned clip_set : 1; - unsigned color_set : 1; - unsigned cursor_set : 1; - unsigned overflow_set : 1; - unsigned clip_path_set : 1; - unsigned mask_set : 1; - /** clip-rule: 0 nonzero, 1 evenodd */ SPIEnum clip_rule; @@ -121,8 +171,10 @@ struct SPStyle { // Could be shared with Filter blending mode SPIEnum blend_mode; + SPIPaintOrder paint_order; + /** color */ - SPIPaint color; + SPIColor color; /** color-interpolation */ SPIEnum color_interpolation; /** color-interpolation-filters */ @@ -155,16 +207,17 @@ struct SPStyle { /** Marker list */ SPIString marker[SP_MARKER_LOC_QTY]; - SPIPaintOrder paint_order; /** Filter effect */ SPIFilter filter; - + /** Filter blend mode */ SPIEnum filter_blend_mode; - - /** normally not used, but duplicates the Gaussian blur deviation (if any) from the attached + /** normally not used, but duplicates the Gaussian blur deviation (if any) from the attached filter when the style is used for querying */ SPILength filter_gaussianBlur_deviation; + /** enable-background, used for defining where filter effects get their background image */ + SPIEnum enable_background; + /** hints on how to render: e.g. speed vs. accuracy. * As of April, 2013, only image_rendering used. */ @@ -173,9 +226,7 @@ struct SPStyle { SPIEnum shape_rendering; SPIEnum text_rendering; - /** enable-background, used for defining where filter effects get - * their background image */ - SPIEnum enable_background; + /* ----------------------- END PROPERTIES ------------------------- */ /// style belongs to a cloned object bool cloned; @@ -186,46 +237,46 @@ struct SPStyle { sigc::connection fill_ps_modified_connection; sigc::connection stroke_ps_modified_connection; - SPObject *getFilter() { return (filter.href) ? filter.href->getObject() : NULL; } - SPObject const *getFilter() const { return (filter.href) ? filter.href->getObject() : NULL; } - gchar const *getFilterURI() const { return (filter.href) ? filter.href->getURI()->toString() : NULL; } + SPObject *getFilter() { return (filter.href) ? filter.href->getObject() : NULL; } + SPObject const *getFilter() const { return (filter.href) ? filter.href->getObject() : NULL; } + gchar const *getFilterURI() const { return (filter.href) ? filter.href->getURI()->toString() : NULL; } - SPPaintServer *getFillPaintServer() { return (fill.value.href) ? fill.value.href->getObject() : NULL; } - SPPaintServer const *getFillPaintServer() const { return (fill.value.href) ? fill.value.href->getObject() : NULL; } - gchar const *getFillURI() const { return (fill.value.href) ? fill.value.href->getURI()->toString() : NULL; } + SPPaintServer *getFillPaintServer() { return (fill.value.href) ? fill.value.href->getObject() : NULL; } + SPPaintServer const *getFillPaintServer() const { return (fill.value.href) ? fill.value.href->getObject() : NULL; } + gchar const *getFillURI() const { return (fill.value.href) ? fill.value.href->getURI()->toString() : NULL; } - SPPaintServer *getStrokePaintServer() { return (stroke.value.href) ? stroke.value.href->getObject() : NULL; } + SPPaintServer *getStrokePaintServer() { return (stroke.value.href) ? stroke.value.href->getObject() : NULL; } SPPaintServer const *getStrokePaintServer() const { return (stroke.value.href) ? stroke.value.href->getObject() : NULL; } - gchar const *getStrokeURI() const { return (stroke.value.href) ? stroke.value.href->getURI()->toString() : NULL; } + gchar const *getStrokeURI() const { return (stroke.value.href) ? stroke.value.href->getURI()->toString() : NULL; } }; -SPStyle *sp_style_new(SPDocument *document); +SPStyle *sp_style_new(SPDocument *document); // SPStyle::SPStyle( SPDocument *document = NULL ); -SPStyle *sp_style_new_from_object(SPObject *object); +SPStyle *sp_style_new_from_object(SPObject *object); // SPStyle::SPStyle( SPObject *object ); -SPStyle *sp_style_ref(SPStyle *style); +SPStyle *sp_style_ref(SPStyle *style); // SPStyle::ref(); -SPStyle *sp_style_unref(SPStyle *style); +SPStyle *sp_style_unref(SPStyle *style); // SPStyle::unref(); -void sp_style_read_from_object(SPStyle *style, SPObject *object); +void sp_style_read_from_object(SPStyle *style, SPObject *object); //SPStyle::read( SPObject * object); -void sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path); +void sp_style_read_from_prefs(SPStyle *style, Glib::ustring const &path); // SPStyle::read( ... ); -void sp_style_merge_from_style_string(SPStyle *style, gchar const *p); +void sp_style_merge_from_style_string(SPStyle *style, gchar const *p); // SPStyle::merge( ... );? -void sp_style_merge_from_parent(SPStyle *style, SPStyle const *parent); +void sp_style_merge_from_parent(SPStyle *style, SPStyle const *parent); // SPStyle::cascade( ... ); -void sp_style_merge_from_dying_parent(SPStyle *style, SPStyle const *parent); +void sp_style_merge_from_dying_parent(SPStyle *style, SPStyle const *parent); // SPStyle::merge( ... ) -gchar *sp_style_write_string(SPStyle const *style, guint flags = SP_STYLE_FLAG_IFSET); +gchar *sp_style_write_string(SPStyle const *style, guint flags = SP_STYLE_FLAG_IFSET);//SPStyle::write -gchar *sp_style_write_difference(SPStyle const *from, SPStyle const *to); +gchar *sp_style_write_difference(SPStyle const *from, SPStyle const *to); // SPStyle::write -void sp_style_set_to_uri_string (SPStyle *style, bool isfill, const gchar *uri); +void sp_style_set_to_uri_string (SPStyle *style, bool isfill, const gchar *uri); // ? -gchar const *sp_style_get_css_unit_string(int unit); -double sp_style_css_size_px_to_units(double size, int unit); -double sp_style_css_size_units_to_px(double size, int unit); +gchar const *sp_style_get_css_unit_string(int unit); // No change? +double sp_style_css_size_px_to_units(double size, int unit); // No change? +double sp_style_css_size_units_to_px(double size, int unit); // No change? SPCSSAttr *sp_css_attr_from_style (SPStyle const *const style, guint flags); @@ -254,3 +305,4 @@ Glib::ustring css2_escape_quote(gchar const *val); End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : + -- cgit v1.2.3 From e7793916fa449438c8e413cc7f500cd91b6b1030 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Apr 2014 06:42:06 +0200 Subject: Add missing style-internal.cpp (bzr r13299) --- src/style-internal.cpp | 2535 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2535 insertions(+) create mode 100644 src/style-internal.cpp (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp new file mode 100644 index 000000000..ede543078 --- /dev/null +++ b/src/style-internal.cpp @@ -0,0 +1,2535 @@ +/** + * @file + * SVG stylesheets implementation - Classes used by SPStyle class. + */ + +/* Authors: + * C++ conversion: + * Tavmjong Bah + * Legacy C implementation: + * Lauris Kaplinski + * Peter Moulder + * bulia byak + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2005 Monash University + * Copyright (C) 2012 Kris De Gussem + * Copyright (C) 2014 Tavmjong Bah + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "style-internal.h" +#include "style-enums.h" +#include "style.h" + +#include "svg/svg.h" +#include "svg/svg-color.h" +#include "svg/svg-icc-color.h" + +#include "streq.h" +#include "strneq.h" + +#include "extract-uri.h" +#include "preferences.h" +#include "svg/css-ostringstream.h" +#include "util/units.h" + +#include +#include + +// TODO REMOVE OR MAKE MEMBER FUNCTIONS +void sp_style_fill_paint_server_ref_changed( SPObject *old_ref, SPObject *ref, SPStyle *style); +void sp_style_stroke_paint_server_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style); +void sp_style_filter_ref_changed( SPObject *old_ref, SPObject *ref, SPStyle *style); +void sp_style_set_ipaint_to_uri(SPStyle *style, SPIPaint *paint, const Inkscape::URI *uri, SPDocument *document); +void sp_style_set_ipaint_to_uri_string (SPStyle *style, SPIPaint *paint, const gchar *uri); + +using Inkscape::CSSOStringStream; + +// SPIBase -------------------------------------------------------------- + + +// SPIFloat ------------------------------------------------------------- + +void +SPIFloat::read( gchar const *str ) { + + if( !str ) return; + + if ( !strcmp(str, "inherit") ) { + set = TRUE; + inherit = TRUE; + } else { + gfloat value_tmp; + if (sp_svg_number_read_f(str, &value_tmp)) { + set = TRUE; + inherit = FALSE; + value = value_tmp; + } + } +} + +const Glib::ustring +SPIFloat::write( guint const flags, SPIBase const *const base) const { + + SPIFloat const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + if (this->inherit) { + return (name + ":inherit;"); + } else { + Inkscape::CSSOStringStream os; + os << name << ":" << this->value << ";"; + return os.str(); + } + } + return Glib::ustring(""); +} + +void +SPIFloat::cascade( const SPIBase* const parent ) { + if( const SPIFloat* p = dynamic_cast(parent) ) { + if( (inherits && !set) || inherit ) value = p->value; + } else { + std::cerr << "SPIFloat::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPIFloat::merge( const SPIBase* const parent ) { + if( const SPIFloat* p = dynamic_cast(parent) ) { + if( inherits ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + value = p->value; + } + } + } else { + std::cerr << "SPIFloat::merge(): Incorrect parent type" << std::endl; + } +} + +bool +SPIFloat::operator==(const SPIBase& rhs) { + if( const SPIFloat* r = dynamic_cast(&rhs) ) { + return (value == r->value && SPIBase::operator==(rhs)); + } else { + return false; + } +} + + + +// SPIScale24 ----------------------------------------------------------- + +void +SPIScale24::read( gchar const *str ) { + + if( !str ) return; + + if ( !strcmp(str, "inherit") ) { + set = TRUE; + inherit = TRUE; + } else { + gfloat value_in; + if (sp_svg_number_read_f(str, &value_in)) { + set = TRUE; + inherit = FALSE; + value_in = CLAMP(value_in, 0.0, 1.0); + value = SP_SCALE24_FROM_FLOAT( value_in ); + } + } +} + +const Glib::ustring +SPIScale24::write( guint const flags, SPIBase const *const base) const { + + SPIScale24 const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + if (this->inherit) { + return (name + ":inherit;"); + } else { + Inkscape::CSSOStringStream os; + os << name << ":" << SP_SCALE24_TO_FLOAT(this->value) << ";"; + return os.str(); + } + } + return Glib::ustring(""); +} + +void +SPIScale24::cascade( const SPIBase* const parent ) { + if( const SPIScale24* p = dynamic_cast(parent) ) { + if( (inherits && !set) || inherit ) value = p->value; + } else { + std::cerr << "SPIScale24::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPIScale24::merge( const SPIBase* const parent ) { + if( const SPIScale24* p = dynamic_cast(parent) ) { + if( inherits ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + value = p->value; + } + } else { + // Needed only for 'opacity' which does not inherit. See comment at bottom of file. + if( name.compare( "opacity" ) != 0 ) + std::cerr << "SPIScale24::merge: unhandled property: " << name << std::endl; + if( !set || (!inherit && value == SP_SCALE24_MAX) ) { + value = p->value; + } else { + if( inherit ) value = p->value; // Insures child is up-to-date + value = SP_SCALE24_MUL( value, p->value ); + inherit = (inherit && p->inherit && (p->value == 0 || p->value == SP_SCALE24_MAX) ); + set = (inherit || value < SP_SCALE24_MAX); + } + } + } else { + std::cerr << "SPIScale24::merge(): Incorrect parent type" << std::endl; + } +} + +bool +SPIScale24::operator==(const SPIBase& rhs) { + if( const SPIScale24* r = dynamic_cast(&rhs) ) { + return (value == r->value && SPIBase::operator==(rhs)); + } else { + return false; + } +} + + + +// SPILength ------------------------------------------------------------ + +void +SPILength::read( gchar const *str ) { + + if( !str ) return; + + if (!strcmp(str, "inherit")) { + set = TRUE; + inherit = TRUE; + unit = SP_CSS_UNIT_NONE; + value = computed = 0.0; + } else { + gdouble value_tmp; + gchar *e; + /** \todo fixme: Move this to standard place (Lauris) */ + value_tmp = g_ascii_strtod(str, &e); + if ( !IS_FINITE(value_tmp) ) { // fix for bug lp:935157 + return; + } + if ((gchar const *) e != str) { + + value = value_tmp; + if (!*e) { + /* Userspace */ + unit = SP_CSS_UNIT_NONE; + computed = value; + } else if (!strcmp(e, "px")) { + /* Userspace */ + unit = SP_CSS_UNIT_PX; + computed = value; + } else if (!strcmp(e, "pt")) { + /* Userspace / DEVICESCALE */ + unit = SP_CSS_UNIT_PT; + computed = Inkscape::Util::Quantity::convert(value, "pt", "px"); + } else if (!strcmp(e, "pc")) { + unit = SP_CSS_UNIT_PC; + computed = Inkscape::Util::Quantity::convert(value, "pc", "px"); + } else if (!strcmp(e, "mm")) { + unit = SP_CSS_UNIT_MM; + computed = Inkscape::Util::Quantity::convert(value, "mm", "px"); + } else if (!strcmp(e, "cm")) { + unit = SP_CSS_UNIT_CM; + computed = Inkscape::Util::Quantity::convert(value, "cm", "px"); + } else if (!strcmp(e, "in")) { + unit = SP_CSS_UNIT_IN; + computed = Inkscape::Util::Quantity::convert(value, "in", "px"); + } else if (!strcmp(e, "em")) { + /* EM square */ + unit = SP_CSS_UNIT_EM; + if( style && &style->font_size ) { + computed = value * style->font_size.computed; + } else { + computed = value * style->font_size.font_size_default; + } + } else if (!strcmp(e, "ex")) { + /* ex square */ + unit = SP_CSS_UNIT_EX; + if( style && &style->font_size ) { + computed = value * style->font_size.computed * 0.5; // FIXME + } else { + computed = value * style->font_size.font_size_default * 0.5; + } + } else if (!strcmp(e, "%")) { + /* Percentage */ + unit = SP_CSS_UNIT_PERCENT; + value = value * 0.01; + } else { + /* Invalid */ + return; + } + set = TRUE; + inherit = FALSE; + } + } +} + +const Glib::ustring +SPILength::write( guint const flags, SPIBase const *const base) const { + + SPILength const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + if (this->inherit) { + return (name + ":inherit;"); + } else { + Inkscape::CSSOStringStream os; + switch (this->unit) { + case SP_CSS_UNIT_NONE: + os << name << ":" << this->computed << ";"; + break; + case SP_CSS_UNIT_PX: + os << name << ":" << this->computed << "px;"; + break; + case SP_CSS_UNIT_PT: + os << name << ":" << Inkscape::Util::Quantity::convert(this->computed, "px", "pt") << "pt;"; + break; + case SP_CSS_UNIT_PC: + os << name << ":" << Inkscape::Util::Quantity::convert(this->computed, "px", "pc") << "pc;"; + break; + case SP_CSS_UNIT_MM: + os << name << ":" << Inkscape::Util::Quantity::convert(this->computed, "px", "mm") << "mm;"; + break; + case SP_CSS_UNIT_CM: + os << name << ":" << Inkscape::Util::Quantity::convert(this->computed, "px", "cm") << "cm;"; + break; + case SP_CSS_UNIT_IN: + os << name << ":" << Inkscape::Util::Quantity::convert(this->computed, "px", "in") << "in;"; + break; + case SP_CSS_UNIT_EM: + os << name << ":" << this->value << "em;"; + break; + case SP_CSS_UNIT_EX: + os << name << ":" << this->value << "ex;"; + break; + case SP_CSS_UNIT_PERCENT: + os << name << ":" << (this->value * 100.0) << "%;"; + break; + default: + /* Invalid */ + break; + } + return os.str(); + } + } + return Glib::ustring(""); +} + +void +SPILength::cascade( const SPIBase* const parent ) { + if( const SPILength* p = dynamic_cast(parent) ) { + if( (inherits && !set) || inherit ) { + value = p->value; + computed = p->computed; + } else { + // Recalculate based on new font-size, font-family inherited from parent + double const em = style->font_size.computed; + if (unit == SP_CSS_UNIT_EM) { + computed = value * em; + } else if (unit == SP_CSS_UNIT_EX) { + // FIXME: Get x height from libnrtype or pango. + computed = value * em * 0.5; + } + } + } else { + std::cerr << "SPILength::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPILength::merge( const SPIBase* const parent ) { + if( const SPILength* p = dynamic_cast(parent) ) { + if( inherits ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + unit = p->unit; + value = p->value; + computed = p->computed; + + // Fix up so values are correct + switch (p->unit) { + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_EX: + g_assert( &style->font_size != NULL && &p->style->font_size != NULL ); + value *= p->style->font_size.computed / style->font_size.computed; + /** \todo + * FIXME: Have separate ex ratio parameter. + * Get x height from libnrtype or pango. + */ + if (!IS_FINITE(value)) { + value = computed; + unit = SP_CSS_UNIT_NONE; + } + break; + + default: + break; + } + } + } + } else { + std::cerr << "SPIFloat::merge(): Incorrect parent type" << std::endl; + } +} + +bool +SPILength::operator==(const SPIBase& rhs) { + if( const SPILength* r = dynamic_cast(&rhs) ) { + + if( unit != r->unit ) return false; + + // If length depends on external parameter, lengths cannot be equal. + if (unit == SP_CSS_UNIT_EM) return false; + if (unit == SP_CSS_UNIT_EX) return false; + if (unit == SP_CSS_UNIT_PERCENT) return false; + if (r->unit == SP_CSS_UNIT_EM) return false; + if (r->unit == SP_CSS_UNIT_EX) return false; + if (r->unit == SP_CSS_UNIT_PERCENT) return false; + + return (computed == r->computed ); + } else { + return false; + } +} + + + +// SPILengthOrNormal ---------------------------------------------------- + +void +SPILengthOrNormal::read( gchar const *str ) { + + if( !str ) return; + + if ( !strcmp(str, "normal") ) { + set = TRUE; + inherit = FALSE; + unit = SP_CSS_UNIT_NONE; + value = computed = 0.0; + normal = TRUE; + } else { + SPILength::read( str ); + normal = false; + } +}; + +const Glib::ustring +SPILengthOrNormal::write( guint const flags, SPIBase const *const base) const { + + SPILength const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + if (this->normal) { + return (name + ":normal;"); + } else { + return SPILength::write(flags, base); + } + } + return Glib::ustring(""); +} + +void +SPILengthOrNormal::merge( const SPIBase* const parent ) { + if( const SPILengthOrNormal* p = dynamic_cast(parent) ) { + if( inherits ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + normal = p->normal; + SPILength::merge( parent ); + } + } + } +} + +bool +SPILengthOrNormal::operator==(const SPIBase& rhs) { + if( const SPILengthOrNormal* r = dynamic_cast(&rhs) ) { + if( normal && r->normal ) { return true; } + if( normal != r->normal ) { return false; } + return SPILength::operator==(rhs); + } else { + return false; + } +} + + + +// SPIEnum -------------------------------------------------------------- + +void +SPIEnum::read( gchar const *str ) { + + if( !str ) return; + + if( !strcmp(str, "inherit") ) { + set = TRUE; + inherit = TRUE; + } else { + for (unsigned i = 0; enums[i].key; i++) { + if (!strcmp(str, enums[i].key)) { + set = TRUE; + inherit = FALSE; + value = enums[i].value; + /* Save copying for values not needing it */ + computed = value; + break; + } + } + // The following is defined in CSS 2.1 + if( name.compare("font-weight" ) == 0 ) { + if( value == SP_CSS_FONT_WEIGHT_NORMAL ) { + computed = SP_CSS_FONT_WEIGHT_400; + } else if (value == SP_CSS_FONT_WEIGHT_BOLD ) { + computed = SP_CSS_FONT_WEIGHT_700; + } + } + } +} + +const Glib::ustring +SPIEnum::write( guint const flags, SPIBase const *const base) const { + + SPIEnum const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + if (this->inherit) { + return (name + ":inherit;"); + } + for (unsigned i = 0; enums[i].key; ++i) { + if (enums[i].value == static_cast< gint > (this->value) ) { + return (name + ":" + enums[i].key + ";"); + } + } + } + return Glib::ustring(""); +} + +void +SPIEnum::cascade( const SPIBase* const parent ) { + if( const SPIEnum* p = dynamic_cast(parent) ) { + if( inherits && (!set || inherit) ) { + computed = p->computed; + } else { + if( name.compare("font-stretch" ) == 0 ) { + unsigned const parent_val = p->computed; + if( value == SP_CSS_FONT_STRETCH_NARROWER ) { + computed = (parent_val == SP_CSS_FONT_STRETCH_ULTRA_CONDENSED ? + parent_val : parent_val - 1); + } else if (value == SP_CSS_FONT_STRETCH_WIDER ) { + computed = (parent_val == SP_CSS_FONT_STRETCH_ULTRA_EXPANDED ? + parent_val : parent_val + 1); + } + } + // strictly, 'bolder' and 'lighter' should go to the next weight + // expressible in the current font family, but that's difficult to + // find out, so jumping by 3 seems an appropriate approximation + if( name.compare("font-weight" ) == 0 ) { + unsigned const parent_val = p->computed; + if( value == SP_CSS_FONT_WEIGHT_LIGHTER ) { + computed = (parent_val <= SP_CSS_FONT_WEIGHT_100 + 3 ? + (unsigned)SP_CSS_FONT_WEIGHT_100 : parent_val - 3); + } else if (value == SP_CSS_FONT_WEIGHT_BOLDER ) { + computed = (parent_val >= SP_CSS_FONT_WEIGHT_900 - 3 ? + (unsigned)SP_CSS_FONT_WEIGHT_900 : parent_val + 3); + } + } + } + } else { + std::cerr << "SPIEnum::cascade(): Incorrect parent type" << std::endl; + } +} + +// FIXME Handle font_stretch and font_weight (relative values) New derived class? +void +SPIEnum::merge( const SPIBase* const parent ) { + if( const SPIEnum* p = dynamic_cast(parent) ) { + if( inherits ) { + if( p->set && !p->inherit ) { + if( !set || inherit ) { + set = p->set; + inherit = p->inherit; + value = p->value; + computed = p->computed; // Different from value for font-weight and font-stretch + } else { + // The following is to special case 'font-stretch' and 'font-weight' + unsigned max_computed_val = 100; + unsigned smaller_val = 100; + if( name.compare("font-stretch" ) == 0 ) { + max_computed_val = SP_CSS_FONT_STRETCH_ULTRA_EXPANDED; + smaller_val = SP_CSS_FONT_STRETCH_NARROWER; + } else if( name.compare("font-weight" ) == 0 ) { + max_computed_val = SP_CSS_FONT_WEIGHT_900; + smaller_val = SP_CSS_FONT_WEIGHT_LIGHTER; + } + unsigned const min_computed_val = 0; + unsigned const larger_val = smaller_val + 1; + if( value < smaller_val ) { + // Child has absolute value, leave as is. + // Works for all enum properties + } else if( (value == smaller_val && p->value == larger_val ) || + (value == larger_val && p->value == smaller_val) ) { + // Values cancel, unset + set = false; + } else if( value == p->value ) { + // Leave as is, what does applying "wider" twice do? + } else { + // Child is smaller or larger, adjust parent value accordingly + unsigned const parent_val = p->computed; + value = (value == smaller_val ? + ( parent_val == min_computed_val ? parent_val : parent_val - 1 ) : + ( parent_val == max_computed_val ? parent_val : parent_val + 1 ) ); + g_assert(value <= max_computed_val); + inherit = false; + g_assert(set); + } + } + } + } + } +} + +bool +SPIEnum::operator==(const SPIBase& rhs) { + if( const SPIEnum* r = dynamic_cast(&rhs) ) { + return (computed == r->computed && SPIBase::operator==(rhs)); + } else { + return false; + } +} + + + +// SPIString ------------------------------------------------------------ + +void +SPIString::read( gchar const *str ) { + + if( !str ) return; + + g_free(value); + + if (!strcmp(str, "inherit")) { + set = TRUE; + inherit = TRUE; + value = NULL; + } else { + set = TRUE; + inherit = FALSE; + value = g_strdup(str); + } +} + + +const Glib::ustring +SPIString::write( guint const flags, SPIBase const *const base) const { + + SPIString const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + if (this->inherit) { + return (name + ":inherit;"); + } else { + if( this->value ) { + if( name.compare( "font-family" ) == 0 ) { + // This is for compatibilty with the C version of code. + // This is incorrect as it puts single quotes around the + // entire string rather around the individule font names. + // This should be handled by the routines that extract + // out the font family names and reassembles them into a + // font fallback list. FIXME + return (name + ":" + css2_escape_quote(this->value) + ";"); + } else { + return (name + ":" + this->value + ";"); + } + } + } + } + return Glib::ustring(""); +} + +void +SPIString::cascade( const SPIBase* const parent ) { + if( const SPIString* p = dynamic_cast(parent) ) { + if( inherits && (!set || inherit) ) { + g_free(value); + value = g_strdup(p->value); + } + } else { + std::cerr << "SPIString::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPIString::merge( const SPIBase* const parent ) { + if( const SPIString* p = dynamic_cast(parent) ) { + if( inherits ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + g_free(value); + value = g_strdup(p->value); + } + } + } +} + +bool +SPIString::operator==(const SPIBase& rhs) { + if( const SPIString* r = dynamic_cast(&rhs) ) { + if( value == NULL && r->value == NULL ) return (SPIBase::operator==(rhs)); + if( value == NULL || r->value == NULL ) return false; + + return (strcmp(value, r->value) == 0 && SPIBase::operator==(rhs)); + } else { + return false; + } +} + + + +// SPIColor ------------------------------------------------------------- + +// Used for 'color', 'text-decoration-color', 'flood-color', 'lighting-color', and 'stop-color'. +// (The last three have yet to be implemented.) +// CSS3: 'currentcolor' is allowed value and is equal to inherit for the 'color' property. +// FIXME: We should preserve named colors, hsl colors, etc. +void SPIColor::read( gchar const *str ) { + + if( !str ) return; + + set = false; + inherit = false; + currentcolor = false; + if ( !strcmp(str, "inherit") ) { + set = true; + inherit = true; + } else if ( !strcmp(str, "currentColor") ) { + set = true; + currentcolor = true; + if( name.compare( "color") == 0 ) { + inherit = true; // CSS3 + } else { + value.color = style->color.value.color; + } + } else { + guint32 const rgb0 = sp_svg_read_color(str, 0xff); + if (rgb0 != 0xff) { + setColor(rgb0); + set = TRUE; + } + } +} + +const Glib::ustring +SPIColor::write( guint const flags, SPIBase const *const base) const { + + SPIColor const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + CSSOStringStream css; + + if (this->currentcolor) { + // currentcolor goes first to handle special case for 'color' property + css << "currentColor"; + } else if (this->inherit) { + css << "inherit"; + } else { + char color_buf[8]; + sp_svg_write_color(color_buf, sizeof(color_buf), this->value.color.toRGBA32( 0 )); + css << color_buf; + + if (this->value.color.icc) { + if ( !css.str().empty() ) { + css << " "; + } + css << "icc-color(" << this->value.color.icc->colorProfile; + for (std::vector::const_iterator i(this->value.color.icc->colors.begin()), + iEnd(this->value.color.icc->colors.end()); + i != iEnd; ++i) { + css << ", " << *i; + } + css << ')'; + } + } + + if ( !css.str().empty() ) { + return (name + ":" + css.str() + ";"); + } + } + + return Glib::ustring(""); +} + +void +SPIColor::cascade( const SPIBase* const parent ) { + if( const SPIColor* p = dynamic_cast(parent) ) { + if( (inherits && !set) || inherit) { // FIXME verify for 'color' + if( !(inherit && currentcolor) ) currentcolor = p->currentcolor; + value.color = p->value.color; + } else { + // Add CSS4 Color: Lighter, Darker + } + } else { + std::cerr << "SPIColor::cascade(): Incorrect parent type" << std::endl; + } + +} + +void +SPIColor::merge( const SPIBase* const parent ) { + if( const SPIColor* p = dynamic_cast(parent) ) { + if( inherits ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + currentcolor = p->currentcolor; + value.color = p->value.color; + } + } + } +} + +bool +SPIColor::operator==(const SPIBase& rhs) { + if( const SPIColor* r = dynamic_cast(&rhs) ) { + + if ( (this->currentcolor != r->currentcolor ) || + (this->value.color != r->value.color ) || + (this->value.color.icc != r->value.color.icc ) || + (this->value.color.icc && r->value.color.icc && + this->value.color.icc->colorProfile != r->value.color.icc->colorProfile && + this->value.color.icc->colors != r->value.color.icc->colors ) ) { + return false; + } + + return SPIBase::operator==(rhs); + + } else { + return false; + } +} + + + +// SPIPaint ------------------------------------------------------------- + +// Paint is used for 'fill' and 'stroke'. SPIPaint perhaps should be derived from SPIColor. +// 'style' is set in SPStyle::SPStyle or in the legacy SPIPaint::read( gchar, style, document ) +// It is needed for computed value when value is 'currentColor'. It is also needed to +// find the object for creating an href (this is done through document but should be done +// directly so document not needed.. FIXME). + +SPIPaint::~SPIPaint() { + if( value.href ) { + clear(); + delete value.href; + value.href = NULL; + } +} + +/** + * Set SPIPaint object from string. + * + * \pre paint == \&style.fill || paint == \&style.stroke. + */ +void +SPIPaint::read( gchar const *str ) { + + // std::cout << "SPIPaint::read: Entrance: " << " |" << (str?str:"null") << "|" << std::endl; + // if( style ) { + // std::cout << " document: " << (void*)style->document << std::endl; + // std::cout << " object: " << (style->object?"present":"null") << std::endl; + // if( style->object ) + // std::cout << " : " << (style->object->getId()?style->object->getId():"no ID") + // << " document: " << (style->object->document?"yes":"no") << std::endl; + // } + + if(!str ) return; + + reset( false ); // Do not init + + // Is this necessary? + while (g_ascii_isspace(*str)) { + ++str; + } + + if (streq(str, "inherit")) { + set = TRUE; + inherit = TRUE; + } else { + // Read any URL first. The other values can be stand-alone or backup to the URL. + + if ( strneq(str, "url", 3) ) { + + // FIXME: THE FOLLOWING CODE SHOULD BE PUT IN A PRIVATE FUNCTION FOR REUSE + gchar *uri = extract_uri( str, &str ); + if(uri == NULL || uri[0] == '\0') { + std::cerr << "SPIPaint::read: url is empty or invalid" << std::endl; + } else if (!style ) { + std::cerr << "SPIPaint::read: url with empty SPStyle pointer" << std::endl; + } else { + set = TRUE; + SPDocument *document = (style->object) ? style->object->document : NULL; + + // Create href if not done already + if (!value.href && document) { + // std::cout << " Creating value.href" << std::endl; + value.href = new SPPaintServerReference(document); + value.href->changedSignal().connect(sigc::bind(sigc::ptr_fun((this == &style->fill)? sp_style_fill_paint_server_ref_changed : sp_style_stroke_paint_server_ref_changed), style)); + } + + // std::cout << "uri: " << (uri?uri:"null") << std::endl; + // TODO check what this does in light of move away from union + sp_style_set_ipaint_to_uri_string ( style, this, uri); + } + g_free( uri ); + } + + while ( g_ascii_isspace(*str) ) { + ++str; + } + + if (streq(str, "currentColor")) { + set = TRUE; + currentcolor = TRUE; + value.color = style->color.value.color; + } else if (streq(str, "none")) { + set = TRUE; + noneSet = TRUE; + } else { + guint32 const rgb0 = sp_svg_read_color(str, &str, 0xff); + if (rgb0 != 0xff) { + setColor( rgb0 ); + set = TRUE; + + while (g_ascii_isspace(*str)) { + ++str; + } + if (strneq(str, "icc-color(", 10)) { + SVGICCColor* tmp = new SVGICCColor(); + if ( ! sp_svg_read_icc_color( str, &str, tmp ) ) { + delete tmp; + tmp = 0; + } + value.color.icc = tmp; + } + } + } + } +} + +// Stand-alone read (Legacy read()), used multiple places, e.g. sp-stop.cpp +// This function should not be necessary. FIXME +void +SPIPaint::read( gchar const *str, SPStyle &style_in, SPDocument *document_in ) { + style = &style_in; + style->document = document_in; + read( str ); +} + +const Glib::ustring +SPIPaint::write( guint const flags, SPIBase const *const base) const { + + SPIPaint const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + CSSOStringStream css; + + if (this->inherit) { + css << "inherit"; + } else { + + // url must go first as other values can serve as fallbacks + if ( this->value.href && this->value.href->getURI() ) { + const gchar* uri = this->value.href->getURI()->toString(); + css << "url(" << uri << ")"; + g_free((void *)uri); + } + + if ( this->noneSet ) { + if ( !css.str().empty() ) { + css << " "; + } + css << "none"; + } + + if ( this->currentcolor ) { + if ( !css.str().empty() ) { + css << " "; + } + css << "currentColor"; + } + + if ( this->colorSet && !this->currentcolor ) { + if ( !css.str().empty() ) { + css << " "; + } + char color_buf[8]; + sp_svg_write_color(color_buf, sizeof(color_buf), this->value.color.toRGBA32( 0 )); + css << color_buf; + } + + if (this->value.color.icc && !this->currentcolor) { + if ( !css.str().empty() ) { + css << " "; + } + css << "icc-color(" << this->value.color.icc->colorProfile; + for (std::vector::const_iterator i(this->value.color.icc->colors.begin()), + iEnd(this->value.color.icc->colors.end()); + i != iEnd; ++i) { + css << ", " << *i; + } + css << ')'; + } + } + + if ( !css.str().empty() ) { + return (name + ":" + css.str() + ";"); + } + } + + return Glib::ustring(""); +} + +void +SPIPaint::clear() { + // std::cout << "SPIPaint::clear(): " << name << std::endl; + reset( true ); // Reset and Init +} + +void +SPIPaint::reset( bool init ) { + + // std::cout << "SPIPaint::reset(): " << name << " " << init << std::endl; + SPIBase::clear(); + currentcolor = false; + colorSet = false; + noneSet = false; + value.color.set( false ); + if (value.href){ + if (value.href->getObject()) { + value.href->detach(); + } + } + if( init ) { + if( name.compare( "fill" ) == 0 ) { + // 'black' is default for 'fill' + setColor(0.0, 0.0, 0.0); + } + if( name.compare( "text-decoration-color" ) == 0 ) { + currentcolor = true; + } + } +} + +void +SPIPaint::cascade( const SPIBase* const parent ) { + + // std::cout << "SPIPaint::cascade" << std::endl; + if( const SPIPaint* p = dynamic_cast(parent) ) { + if(!set || inherit) { // Always inherits + + reset( false ); // Do not init + + if( p->isPaintserver() ) { + if( p->value.href) { + // Why can we use p->document ? + sp_style_set_ipaint_to_uri( style, this, p->value.href->getURI(), p->value.href->getOwnerDocument()); + } else { + std::cerr << "SPIPaint::cascade: Expected paint server not found." << std::endl; + } + } else if( p->isColor() ) { + setColor( p->value.color ); + } else if( p->isNoneSet() ) { + noneSet = TRUE; + } else if( p->currentcolor ) { + currentcolor = TRUE; + value.color = style->color.value.color; + } else if( isNone() ) { + // + } else { + g_assert_not_reached(); + } + } else { + if( currentcolor ) { + // Update in case color value changed. + value.color = style->color.value.color; + } + } + + } else { + std::cerr << "SPIPaint::cascade(): Incorrect parent type" << std::endl; + } + +} + +void +SPIPaint::merge( const SPIBase* const parent ) { + if( const SPIPaint* p = dynamic_cast(parent) ) { + // if( inherits ) { Paint always inherits + if( (!set || inherit) && p->set && !(p->inherit) ) { + this->cascade( parent ); // Must call before setting 'set' + set = p->set; + inherit = p->inherit; + } + } +} + +bool +SPIPaint::operator==(const SPIBase& rhs) { + + if( const SPIPaint* r = dynamic_cast(&rhs) ) { + + if ( (this->isColor() != r->isColor() ) || + (this->isPaintserver() != r->isPaintserver() ) || + (this->currentcolor != r->currentcolor ) ) { + return false; + } + + if ( this->isPaintserver() ) { + if( this->value.href == NULL || r->value.href == NULL || + this->value.href->getObject() != r->value.href->getObject() ) { + return false; + } + } + + if ( this->isColor() ) { + if ( (this->value.color != r->value.color ) || + (this->value.color.icc != r->value.color.icc ) || + (this->value.color.icc && r->value.color.icc && + this->value.color.icc->colorProfile != r->value.color.icc->colorProfile && + this->value.color.icc->colors != r->value.color.icc->colors ) ) { + return false; + } + } + + return SPIBase::operator==(rhs); + + } else { + return false; + } +} + + + +// SPIPaintOrder -------------------------------------------------------- + +void +SPIPaintOrder::read( gchar const *str ) { + + if( !str ) return; + + g_free(value); + set = FALSE; + inherit = FALSE; + + if (!strcmp(str, "inherit")) { + set = TRUE; + inherit = TRUE; + } else { + set = TRUE; + value = g_strdup(str); + + if (!strcmp(value, "normal")) { + layer[0] = SP_CSS_PAINT_ORDER_NORMAL; + layer_set[0] = true; + } else { + // This certainly can be done more efficiently + gchar** c = g_strsplit(value, " ", PAINT_ORDER_LAYERS + 1); + bool used[3] = {false, false, false}; + unsigned int i = 0; + for( ; i < PAINT_ORDER_LAYERS; ++i ) { + if( c[i] ) { + layer_set[i] = false; + if( !strcmp( c[i], "fill")) { + layer[i] = SP_CSS_PAINT_ORDER_FILL; + layer_set[i] = true; + used[0] = true; + } else if( !strcmp( c[i], "stroke")) { + layer[i] = SP_CSS_PAINT_ORDER_STROKE; + layer_set[i] = true; + used[1] = true; + } else if( !strcmp( c[i], "markers")) { + layer[i] = SP_CSS_PAINT_ORDER_MARKER; + layer_set[i] = true; + used[2] = true; + } else { + std::cerr << "sp_style_read_ipaintorder: illegal value: " << c[i] << std::endl; + break; + } + } else { + break; + } + } + g_strfreev(c); + + // Fill out rest of the layers using the default order + if( !used[0] && i < PAINT_ORDER_LAYERS ) { + layer[i] = SP_CSS_PAINT_ORDER_FILL; + layer_set[i] = false; + ++i; + } + if( !used[1] && i < PAINT_ORDER_LAYERS ) { + layer[i] = SP_CSS_PAINT_ORDER_STROKE; + layer_set[i] = false; + ++i; + } + if( !used[2] && i < PAINT_ORDER_LAYERS ) { + layer[i] = SP_CSS_PAINT_ORDER_MARKER; + layer_set[i] = false; + } + } + } +} + +const Glib::ustring +SPIPaintOrder::write( guint const flags, SPIBase const *const base) const { + + SPIPaintOrder const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + CSSOStringStream css; + + if (this->inherit) { + css << "inherit"; + } else { + for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) { + if( this->layer_set[i] == true ) { + switch (this->layer[i]) { + case SP_CSS_PAINT_ORDER_NORMAL: + css << "normal"; + assert( i == 0 ); + break; + case SP_CSS_PAINT_ORDER_FILL: + if (i!=0) css << " "; + css << "fill"; + break; + case SP_CSS_PAINT_ORDER_STROKE: + if (i!=0) css << " "; + css << "stroke"; + break; + case SP_CSS_PAINT_ORDER_MARKER: + if (i!=0) css << " "; + css << "markers"; + break; + } + } else { + break; + } + } + } + return (name + ":" + css.str() + ";"); + } + return Glib::ustring(""); +} + +void +SPIPaintOrder::cascade( const SPIBase* const parent ) { + if( const SPIPaintOrder* p = dynamic_cast(parent) ) { + if(!set || inherit) { // Always inherits + for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) { + layer[i] = p->layer[i]; + layer_set[i] = p->layer_set[i]; + } + g_free( value ); + value = g_strdup(p->value); + } + } else { + std::cerr << "SPIPaintOrder::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPIPaintOrder::merge( const SPIBase* const parent ) { + if( const SPIPaintOrder* p = dynamic_cast(parent) ) { + // if( inherits ) { PaintOrder always inherits + if( (!set || inherit) && p->set && !(p->inherit) ) { + this->cascade( parent ); // Must call be setting 'set' + set = p->set; + inherit = p->inherit; + } + } +} + +bool +SPIPaintOrder::operator==(const SPIBase& rhs) { + if( const SPIPaintOrder* r = dynamic_cast(&rhs) ) { + if( layer[0] == SP_CSS_PAINT_ORDER_NORMAL && + r->layer[0] == SP_CSS_PAINT_ORDER_NORMAL ) return SPIBase::operator==(rhs); + for (unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) { + if( layer[i] != r->layer[i] ) return false; + } + return SPIBase::operator==(rhs); + } else { + return false; + } +} + + + +// SPIFilter ------------------------------------------------------------ + +SPIFilter::~SPIFilter() { + if( href ) { + clear(); + delete href; + href = NULL; + } +} + +void +SPIFilter::read( gchar const *str ) { + + if( !str ) return; + + clear(); + + if ( streq(str, "inherit") ) { + set = TRUE; + inherit = TRUE; + } else if(streq(str, "none")) { + set = TRUE; + } else if (strneq(str, "url", 3)) { + gchar *uri = extract_uri(str); + if(uri == NULL || uri[0] == '\0') { + std::cerr << "SPIFilter::read: url is empty or invalid" << std::endl; + return; + } else if (!style) { + std::cerr << "SPIFilter::read: url with empty SPStyle pointer" << std::endl; + return; + } + set = TRUE; + + // Create href if not already done. + if (!href && style->object) { + href = new SPFilterReference(style->object); + href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); + } + + try { + href->attach(Inkscape::URI(uri)); + } catch (Inkscape::BadURIException &e) { + std::cerr << "SPIFilter::read() " << e.what() << std::endl; + href->detach(); + } + g_free (uri); + + } else { + std::cerr << "SPIFilter::read(): malformed value: " << str << std::endl; + } +} + +const Glib::ustring +SPIFilter::write( guint const flags, SPIBase const *const base) const { + + // TODO: fix base + //SPILength const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set)) + { + if (this->inherit) { + return (name + ":inherit;"); + } else if(this->href && this->href->getURI()) { + gchar *uri = this->href->getURI()->toString(); + Glib::ustring retval = name + ":url(" + uri + ");"; + g_free(uri); + return retval; + } + } + return Glib::ustring(""); +} + + +void +SPIFilter::clear() { + + SPIBase::clear(); + if( href ) { + if( href->getObject() ) { + href->detach(); + } + } +} + +void +SPIFilter::cascade( const SPIBase* const parent ) { + if( const SPIFilter* p = dynamic_cast(parent) ) { + if( inherit ) { // Only inherits if 'inherit' true/ + // This is rather unlikely so ignore for now. FIXME + (void)p; + std::cerr << "SPIFilter::cascade: value 'inherit' not supported." << std::endl; + } else { + // Do nothing + } + } else { + std::cerr << "SPIFilter::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPIFilter::merge( const SPIBase* const parent ) { + if( const SPIFilter* p = dynamic_cast(parent) ) { + // The "correct" thing to due is to combine the filter primitives. + // The next best thing is to keep any filter on this object. If there + // is no filter on this object, then use any filter on the parent. + if( (!set || inherit) && p->href && p->href->getObject() ) { // is the getObject() needed? + set = p->set; + inherit = p->inherit; + if( href ) { + // If we alread have an href, use it (unlikely but heck...) + if( href->getObject() ) { + href->detach(); + } + } else { + // If we don't have an href, create it + if( &style->document ) { // FIXME + href = new SPFilterReference(style->document); + //href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); + } + } + if( href ) { + // If we now have an href, try to attach parent filter + try { + href->attach(*p->href->getURI()); + } catch (Inkscape::BadURIException &e) { + std::cerr << "SPIFilter::merge: " << e.what() << std::endl; + href->detach(); + } + } + } + } +} + +// FIXME +bool +SPIFilter::operator==(const SPIBase& rhs) { + if( const SPIFilter* r = dynamic_cast(&rhs) ) { + (void)r; + return true; + } else { + return false; + } +} + + + +// SPIDashArray --------------------------------------------------------- + +void +SPIDashArray::read( gchar const *str ) { + + if( !str ) return; + + set = true; + + if( strcmp( str, "inherit") == 0 ) { + inherit = true; + return; + } + + values.clear(); + + if( strcmp(str, "none") == 0) { + return; + } + + gchar *e = NULL; + bool LineSolid = true; + while (e != str) { + /* TODO: Should allow rather than just a unitless (px) number. */ + double number = g_ascii_strtod(str, (char **) &e); + values.push_back( number ); + if (number > 0.00000001) + LineSolid = false; + if (e != str) { + str = e; + } + while (str && *str && !isalnum(*str)) str += 1; + } + + if (LineSolid) { + values.clear(); + } + return; +} + +const Glib::ustring +SPIDashArray::write( guint const flags, SPIBase const *const base) const { + + SPIDashArray const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + if (this->inherit) { + return (name + ":inherit;"); + } else if (this->values.empty() ) { + return (name + ":none;"); + } else { + Inkscape::CSSOStringStream os; + os << name << ":"; + for (unsigned i = 0; i < this->values.size(); ++i) { + if (i) { + os << ", "; + } + os << this->values[i]; + } + os << ";"; + return os.str(); + } + } + return Glib::ustring(""); +} + + +void +SPIDashArray::cascade( const SPIBase* const parent ) { + if( const SPIDashArray* p = dynamic_cast(parent) ) { + if( !set || inherit ) values = p->values; // Always inherits + } else { + std::cerr << "SPIDashArray::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPIDashArray::merge( const SPIBase* const parent ) { + if( const SPIDashArray* p = dynamic_cast(parent) ) { + if( inherits ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + values = p->values; + } + } + } else { + std::cerr << "SPIDashArray::merge(): Incorrect parent type" << std::endl; + } +} + +bool +SPIDashArray::operator==(const SPIBase& rhs) { + if( const SPIDashArray* r = dynamic_cast(&rhs) ) { + return values == r->values && SPIBase::operator==(rhs); + } else { + return false; + } +} + + + +// SPIFontSize ---------------------------------------------------------- + +/** Indexed by SP_CSS_FONT_SIZE_blah. These seem a bit small */ +float const SPIFontSize::font_size_table[] = {6.0, 8.0, 10.0, 12.0, 14.0, 18.0, 24.0}; +float const SPIFontSize::font_size_default = 12.0; + +void +SPIFontSize::read( gchar const *str ) { + + if( !str ) return; + + if (!strcmp(str, "inherit")) { + set = TRUE; + inherit = TRUE; + } else if ((*str == 'x') || (*str == 's') || (*str == 'm') || (*str == 'l')) { + // xx-small, x-small, etc. + for (unsigned i = 0; enum_font_size[i].key; i++) { + if (!strcmp(str, enum_font_size[i].key)) { + set = TRUE; + inherit = FALSE; + type = SP_FONT_SIZE_LITERAL; + literal = enum_font_size[i].value; + return; + } + } + /* Invalid */ + return; + } else { + SPILength length("temp"); + length.set = FALSE; + length.read( str ); + if( length.set ) { + set = TRUE; + inherit = length.inherit; + unit = length.unit; + value = length.value; + computed = length.computed; + if( unit == SP_CSS_UNIT_PERCENT ) { + type = SP_FONT_SIZE_PERCENTAGE; + } else { + type = SP_FONT_SIZE_LENGTH; + } + } + return; + } +} + +const Glib::ustring +SPIFontSize::write( guint const flags, SPIBase const *const base) const { + + SPIFontSize const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + CSSOStringStream css; + + if (this->inherit) { + css << "inherit"; + } else if (this->type == SP_FONT_SIZE_LITERAL) { + for (unsigned i = 0; enum_font_size[i].key; i++) { + if (enum_font_size[i].value == static_cast< gint > (this->literal) ) { + css << enum_font_size[i].key; + } + } + } else if (this->type == SP_FONT_SIZE_LENGTH) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); + if (prefs->getBool("/options/font/textOutputPx", true)) { + unit = SP_CSS_UNIT_PX; + } + css << sp_style_css_size_px_to_units(this->computed, unit) << sp_style_get_css_unit_string(unit); + } else if (this->type == SP_FONT_SIZE_PERCENTAGE) { + css << (this->value * 100.0) << "%"; + } + return (name + ":" + css.str() + ";"); + } + return Glib::ustring(""); +} + +void +SPIFontSize::cascade( const SPIBase* const parent ) { + if( const SPIFontSize* p = dynamic_cast(parent) ) { + if( !set || inherit ) { // Always inherits + computed = p->computed;value = p->value; + + + // Calculate computed based on parent as needed + } else if( type == SP_FONT_SIZE_LITERAL ) { + if( literal < SP_CSS_FONT_SIZE_SMALLER ) { + computed = font_size_table[ literal ]; + } else if( literal == SP_CSS_FONT_SIZE_SMALLER ) { + computed = p->computed / 1.2; + } else if( literal == SP_CSS_FONT_SIZE_LARGER ) { + computed = p->computed * 1.2; + } else { + std::cerr << "SPIFontSize::cascade: Illegal literal value" << std::endl; + } + } else if( type == SP_FONT_SIZE_PERCENTAGE ) { + // Percentage for font size is relative to parent computed (rather than viewport) + computed = p->computed * value; + } else if( type == SP_FONT_SIZE_LENGTH ) { + switch ( unit ) { + case SP_CSS_UNIT_EM: + /* Relative to parent font size */ + computed = p->computed * value; + break; + case SP_CSS_UNIT_EX: + /* Relative to parent font size */ + computed = p->computed * value * 0.5; /* Hack FIXME */ + break; + default: + /* No change */ + break; + } + } + } else { + std::cerr << "SPIFontSize::cascade(): Incorrect parent type" << std::endl; + } +} + +double +SPIFontSize::relative_fraction() const { + + switch (type) { + case SP_FONT_SIZE_LITERAL: { + switch (literal) { + case SP_CSS_FONT_SIZE_SMALLER: + return 5.0 / 6.0; + + case SP_CSS_FONT_SIZE_LARGER: + return 6.0 / 5.0; + + default: + g_assert_not_reached(); + } + } + + case SP_FONT_SIZE_PERCENTAGE: + return value; + + case SP_FONT_SIZE_LENGTH: { + switch (unit ) { + case SP_CSS_UNIT_EM: + return value; + + case SP_CSS_UNIT_EX: + return value * 0.5; + + default: + g_assert_not_reached(); + } + } + } + g_assert_not_reached(); +} + +void +SPIFontSize::merge( const SPIBase* const parent ) { + if( const SPIFontSize* p = dynamic_cast(parent) ) { + if( p->set && !(p->inherit) ) { + // Parent has definined font-size + if( (!set || inherit) ) { + // Computed value same as parent + set = p->set; + inherit = p->inherit; + value = p->value; + computed = p->computed; // Just to be sure + } else if ( type == SP_FONT_SIZE_LENGTH && + unit != SP_CSS_UNIT_EM && + unit != SP_CSS_UNIT_EX ) { + // Absolute size, computed value already set + } else if ( type == SP_FONT_SIZE_LITERAL && + literal < SP_CSS_FONT_SIZE_SMALLER ) { + // Absolute size, computed value already set + //g_assert( literal < G_N_ELEMENTS(font_size_table) ); + g_assert( computed == font_size_table[literal] ); + } else { + // Relative size + double const child_frac( relative_fraction() ); + set = true; + inherit = false; + computed = p->computed * child_frac; + + if ( ( p->type == SP_FONT_SIZE_LITERAL && + p->literal < SP_CSS_FONT_SIZE_SMALLER ) || + ( p->type == SP_FONT_SIZE_LENGTH && + p->unit != SP_CSS_UNIT_EM && + p->unit != SP_CSS_UNIT_EX ) ) { + // Parent absolut size + type = SP_FONT_SIZE_LENGTH; + + } else { + // Parent relative size + double const parent_frac( p->relative_fraction() ); + if( type == SP_FONT_SIZE_LENGTH ) { + // ex/em + value *= parent_frac; + } else { + value = parent_frac * child_frac; + type = SP_FONT_SIZE_PERCENTAGE; + } + } + } // Relative size + } // Parent set and not inherit + } else { + std::cerr << "SPIFontSize::merge(): Incorrect parent type" << std::endl; + } +} + +// What about different SVG units? +bool +SPIFontSize::operator==(const SPIBase& rhs) { + if( const SPIFontSize* r = dynamic_cast(&rhs) ) { + if( type != r->type ) { return false;} + if( type == SP_FONT_SIZE_LENGTH ) { + if( computed != r->computed ) { return false;} + } else if (type == SP_FONT_SIZE_LITERAL ) { + if( literal != r->literal ) { return false;} + } else { + if( value != r->value ) { return false;} + } + return SPIBase::operator==(rhs); + } else { + return false; + } +} + + + +// SPIFont ---------------------------------------------------------- + +void +SPIFont::read( gchar const *str ) { + + if( !str ) return; + + if( !style ) { + std::cerr << "SPIFont::read(): style is void" << std::endl; + return; + } + + if ( !strcmp(str, "inherit") ) { + set = TRUE; + inherit = TRUE; + } else { + + // Break string into white space separated tokens + std::stringstream os( str ); + Glib::ustring param; + + while (os >> param) { + + // CSS is case insensitive but we're comparing against lowercase strings + Glib::ustring lparam = param.lowercase(); + + if (lparam == "/" ) { + // line_height follows... note: font-size already read + + os >> param; + lparam = param.lowercase(); + style->line_height.readIfUnset( lparam.c_str() ); + + } else { + // Try to parse each property in turn + + SPIEnum test_style("font-style", enum_font_style); + test_style.read( lparam.c_str() ); + if( test_style.set ) { + style->font_style = test_style; + continue; + } + + // font-variant (Note: only CSS2.1 value small-caps is valid in shortcut.) + SPIEnum test_variant("font-variant", enum_font_variant); + test_variant.read( lparam.c_str() ); + if( test_variant.set ) { + style->font_variant = test_variant; + continue; + } + + // font-weight + SPIEnum test_weight("font-weight", enum_font_weight); + test_weight.read( lparam.c_str() ); + if( test_weight.set ) { + style->font_weight = test_weight; + continue; + } + + // font-stretch (added in CSS 3 Fonts) + SPIEnum test_stretch("font-stretch", enum_font_stretch); + test_stretch.read( lparam.c_str() ); + if( test_stretch.set ) { + style->font_stretch = test_stretch; + continue; + } + + // font-size + SPIFontSize test_size; + test_size.read( lparam.c_str() ); + if( test_size.set ) { + style->font_size = test_size; + continue; + } + + // No valid property value found. + break; + } + } // params + + // The rest must be font-family... + std::string str_s = str; // Why this extra step? + std::string family = str_s.substr( str_s.find( param ) ); + + style->text->font_family.readIfUnset( family.c_str() ); + + // Everything in shorthand is set per CSS rules, this works since + // properties are read backwards from end to start. + style->font_style.set = true; + style->font_variant.set = true; + style->font_weight.set = true; + style->font_stretch.set = true; + style->font_size.set = true; + style->line_height.set = true; + style->text->font_family.set = true; + // style->font_size_adjust.set = true; + // style->font_kerning.set = true; + // style->font_language_override.set = true;; + } +} + +const Glib::ustring +SPIFont::write( guint const flags, SPIBase const *const base) const { + + // At the moment, do nothing. We could add a preference to write out + // 'font' shorthand rather than longhand properties. + + // SPIFontSize const *const my_base = dynamic_cast(base); + // if ( (flags & SP_STYLE_FLAG_ALWAYS) || + // ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + // ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + // && (!my_base->set || this != my_base ))) + // { + // CSSOStringStream css; + // } + return Glib::ustring(""); +} + +// void +// SPIFont::cascade( const SPIBase* const parent ) { +// } + +// void +// SPIFont::merge( const SPIBase* const parent ) { +// } + +// Does nothing... +bool +SPIFont::operator==(const SPIBase& rhs) { + if( /* const SPIFont* r = */ dynamic_cast(&rhs) ) { + return SPIBase::operator==(rhs); + } else { + return false; + } +} + + + +// SPIBaselineShift ----------------------------------------------------- + +void +SPIBaselineShift::read( gchar const *str ) { + + if( !str ) return; + + if (!strcmp(str, "inherit")) { + set = TRUE; + inherit = TRUE; + } else if ((*str == 'b') || (*str == 's')) { + // baseline or sub or super + for (unsigned i = 0; enum_baseline_shift[i].key; i++) { + if (!strcmp(str, enum_baseline_shift[i].key)) { + set = TRUE; + inherit = FALSE; + type = SP_BASELINE_SHIFT_LITERAL; + literal = enum_baseline_shift[i].value; + return; + } + } + /* Invalid */ + return; + } else { + SPILength length( "temp" ); + length.read( str ); + set = length.set; + inherit = length.inherit; + unit = length.unit; + value = length.value; + computed = length.computed; + if( unit == SP_CSS_UNIT_PERCENT ) { + type = SP_BASELINE_SHIFT_PERCENTAGE; + } else { + type = SP_BASELINE_SHIFT_LENGTH; + } + return; + } +} + +const Glib::ustring +SPIBaselineShift::write( guint const flags, SPIBase const *const base) const { + + SPIBaselineShift const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || !this->isZero() ))) + { + CSSOStringStream css; + + if (this->inherit) { + css << "inherit"; + } else if (this->type == SP_BASELINE_SHIFT_LITERAL) { + for (unsigned i = 0; enum_baseline_shift[i].key; i++) { + if (enum_baseline_shift[i].value == static_cast< gint > (this->literal) ) { + css << enum_baseline_shift[i].key; + } + } + } else if (this->type == SP_BASELINE_SHIFT_LENGTH) { + if( this->unit == SP_CSS_UNIT_EM || this->unit == SP_CSS_UNIT_EX ) { + css << this->value << (this->unit == SP_CSS_UNIT_EM ? "em" : "ex"); + } else { + css << this->computed << "px"; // must specify px, see inkscape bug 1221626, mozilla bug 234789 + } + } else if (this->type == SP_BASELINE_SHIFT_PERCENTAGE) { + css << (this->value * 100.0) << "%"; + } + return (name + ":" + css.str() + ";"); + } + return Glib::ustring(""); +} + +void +SPIBaselineShift::cascade( const SPIBase* const parent ) { + if( const SPIBaselineShift* p = dynamic_cast(parent) ) { + SPIFontSize *pfont_size = &(p->style->font_size); + g_assert( pfont_size != NULL ); + + if( !set || inherit ) { + computed = p->computed; // Shift relative to parent shift, corrected below + } else if (type == SP_BASELINE_SHIFT_LITERAL) { + if( literal == SP_CSS_BASELINE_SHIFT_BASELINE ) { + computed = 0; // No change + } else if (literal == SP_CSS_BASELINE_SHIFT_SUB ) { + // Should use subscript position from font relative to alphabetic baseline + // OpenOffice, Adobe: -0.33, Word -0.14, LaTex about -0.2. + computed = -0.2 * pfont_size->computed; + } else if (literal == SP_CSS_BASELINE_SHIFT_SUPER ) { + // Should use superscript position from font relative to alphabetic baseline + // OpenOffice, Adobe: 0.33, Word 0.35, LaTex about 0.45. + computed = 0.4 * pfont_size->computed; + } else { + /* Illegal value */ + } + } else if (type == SP_BASELINE_SHIFT_PERCENTAGE) { + // Percentage for baseline shift is relative to computed "line-height" + // which is just font-size (see SVG1.1 'font'). + computed = pfont_size->computed * value; + } else if (type == SP_BASELINE_SHIFT_LENGTH) { + switch (unit) { + case SP_CSS_UNIT_EM: + computed = value * pfont_size->computed; + break; + case SP_CSS_UNIT_EX: + computed = value * 0.5 * pfont_size->computed; + break; + default: + /* No change */ + break; + } + } + // baseline-shifts are relative to parent baseline + computed += p->computed; + + } else { + std::cerr << "SPIBaselineShift::cascade(): Incorrect parent type" << std::endl; + } +} + +// This was not defined in the legacy C code, it needs some serious thinking (but is low priority). +// FIX ME +void +SPIBaselineShift::merge( const SPIBase* const parent ) { + if( const SPIBaselineShift* p = dynamic_cast(parent) ) { + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + value = p->value; + } + } else { + std::cerr << "SPIBaselineShift::merge(): Incorrect parent type" << std::endl; + } +} + +// This is not used but we have it for completeness, it has not been tested. +bool +SPIBaselineShift::operator==(const SPIBase& rhs) { + if( const SPIBaselineShift* r = dynamic_cast(&rhs) ) { + if( type != r->type ) return false; + if( type == SP_BASELINE_SHIFT_LENGTH ) { + if( computed != r->computed ) return false; + } else if ( type == SP_BASELINE_SHIFT_LITERAL ) { + if( literal != r->literal ) return false; + } else { + if( value != r->value ) return false; + } + return SPIBase::operator==(rhs); + } else { + return false; + } +} + +bool +SPIBaselineShift::isZero() const { + if( type == SP_BASELINE_SHIFT_LITERAL ) { + if( literal == SP_CSS_BASELINE_SHIFT_BASELINE ) return true; + } else { + if( value == 0.0 ) return true; + } + return false; +} + + + +// SPITextDecorationLine ------------------------------------------------ + +void +SPITextDecorationLine::read( gchar const *str ) { + + if( !str ) return; + + if (!strcmp(str, "inherit")) { + set = true; + inherit = true; + } else if (!strcmp(str, "none")) { + set = true; + inherit = false; + underline = false; + overline = false; + line_through = false; + blink = false; + } else { + bool found_one = false; + bool hit_one = false; + + // CSS 2 keywords + bool found_underline = false; + bool found_overline = false; + bool found_line_through = false; + bool found_blink = false; + + // This method ignores inlineid keys and extra delimiters, so " ,,, blink hello" will set + // blink and ignore hello + const gchar *hstr = str; + while (1) { + if (*str == ' ' || *str == ',' || *str == '\0'){ + int slen = str - hstr; + // CSS 2 keywords + while(1){ // not really a loop, used to avoid a goto + hit_one = true; // most likely we will + if ((slen == 9) && strneq(hstr, "underline", slen)){ found_underline = true; break; } + if ((slen == 8) && strneq(hstr, "overline", slen)){ found_overline = true; break; } + if ((slen == 12) && strneq(hstr, "line-through", slen)){ found_line_through = true; break; } + if ((slen == 5) && strneq(hstr, "blink", slen)){ found_blink = true; break; } + if ((slen == 4) && strneq(hstr, "none", slen)){ break; } + + hit_one = false; // whatever this thing is, we do not recognize it + break; + } + found_one |= hit_one; + if(*str == '\0')break; + hstr = str + 1; + } + str++; + } + if (found_one) { + set = true; + inherit = false; + underline = found_underline; + overline = found_overline; + line_through = found_line_through; + blink = found_blink; + } + else { + set = false; + inherit = false; + } + } +} + +const Glib::ustring +SPITextDecorationLine::write( guint const flags, SPIBase const *const base) const { + SPITextDecorationLine const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + Inkscape::CSSOStringStream os; + os << name << ":"; + if( inherit ) { + os << "inherit"; + } else if (this->underline || this->overline || this->line_through || this->blink) { + if (this->underline) os << " underline"; + if (this->overline) os << " overline"; + if (this->line_through) os << " line-through"; + if (this->blink) os << " blink"; // Deprecated + } else { + os << "none"; + } + os << ";"; + return ( os.str() ); + } + return Glib::ustring(""); +} + +void +SPITextDecorationLine::cascade( const SPIBase* const parent ) { + if( const SPITextDecorationLine* p = dynamic_cast(parent) ) { + if( inherits && (!set || inherit) ) { + underline = p->underline; + overline = p->overline; + line_through = p->line_through; + blink = p->blink; + } + } else { + std::cerr << "SPITextDecorationLine::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPITextDecorationLine::merge( const SPIBase* const parent ) { + if( const SPITextDecorationLine* p = dynamic_cast(parent) ) { + if( inherits ) { // Always inherits... but special rules? + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + underline = p->underline; + overline = p->overline; + line_through = p->line_through; + blink = p->blink; + } + } + } +} + +bool +SPITextDecorationLine::operator==(const SPIBase& rhs) { + if( const SPITextDecorationLine* r = dynamic_cast(&rhs) ) { + return + (underline == r->underline ) && + (overline == r->overline ) && + (line_through == r->line_through ) && + (blink == r->blink ) && + SPIBase::operator==(rhs); + } else { + return false; + } +} + + + +// SPITextDecorationStyle ----------------------------------------------- + +void +SPITextDecorationStyle::read( gchar const *str ) { + + if( !str ) return; + + set = false; + inherit = false; + + solid = true; // Default + isdouble = false; + dotted = false; + dashed = false; + wavy = false; + + if (!strcmp(str, "inherit")) { + set = true; + inherit = true; + solid = false; + } else { + // note, these are CSS 3 keywords + bool found_solid = false; + bool found_double = false; + bool found_dotted = false; + bool found_dashed = false; + bool found_wavy = false; + bool found_one = false; + + // this method ignores inlineid keys and extra delimiters, so " ,,, style hello" will set style and ignore hello + // if more than one style is present, the first is used + const gchar *hstr = str; + while (1) { + if (*str == ' ' || *str == ',' || *str == '\0'){ + int slen = str - hstr; + if ( (slen == 5) && strneq(hstr, "solid", slen)){ found_solid = true; found_one = true; break; } + else if ((slen == 6) && strneq(hstr, "double", slen)){ found_double = true; found_one = true; break; } + else if ((slen == 6) && strneq(hstr, "dotted", slen)){ found_dotted = true; found_one = true; break; } + else if ((slen == 6) && strneq(hstr, "dashed", slen)){ found_dashed = true; found_one = true; break; } + else if ((slen == 4) && strneq(hstr, "wavy", slen)){ found_wavy = true; found_one = true; break; } + if(*str == '\0')break; // nothing more to test + hstr = str + 1; + } + str++; + } + if(found_one){ + set = true; + solid = found_solid; + isdouble = found_double; + dotted = found_dotted; + dashed = found_dashed; + wavy = found_wavy; + } + else { + set = false; + inherit = false; + } + } +} + +const Glib::ustring +SPITextDecorationStyle::write( guint const flags, SPIBase const *const base) const { + SPITextDecorationStyle const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set + && (!my_base->set || this != my_base ))) + { + Inkscape::CSSOStringStream os; + os << name << ":"; + if( inherit ) { + os << "inherit"; + } else if (this->solid ) { + os << "solid"; + } else if (this->isdouble ) { + os << "double"; + } else if (this->dotted ) { + os << "dotted"; + } else if (this->dashed ) { + os << "dashed"; + } else if (this->wavy ) { + os << "wavy"; + } else { + std::cerr << "SPITextDecorationStyle::write(): No valid value for property" << std::endl; + return Glib::ustring(""); + } + os << ";"; + return ( os.str() ); + } + return Glib::ustring(""); +} + +void +SPITextDecorationStyle::cascade( const SPIBase* const parent ) { + if( const SPITextDecorationStyle* p = dynamic_cast(parent) ) { + if( inherits && (!set || inherit) ) { + solid = p->solid; + isdouble = p->isdouble; + dotted = p->dotted; + dashed = p->dashed; + wavy = p->wavy; + } + } else { + std::cerr << "SPITextDecorationStyle::cascade(): Incorrect parent type" << std::endl; + } +} + +void +SPITextDecorationStyle::merge( const SPIBase* const parent ) { + if( const SPITextDecorationStyle* p = dynamic_cast(parent) ) { + if( inherits ) { // Always inherits... but special rules? + if( (!set || inherit) && p->set && !(p->inherit) ) { + set = p->set; + inherit = p->inherit; + solid = p->solid; + isdouble = p->isdouble; + dotted = p->dotted; + dashed = p->dashed; + wavy = p->wavy; + } + } + } +} + +bool +SPITextDecorationStyle::operator==(const SPIBase& rhs) { + if( const SPITextDecorationStyle* r = dynamic_cast(&rhs) ) { + return + (solid == r->solid ) && + (isdouble == r->isdouble ) && + (dotted == r->dotted ) && + (dashed == r->dashed ) && + (wavy == r->wavy ) && + SPIBase::operator==(rhs); + } else { + return false; + } +} + + + +// TextDecorationColor is handled by SPIPaint (should be SPIColor), default value is "currentColor" +// FIXME + + + +// SPITextDecoration ---------------------------------------------------- + +void +SPITextDecoration::read( gchar const *str ) { + + if( !str ) return; + + style->text_decoration_line.read( str ); + style->text_decoration_style.read( str ); + // the color routine must be fed one token at a time - if multiple colors are found the LAST + // one is used ???? then why break on set? + const gchar *hstr = str; + + style->text_decoration_color.read( "currentColor" ); // Default value + style->text_decoration_color.set = false; + while (1) { + if (*str == ' ' || *str == ',' || *str == '\0'){ + int slen = str - hstr; + gchar *frag = g_strndup(hstr,slen+1); // only send one piece at a time, since keywords may be intermixed + + if( strcmp( frag, "none" ) != 0 ) { // 'none' not allowed + style->text_decoration_color.read( frag ); + } + + free(frag); + if( style->text_decoration_color.set ) break; + style->text_decoration_color.read( "currentColor" ); // Default value + if( *str == '\0' )break; + hstr = str + 1; + } + str++; + } +} + +// Returns CSS2 'text-decoration' (using settings in SPTextDecorationLine) +// This is required until all SVG renderers support CSS3 'text-decoration' +const Glib::ustring +SPITextDecoration::write( guint const flags, SPIBase const *const base) const { + SPITextDecoration const *const my_base = dynamic_cast(base); + if ( (flags & SP_STYLE_FLAG_ALWAYS) || + ((flags & SP_STYLE_FLAG_IFSET) && style->text_decoration_line.set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && style->text_decoration_line.set + && (!my_base->style->text_decoration_line.set || + style->text_decoration_line != my_base->style->text_decoration_line ))) + { + Inkscape::CSSOStringStream os; + os << name << ":"; + if( inherit ) { + os << "inherit"; + } else if (style->text_decoration_line.underline || + style->text_decoration_line.overline || + style->text_decoration_line.line_through || + style->text_decoration_line.blink) { + if (style->text_decoration_line.underline) os << " underline"; + if (style->text_decoration_line.overline) os << " overline"; + if (style->text_decoration_line.line_through) os << " line-through"; + if (style->text_decoration_line.blink) os << " blink"; // Deprecated + } else { + os << "none"; + } + os << ";"; + return ( os.str() ); + } + return Glib::ustring(""); +} + +// Done in SPITextDecorationLine +// void +// SPITextDecoration::cascade( const SPIBase* const parent ) { +// } + +// void +// SPITextDecoration::merge( const SPIBase* const parent ) { +// } + +// Use CSS2 value +bool +SPITextDecoration::operator==(const SPIBase& rhs) { + if( const SPITextDecoration* r = dynamic_cast(&rhs) ) { + return (style->text_decoration_line == r->style->text_decoration_line && + SPIBase::operator==(rhs)); + } else { + return false; + } +} + + + +/* ---------------------------- NOTES ----------------------------- */ + +/* + * opacity's effect is cumulative; we set the new value to the combined effect. The + * default value for opacity is 1.0, not inherit. (Note that stroke-opacity and + * fill-opacity are quite different from opacity, and don't need any special handling.) + * + * Cases: + * - parent & child were each previously unset, in which case the effective + * opacity value is 1.0, and style should remain unset. + * - parent was previously unset (so computed opacity value of 1.0) + * and child was set to inherit. The merged child should + * get a value of 1.0, and shouldn't inherit (lest the new parent + * has a different opacity value). Given that opacity's default + * value is 1.0 (rather than inherit), we might as well have the + * merged child's opacity be unset. + * - parent was previously unset (so opacity 1.0), and child was set to a number. + * The merged child should retain its existing settings (though it doesn't matter + * if we make it unset if that number was 1.0). + * - parent was inherit and child was unset. Merged child should be set to inherit. + * - parent was inherit and child was inherit. (We can't in general reproduce this + * effect (short of introducing a new group), but setting opacity to inherit is rare.) + * If the inherited value was strictly between 0.0 and 1.0 (exclusive) then the merged + * child's value should be set to the product of the two, i.e. the square of the + * inherited value, and should not be marked as inherit. (This decision assumes that it + * is more important to retain the effective opacity than to retain the inheriting + * effect, and assumes that the inheriting effect either isn't important enough to create + * a group or isn't common enough to bother maintaining the code to create a group.) If + * the inherited value was 0.0 or 1.0, then marking the merged child as inherit comes + * closer to maintaining the effect. + * - parent was inherit and child was set to a numerical value. If the child's value + * was 1.0, then the merged child should have the same settings as the parent. + * If the child's value was 0, then the merged child should also be set to 0. + * If the child's value was anything else, then we do the same as for the inherit/inherit + * case above: have the merged child set to the product of the two opacities and not + * marked as inherit, for the same reasons as for that case. + * - parent was set to a value, and child was unset. The merged child should have + * parent's settings. + * - parent was set to a value, and child was inherit. The merged child should + * be set to the product, i.e. the square of the parent's value. + * - parent & child are each set to a value. The merged child should be set to the + * product. + */ + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 67c3fc5586ae05506f75bb30fe46a071e20613d2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Apr 2014 14:04:31 +0200 Subject: Clean up of style code, removal of SPFontStyle. Step 2. (bzr r13300) --- src/desktop-style.cpp | 50 ++++++++++++++++++------------------ src/extension/internal/emf-print.cpp | 4 +-- src/extension/internal/wmf-print.cpp | 4 +-- src/libnrtype/FontFactory.cpp | 10 ++++---- src/libnrtype/Layout-TNG-Input.cpp | 5 ++-- src/libnrtype/font-lister.cpp | 14 +++++----- src/style-internal.cpp | 4 +-- src/style-internal.h | 13 ---------- src/style.cpp | 28 ++++++++------------ src/style.h | 8 +++--- src/ui/dialog/font-substitution.cpp | 18 ++++++------- src/widgets/text-toolbar.cpp | 23 ++++++++--------- 12 files changed, 80 insertions(+), 101 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index bab9635a9..a7097b4c9 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -1227,11 +1227,11 @@ objects_query_fontfamily (GSList *objects, SPStyle *style_res) bool different = false; int texts = 0; - if (style_res->text->font_family.value) { - g_free(style_res->text->font_family.value); - style_res->text->font_family.value = NULL; + if (style_res->font_family.value) { + g_free(style_res->font_family.value); + style_res->font_family.value = NULL; } - style_res->text->font_family.set = FALSE; + style_res->font_family.set = FALSE; for (GSList const *i = objects; i != NULL; i = i->next) { SPObject *obj = SP_OBJECT (i->data); @@ -1250,21 +1250,21 @@ objects_query_fontfamily (GSList *objects, SPStyle *style_res) texts ++; - if (style_res->text->font_family.value && style->text->font_family.value && - strcmp (style_res->text->font_family.value, style->text->font_family.value)) { + if (style_res->font_family.value && style->font_family.value && + strcmp (style_res->font_family.value, style->font_family.value)) { different = true; // different fonts } - if (style_res->text->font_family.value) { - g_free(style_res->text->font_family.value); - style_res->text->font_family.value = NULL; + if (style_res->font_family.value) { + g_free(style_res->font_family.value); + style_res->font_family.value = NULL; } - style_res->text->font_family.set = TRUE; - style_res->text->font_family.value = g_strdup(style->text->font_family.value); + style_res->font_family.set = TRUE; + style_res->font_family.value = g_strdup(style->font_family.value); } - if (texts == 0 || !style_res->text->font_family.set) { + if (texts == 0 || !style_res->font_family.set) { return QUERY_STYLE_NOTHING; } @@ -1285,11 +1285,11 @@ objects_query_fontspecification (GSList *objects, SPStyle *style_res) bool different = false; int texts = 0; - if (style_res->text->font_specification.value) { - g_free(style_res->text->font_specification.value); - style_res->text->font_specification.value = NULL; + if (style_res->font_specification.value) { + g_free(style_res->font_specification.value); + style_res->font_specification.value = NULL; } - style_res->text->font_specification.set = FALSE; + style_res->font_specification.set = FALSE; for (GSList const *i = objects; i != NULL; i = i->next) { SPObject *obj = SP_OBJECT (i->data); @@ -1308,21 +1308,21 @@ objects_query_fontspecification (GSList *objects, SPStyle *style_res) texts ++; - if (style_res->text->font_specification.value && style_res->text->font_specification.set && - style->text->font_specification.value && style->text->font_specification.set && - strcmp (style_res->text->font_specification.value, style->text->font_specification.value)) { + if (style_res->font_specification.value && style_res->font_specification.set && + style->font_specification.value && style->font_specification.set && + strcmp (style_res->font_specification.value, style->font_specification.value)) { different = true; // different fonts } - if (style->text->font_specification.set) { + if (style->font_specification.set) { - if (style_res->text->font_specification.value) { - g_free(style_res->text->font_specification.value); - style_res->text->font_specification.value = NULL; + if (style_res->font_specification.value) { + g_free(style_res->font_specification.value); + style_res->font_specification.value = NULL; } - style_res->text->font_specification.set = TRUE; - style_res->text->font_specification.value = g_strdup(style->text->font_specification.value); + style_res->font_specification.set = TRUE; + style_res->font_specification.value = g_strdup(style->font_specification.value); } } diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index f4f7f08cb..8b80fec1c 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -1869,7 +1869,7 @@ unsigned int PrintEmf::text(Inkscape::Extension::Print * /*mod*/, char const *te _lookup_ppt_fontfix("Convert To Wingdings", params); break; default: //also CVTNON - _lookup_ppt_fontfix(style->text->font_family.value, params); + _lookup_ppt_fontfix(style->font_family.value, params); break; } if (params.f2 != 0 || params.f3 != 0) { @@ -1897,7 +1897,7 @@ unsigned int PrintEmf::text(Inkscape::Extension::Print * /*mod*/, char const *te // of the special fonts. uint16_t *wfacename; if (!newfont) { - wfacename = U_Utf8ToUtf16le(style->text->font_family.value, 0, NULL); + wfacename = U_Utf8ToUtf16le(style->font_family.value, 0, NULL); } else { wfacename = U_Utf8ToUtf16le(FontName(newfont), 0, NULL); } diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp index 5a552ad83..55ad5da5f 100644 --- a/src/extension/internal/wmf-print.cpp +++ b/src/extension/internal/wmf-print.cpp @@ -1387,7 +1387,7 @@ unsigned int PrintWmf::text(Inkscape::Extension::Print * /*mod*/, char const *te _lookup_ppt_fontfix("Convert To Wingdings", params); break; default: //also CVTNON - _lookup_ppt_fontfix(style->text->font_family.value, params); + _lookup_ppt_fontfix(style->font_family.value, params); break; } if (params.f2 != 0 || params.f3 != 0) { @@ -1416,7 +1416,7 @@ unsigned int PrintWmf::text(Inkscape::Extension::Print * /*mod*/, char const *te // of the special fonts. char *facename; if (!newfont) { - facename = U_Utf8ToLatin1(style->text->font_family.value, 0, NULL); + facename = U_Utf8ToLatin1(style->font_family.value, 0, NULL); } else { facename = U_Utf8ToLatin1(FontName(newfont), 0, NULL); } diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 7c0b4ffba..4ae408397 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -825,17 +825,17 @@ font_instance* font_factory::FaceFromStyle(SPStyle const *style) if (style) { // First try to use the font specification if it is set - if (style->text->font_specification.set - && style->text->font_specification.value - && *style->text->font_specification.value) { + if (style->font_specification.set + && style->font_specification.value + && *style->font_specification.value) { - font = FaceFromFontSpecification(style->text->font_specification.value); + font = FaceFromFontSpecification(style->font_specification.value); } // If that failed, try using the CSS information in the style if (!font) { - font = Face(style->text->font_family.value, font_style_to_pos(*style)); + font = Face(style->font_family.value, font_style_to_pos(*style)); // That was a hatchet job... so we need to check if this font exists!! Glib::ustring fontSpec = font_factory::Default()->ConstructFontSpecification(font); diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp index cb3e6f620..fa1e8c11b 100644 --- a/src/libnrtype/Layout-TNG-Input.cpp +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -286,16 +286,15 @@ font_instance *Layout::InputStreamTextSource::styleGetFontInstance() const PangoFontDescription *Layout::InputStreamTextSource::styleGetFontDescription() const { - if (style->text == NULL) return NULL; PangoFontDescription *descr = pango_font_description_new(); // Pango can't cope with spaces before or after the commas - let's remove them. // this code is not exactly unicode-safe, but it's similar to what's done in // pango, so it's not the limiting factor Glib::ustring family; - if (style->text->font_family.value == NULL) { + if (style->font_family.value == NULL) { family = "sans-serif"; } else { - gchar **families = g_strsplit(style->text->font_family.value, ",", -1); + gchar **families = g_strsplit(style->font_family.value, ",", -1); if (families) { for (gchar **f = families ; *f ; ++f) { g_strstrip(*f); diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index dde0ee4a9..98589d9d7 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -358,8 +358,8 @@ namespace Inkscape sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); //std::cout << " Attempting selected style" << std::endl; - if( result != QUERY_STYLE_NOTHING && query->text->font_specification.set ) { - fontspec = query->text->font_specification.value; + if( result != QUERY_STYLE_NOTHING && query->font_specification.set ) { + fontspec = query->font_specification.value; //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; } @@ -693,15 +693,15 @@ std::pair FontLister::new_font_family (Glib::ustri if (style) { // First try to use the font specification if it is set - if (style->text->font_specification.set - && style->text->font_specification.value - && *style->text->font_specification.value) { + if (style->font_specification.set + && style->font_specification.value + && *style->font_specification.value) { - fontspec = style->text->font_specification.value; + fontspec = style->font_specification.value; } else { - fontspec = style->text->font_family.value; + fontspec = style->font_family.value; fontspec += ","; switch (style->font_weight.computed) { diff --git a/src/style-internal.cpp b/src/style-internal.cpp index ede543078..b03e848ba 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -1887,7 +1887,7 @@ SPIFont::read( gchar const *str ) { std::string str_s = str; // Why this extra step? std::string family = str_s.substr( str_s.find( param ) ); - style->text->font_family.readIfUnset( family.c_str() ); + style->font_family.readIfUnset( family.c_str() ); // Everything in shorthand is set per CSS rules, this works since // properties are read backwards from end to start. @@ -1897,7 +1897,7 @@ SPIFont::read( gchar const *str ) { style->font_stretch.set = true; style->font_size.set = true; style->line_height.set = true; - style->text->font_family.set = true; + style->font_family.set = true; // style->font_size_adjust.set = true; // style->font_kerning.set = true; // style->font_language_override.set = true;; diff --git a/src/style-internal.h b/src/style-internal.h index e5ef72c76..665c7abd4 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -867,19 +867,6 @@ struct SPITextDecorationData { float line_through_position; }; - -/// An SPFontStyle has a 'font', 'font-family', and font_specification (ala Pango). -struct SPFontStyle { - /* CSS font properties */ - SPIString font_family; - - /* Full font name, as font_factory::ConstructFontSpecification would give */ - SPIString font_specification; - - /** \todo fixme: The 'font' property is ugly, and not working (lauris) */ -// SPIString font; -}; - #endif // SEEN_SP_STYLE_INTERNAL_H diff --git a/src/style.cpp b/src/style.cpp index 97d9c811c..fa99d278c 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -112,7 +112,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : font_stretch( "font-stretch", enum_font_stretch, SP_CSS_FONT_STRETCH_NORMAL ), font_size(), line_height( "line-height", 1.0 ), // SPILengthOrNormal + font_family( "font-family" ), // SPIString font(), // SPIFont + font_specification( "-inkscape-font-specification" ), // SPIString // Text related properties text_indent( "text-indent", 0.0 ), // SPILength @@ -225,11 +227,6 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : new (&fill_ps_modified_connection) sigc::connection(); new (&stroke_ps_modified_connection) sigc::connection(); - - // FIX-ME Remove SPFontStyle - text = new SPFontStyle(); - text->font_family = SPIString( "font-family" ); - text->font_specification = SPIString( "-inkscape-font-specification" ); // 'font' shorthand requires access to included properties. font.setStylePointer( this ); @@ -274,7 +271,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &font_stretch ); _properties.push_back( &font_size ); _properties.push_back( &line_height ); + _properties.push_back( &font_family ); _properties.push_back( &font ); + _properties.push_back( &font_specification ); _properties.push_back( &text_indent ); _properties.push_back( &text_align ); @@ -337,9 +336,6 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &enable_background ); - _properties.push_back( &text->font_family ); // Must be first as other values depend on it ('ex') - _properties.push_back( &text->font_specification ); - // MAP ------------------------------------------- // if( _propmap.size() == 0 ) { @@ -348,13 +344,15 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( color.name, reinterpret_cast(&SPStyle::color ) ) ); // // 'font-size' must be before properties that need to know em, ex size (SPILength, SPILenghtOrNormal) - // _propmap.insert( std::make_pair( font.name, reinterpret_cast(&SPStyle::font ) ) ); // _propmap.insert( std::make_pair( font_style.name, reinterpret_cast(&SPStyle::font_style ) ) ); // _propmap.insert( std::make_pair( font_variant.name, reinterpret_cast(&SPStyle::font_variant ) ) ); // _propmap.insert( std::make_pair( font_weight.name, reinterpret_cast(&SPStyle::font_weight ) ) ); // _propmap.insert( std::make_pair( font_stretch.name, reinterpret_cast(&SPStyle::font_stretch ) ) ); // _propmap.insert( std::make_pair( font_size.name, reinterpret_cast(&SPStyle::font_size ) ) ); // _propmap.insert( std::make_pair( line_height.name, reinterpret_cast(&SPStyle::line_height ) ) ); + // _propmap.insert( std::make_pair( font_family.name, reinterpret_cast(&SPStyle::font_family ) ) ); + // _propmap.insert( std::make_pair( font.name, reinterpret_cast(&SPStyle::font ) ) ); + // _propmap.insert( std::make_pair( font_specification.name, reinterpret_cast(&SPStyle::font_specification ) ) ); // _propmap.insert( std::make_pair( text_indent.name, reinterpret_cast(&SPStyle::text_indent ) ) ); // _propmap.insert( std::make_pair( text_align.name, reinterpret_cast(&SPStyle::text_align ) ) ); @@ -448,7 +446,6 @@ SPStyle::~SPStyle() { _properties.clear(); //_propmap.clear(); - delete text; // std::cout << "SPStyle::~SPstyle(): Exit\n" << std::endl; } @@ -594,10 +591,10 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { switch (id) { case SP_PROP_INKSCAPE_FONT_SPEC: - text->font_specification.readIfUnset( val ); + font_specification.readIfUnset( val ); break; case SP_PROP_FONT_FAMILY: - text->font_family.readIfUnset( val ); + font_family.readIfUnset( val ); break; case SP_PROP_FONT_SIZE: font_size.readIfUnset( val ); @@ -1599,10 +1596,10 @@ sp_style_unset_property_attrs(SPObject *o) if (style->paint_order.set) { repr->setAttribute("paint-order", NULL); } - if (style->text->font_specification.set) { + if (style->font_specification.set) { repr->setAttribute("-inkscape-font-specification", NULL); } - if (style->text->font_family.set) { + if (style->font_family.set) { repr->setAttribute("font-family", NULL); } if (style->text_anchor.set) { @@ -1856,9 +1853,6 @@ attribute_unquote(gchar const *val) */ Glib::ustring css2_escape_quote(gchar const *val) { - std::cout << "css2_escape_quote: " << (val?val:"null") << std::endl; - //return val; - Glib::ustring t; bool quote = false; bool last_was_space = false; diff --git a/src/style.h b/src/style.h index 76a0929cd..9784ee48d 100644 --- a/src/style.h +++ b/src/style.h @@ -93,10 +93,6 @@ public: /* ----------------------- THE PROPERTIES ------------------------- */ - /** Our font style component */ - SPFontStyle *text; // FIXME: Break into font, font-family, ... - - /* CSS2 */ /* Font */ /** Font style */ SPIEnum font_style; @@ -110,8 +106,12 @@ public: SPIFontSize font_size; /** Line height (css2 10.8.1) */ SPILengthOrNormal line_height; + /** Font family */ + SPIString font_family; /** Font shorthand */ SPIFont font; + /** Full font name, as font_factory::ConstructFontSpecification would give, for internal use. */ + SPIString font_specification; /** First line indent of paragraphs (css2 16.1) */ SPILength text_indent; diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index bf9133086..6e9ecc3c8 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -200,16 +200,16 @@ GSList * FontSubstitution::getFontReplacedItems(SPDocument* doc, Glib::ustring * } } - if (style && style->text) { + if (style) { gchar const *style_font = NULL; - if (style->text->font_family.set) - style_font = style->text->font_family.value; - else if (style->text->font_specification.set) - style_font = style->text->font_specification.value; - else if (style->text->font_family.value) - style_font = style->text->font_family.value; - else if (style->text->font_specification.value) - style_font = style->text->font_specification.value; + if (style->font_family.set) + style_font = style->font_family.value; + else if (style->font_specification.set) + style_font = style->font_specification.value; + else if (style->font_family.value) + style_font = style->font_family.value; + else if (style->font_specification.value) + style_font = style->font_specification.value; if (style_font) { if (has_visible_text(item)) { diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 7b59fa633..3a4f315da 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -72,20 +72,20 @@ using Inkscape::UI::PrefPusher; static void sp_print_font( SPStyle *query ) { - bool family_set = query->text->font_family.set; + bool family_set = query->font_family.set; bool style_set = query->font_style.set; - bool fontspec_set = query->text->font_specification.set; + bool fontspec_set = query->font_specification.set; std::cout << " Family set? " << family_set << " Style set? " << style_set << " FontSpec set? " << fontspec_set << std::endl; std::cout << " Family: " - << (query->text->font_family.value ? query->text->font_family.value : "No value") + << (query->font_family.value ? query->font_family.value : "No value") << " Style: " << query->font_style.computed << " Weight: " << query->font_weight.computed << " FontSpec: " - << (query->text->font_specification.value ? query->text->font_specification.value : "No value") + << (query->font_specification.value ? query->font_specification.value : "No value") << std::endl; std::cout << " LineHeight: " << query->line_height.computed << " WordSpacing: " << query->word_spacing.computed @@ -930,7 +930,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } // If we have valid query data for text (font-family, font-specification) set toolbar accordingly. - if (query->text) { // Size (average of text selected) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1058,11 +1057,11 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ ege_select_one_action_set_active( textOrientationAction, activeButton2 ); - } // if( query->text ) + } #ifdef DEBUG_TEXT std::cout << " GUI: fontfamily.value: " - << (query->text->font_family.value ? query->text->font_family.value : "No value") + << (query->font_family.value ? query->font_family.value : "No value") << std::endl; std::cout << " GUI: font_size.computed: " << query->font_size.computed << std::endl; std::cout << " GUI: font_weight.computed: " << query->font_weight.computed << std::endl; @@ -1174,15 +1173,15 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p SPItem *item = SP_ITEM(i->data); SPStyle *style = item->style; - if (style && style->text) { + if (style) { Glib::ustring family_style; - if (style->text->font_family.set) { - family_style = style->text->font_family.value; + if (style->font_family.set) { + family_style = style->font_family.value; //std::cout << " family style from font_family: " << family_style << std::endl; } - else if (style->text->font_specification.set) { - family_style = style->text->font_specification.value; + else if (style->font_specification.set) { + family_style = style->font_specification.value; //std::cout << " family style from font_spec: " << family_style << std::endl; } -- cgit v1.2.3 From 20452bbd40fe1d93b2093cb5dea8e4cb8ae967d3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Apr 2014 14:53:30 +0200 Subject: Clean up of style code: refactor marker properties. Step 3. (bzr r13301) --- src/desktop-style.cpp | 8 ++++---- src/graphlayout.cpp | 4 ++-- src/id-clash.cpp | 2 +- src/selection-chemistry.cpp | 6 +++--- src/sp-shape.cpp | 6 +++--- src/style-internal.h | 2 +- src/style.cpp | 48 ++++++++++++++++++++++++-------------------- src/style.h | 7 +++++-- src/widgets/stroke-style.cpp | 7 ++++--- 9 files changed, 49 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index a7097b4c9..37f537cc5 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -722,10 +722,10 @@ objects_query_strokewidth (GSList *objects, SPStyle *style_res) } if ( style->stroke.isNone() && !( - style->marker[SP_MARKER_LOC].set || // stroke width affects markers, so if there's no stroke but only markers then we should - style->marker[SP_MARKER_LOC_START].set || // still calculate the stroke width - style->marker[SP_MARKER_LOC_MID].set || - style->marker[SP_MARKER_LOC_END].set)) + style->marker.set || // stroke width affects markers, so if there's no + style->marker_start.set || // stroke but only markers then we should + style->marker_mid.set || // still calculate the stroke width + style->marker_end.set)) { continue; } diff --git a/src/graphlayout.cpp b/src/graphlayout.cpp index 7e10ccca1..18159cb41 100644 --- a/src/graphlayout.cpp +++ b/src/graphlayout.cpp @@ -195,8 +195,8 @@ void graphlayout(GSList const *const items) { unsigned v=v_pair->second; //cout << "Edge: (" << u <<","<style->marker[SP_MARKER_LOC_END].set) { - if(directed && strcmp(conn->style->marker[SP_MARKER_LOC_END].value,"none")) { + if(conn->style->marker_end.set) { + if(directed && strcmp(conn->style->marker_end.value,"none")) { scy.push_back(new SimpleConstraint(v, u, (ideal_connector_length * directed_edge_height_modifier))); } diff --git a/src/id-clash.cpp b/src/id-clash.cpp index 7a0bb9c4a..8d852315f 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -161,7 +161,7 @@ find_references(SPObject *elem, refmap_type *refmap) /* check for url(#...) references in markers */ const gchar *markers[4] = { "", "marker-start", "marker-mid", "marker-end" }; for (unsigned i = SP_MARKER_LOC_START; i < SP_MARKER_LOC_QTY; i++) { - const gchar *value = style->marker[i].value; + const gchar *value = style->marker_ptrs[i]->value; if (value) { gchar *uri = extract_uri(value); if (uri && uri[0] == '#') { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 5a981c6a0..868a9d743 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2076,9 +2076,9 @@ GSList *sp_get_same_stroke_style(SPItem *sel, GSList *src, SPSelectStrokeStyleTy match = true; int len = sizeof(sel_style->marker)/sizeof(SPIString); for (int i = 0; i < len; i++) { - match = (sel_style->marker[i].set == iter_style->marker[i].set); - if (sel_style->marker[i].set && iter_style->marker[i].set && - (strcmp(sel_style->marker[i].value, iter_style->marker[i].value))) { + match = (sel_style->marker_ptrs[i]->set == iter_style->marker_ptrs[i]->set); + if (sel_style->marker_ptrs[i]->set && iter_style->marker_ptrs[i]->set && + (strcmp(sel_style->marker_ptrs[i]->value, iter_style->marker_ptrs[i]->value))) { match = false; break; } diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index b3a331cba..61d35e6ff 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -77,7 +77,7 @@ void SPShape::build(SPDocument *document, Inkscape::XML::Node *repr) { SPLPEItem::build(document, repr); for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - sp_shape_set_marker (this, i, this->style->marker[i].value); + sp_shape_set_marker (this, i, this->style->marker_ptrs[i]->value); } } @@ -136,7 +136,7 @@ void SPShape::update(SPCtx* ctx, guint flags) { * match the style. */ for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - sp_shape_set_marker (this, i, this->style->marker[i].value); + sp_shape_set_marker (this, i, this->style->marker_ptrs[i]->value); } if (flags & (SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { @@ -723,7 +723,7 @@ Inkscape::DrawingItem* SPShape::show(Inkscape::Drawing &drawing, unsigned int /* * match the style. */ for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { - sp_shape_set_marker (this, i, this->style->marker[i].value); + sp_shape_set_marker (this, i, this->style->marker_ptrs[i]->value); } if (this->hasMarkers ()) { diff --git a/src/style-internal.h b/src/style-internal.h index 665c7abd4..131b77b77 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -137,7 +137,7 @@ class SPIBase { // To do: make private public: - Glib::ustring name; // Make const when we switch to C++11 and change marker[] initializer + Glib::ustring name; // Make const unsigned inherits : 1; // Property inherits by default from parent. unsigned set : 1; // Property has been explicitly set (vs. inherited). unsigned inherit : 1; // Property value set to 'inherit'. diff --git a/src/style.cpp b/src/style.cpp index fa99d278c..2d66284d4 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -165,9 +165,12 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : stroke_dasharray(), // SPIDashArray stroke_dashoffset("stroke-dashoffset", 0.0 ), // SPILength for now - stroke_opacity( "stroke-opacity", SP_SCALE24_MAX), + stroke_opacity( "stroke-opacity", SP_SCALE24_MAX ), -// marker({ "marker", "marker-start", "marker-mid", "marker-end" }), C++11 + marker( "marker" ), // SPIString + marker_start( "marker-start" ), // SPIString + marker_mid( "marker-mid" ), // SPIString + marker_end( "marker-end" ), // SPIString // Filter properties filter(), @@ -252,10 +255,11 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // for setting up signals... 'fill', 'stroke' already done filter.setStylePointer( this ); - marker[SP_MARKER_LOC] = SPIString( "marker" ); - marker[SP_MARKER_LOC_START] = SPIString( "marker-start" ); - marker[SP_MARKER_LOC_MID] = SPIString( "marker-mid" ); - marker[SP_MARKER_LOC_END] = SPIString( "marker-end" ); + // Used to iterate over markers + marker_ptrs[SP_MARKER_LOC] = ▮ + marker_ptrs[SP_MARKER_LOC_START] = &marker_start; + marker_ptrs[SP_MARKER_LOC_MID] = &marker_mid; + marker_ptrs[SP_MARKER_LOC_END] = &marker_end; // This might be too resource hungary... but for now it possible to loop over properties @@ -318,10 +322,10 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &stroke_dashoffset ); _properties.push_back( &stroke_opacity ); - _properties.push_back( &marker[SP_MARKER_LOC] ); - _properties.push_back( &marker[SP_MARKER_LOC_START] ); - _properties.push_back( &marker[SP_MARKER_LOC_MID] ); - _properties.push_back( &marker[SP_MARKER_LOC_END] ); + _properties.push_back( &marker ); + _properties.push_back( &marker_start ); + _properties.push_back( &marker_mid ); + _properties.push_back( &marker_end ); _properties.push_back( &paint_order ); @@ -397,10 +401,10 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( stroke_dashoffset.name, reinterpret_cast(&SPStyle::stroke_dashoffset ) ) ); // _propmap.insert( std::make_pair( stroke_opacity.name, reinterpret_cast(&SPStyle::stroke_opacity ) ) ); - // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC] ) ) ); - // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC_START].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC_START] ) ) ); - // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC_MID].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC_MID] ) ) ); - // //_propmap.insert( std::make_pair( marker[SP_MARKER_LOC_END].name, reinterpret_cast(&SPStyle::marker[SP_MARKER_LOC_END] ) ) ); + // _propmap.insert( std::make_pair( marker.name, reinterpret_cast(&SPStyle::marker ) ) ); + // _propmap.insert( std::make_pair( marker_start.name, reinterpret_cast(&SPStyle::marker_start ) ) ); + // _propmap.insert( std::make_pair( marker_mid.name, reinterpret_cast(&SPStyle::marker_mid ) ) ); + // _propmap.insert( std::make_pair( marker_end.name, reinterpret_cast(&SPStyle::marker_end ) ) ); // _propmap.insert( std::make_pair( paint_order.name, reinterpret_cast(&SPStyle::paint_order ) ) ); @@ -798,19 +802,19 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { break; case SP_PROP_MARKER: /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - marker[SP_MARKER_LOC].readIfUnset( val ); + marker.readIfUnset( val ); break; case SP_PROP_MARKER_START: /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - marker[SP_MARKER_LOC_START].readIfUnset( val ); + marker_start.readIfUnset( val ); break; case SP_PROP_MARKER_MID: /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - marker[SP_MARKER_LOC_MID].readIfUnset( val ); + marker_mid.readIfUnset( val ); break; case SP_PROP_MARKER_END: /* TODO: Call sp_uri_reference_resolve(SPDocument *document, guchar const *uri) */ - marker[SP_MARKER_LOC_END].readIfUnset( val ); + marker_end.readIfUnset( val ); break; case SP_PROP_SHAPE_RENDERING: shape_rendering.readIfUnset( val ); @@ -1572,16 +1576,16 @@ sp_style_unset_property_attrs(SPObject *o) if (style->stroke_linejoin.set) { repr->setAttribute("stroke-linejoin", NULL); } - if (style->marker[SP_MARKER_LOC].set) { + if (style->marker.set) { repr->setAttribute("marker", NULL); } - if (style->marker[SP_MARKER_LOC_START].set) { + if (style->marker_start.set) { repr->setAttribute("marker-start", NULL); } - if (style->marker[SP_MARKER_LOC_MID].set) { + if (style->marker_mid.set) { repr->setAttribute("marker-mid", NULL); } - if (style->marker[SP_MARKER_LOC_END].set) { + if (style->marker_end.set) { repr->setAttribute("marker-end", NULL); } if (style->stroke_opacity.set) { diff --git a/src/style.h b/src/style.h index 9784ee48d..9e592b78f 100644 --- a/src/style.h +++ b/src/style.h @@ -205,8 +205,11 @@ public: SPIScale24 stroke_opacity; /** Marker list */ - SPIString marker[SP_MARKER_LOC_QTY]; - + SPIString marker; + SPIString marker_start; + SPIString marker_mid; + SPIString marker_end; + SPIString* marker_ptrs[SP_MARKER_LOC_QTY]; /** Filter effect */ SPIFilter filter; diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index a4cca9472..0e0a4fd72 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -581,7 +581,8 @@ StrokeStyle::forkMarker(SPObject *marker, int loc, SPItem *item) Glib::ustring urlId = Glib::ustring::format("url(#", marker->getRepr()->attribute("id"), ")"); unsigned int refs = 0; for (int i = SP_MARKER_LOC_START; i < SP_MARKER_LOC_QTY; i++) { - if (item->style->marker[i].set && !strcmp(urlId.c_str(), item->style->marker[i].value)) { + if (item->style->marker_ptrs[i]->set && + !strcmp(urlId.c_str(), item->style->marker_ptrs[i]->value)) { refs++; } } @@ -1176,11 +1177,11 @@ StrokeStyle::updateAllMarkers(GSList const *objects) combo->setDesktop(desktop); - if (object->style->marker[keyloc[i].loc].value != NULL && !all_texts) { + if (object->style->marker_ptrs[keyloc[i].loc]->value != NULL && !all_texts) { // If the object has this type of markers, // Extract the name of the marker that the object uses - SPObject *marker = getMarkerObj(object->style->marker[keyloc[i].loc].value, object->document); + SPObject *marker = getMarkerObj(object->style->marker_ptrs[keyloc[i].loc]->value, object->document); // Scroll the combobox to that marker combo->set_current(marker); -- cgit v1.2.3 From 444217df4c55243d5110c18e1a67110b9893a862 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 25 Apr 2014 07:46:24 +0200 Subject: Clean up of style code: 'color' is not a paint. Step 1.1. Fixes bug 1312120. modified: src/id-clash.cpp unknown: .comments/ FILTERS/ doxygen/ style-internal.h share/attributes/attindex.html share/attributes/propidx.html share/symbols/FlowSymbolsNew.svg src/cxxtests src/cxxtests.cpp src/cxxtests.log src/cxxtests.xml src/ui/dialog/symbols.cpp_new (bzr r13302) --- src/id-clash.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/id-clash.cpp b/src/id-clash.cpp index 8d852315f..66357b75b 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -58,7 +58,7 @@ const SPIPaint SPStyle::* SPIPaint_members[] = { &SPStyle::stroke, }; const char* SPIPaint_properties[] = { - "color", + //"color", "fill", "stroke", }; @@ -76,7 +76,7 @@ const char* other_url_properties[] = { #define NUM_OTHER_URL_PROPERTIES (sizeof(other_url_properties) / sizeof(*other_url_properties)) const char* clipboard_properties[] = { - "color", + //"color", "fill", "filter", "stroke", -- cgit v1.2.3 From b9f02c6200865e24150ce14a1e480c4283b0472a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 25 Apr 2014 12:49:54 -0700 Subject: Improve keyboard navigation in LPE dialog. Fixed bugs: - https://launchpad.net/bugs/1310688 (bzr r13305) --- src/ui/dialog/livepatheffect-add.cpp | 14 ++++++++++++++ src/ui/dialog/livepatheffect-add.h | 4 ++++ 2 files changed, 18 insertions(+) (limited to 'src') diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp index b5f51d81d..c558eddaf 100644 --- a/src/ui/dialog/livepatheffect-add.cpp +++ b/src/ui/dialog/livepatheffect-add.cpp @@ -38,6 +38,7 @@ LivePathEffectAdd::LivePathEffectAdd() : scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); scrolled_window.set_shadow_type(Gtk::SHADOW_IN); scrolled_window.set_size_request(250, 200); + scrolled_window.set_can_focus(); /** * Effect Store and Tree @@ -83,10 +84,12 @@ LivePathEffectAdd::LivePathEffectAdd() : add_action_widget(close_button, Gtk::RESPONSE_CLOSE); add_action_widget(add_button, Gtk::RESPONSE_APPLY); + /** * Signal handlers */ effectlist_treeview.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LivePathEffectAdd::onButtonEvent) ); + effectlist_treeview.signal_key_press_event().connect_notify(sigc::mem_fun(*this, &LivePathEffectAdd::onKeyEvent)); close_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)); add_button.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectAdd::onAdd)); signal_delete_event().connect( sigc::bind_return(sigc::hide(sigc::mem_fun(*this, &LivePathEffectAdd::onClose)), true ) ); @@ -107,6 +110,16 @@ void LivePathEffectAdd::onClose() hide(); } +void LivePathEffectAdd::onKeyEvent(GdkEventKey* evt) +{ + if (evt->keyval == GDK_KEY_Return) { + onAdd(); + } + if (evt->keyval == GDK_KEY_Escape) { + onClose(); + } +} + void LivePathEffectAdd::onButtonEvent(GdkEventButton* evt) { // Double click on tree is same as clicking the add button @@ -135,6 +148,7 @@ void LivePathEffectAdd::show(SPDesktop *desktop) dial.set_modal(true); desktop->setWindowTransient (dial.gobj()); dial.property_destroy_with_parent() = true; + dial.effectlist_treeview.grab_focus(); dial.run(); } diff --git a/src/ui/dialog/livepatheffect-add.h b/src/ui/dialog/livepatheffect-add.h index 7fa766272..99ead878c 100644 --- a/src/ui/dialog/livepatheffect-add.h +++ b/src/ui/dialog/livepatheffect-add.h @@ -74,6 +74,10 @@ protected: */ void onButtonEvent(GdkEventButton* evt); + /** + * Key event + */ + void onKeyEvent(GdkEventKey* evt); private: Gtk::TreeView effectlist_treeview; -- cgit v1.2.3 From 8171b3f6ffaabe434dcf4802d984f90e58da4f52 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 25 Apr 2014 13:59:30 -0700 Subject: Fix for on-canvas LPE controls to display immediately. Fixed bugs: - https://launchpad.net/bugs/1219324 (bzr r13306) --- src/sp-lpe-item.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 7dd14f5d9..6e58f7cd4 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -16,6 +16,8 @@ # include "config.h" #endif +#include "ui/tool/multi-path-manipulator.h" + #include #include "live_effects/effect.h" @@ -36,6 +38,9 @@ #include "desktop.h" #include "shape-editor.h" #include "sp-ellipse.h" +#include "tools-switch.h" +#include "ui/tools/node-tool.h" +#include "ui/tools/tool-base.h" #include @@ -417,6 +422,17 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); + + //fix bug 1219324 + Inkscape::UI::Tools::NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + tools_switch(SP_ACTIVE_DESKTOP, TOOLS_LPETOOL); //mhh + tools_switch(SP_ACTIVE_DESKTOP, TOOLS_NODES); + } + } } } -- cgit v1.2.3 From 512ef0bfb6e8a671be141e163c91390380bceb14 Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Fri, 25 Apr 2014 17:18:51 -0700 Subject: Fix warning from previous commit. (bzr r13307) --- src/sp-lpe-item.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 6e58f7cd4..f59bc33ee 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -424,11 +424,9 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) sp_lpe_item_update_patheffect(this, true, true); //fix bug 1219324 - Inkscape::UI::Tools::NodeTool *tool = 0; if (SP_ACTIVE_DESKTOP ) { Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; if (INK_IS_NODE_TOOL(ec)) { - tool = static_cast(ec); tools_switch(SP_ACTIVE_DESKTOP, TOOLS_LPETOOL); //mhh tools_switch(SP_ACTIVE_DESKTOP, TOOLS_NODES); } -- cgit v1.2.3 From e0fd52e75c554c3d4e4f0e08878b918fd723165e Mon Sep 17 00:00:00 2001 From: Shlomi Fish Date: Sat, 26 Apr 2014 08:39:24 +0200 Subject: Fix remaining cmake build error in 2geom (bug #1283174) Fixed bugs: - https://launchpad.net/bugs/1283174 (bzr r13308) --- src/2geom/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/2geom/CMakeLists.txt b/src/2geom/CMakeLists.txt index 3d516dc18..a2c02e682 100644 --- a/src/2geom/CMakeLists.txt +++ b/src/2geom/CMakeLists.txt @@ -115,7 +115,6 @@ set(2geom_SRC solver.h svg-elliptical-arc.h svg-path-parser.h - svg-path.h sweep.h toposweep.h transforms.h -- cgit v1.2.3 From b9f4d7dfe7411f551192a98a3d8151e14149c5ae Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 26 Apr 2014 10:17:28 +0200 Subject: Clean up of style code: Patch from suv: SPStyle: struct -> class (bzr r13309) --- src/desktop-style.h | 8 ++++---- src/desktop.h | 6 +++--- src/display/drawing-group.h | 2 +- src/display/drawing-item.h | 2 +- src/display/drawing-shape.h | 2 +- src/display/drawing-text.h | 2 +- src/display/nr-filter-primitive.h | 2 +- src/display/nr-style.h | 2 +- src/extension/implementation/implementation.h | 2 +- src/extension/internal/emf-inout.h | 2 +- src/extension/internal/wmf-inout.h | 2 +- src/libnrtype/Layout-TNG.h | 2 +- src/libnrtype/font-lister.h | 2 +- src/libnrtype/font-style-to-pos.h | 2 +- src/livarot/Path.h | 2 +- src/print.h | 2 +- src/sp-object.h | 2 +- src/text-editing.h | 10 +++++----- src/ui/widget/style-subject.h | 2 +- src/ui/widget/style-swatch.h | 2 +- src/widgets/paint-selector.h | 2 +- 21 files changed, 30 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/desktop-style.h b/src/desktop-style.h index 47575de75..fc20e97b9 100644 --- a/src/desktop-style.h +++ b/src/desktop-style.h @@ -16,10 +16,10 @@ #include class ColorRGBA; -class SPCSSAttr; -class SPDesktop; -class SPObject; -struct SPStyle; +class SPCSSAttr; +class SPDesktop; +class SPObject; +class SPStyle; namespace Inkscape { namespace XML { class Node; diff --git a/src/desktop.h b/src/desktop.h index fec6249e9..be2bf891f 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -54,10 +54,10 @@ class ToolBase; } } -class SPItem; +class SPItem; class SPNamedView; -class SPObject; -struct SPStyle; +class SPObject; +class SPStyle; typedef struct _DocumentInterface DocumentInterface;//struct DocumentInterface; namespace Gtk diff --git a/src/display/drawing-group.h b/src/display/drawing-group.h index 651e9d8af..ab1f9895d 100644 --- a/src/display/drawing-group.h +++ b/src/display/drawing-group.h @@ -14,7 +14,7 @@ #include "display/drawing-item.h" -struct SPStyle; +class SPStyle; namespace Inkscape { diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index db803cf60..d89299eeb 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -20,7 +20,7 @@ #include <2geom/rect.h> #include <2geom/affine.h> -struct SPStyle; +class SPStyle; namespace Inkscape { diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h index 405c789e0..f37de9ce7 100644 --- a/src/display/drawing-shape.h +++ b/src/display/drawing-shape.h @@ -15,7 +15,7 @@ #include "display/drawing-item.h" #include "display/nr-style.h" -struct SPStyle; +class SPStyle; class SPCurve; namespace Inkscape { diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h index b863ca2a4..41039d85d 100644 --- a/src/display/drawing-text.h +++ b/src/display/drawing-text.h @@ -15,7 +15,7 @@ #include "display/drawing-group.h" #include "display/nr-style.h" -struct SPStyle; +class SPStyle; class font_instance; namespace Inkscape { diff --git a/src/display/nr-filter-primitive.h b/src/display/nr-filter-primitive.h index 94bd6abb0..214b2cfc5 100644 --- a/src/display/nr-filter-primitive.h +++ b/src/display/nr-filter-primitive.h @@ -16,7 +16,7 @@ #include "display/nr-filter-types.h" #include "svg/svg-length.h" -struct SPStyle; +class SPStyle; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-style.h b/src/display/nr-style.h index 717cda899..8b5a0ee3d 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -17,7 +17,7 @@ #include "color.h" class SPPaintServer; -struct SPStyle; +class SPStyle; namespace Inkscape { class DrawingContext; diff --git a/src/extension/implementation/implementation.h b/src/extension/implementation/implementation.h index 9d679982a..fb323cd78 100644 --- a/src/extension/implementation/implementation.h +++ b/src/extension/implementation/implementation.h @@ -29,7 +29,7 @@ namespace Gtk { } class SPDocument; -struct SPStyle; +class SPStyle; namespace Inkscape { diff --git a/src/extension/internal/emf-inout.h b/src/extension/internal/emf-inout.h index a97cb0a54..fc98958bb 100644 --- a/src/extension/internal/emf-inout.h +++ b/src/extension/internal/emf-inout.h @@ -40,7 +40,7 @@ typedef struct { } EMF_STRINGS, *PEMF_STRINGS; typedef struct emf_device_context { - struct SPStyle style; + class SPStyle style; char *font_name; bool stroke_set; int stroke_mode; // enumeration from drawmode, not used if fill_set is not True diff --git a/src/extension/internal/wmf-inout.h b/src/extension/internal/wmf-inout.h index 3d23ca749..94a290873 100644 --- a/src/extension/internal/wmf-inout.h +++ b/src/extension/internal/wmf-inout.h @@ -39,7 +39,7 @@ typedef struct { } WMF_STRINGS, *PWMF_STRINGS; typedef struct wmf_device_context { - struct SPStyle style; + class SPStyle style; char *font_name; bool stroke_set; int stroke_mode; // enumeration from drawmode, not used if fill_set is not True diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h index c3ccbffb5..efb5ebc24 100644 --- a/src/libnrtype/Layout-TNG.h +++ b/src/libnrtype/Layout-TNG.h @@ -34,7 +34,7 @@ namespace Inkscape { using Inkscape::Extension::Internal::CairoRenderContext; #endif -struct SPStyle; +class SPStyle; class Shape; struct SPPrintContext; class SVGLength; diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index c42bf98fd..a460388d3 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -26,7 +26,7 @@ class SPObject; class SPDocument; class SPCSSAttr; -struct SPStyle; +class SPStyle; namespace Inkscape { diff --git a/src/libnrtype/font-style-to-pos.h b/src/libnrtype/font-style-to-pos.h index 56eb391c2..41ba6cf72 100644 --- a/src/libnrtype/font-style-to-pos.h +++ b/src/libnrtype/font-style-to-pos.h @@ -3,7 +3,7 @@ #include -struct SPStyle; +class SPStyle; NRTypePosDef font_style_to_pos(SPStyle const &style); diff --git a/src/livarot/Path.h b/src/livarot/Path.h index a109298a2..32ee71ffc 100644 --- a/src/livarot/Path.h +++ b/src/livarot/Path.h @@ -20,7 +20,7 @@ struct PathDescrCubicTo; struct PathDescrBezierTo; struct PathDescrIntermBezierTo; -struct SPStyle; +class SPStyle; /* * the Path class: a structure to hold path description and their polyline approximation (not kept in sync) diff --git a/src/print.h b/src/print.h index 80d0446fd..bbf95b833 100644 --- a/src/print.h +++ b/src/print.h @@ -18,7 +18,7 @@ class Window; } class SPDocument; -struct SPStyle; +class SPStyle; namespace Inkscape { namespace Extension { diff --git a/src/sp-object.h b/src/sp-object.h index 9ce5629e6..e58f161d6 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -56,7 +56,7 @@ class SPObject; #include "util/forward-pointer-iterator.h" class SPCSSAttr; -struct SPStyle; +class SPStyle; namespace Inkscape { namespace XML { diff --git a/src/text-editing.h b/src/text-editing.h index 04ef6461d..290a39194 100644 --- a/src/text-editing.h +++ b/src/text-editing.h @@ -18,11 +18,11 @@ #include "libnrtype/Layout-TNG.h" #include "text-tag-attributes.h" -class SPCSSAttr; -class SPDesktop; -class SPItem; -class SPObject; -struct SPStyle; +class SPCSSAttr; +class SPDesktop; +class SPItem; +class SPObject; +class SPStyle; typedef std::pair iterator_pair; diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h index c2941d995..47da91732 100644 --- a/src/ui/widget/style-subject.h +++ b/src/ui/widget/style-subject.h @@ -20,7 +20,7 @@ class SPDesktop; class SPObject; class SPCSSAttr; -struct SPStyle; +class SPStyle; namespace Inkscape { class Selection; diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index 23ecbdfda..557ca82e2 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -29,7 +29,7 @@ #include "desktop.h" #include "preferences.h" -struct SPStyle; +class SPStyle; class SPCSSAttr; namespace Gtk { diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index d3b3f4116..d6ad3f50c 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -23,7 +23,7 @@ class SPGradient; class SPDesktop; class SPPattern; -struct SPStyle; +class SPStyle; #define SP_TYPE_PAINT_SELECTOR (sp_paint_selector_get_type ()) #define SP_PAINT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_PAINT_SELECTOR, SPPaintSelector)) -- cgit v1.2.3 From bd5ec5dcbc3e9626103bbbcee7d931d2e0b8eb84 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 27 Apr 2014 12:11:08 +0200 Subject: Replace 'memset' by constructors. Fixes segfault from turning SPStyle into a class. (bzr r13310) --- src/extension/internal/emf-inout.cpp | 343 +++++++++++++++-------------------- src/extension/internal/emf-inout.h | 76 +++++++- 2 files changed, 217 insertions(+), 202 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index eae3bfb5a..711d7e3a4 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -273,54 +273,54 @@ uint32_t Emf::add_hatch(PEMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hpathname); - *(d->defs) += "\n"; + d->defs += "\n"; switch(hatchType){ case U_HS_HORIZONTAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 6 0\" style=\"fill:none;stroke:#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 6 0\" style=\"fill:none;stroke:#"; + d->defs += tmpcolor; + d->defs += "\" />\n"; break; case U_HS_VERTICAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 0 6\" style=\"fill:none;stroke:#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 0 6\" style=\"fill:none;stroke:#"; + d->defs += tmpcolor; + d->defs += "\" />\n"; break; case U_HS_FDIAGONAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; break; case U_HS_BDIAGONAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; break; case U_HS_CROSS: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 6 0 M 0 0 0 6\" style=\"fill:none;stroke:#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 6 0 M 0 0 0 6\" style=\"fill:none;stroke:#"; + d->defs += tmpcolor; + d->defs += "\" />\n"; break; case U_HS_DIAGCROSS: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; break; case U_HS_SOLIDCLR: case U_HS_DITHEREDCLR: @@ -329,12 +329,12 @@ uint32_t Emf::add_hatch(PEMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat case U_HS_SOLIDBKCLR: case U_HS_DITHEREDBKCLR: default: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 6 0 6 6 0 6 z\" style=\"fill:#"; - *(d->defs) += tmpcolor; - *(d->defs) += ";stroke:none"; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 6 0 6 6 0 6 z\" style=\"fill:#"; + d->defs += tmpcolor; + d->defs += ";stroke:none"; + d->defs += "\" />\n"; break; } } @@ -396,12 +396,12 @@ uint32_t Emf::add_hatch(PEMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(!idx){ // add it if not already present if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hatchname); - *(d->defs) += "\n"; - *(d->defs) += " defs) += hatchname; - *(d->defs) += "\" xlink:href=\"#EMFhbasepattern\">\n"; - *(d->defs) += refpath; - *(d->defs) += " \n"; + d->defs += "\n"; + d->defs += " defs += hatchname; + d->defs += "\" xlink:href=\"#EMFhbasepattern\">\n"; + d->defs += refpath; + d->defs += " \n"; idx = d->hatches.count; } } @@ -414,12 +414,12 @@ uint32_t Emf::add_hatch(PEMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hbkname); - *(d->defs) += "\n"; - *(d->defs) += " defs) += hbkname; - *(d->defs) += "\" x=\"0\" y=\"0\" width=\"6\" height=\"6\" fill=\"#"; - *(d->defs) += bkcolor; - *(d->defs) += "\" />\n"; + d->defs += "\n"; + d->defs += " defs += hbkname; + d->defs += "\" x=\"0\" y=\"0\" width=\"6\" height=\"6\" fill=\"#"; + d->defs += bkcolor; + d->defs += "\" />\n"; } // this is the pattern, its name will show up in Inkscape's pattern selector @@ -428,15 +428,15 @@ uint32_t Emf::add_hatch(PEMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(!idx){ // add it if not already present if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hatchname); - *(d->defs) += "\n"; - *(d->defs) += " defs) += hatchname; - *(d->defs) += "\" xlink:href=\"#EMFhbasepattern\">\n"; - *(d->defs) += " defs) += hbkname; - *(d->defs) += "\" />\n"; - *(d->defs) += refpath; - *(d->defs) += " \n"; + d->defs += "\n"; + d->defs += " defs += hatchname; + d->defs += "\" xlink:href=\"#EMFhbasepattern\">\n"; + d->defs += " defs += hbkname; + d->defs += "\" />\n"; + d->defs += refpath; + d->defs += " \n"; idx = d->hatches.count; } } @@ -544,35 +544,35 @@ uint32_t Emf::add_image(PEMF_CALLBACK_DATA d, void *pEmr, uint32_t cbBits, uint sprintf(imagename,"EMFimage%d",idx++); sprintf(xywh," x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" ",width,height); // reuse this buffer - *(d->defs) += "\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "\"\n "; - *(d->defs) += xywh; - *(d->defs) += "\n"; - if(dibparams == U_BI_JPEG){ *(d->defs) += " xlink:href=\"data:image/jpeg;base64,"; } - else { *(d->defs) += " xlink:href=\"data:image/png;base64,"; } - *(d->defs) += base64String; - *(d->defs) += "\"\n"; - *(d->defs) += " preserveAspectRatio=\"none\"\n"; - *(d->defs) += " />\n"; - - - *(d->defs) += "\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "_ref\"\n "; - *(d->defs) += xywh; - *(d->defs) += "\n patternUnits=\"userSpaceOnUse\""; - *(d->defs) += " >\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "_ign\" "; - *(d->defs) += " xlink:href=\"#"; - *(d->defs) += imagename; - *(d->defs) += "\" />\n"; - *(d->defs) += " "; - *(d->defs) += " \n"; + d->defs += "\n"; + d->defs += " defs += imagename; + d->defs += "\"\n "; + d->defs += xywh; + d->defs += "\n"; + if(dibparams == U_BI_JPEG){ d->defs += " xlink:href=\"data:image/jpeg;base64,"; } + else { d->defs += " xlink:href=\"data:image/png;base64,"; } + d->defs += base64String; + d->defs += "\"\n"; + d->defs += " preserveAspectRatio=\"none\"\n"; + d->defs += " />\n"; + + + d->defs += "\n"; + d->defs += " defs += imagename; + d->defs += "_ref\"\n "; + d->defs += xywh; + d->defs += "\n patternUnits=\"userSpaceOnUse\""; + d->defs += " >\n"; + d->defs += " defs += imagename; + d->defs += "_ign\" "; + d->defs += " xlink:href=\"#"; + d->defs += imagename; + d->defs += "\" />\n"; + d->defs += " "; + d->defs += " \n"; } g_free(base64String);//wait until this point to free because it might be a duplicate image @@ -596,17 +596,17 @@ uint32_t Emf::add_image(PEMF_CALLBACK_DATA d, void *pEmr, uint32_t cbBits, uint d->images.strings[d->images.count++]=strdup(base64String); sprintf(imrotname,"EMFimage%d",idx++); - *(d->defs) += "\n"; - *(d->defs) += " defs) += " id=\""; - *(d->defs) += imrotname; - *(d->defs) += "_ref\"\n"; - *(d->defs) += " xlink:href=\"#"; - *(d->defs) += imagename; - *(d->defs) += "_ref\"\n"; - *(d->defs) += " patternTransform="; - *(d->defs) += current_matrix(d, 0.0, 0.0, 0); //j use offset 0,0 - *(d->defs) += " />\n"; + d->defs += "\n"; + d->defs += " defs += " id=\""; + d->defs += imrotname; + d->defs += "_ref\"\n"; + d->defs += " xlink:href=\"#"; + d->defs += imagename; + d->defs += "_ref\"\n"; + d->defs += " patternTransform="; + d->defs += current_matrix(d, 0.0, 0.0, 0); //j use offset 0,0 + d->defs += " />\n"; } g_free(base64String); } @@ -716,7 +716,7 @@ uint32_t Emf::add_gradient(PEMF_CALLBACK_DATA d, uint32_t gradientType, U_TRIVER stmp << tmpcolor2; stmp << ";stop-opacity:1\" />\n"; stmp << " \n"; - *(d->defs) += stmp.str().c_str(); + d->defs += stmp.str().c_str(); } return(idx-1); @@ -811,8 +811,8 @@ Emf::output_style(PEMF_CALLBACK_DATA d, int iType) // tmp_id << "\n\tid=\"" << (d->id++) << "\""; -// *(d->outsvg) += tmp_id.str().c_str(); - *(d->outsvg) += "\n\tstyle=\""; +// d->outsvg += tmp_id.str().c_str(); + d->outsvg += "\n\tstyle=\""; if (iType == U_EMR_STROKEPATH || !d->dc[d->level].fill_set) { tmp_style << "fill:none;"; } else { @@ -936,7 +936,7 @@ Emf::output_style(PEMF_CALLBACK_DATA d, int iType) tmp_style << "\n\tclip-path=\"url(#clipEmfPath" << d->id << ")\" "; clipset = false; - *(d->outsvg) += tmp_style.str().c_str(); + d->outsvg += tmp_style.str().c_str(); } @@ -1525,8 +1525,8 @@ void Emf::common_image_extraction(PEMF_CALLBACK_DATA d, void *pEmr, tmp_image << " preserveAspectRatio=\"none\"\n"; tmp_image << "/> \n"; - *(d->outsvg) += tmp_image.str().c_str(); - *(d->path) = ""; + d->outsvg += tmp_image.str().c_str(); + d->path = ""; } /** @@ -1595,7 +1595,7 @@ int Emf::myEnhMetaFileProc(char *contents, unsigned int length, PEMF_CALLBACK_DA TR_layout_2_svg(d->tri); SVGOStringStream ts; ts << d->tri->out; - *(d->outsvg) += ts.str().c_str(); + d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); } if(d->dc[d->level].dirty){ //Apply the delayed background changes, clear the flag @@ -1652,7 +1652,7 @@ std::cout << "BEFORE DRAW" ) ){ // std::cout << "PATH DRAW at TOP" << std::endl; - *(d->outsvg) += " outsvg += " drawtype){ // explicit draw type EMR record output_style(d, d->drawtype); } @@ -1662,11 +1662,11 @@ std::cout << "BEFORE DRAW" else { output_style(d, U_EMR_STROKEPATH); } - *(d->outsvg) += "\n\t"; - *(d->outsvg) += "\n\td=\""; // this is the ONLY place d=" should be used!!!! One exception, gradientfill. - *(d->outsvg) += *(d->path); - *(d->outsvg) += " \" /> \n"; - *(d->path) = ""; + d->outsvg += "\n\t"; + d->outsvg += "\n\td=\""; // this is the ONLY place d=" should be used!!!! One exception, gradientfill. + d->outsvg += d->path; + d->outsvg += " \" /> \n"; + d->path = ""; // reset the flags d->mask = 0; d->drawtype = 0; @@ -1679,12 +1679,12 @@ std::cout << "BEFORE DRAW" { dbg_str << "\n"; - *(d->outdef) += "\n"; + d->outdef += "\n"; if (d->pDesc) { - *(d->outdef) += "\n"; + d->outdef += "\n"; } PU_EMRHEADER pEmr = (PU_EMRHEADER) lpEMFR; @@ -1745,8 +1745,8 @@ std::cout << "BEFORE DRAW" tmp_outdef << " width=\"" << d->MMX << "mm\"\n" << " height=\"" << d->MMY << "mm\">\n"; - *(d->outdef) += tmp_outdef.str().c_str(); - *(d->outdef) += ""; // temporary end of header + d->outdef += tmp_outdef.str().c_str(); + d->outdef += ""; // temporary end of header // d->defs holds any defines which are read in. @@ -2015,7 +2015,7 @@ std::cout << "BEFORE DRAW" dbg_str << "\n"; tmp_outsvg << "\n"; - *(d->outsvg) = *(d->outdef) + *(d->defs) + *(d->outsvg); + d->outsvg = d->outdef + d->defs + d->outsvg; OK=0; break; } @@ -2167,8 +2167,8 @@ std::cout << "BEFORE DRAW" tmp_rectangle << "\n transform=" << current_matrix(d, dx, dy, 1); // calculate appropriate offset tmp_rectangle << "/>\n"; - *(d->outdef) += tmp_rectangle.str().c_str(); - *(d->path) = ""; + d->outdef += tmp_rectangle.str().c_str(); + d->path = ""; break; } case U_EMR_SCALEVIEWPORTEXTEX: dbg_str << "\n"; break; @@ -2453,12 +2453,12 @@ std::cout << "BEFORE DRAW" d->mask |= emr_mask; - *(d->outsvg) += " outsvg += " iType); // - *(d->outsvg) += "\n\t"; - *(d->outsvg) += tmp_ellipse.str().c_str(); - *(d->outsvg) += "/> \n"; - *(d->path) = ""; + d->outsvg += "\n\t"; + d->outsvg += tmp_ellipse.str().c_str(); + d->outsvg += "/> \n"; + d->path = ""; break; } case U_EMR_RECTANGLE: @@ -2679,7 +2679,7 @@ std::cout << "BEFORE DRAW" // The next line should never be needed, should have been handled before main switch // qualifier added because EMF's encountered where moveto preceded beginpath followed by lineto if(d->mask & U_DRAW_VISIBLE){ - *(d->path) = ""; + d->path = ""; } d->mask |= emr_mask; break; @@ -2739,7 +2739,7 @@ std::cout << "BEFORE DRAW" case U_EMR_ABORTPATH: { dbg_str << "\n"; - *(d->path) = ""; + d->path = ""; d->drawtype = 0; break; } @@ -3048,7 +3048,7 @@ std::cout << "BEFORE DRAW" TR_layout_analyze(d->tri); TR_layout_2_svg(d->tri); ts << d->tri->out; - *(d->outsvg) += ts.str().c_str(); + d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); (void) trinfo_load_textrec(d->tri, &tsp, tsp.ori,TR_EMFBOT); // ignore return status, it must work } @@ -3292,7 +3292,7 @@ std::cout << "BEFORE DRAW" tmp_rectangle << d->gradients.strings[fill_idx]; tmp_rectangle << ");\"\n/>\n"; } - *(d->outsvg) += tmp_rectangle.str().c_str(); + d->outsvg += tmp_rectangle.str().c_str(); } else if(pEmr->ulMode == U_GRADIENT_FILL_TRIANGLE){ SVGOStringStream tmp_triangle; @@ -3310,9 +3310,9 @@ std::cout << "BEFORE DRAW" tmp_triangle << tmpcolor; tmp_triangle << ";\"\n/>\n"; } - *(d->outsvg) += tmp_triangle.str().c_str(); + d->outsvg += tmp_triangle.str().c_str(); } - *(d->path) = ""; + d->path = ""; // if it is anything else the record is bogus, so ignore it break; } @@ -3325,13 +3325,13 @@ std::cout << "BEFORE DRAW" break; } //end of switch // When testing, uncomment the following to place a comment for each processed EMR record in the SVG -// *(d->outsvg) += dbg_str.str().c_str(); - *(d->outsvg) += tmp_outsvg.str().c_str(); - *(d->path) += tmp_path.str().c_str(); +// d->outsvg += dbg_str.str().c_str(); + d->outsvg += tmp_outsvg.str().c_str(); + d->path += tmp_path.str().c_str(); } //end of while // When testing, uncomment the following to show the final SVG derived from the EMF -// std::cout << *(d->outsvg) << std::endl; +// std::cout << d->outsvg << std::endl; (void) emr_properties(U_EMR_INVALID); // force the release of the lookup table memory, returned value is irrelevant return 1; @@ -3349,61 +3349,20 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) { EMF_CALLBACK_DATA d; -// memset(&d, 0, sizeof(d)); - memset(&d, 0, sizeof(EMF_CALLBACK_DATA)); - - for(int i = 0; i < EMF_MAX_DC+1; i++){ // be sure all values and pointers are empty to start with - memset(&(d.dc[i]),0,sizeof(EMF_DEVICE_CONTEXT)); - } - - d.dc[0].worldTransform.eM11 = 1.0; - d.dc[0].worldTransform.eM12 = 0.0; - d.dc[0].worldTransform.eM21 = 0.0; - d.dc[0].worldTransform.eM22 = 1.0; - d.dc[0].worldTransform.eDx = 0.0; - d.dc[0].worldTransform.eDy = 0.0; - d.dc[0].font_name = strdup("Arial"); // Default font, EMF spec says device can pick whatever it wants - d.dc[0].textColor = U_RGB(0, 0, 0); // default foreground color (black) - d.dc[0].bkColor = U_RGB(255, 255, 255); // default background color (white) - d.dc[0].bkMode = U_TRANSPARENT; - d.dc[0].dirty = 0; - if (uri == NULL) { return NULL; } - d.outsvg = new Glib::ustring(""); - d.path = new Glib::ustring(""); - d.outdef = new Glib::ustring(""); - d.defs = new Glib::ustring(""); - d.mask = 0; - d.drawtype = 0; - d.arcdir = U_AD_COUNTERCLOCKWISE; - d.dwRop2 = U_R2_COPYPEN; - d.dwRop3 = 0; - d.E2IdirY = 1.0; - d.D2PscaleX = 1.0; - d.D2PscaleY = 1.0; - d.hatches.size = 0; - d.hatches.count = 0; - d.hatches.strings = NULL; - d.images.size = 0; - d.images.count = 0; - d.images.strings = NULL; - d.gradients.size = 0; - d.gradients.count = 0; - d.gradients.strings = NULL; - // set up the size default for patterns in defs. This might not be referenced if there are no patterns defined in the drawing. - *(d.defs) += "\n"; - *(d.defs) += " \n"; - *(d.defs) += " \n"; + d.defs += "\n"; + d.defs += " \n"; + d.defs += " \n"; size_t length; @@ -3425,12 +3384,8 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) // std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl; - SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg->c_str(), strlen(d.outsvg->c_str()), TRUE); + SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg.c_str(), strlen(d.outsvg.c_str()), TRUE); - delete d.outsvg; - delete d.path; - delete d.outdef; - delete d.defs; free_emf_strings(d.hatches); free_emf_strings(d.images); free_emf_strings(d.gradients); diff --git a/src/extension/internal/emf-inout.h b/src/extension/internal/emf-inout.h index fc98958bb..280269d0d 100644 --- a/src/extension/internal/emf-inout.h +++ b/src/extension/internal/emf-inout.h @@ -27,20 +27,59 @@ namespace Internal { #define DIRTY_FILL 0x02 #define DIRTY_STROKE 0x04 -typedef struct { +typedef struct emf_object { + emf_object() : + type(0), + level(0), + lpEMFR(NULL) + {}; int type; int level; char *lpEMFR; } EMF_OBJECT, *PEMF_OBJECT; -typedef struct { +typedef struct emf_strings { + emf_strings() : + size(0), + count(0), + strings(NULL) + {}; int size; // number of slots allocated in strings int count; // number of slots used in strings char **strings; // place to store strings } EMF_STRINGS, *PEMF_STRINGS; typedef struct emf_device_context { - class SPStyle style; + emf_device_context() : + // SPStyle: class with constructor + font_name(NULL), + stroke_set(false), stroke_mode(0), stroke_idx(0), stroke_recidx(0), + fill_set(false), fill_mode(0), fill_idx(0), fill_recidx(0), + dirty(0), + // sizeWnd, sizeView, winorg, vieworg, + ScaleInX(0), ScaleInY(0), + ScaleOutX(0), ScaleOutY(0), + bkMode(U_TRANSPARENT), + // bkColor, textColor + textAlign(0) + // worldTransform, cur + { + font_name = strdup("Arial"); // Default font, EMF spec says device can pick whatever it wants + sizeWnd = sizel_set( 0.0, 0.0 ); + sizeView = sizel_set( 0.0, 0.0 ); + winorg = point32_set( 0.0, 0.0 ); + vieworg = point32_set( 0.0, 0.0 ); + bkColor = U_RGB(255, 255, 255); // default foreground color (white) + textColor = U_RGB(0, 0, 0); // default foreground color (black) + worldTransform.eM11 = 1.0; + worldTransform.eM12 = 0.0; + worldTransform.eM21 = 0.0; + worldTransform.eM22 = 1.0; + worldTransform.eDx = 0.0; + worldTransform.eDy = 0.0; + cur = point32_set( 0, 0 ); + }; + SPStyle style; char *font_name; bool stroke_set; int stroke_mode; // enumeration from drawmode, not used if fill_set is not True @@ -67,11 +106,32 @@ typedef struct emf_device_context { #define EMF_MAX_DC 128 -typedef struct { - Glib::ustring *outsvg; - Glib::ustring *path; - Glib::ustring *outdef; - Glib::ustring *defs; +typedef struct emf_callback_data { + + emf_callback_data() : + // dc: array, structure w/ constructor + level(0), + E2IdirY(1.0), + D2PscaleX(1.0), D2PscaleY(1.0), + MM100InX(0), MM100InY(0), + PixelsInX(0), PixelsInY(0), + PixelsOutX(0), PixelsOutY(0), + ulCornerInX(0), ulCornerInY(0), + ulCornerOutX(0), ulCornerOutY(0), + mask(0), + arcdir(U_AD_COUNTERCLOCKWISE), + dwRop2(U_R2_COPYPEN), dwRop3(0), + MMX(0),MMY(0), + id(0), drawtype(0), + pDesc(NULL), + // hatches, images, gradients, struct w/ constructor + tri(NULL) + {}; + + Glib::ustring outsvg; + Glib::ustring path; + Glib::ustring outdef; + Glib::ustring defs; EMF_DEVICE_CONTEXT dc[EMF_MAX_DC+1]; // FIXME: This should be dynamic.. int level; -- cgit v1.2.3 From 7b947c3d7f46b948674f68ac5a8d592f5445cf25 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 27 Apr 2014 14:05:57 +0200 Subject: Replace 'memset' by constructors. Fixes segfault from turning SPStyle into a class. (WMF) modified: src/extension/internal/emf-inout.h src/extension/internal/wmf-inout.cpp src/extension/internal/wmf-inout.h unknown: .comments/ 1232425-fix-clang-warnings-mismatched-tags-SPStyle-r13299-v1.diff FILTERS/ RecentTextDecoChagnes.zip doxygen/ share/attributes/attindex.html share/attributes/propidx.html share/symbols/FlowSymbolsNew.svg src/cxxtests src/cxxtests.cpp src/cxxtests.log src/cxxtests.xml src/ui/dialog/symbols.cpp_new (bzr r13311) --- src/extension/internal/emf-inout.h | 4 +- src/extension/internal/wmf-inout.cpp | 358 ++++++++++++++++------------------- src/extension/internal/wmf-inout.h | 71 ++++++- 3 files changed, 226 insertions(+), 207 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.h b/src/extension/internal/emf-inout.h index 280269d0d..f15db5518 100644 --- a/src/extension/internal/emf-inout.h +++ b/src/extension/internal/emf-inout.h @@ -125,7 +125,9 @@ typedef struct emf_callback_data { id(0), drawtype(0), pDesc(NULL), // hatches, images, gradients, struct w/ constructor - tri(NULL) + tri(NULL), + n_obj(0) + // emf_obj; {}; Glib::ustring outsvg; diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index ef95dbe45..d13998d81 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -251,54 +251,54 @@ uint32_t Wmf::add_hatch(PWMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hpathname); - *(d->defs) += "\n"; + d->defs += "\n"; switch(hatchType){ case U_HS_HORIZONTAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 6 0\" style=\"fill:none;stroke:#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 6 0\" style=\"fill:none;stroke:#"; + d->defs += tmpcolor; + d->defs += "\" />\n"; break; case U_HS_VERTICAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 0 6\" style=\"fill:none;stroke:#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 0 6\" style=\"fill:none;stroke:#"; + d->defs += tmpcolor; + d->defs += "\" />\n"; break; case U_HS_FDIAGONAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; break; case U_HS_BDIAGONAL: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; break; case U_HS_CROSS: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 6 0 M 0 0 0 6\" style=\"fill:none;stroke:#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 6 0 M 0 0 0 6\" style=\"fill:none;stroke:#"; + d->defs += tmpcolor; + d->defs += "\" />\n"; break; case U_HS_DIAGCROSS: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; - *(d->defs) += tmpcolor; - *(d->defs) += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"-1\" x2=\"7\" y2=\"7\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; + d->defs += " defs += hpathname; + d->defs += "\" x1=\"-1\" y1=\"7\" x2=\"7\" y2=\"-1\" stroke=\"#"; + d->defs += tmpcolor; + d->defs += "\"/>\n"; break; case U_HS_SOLIDCLR: case U_HS_DITHEREDCLR: @@ -307,12 +307,12 @@ uint32_t Wmf::add_hatch(PWMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat case U_HS_SOLIDBKCLR: case U_HS_DITHEREDBKCLR: default: - *(d->defs) += " defs) += hpathname; - *(d->defs) += "\" d=\"M 0 0 6 0 6 6 0 6 z\" style=\"fill:#"; - *(d->defs) += tmpcolor; - *(d->defs) += ";stroke:none"; - *(d->defs) += "\" />\n"; + d->defs += " defs += hpathname; + d->defs += "\" d=\"M 0 0 6 0 6 6 0 6 z\" style=\"fill:#"; + d->defs += tmpcolor; + d->defs += ";stroke:none"; + d->defs += "\" />\n"; break; } } @@ -374,12 +374,12 @@ uint32_t Wmf::add_hatch(PWMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(!idx){ // add it if not already present if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hatchname); - *(d->defs) += "\n"; - *(d->defs) += " defs) += hatchname; - *(d->defs) += "\" xlink:href=\"#WMFhbasepattern\">\n"; - *(d->defs) += refpath; - *(d->defs) += " \n"; + d->defs += "\n"; + d->defs += " defs += hatchname; + d->defs += "\" xlink:href=\"#WMFhbasepattern\">\n"; + d->defs += refpath; + d->defs += " \n"; idx = d->hatches.count; } } @@ -392,12 +392,12 @@ uint32_t Wmf::add_hatch(PWMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hbkname); - *(d->defs) += "\n"; - *(d->defs) += " defs) += hbkname; - *(d->defs) += "\" x=\"0\" y=\"0\" width=\"6\" height=\"6\" fill=\"#"; - *(d->defs) += bkcolor; - *(d->defs) += "\" />\n"; + d->defs += "\n"; + d->defs += " defs += hbkname; + d->defs += "\" x=\"0\" y=\"0\" width=\"6\" height=\"6\" fill=\"#"; + d->defs += bkcolor; + d->defs += "\" />\n"; } // this is the pattern, its name will show up in Inkscape's pattern selector @@ -406,15 +406,15 @@ uint32_t Wmf::add_hatch(PWMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hat if(!idx){ // add it if not already present if(d->hatches.count == d->hatches.size){ enlarge_hatches(d); } d->hatches.strings[d->hatches.count++]=strdup(hatchname); - *(d->defs) += "\n"; - *(d->defs) += " defs) += hatchname; - *(d->defs) += "\" xlink:href=\"#WMFhbasepattern\">\n"; - *(d->defs) += " defs) += hbkname; - *(d->defs) += "\" />\n"; - *(d->defs) += refpath; - *(d->defs) += " \n"; + d->defs += "\n"; + d->defs += " defs += hatchname; + d->defs += "\" xlink:href=\"#WMFhbasepattern\">\n"; + d->defs += " defs += hbkname; + d->defs += "\" />\n"; + d->defs += refpath; + d->defs += " \n"; idx = d->hatches.count; } } @@ -503,35 +503,35 @@ uint32_t Wmf::add_dib_image(PWMF_CALLBACK_DATA d, const char *dib, uint32_t iUsa sprintf(imagename,"WMFimage%d",idx++); sprintf(xywh," x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" ",width,height); // reuse this buffer - *(d->defs) += "\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "\"\n "; - *(d->defs) += xywh; - *(d->defs) += "\n"; - if(dibparams == U_BI_JPEG){ *(d->defs) += " xlink:href=\"data:image/jpeg;base64,"; } - else { *(d->defs) += " xlink:href=\"data:image/png;base64,"; } - *(d->defs) += base64String; - *(d->defs) += "\"\n"; - *(d->defs) += " preserveAspectRatio=\"none\"\n"; - *(d->defs) += " />\n"; - - - *(d->defs) += "\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "_ref\"\n "; - *(d->defs) += xywh; - *(d->defs) += "\n patternUnits=\"userSpaceOnUse\""; - *(d->defs) += " >\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "_ign\" "; - *(d->defs) += " xlink:href=\"#"; - *(d->defs) += imagename; - *(d->defs) += "\" />\n"; - *(d->defs) += " "; - *(d->defs) += " \n"; + d->defs += "\n"; + d->defs += " defs += imagename; + d->defs += "\"\n "; + d->defs += xywh; + d->defs += "\n"; + if(dibparams == U_BI_JPEG){ d->defs += " xlink:href=\"data:image/jpeg;base64,"; } + else { d->defs += " xlink:href=\"data:image/png;base64,"; } + d->defs += base64String; + d->defs += "\"\n"; + d->defs += " preserveAspectRatio=\"none\"\n"; + d->defs += " />\n"; + + + d->defs += "\n"; + d->defs += " defs += imagename; + d->defs += "_ref\"\n "; + d->defs += xywh; + d->defs += "\n patternUnits=\"userSpaceOnUse\""; + d->defs += " >\n"; + d->defs += " defs += imagename; + d->defs += "_ign\" "; + d->defs += " xlink:href=\"#"; + d->defs += imagename; + d->defs += "\" />\n"; + d->defs += " "; + d->defs += " \n"; } g_free(base64String); //wait until this point to free because it might be a duplicate image return(idx-1); @@ -599,33 +599,33 @@ uint32_t Wmf::add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char * sprintf(imagename,"WMFimage%d",idx++); sprintf(xywh," x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" ",width,height); // reuse this buffer - *(d->defs) += "\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "\"\n "; - *(d->defs) += xywh; - *(d->defs) += "\n"; - *(d->defs) += " xlink:href=\"data:image/png;base64,"; - *(d->defs) += base64String; - *(d->defs) += "\"\n"; - *(d->defs) += " preserveAspectRatio=\"none\"\n"; - *(d->defs) += " />\n"; - - - *(d->defs) += "\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "_ref\"\n "; - *(d->defs) += xywh; - *(d->defs) += "\n patternUnits=\"userSpaceOnUse\""; - *(d->defs) += " >\n"; - *(d->defs) += " defs) += imagename; - *(d->defs) += "_ign\" "; - *(d->defs) += " xlink:href=\"#"; - *(d->defs) += imagename; - *(d->defs) += "\" />\n"; - *(d->defs) += " \n"; + d->defs += "\n"; + d->defs += " defs += imagename; + d->defs += "\"\n "; + d->defs += xywh; + d->defs += "\n"; + d->defs += " xlink:href=\"data:image/png;base64,"; + d->defs += base64String; + d->defs += "\"\n"; + d->defs += " preserveAspectRatio=\"none\"\n"; + d->defs += " />\n"; + + + d->defs += "\n"; + d->defs += " defs += imagename; + d->defs += "_ref\"\n "; + d->defs += xywh; + d->defs += "\n patternUnits=\"userSpaceOnUse\""; + d->defs += " >\n"; + d->defs += " defs += imagename; + d->defs += "_ign\" "; + d->defs += " xlink:href=\"#"; + d->defs += imagename; + d->defs += "\" />\n"; + d->defs += " \n"; } g_free(base64String); //wait until this point to free because it might be a duplicate image return(idx-1); @@ -714,8 +714,8 @@ Wmf::output_style(PWMF_CALLBACK_DATA d) // tmp_id << "\n\tid=\"" << (d->id++) << "\""; -// *(d->outsvg) += tmp_id.str().c_str(); - *(d->outsvg) += "\n\tstyle=\""; +// d->outsvg += tmp_id.str().c_str(); + d->outsvg += "\n\tstyle=\""; if (!d->dc[d->level].fill_set || ( d->mask & U_DRAW_NOFILL)) { // nofill are lines and arcs tmp_style << "fill:none;"; } else { @@ -842,7 +842,7 @@ Wmf::output_style(PWMF_CALLBACK_DATA d) tmp_style << "\n\tclip-path=\"url(#clipWmfPath" << d->id << ")\" "; clipset = false; - *(d->outsvg) += tmp_style.str().c_str(); + d->outsvg += tmp_style.str().c_str(); } @@ -1326,8 +1326,8 @@ void Wmf::common_dib_to_image(PWMF_CALLBACK_DATA d, const char *dib, tmp_image << " preserveAspectRatio=\"none\"\n"; tmp_image << "/> \n"; - *(d->outsvg) += tmp_image.str().c_str(); - *(d->path) = ""; + d->outsvg += tmp_image.str().c_str(); + d->path = ""; } /** @@ -1418,8 +1418,8 @@ void Wmf::common_bm16_to_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char tmp_image << " preserveAspectRatio=\"none\"\n"; tmp_image << "/> \n"; - *(d->outsvg) += tmp_image.str().c_str(); - *(d->path) = ""; + d->outsvg += tmp_image.str().c_str(); + d->path = ""; } /** @@ -1579,7 +1579,7 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK d->dc[0].style.stroke_width.value = pix_to_abs_size( d, 1 ); // This could not be set until the size of the WMF was known dbg_str << "\n"; - *(d->outdef) += "\n"; + d->outdef += "\n"; SVGOStringStream tmp_outdef; tmp_outdef << "PixelsOutX, "px", "mm") << "mm\"\n" << " height=\"" << Inkscape::Util::Quantity::convert(d->PixelsOutY, "px", "mm") << "mm\">\n"; - *(d->outdef) += tmp_outdef.str().c_str(); - *(d->outdef) += ""; // temporary end of header + d->outdef += tmp_outdef.str().c_str(); + d->outdef += ""; // temporary end of header // d->defs holds any defines which are read in. @@ -1636,7 +1636,7 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK TR_layout_2_svg(d->tri); SVGOStringStream ts; ts << d->tri->out; - *(d->outsvg) += ts.str().c_str(); + d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); } if(d->dc[d->level].dirty){ //Apply the delayed background changes, clear the flag @@ -1688,13 +1688,13 @@ std::cout << "BEFORE DRAW" ) ){ // std::cout << "PATH DRAW at TOP <<+++++++++++++++++++++++++++++++++++++" << std::endl; - *(d->outsvg) += " outsvg += " outsvg) += "\n\t"; - *(d->outsvg) += "\n\td=\""; // this is the ONLY place d=" should be used!!!! - *(d->outsvg) += *(d->path); - *(d->outsvg) += " \" /> \n"; - *(d->path) = ""; //reset the path + d->outsvg += "\n\t"; + d->outsvg += "\n\td=\""; // this is the ONLY place d=" should be used!!!! + d->outsvg += d->path; + d->outsvg += " \" /> \n"; + d->path = ""; //reset the path // reset the flags d->mask = 0; d->drawtype = 0; @@ -1706,7 +1706,7 @@ std::cout << "BEFORE DRAW" { dbg_str << "\n"; - *(d->outsvg) = *(d->outdef) + *(d->defs) + "\n\n\n" + *(d->outsvg) + "\n"; + d->outsvg = d->outdef + d->defs + "\n\n\n" + d->outsvg + "\n"; OK=0; break; } @@ -1944,8 +1944,8 @@ std::cout << "BEFORE DRAW" tmp_rectangle << "\n height=\"" << dh << "\" />"; tmp_rectangle << "\n"; - *(d->outdef) += tmp_rectangle.str().c_str(); - *(d->path) = ""; + d->outdef += tmp_rectangle.str().c_str(); + d->path = ""; break; } case U_WMR_ARC: @@ -1992,12 +1992,12 @@ std::cout << "BEFORE DRAW" d->mask |= wmr_mask; - *(d->outsvg) += " outsvg += " outsvg) += "\n\t"; - *(d->outsvg) += tmp_ellipse.str().c_str(); - *(d->outsvg) += "/> \n"; - *(d->path) = ""; + d->outsvg += "\n\t"; + d->outsvg += tmp_ellipse.str().c_str(); + d->outsvg += "/> \n"; + d->path = ""; break; } case U_WMR_FLOODFILL: dbg_str << "\n"; break; @@ -2503,7 +2503,7 @@ std::cout << "BEFORE DRAW" TR_layout_analyze(d->tri); TR_layout_2_svg(d->tri); ts << d->tri->out; - *(d->outsvg) += ts.str().c_str(); + d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); (void) trinfo_load_textrec(d->tri, &tsp, tsp.ori,TR_EMFBOT); // ignore return status, it must work } @@ -2910,13 +2910,13 @@ std::cout << "BEFORE DRAW" break; } //end of switch // When testing, uncomment the following to place a comment for each processed WMR record in the SVG -// *(d->outsvg) += dbg_str.str().c_str(); - *(d->path) += tmp_path.str().c_str(); +// d->outsvg += dbg_str.str().c_str(); + d->path += tmp_path.str().c_str(); if(!nSize){ OK=0; std::cout << "nSize == 0, oops!!!" << std::endl; } // There was some problem with this record, it is not safe to continue } //end of while // When testing, uncomment the following to show the final SVG derived from the WMF -// std::cout << *(d->outsvg) << std::endl; +// std::cout << d->outsvg << std::endl; (void) U_wmr_properties(U_WMR_INVALID); // force the release of the lookup table memory, returned value is irrelevant return 1; @@ -2935,70 +2935,36 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) WMF_CALLBACK_DATA d; - memset(&d, 0, sizeof(WMF_CALLBACK_DATA)); - - for(int i = 0; i < WMF_MAX_DC+1; i++){ // be sure all values and pointers are empty to start with - memset(&(d.dc[i]),0,sizeof(WMF_DEVICE_CONTEXT)); - } - // set default drawing objects, these are active if no object has been selected - d.dc[0].active_pen = -1; // -1 when the default is used instead of a selected object - d.dc[0].active_brush = -1; - d.dc[0].active_font = -1; - // Default font, WMF spec says device can pick whatever it wants. WMF files that do not specify a font are unlikely to look very good! - d.dc[0].font_name = strdup("Arial"); + // Default font, WMF spec says device can pick whatever it wants. + // WMF files that do not specify a font are unlikely to look very good! d.dc[0].style.font_size.computed = 16.0; d.dc[0].style.font_weight.value = SP_CSS_FONT_WEIGHT_400; d.dc[0].style.font_style.value = SP_CSS_FONT_STYLE_NORMAL; d.dc[0].style.text_decoration_line.underline = 0; d.dc[0].style.text_decoration_line.line_through = 0; d.dc[0].style.baseline_shift.value = 0; - d.dc[0].textColor = U_RGB(0, 0, 0); // default foreground color (black) - d.dc[0].bkColor = U_RGB(255, 255, 255); // default background color (white) - d.dc[0].bkMode = U_TRANSPARENT; - d.dc[0].dirty = 0; + // Default pen, WMF files that do not specify a pen are unlikely to look very good! d.dc[0].style.stroke_dasharray.set = 0; d.dc[0].style.stroke_linecap.computed = 2; // U_PS_ENDCAP_SQUARE; d.dc[0].style.stroke_linejoin.computed = 0; // U_PS_JOIN_MITER; - d.dc[0].stroke_set = true; d.dc[0].style.stroke_width.value = 1.0; // will be reset to something reasonable once WMF draying size is known d.dc[0].style.stroke.value.color.set( 0, 0, 0 ); - // Default brush = none, WMF files that do not specify a brush are unlikely to look very good! - d.dc[0].fill_set = false; if (uri == NULL) { return NULL; } - d.outsvg = new Glib::ustring(""); - d.path = new Glib::ustring(""); - d.outdef = new Glib::ustring(""); - d.defs = new Glib::ustring(""); - d.mask = 0; - d.drawtype = 0; - d.arcdir = U_AD_COUNTERCLOCKWISE; - d.dwRop2 = U_R2_COPYPEN; - d.dwRop3 = 0; - d.E2IdirY = 1.0; - d.D2PscaleX = 1.0; - d.D2PscaleY = 1.0; - d.hatches.size = 0; - d.hatches.count = 0; - d.hatches.strings = NULL; - d.images.size = 0; - d.images.count = 0; - d.images.strings = NULL; - // set up the size default for patterns in defs. This might not be referenced if there are no patterns defined in the drawing. - *(d.defs) += "\n"; - *(d.defs) += " \n"; - *(d.defs) += " \n"; + d.defs += "\n"; + d.defs += " \n"; + d.defs += " \n"; size_t length; @@ -3016,12 +2982,8 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) // std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl; - SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg->c_str(), strlen(d.outsvg->c_str()), TRUE); + SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg.c_str(), strlen(d.outsvg.c_str()), TRUE); - delete d.outsvg; - delete d.path; - delete d.outdef; - delete d.defs; free_wmf_strings(d.hatches); free_wmf_strings(d.images); diff --git a/src/extension/internal/wmf-inout.h b/src/extension/internal/wmf-inout.h index 94a290873..6006479c7 100644 --- a/src/extension/internal/wmf-inout.h +++ b/src/extension/internal/wmf-inout.h @@ -26,20 +26,54 @@ namespace Internal { #define DIRTY_FILL 0x02 #define DIRTY_STROKE 0x04 // not used currently -typedef struct { +typedef struct wmf_object { + wmf_object() : + type(0), + level(0), + record(NULL) + {}; int type; int level; char *record; } WMF_OBJECT, *PWMF_OBJECT; -typedef struct { +typedef struct wmf_strings { + wmf_strings() : + size(0), + count(0), + strings(NULL) + {}; int size; // number of slots allocated in strings int count; // number of slots used in strings char **strings; // place to store strings } WMF_STRINGS, *PWMF_STRINGS; typedef struct wmf_device_context { - class SPStyle style; + wmf_device_context() : + // SPStyle: class with constructor + font_name(NULL), + stroke_set(false), stroke_mode(0), stroke_idx(0), stroke_recidx(0), + fill_set(false), fill_mode(0), fill_idx(0), fill_recidx(0), + dirty(0), + active_pen(-1), active_brush(-1), active_font(-1), // -1 when the default is used + // sizeWnd, sizeView, winorg, vieworg, + ScaleInX(0), ScaleInY(0), + ScaleOutX(0), ScaleOutY(0), + bkMode(U_TRANSPARENT), + // bkColor, textColor + textAlign(0) + // worldTransform, cur + { + font_name = strdup("Arial"); // Default font, WMF spec says device can pick whatever it wants + sizeWnd = point16_set( 0.0, 0.0 ); + sizeView = point16_set( 0.0, 0.0 ); + winorg = point16_set( 0.0, 0.0 ); + vieworg = point16_set( 0.0, 0.0 ); + bkColor = U_RGB(255, 255, 255); // default foreground color (white) + textColor = U_RGB(0, 0, 0); // default foreground color (black) + cur = point16_set( 0.0, 0.0 ); + }; + SPStyle style; char *font_name; bool stroke_set; int stroke_mode; // enumeration from drawmode, not used if fill_set is not True @@ -74,11 +108,32 @@ typedef struct wmf_device_context { // this fixes it, so some confusion between this struct and the one in emf-inout??? //typedef struct wmf_callback_data { // as does this -typedef struct { - Glib::ustring *outsvg; - Glib::ustring *path; - Glib::ustring *outdef; - Glib::ustring *defs; +typedef struct wmf_callback_data { + + wmf_callback_data() : + // dc: array, structure w/ constructor + level(0), + E2IdirY(1.0), + D2PscaleX(1.0), D2PscaleY(1.0), + PixelsInX(0), PixelsInY(0), + PixelsOutX(0), PixelsOutY(0), + ulCornerInX(0), ulCornerInY(0), + ulCornerOutX(0), ulCornerOutY(0), + mask(0), + arcdir(U_AD_COUNTERCLOCKWISE), + dwRop2(U_R2_COPYPEN), dwRop3(0), + id(0), drawtype(0), + // hatches, images, gradients, struct w/ constructor + tri(NULL), + n_obj(0), + low_water(0) + //wmf_obj + {}; + + Glib::ustring outsvg; + Glib::ustring path; + Glib::ustring outdef; + Glib::ustring defs; WMF_DEVICE_CONTEXT dc[WMF_MAX_DC+1]; // FIXME: This should be dynamic.. int level; -- cgit v1.2.3 From 112e440d4b24d60e19c3863a8a092cd50383f584 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 28 Apr 2014 01:46:05 +1000 Subject: Update CMake Files (bzr r13313) --- src/2geom/CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/extension/CMakeLists.txt | 1 + src/libdepixelize/CMakeLists.txt | 4 ++-- src/util/CMakeLists.txt | 2 ++ 5 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/2geom/CMakeLists.txt b/src/2geom/CMakeLists.txt index a2c02e682..eeaecaa39 100644 --- a/src/2geom/CMakeLists.txt +++ b/src/2geom/CMakeLists.txt @@ -94,6 +94,7 @@ set(2geom_SRC nearest-point.h ord.h path-intersection.h + path-sink.h path.h pathvector.h piecewise.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fae4c484c..d40aad802 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -434,6 +434,7 @@ set(inkscape_SRC undo-stack-observer.h unicoderange.h uri-references.h + uri-test.h uri.h vanishing-point.h verbs-test.h diff --git a/src/extension/CMakeLists.txt b/src/extension/CMakeLists.txt index 9bc30a592..759c704f0 100644 --- a/src/extension/CMakeLists.txt +++ b/src/extension/CMakeLists.txt @@ -130,6 +130,7 @@ set(extension_SRC internal/latex-pstricks-out.h internal/latex-pstricks.h internal/latex-text-renderer.h + internal/metafile-inout.h internal/metafile-print.h internal/odf.h internal/pdf-input-cairo.h diff --git a/src/libdepixelize/CMakeLists.txt b/src/libdepixelize/CMakeLists.txt index 895e16e85..a69d37bc7 100644 --- a/src/libdepixelize/CMakeLists.txt +++ b/src/libdepixelize/CMakeLists.txt @@ -7,11 +7,11 @@ set(libdepixelize_SRC kopftracer2011.h splines.h - priv/branchless.h + priv/branchless.h priv/colorspace.h priv/curvature.h priv/homogeneoussplines.h - priv/integral + priv/integral.h priv/iterator.h priv/optimization-kopf2011.h priv/pixelgraph.h diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 924cab355..732e01b0c 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -35,10 +35,12 @@ set(util_SRC reference.h reverse-list.h share.h + signal-blocker.h tuple.h ucompose.hpp units.h unordered-containers.h + ziptool.h ) # add_inkscape_lib(util_LIB "${util_SRC}") -- cgit v1.2.3 From 3466681abbcf33b09fada54e74cf55915714e2b2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 28 Apr 2014 16:13:36 +0200 Subject: Clean up of style code: Add default to SPIString for use with 'font-family'. (bzr r13315) --- src/style-internal.cpp | 8 ++++++++ src/style-internal.h | 9 ++++++--- src/style.cpp | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index b03e848ba..df08d0adf 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -692,6 +692,14 @@ SPIString::write( guint const flags, SPIBase const *const base) const { return Glib::ustring(""); } +void +SPIString::clear() { + SPIBase::clear(); + g_free( value ); + value = NULL; + if( value_default ) value = strdup( value_default ); +} + void SPIString::cascade( const SPIBase* const parent ) { if( const SPIString* p = dynamic_cast(parent) ) { diff --git a/src/style-internal.h b/src/style-internal.h index 131b77b77..d1a331acf 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -385,13 +385,15 @@ class SPIString : public SPIBase { public: SPIString() : SPIBase( "anonymous_string" ), value(NULL) {}; - SPIString( Glib::ustring name ) : - SPIBase( name ) , value(NULL) {}; + SPIString( Glib::ustring name, gchar* value_default_in = NULL ) : + SPIBase( name ) , value(NULL) , value_default(NULL) { + value_default = value_default_in?g_strdup(value_default_in):NULL; + }; virtual ~SPIString() { g_free(value); }; virtual void read( gchar const *str ); virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, SPIBase const *const base = NULL ) const; - virtual void clear() { SPIBase::clear(); g_free( value ); value = NULL; }; + virtual void clear(); virtual void cascade( const SPIBase* const parent ); virtual void merge( const SPIBase* const parent ); @@ -407,6 +409,7 @@ class SPIString : public SPIBase { // To do: make private, convert value to Glib::ustring public: gchar *value; + gchar *value_default; }; /// Color type interal to SPStyle, FIXME Add string value to store SVG named color. diff --git a/src/style.cpp b/src/style.cpp index 2d66284d4..11b1dc440 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -112,7 +112,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : font_stretch( "font-stretch", enum_font_stretch, SP_CSS_FONT_STRETCH_NORMAL ), font_size(), line_height( "line-height", 1.0 ), // SPILengthOrNormal - font_family( "font-family" ), // SPIString + font_family( "font-family", "sans-serif" ), // SPIString w/default font(), // SPIFont font_specification( "-inkscape-font-specification" ), // SPIString -- cgit v1.2.3 From 8840e87d38b6d731ea1b02816fe9f3532fbc146b Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Mon, 28 Apr 2014 18:04:16 +0200 Subject: Extensions. Fix for Bug #1307554 (Don't show the Export > win32 vector print extension on Platforms that don't support it). Fixed bugs: - https://launchpad.net/bugs/1307554 (bzr r13316) --- src/extension/extension.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index d63ec7485..588efb521 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -262,6 +262,18 @@ Extension::check (void) const char * inx_failure = _(" This is caused by an improper .inx file for this extension." " An improper .inx file could have been caused by a faulty installation of Inkscape."); + + // No need to include Windows only extensions + // See LP bug #1307554 for details - https://bugs.launchpad.net/inkscape/+bug/1307554 +#ifndef WIN32 + const char* win_ext[] = {"com.vaxxine.print.win32"}; + std::vector v (win_ext, win_ext + sizeof(win_ext)/sizeof(win_ext[0])); + std::string ext_id(id); + if (std::find(v.begin(), v.end(), ext_id) != v.end()) { + printFailure(Glib::ustring(_("the extension is designed for Windows only.")) + inx_failure); + retval = false; + } +#endif if (id == NULL) { printFailure(Glib::ustring(_("an ID was not defined for it.")) + inx_failure); retval = false; -- cgit v1.2.3 From d3a68551662281c58be1a646838cd6a0d835756e Mon Sep 17 00:00:00 2001 From: mathog <> Date: Mon, 28 Apr 2014 10:44:41 -0700 Subject: Fix for bug 1294840 (bzr r13318) --- src/extension/internal/emf-inout.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 711d7e3a4..f3396c16b 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -1104,14 +1104,11 @@ Emf::select_extpen(PEMF_CALLBACK_DATA d, int index) if (!d->dc[d->level].style.stroke_dasharray.values.empty() && (d->level==0 || (d->level>0 && d->dc[d->level].style.stroke_dasharray.values!=d->dc[d->level-1].style.stroke_dasharray.values))) d->dc[d->level].style.stroke_dasharray.values.clear(); for (unsigned int i=0; ielp.elpNumEntries; i++) { - int cur_level = d->level; - d->level = d->emf_obj[index].level; // Doing it this way typically results in a pattern that is tiny, better to assume the array // is the same scale as for dot/dash below, that is, no scaling should be applied // double dash_length = pix_to_abs_size( d, pEmr->elp.elpStyleEntry[i] ); double dash_length = pEmr->elp.elpStyleEntry[i]; - d->level = cur_level; - d->dc[d->level].style.stroke_dasharray.values[i] = dash_length; + d->dc[d->level].style.stroke_dasharray.values.push_back(dash_length); } d->dc[d->level].style.stroke_dasharray.set = 1; } else { -- cgit v1.2.3 From 50046cd6e986918c481f05e368bbd9fe10f3d6a9 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Mon, 28 Apr 2014 11:27:45 -0700 Subject: Fix for bug 1306138 (bzr r13319) --- src/extension/internal/emf-inout.cpp | 45 ++-------------------- src/extension/internal/metafile-inout.cpp | 63 +++++++++++++++++++++++++++++++ src/extension/internal/metafile-inout.h | 1 + src/extension/internal/wmf-inout.cpp | 45 ++-------------------- 4 files changed, 72 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index f3396c16b..6455e7555 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -33,9 +33,8 @@ #include #include -#include "sp-root.h" +#include "sp-root.h" // even though it is included indirectly by wmf-inout.h #include "sp-path.h" -#include "style.h" #include "print.h" #include "extension/system.h" #include "extension/print.h" @@ -45,12 +44,8 @@ #include "display/drawing.h" #include "display/drawing-item.h" #include "clear-n_.h" -#include "document.h" -#include "util/units.h" -#include "shape-editor.h" -#include "sp-namedview.h" -#include "document-undo.h" -#include "inkscape.h" +#include "util/units.h" // even though it is included indirectly by wmf-inout.h +#include "inkscape.h" // even though it is included indirectly by wmf-inout.h #include "emf-print.h" #include "emf-inout.h" @@ -3402,39 +3397,7 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) d.tri = trinfo_release_except_FC(d.tri); - // Set viewBox if it doesn't exist - if (doc && !doc->getRoot()->viewBox_set) { - bool saved = Inkscape::DocumentUndo::getUndoSensitive(doc); - Inkscape::DocumentUndo::setUndoSensitive(doc, false); - - doc->ensureUpToDate(); - - // Set document unit - Inkscape::XML::Node *repr = sp_document_namedview(doc, 0)->getRepr(); - Inkscape::SVGOStringStream os; - Inkscape::Util::Unit const* doc_unit = doc->getWidth().unit; - os << doc_unit->abbr; - repr->setAttribute("inkscape:document-units", os.str().c_str()); - - // Set viewBox - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc_unit), doc->getHeight().value(doc_unit))); - doc->ensureUpToDate(); - - // Scale and translate objects - double scale = Inkscape::Util::Quantity::convert(1, "px", doc_unit); - ShapeEditor::blockSetItem(true); - double dh; - if(SP_ACTIVE_DOCUMENT){ // for file menu open or import, or paste from clipboard - dh = SP_ACTIVE_DOCUMENT->getHeight().value("px"); - } - else { // for open via --file on command line - dh = doc->getHeight().value("px"); - } - doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, dh)); - ShapeEditor::blockSetItem(false); - - Inkscape::DocumentUndo::setUndoSensitive(doc, saved); - } + setViewBoxIfMissing(doc); return doc; } diff --git a/src/extension/internal/metafile-inout.cpp b/src/extension/internal/metafile-inout.cpp index 1d419a6a0..53bb86d24 100644 --- a/src/extension/internal/metafile-inout.cpp +++ b/src/extension/internal/metafile-inout.cpp @@ -17,6 +17,7 @@ #include #include +#include "sp-root.h" #include "display/curve.h" #include "extension/internal/metafile-inout.h" // picks up PNG #include "extension/print.h" @@ -27,6 +28,13 @@ #include "sp-pattern.h" #include "sp-radial-gradient.h" #include "style.h" +#include "document.h" +#include "util/units.h" +#include "shape-editor.h" +#include "sp-namedview.h" +#include "document-undo.h" +#include "inkscape.h" +#include "preferences.h" namespace Inkscape { namespace Extension { @@ -193,6 +201,61 @@ gchar *Metafile::bad_image_png(void){ return(gstring); } +/* If the viewBox is missing, set one +*/ +void Metafile::setViewBoxIfMissing(SPDocument *doc) { + + if (doc && !doc->getRoot()->viewBox_set) { + bool saved = Inkscape::DocumentUndo::getUndoSensitive(doc); + Inkscape::DocumentUndo::setUndoSensitive(doc, false); + + doc->ensureUpToDate(); + + // Set document unit + Inkscape::XML::Node *repr = sp_document_namedview(doc, 0)->getRepr(); + Inkscape::SVGOStringStream os; + Inkscape::Util::Unit const* doc_unit = doc->getWidth().unit; + os << doc_unit->abbr; + repr->setAttribute("inkscape:document-units", os.str().c_str()); + + // Set viewBox + doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc_unit), doc->getHeight().value(doc_unit))); + doc->ensureUpToDate(); + + // Scale and translate objects + double scale = Inkscape::Util::Quantity::convert(1, "px", doc_unit); + ShapeEditor::blockSetItem(true); + double dh; + if(SP_ACTIVE_DOCUMENT){ // for file menu open or import, or paste from clipboard + dh = SP_ACTIVE_DOCUMENT->getHeight().value("px"); + } + else { // for open via --file on command line + dh = doc->getHeight().value("px"); + } + + // These should not affect input, but they do, so set them to a neutral state + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool transform_stroke = prefs->getBool("/options/transform/stroke", true); + bool transform_rectcorners = prefs->getBool("/options/transform/rectcorners", true); + bool transform_pattern = prefs->getBool("/options/transform/pattern", true); + bool transform_gradient = prefs->getBool("/options/transform/gradient", true); + prefs->setBool("/options/transform/stroke", true); + prefs->setBool("/options/transform/rectcorners", true); + prefs->setBool("/options/transform/pattern", true); + prefs->setBool("/options/transform/gradient", true); + + doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, dh)); + ShapeEditor::blockSetItem(false); + + // restore options + prefs->setBool("/options/transform/stroke", transform_stroke); + prefs->setBool("/options/transform/rectcorners", transform_rectcorners); + prefs->setBool("/options/transform/pattern", transform_pattern); + prefs->setBool("/options/transform/gradient", transform_gradient); + + Inkscape::DocumentUndo::setUndoSensitive(doc, saved); + } +} } // namespace Internal diff --git a/src/extension/internal/metafile-inout.h b/src/extension/internal/metafile-inout.h index 968773a3a..2f7001cf2 100644 --- a/src/extension/internal/metafile-inout.h +++ b/src/extension/internal/metafile-inout.h @@ -71,6 +71,7 @@ protected: static void my_png_write_data(png_structp png_ptr, png_bytep data, png_size_t length); static void toPNG(PMEMPNG accum, int width, int height, const char *px); static gchar *bad_image_png(void); + static void setViewBoxIfMissing(SPDocument *doc); private: diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index d13998d81..5d7fc29d0 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -33,9 +33,8 @@ #include #include -#include "sp-root.h" +#include "sp-root.h" // even though it is included indirectly by wmf-inout.h #include "sp-path.h" -#include "style.h" #include "print.h" #include "extension/system.h" #include "extension/print.h" @@ -44,13 +43,9 @@ #include "extension/output.h" #include "display/drawing.h" #include "display/drawing-item.h" -#include "util/units.h" #include "clear-n_.h" -#include "document.h" -#include "shape-editor.h" -#include "sp-namedview.h" -#include "document-undo.h" -#include "inkscape.h" +#include "util/units.h" // even though it is included indirectly by wmf-inout.h +#include "inkscape.h" // even though it is included indirectly by wmf-inout.h #include "wmf-inout.h" @@ -3002,39 +2997,7 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) d.tri = trinfo_release_except_FC(d.tri); - // Set viewBox if it doesn't exist - if (doc && !doc->getRoot()->viewBox_set) { - bool saved = Inkscape::DocumentUndo::getUndoSensitive(doc); - Inkscape::DocumentUndo::setUndoSensitive(doc, false); - - doc->ensureUpToDate(); - - // Set document unit - Inkscape::XML::Node *repr = sp_document_namedview(doc, 0)->getRepr(); - Inkscape::SVGOStringStream os; - Inkscape::Util::Unit const* doc_unit = doc->getWidth().unit; - os << doc_unit->abbr; - repr->setAttribute("inkscape:document-units", os.str().c_str()); - - // Set viewBox - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc_unit), doc->getHeight().value(doc_unit))); - doc->ensureUpToDate(); - - // Scale and translate objects - double scale = Inkscape::Util::Quantity::convert(1, "px", doc_unit); - ShapeEditor::blockSetItem(true); - double dh; - if(SP_ACTIVE_DOCUMENT){ // for file menu open or import, or paste from clipboard - dh = SP_ACTIVE_DOCUMENT->getHeight().value("px"); - } - else { // for open via --file on command line - dh = doc->getHeight().value("px"); - } - doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, dh)); - ShapeEditor::blockSetItem(false); - - Inkscape::DocumentUndo::setUndoSensitive(doc, saved); - } + setViewBoxIfMissing(doc); return doc; } -- cgit v1.2.3 From 6dd9187e01631f9496b6cea835382397cc770382 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Apr 2014 20:58:32 +0200 Subject: partial 2geom update. linearize the measure of the size of an ellipse (LP Bug 1309225), by Alvin Penner Fixed bugs: - https://launchpad.net/bugs/1309225 (bzr r13320) --- src/2geom/ellipse.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/2geom/ellipse.cpp b/src/2geom/ellipse.cpp index bea99e5dd..2686844b2 100644 --- a/src/2geom/ellipse.cpp +++ b/src/2geom/ellipse.cpp @@ -36,6 +36,7 @@ #include <2geom/numeric/fitting-tool.h> #include <2geom/numeric/fitting-model.h> +using std::swap; namespace Geom { @@ -102,7 +103,7 @@ void Ellipse::set(double A, double B, double C, double D, double E, double F) // the solution is not unique so we choose always the ellipse // with a rotation angle between 0 and PI/2 - if ( swap_axes ) std::swap(rx, ry); + if ( swap_axes ) swap(rx, ry); if ( are_near(rot, M_PI/2) || are_near(rot, -M_PI/2) || are_near(rx, ry) ) @@ -233,7 +234,7 @@ Ellipse Ellipse::transformed(Affine const& m) const Point new_center = center() * m; Affine M = m.withoutTranslation(); Affine AM = A * M; - if ( are_near(AM.det(), 0) ) + if ( are_near(std::sqrt(fabs(AM.det())), 0) ) { double angle; if (AM[0] != 0) @@ -262,7 +263,7 @@ Ellipse Ellipse::transformed(Affine const& m) const Affine invm = M.inverse(); Q = invm * Q ; - std::swap( invm[1], invm[2] ); + swap( invm[1], invm[2] ); Q *= invm; Ellipse e(Q[0], 2*Q[1], Q[3], 0, 0, -1); e.m_centre = new_center; -- cgit v1.2.3 From 8b26a533c4d17e09575abd9bef1e13bd6e6e23d1 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Apr 2014 21:51:55 +0200 Subject: when removing LPE, with 'flattening' option, don't recalculate/rewrite ellipses (which would remove the LPE result). fixes bug introduced in rev. 12670) Fixed bugs: - https://launchpad.net/bugs/1309631 (bzr r13321) --- src/sp-lpe-item.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index f59bc33ee..b5dd74fc6 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -442,6 +442,9 @@ void SPLPEItem::addPathEffect(LivePathEffectObject * new_lpeobj) g_free(hrefstr); } +/** + * If keep_path == true, the item should not be updated, effectively 'flattening' the LPE. + */ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) { Inkscape::LivePathEffect::LPEObjectReference* lperef = this->getCurrentLPEReference(); @@ -456,27 +459,31 @@ void SPLPEItem::removeCurrentPathEffect(bool keep_paths) this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); } else { this->getRepr()->setAttribute("inkscape:path-effect", NULL); + } + + if (!keep_paths) { // Make sure that ellipse is stored as or if possible. if( SP_IS_GENERICELLIPSE(this)) { SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); } - } - if (!keep_paths) { sp_lpe_item_cleanup_original_path_recursive(this); } } +/** + * If keep_path == true, the item should not be updated, effectively 'flattening' the LPE. + */ void SPLPEItem::removeAllPathEffects(bool keep_paths) { this->getRepr()->setAttribute("inkscape:path-effect", NULL); - // Make sure that ellipse is stored as or if possible. - if( SP_IS_GENERICELLIPSE(this)) { - SP_GENERICELLIPSE(this)->write( this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT ); - } - if (!keep_paths) { + // Make sure that ellipse is stored as or if possible. + if (SP_IS_GENERICELLIPSE(this)) { + SP_GENERICELLIPSE(this)->write(this->getRepr()->document(), this->getRepr(), SP_OBJECT_WRITE_EXT); + } + sp_lpe_item_cleanup_original_path_recursive(this); } } -- cgit v1.2.3 From 752397f4edd00eed397464556e845b951ff65c57 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Mon, 28 Apr 2014 17:06:10 -0700 Subject: Improved support for clipping on EMF/WMF import, see bug 1302857 (bzr r13322) --- src/extension/internal/emf-inout.cpp | 178 ++++++++++++++++++++++++------ src/extension/internal/emf-inout.h | 15 ++- src/extension/internal/emf-print.cpp | 4 + src/extension/internal/metafile-inout.cpp | 71 ++++++++---- src/extension/internal/metafile-inout.h | 1 + src/extension/internal/wmf-inout.cpp | 146 ++++++++++++++++++++---- src/extension/internal/wmf-inout.h | 8 ++ src/libuemf/uemf.c | 6 +- src/libuemf/uemf.h | 5 +- src/libuemf/uwmf.c | 6 +- 10 files changed, 346 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 6455e7555..863d1e006 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -44,6 +44,7 @@ #include "display/drawing.h" #include "display/drawing-item.h" #include "clear-n_.h" +#include "svg/svg.h" #include "util/units.h" // even though it is included indirectly by wmf-inout.h #include "inkscape.h" // even though it is included indirectly by wmf-inout.h @@ -60,8 +61,6 @@ namespace Inkscape { namespace Extension { namespace Internal { -static U_RECTL rc_old = rectl_set(pointl_set(-1,-1),pointl_set(-1,-1)); -static bool clipset = false; static uint32_t ICMmode = 0; // not used yet, but code to read it from EMF implemented static uint32_t BLTmode = 0; @@ -447,7 +446,7 @@ void Emf::enlarge_images(PEMF_CALLBACK_DATA d){ /* See if the image string is already in the list. If it is return its position (1->n, not 1-n-1) */ -int Emf::in_images(PEMF_CALLBACK_DATA d, char *test){ +int Emf::in_images(PEMF_CALLBACK_DATA d, const char *test){ int i; for(i=0; iimages.count; i++){ if(strcmp(test,d->images.strings[i])==0)return(i+1); @@ -618,7 +617,7 @@ void Emf::enlarge_gradients(PEMF_CALLBACK_DATA d){ /* See if the gradient name is already in the list. If it is return its position (1->n, not 1-n-1) */ -int Emf::in_gradients(PEMF_CALLBACK_DATA d, char *test){ +int Emf::in_gradients(PEMF_CALLBACK_DATA d, const char *test){ int i; for(i=0; igradients.count; i++){ if(strcmp(test,d->gradients.strings[i])==0)return(i+1); @@ -717,6 +716,65 @@ uint32_t Emf::add_gradient(PEMF_CALLBACK_DATA d, uint32_t gradientType, U_TRIVER return(idx-1); } +/* Add another 100 blank slots to the clips array. +*/ +void Emf::enlarge_clips(PEMF_CALLBACK_DATA d){ + d->clips.size += 100; + d->clips.strings = (char **) realloc(d->clips.strings,d->clips.size * sizeof(char *)); +} + +/* See if the pattern name is already in the list. If it is return its position (1->n, not 1-n-1) +*/ +int Emf::in_clips(PEMF_CALLBACK_DATA d, const char *test){ + int i; + for(i=0; iclips.count; i++){ + if(strcmp(test,d->clips.strings[i])==0)return(i+1); + } + return(0); +} + +/* (Conditionally) add a clip. + If a matching clip already exists nothing happens + If one does exist it is added to the clips list, entered into . +*/ +void Emf::add_clips(PEMF_CALLBACK_DATA d, const char *clippath, unsigned int logic){ + int op = combine_ops_to_livarot(logic); + Geom::PathVector combined_vect; + char *combined = NULL; + if (op >= 0 && d->dc[d->level].clip_id) { + unsigned int real_idx = d->dc[d->level].clip_id - 1; + Geom::PathVector old_vect = sp_svg_read_pathv(d->clips.strings[real_idx]); + Geom::PathVector new_vect = sp_svg_read_pathv(clippath); + combined_vect = sp_pathvector_boolop(new_vect, old_vect, (bool_op) op , (FillRule) fill_oddEven, (FillRule) fill_oddEven); + combined = sp_svg_write_path(combined_vect); + } + else { + combined = strdup(clippath); // COPY operation, erases everything and starts a new one + } + + uint32_t idx = in_clips(d, combined); + if(!idx){ // add clip if not already present + if(d->clips.count == d->clips.size){ enlarge_clips(d); } + d->clips.strings[d->clips.count++]=strdup(combined); + d->dc[d->level].clip_id = d->clips.count; // one more than the slot where it is actually stored + SVGOStringStream tmp_clippath; + tmp_clippath << "\ndc[d->level].clip_id << "\""; + tmp_clippath << " >"; + tmp_clippath << "\n\t"; + tmp_clippath << "\n"; + d->outdef += tmp_clippath.str().c_str(); + } + else { + d->dc[d->level].clip_id = idx; + } + free(combined); +} + void @@ -927,9 +985,8 @@ Emf::output_style(PEMF_CALLBACK_DATA d, int iType) tmp_style << "stroke-opacity:1;"; } tmp_style << "\" "; - if (clipset) - tmp_style << "\n\tclip-path=\"url(#clipEmfPath" << d->id << ")\" "; - clipset = false; + if (d->dc[d->level].clip_id) + tmp_style << "\n\tclip-path=\"url(#clipEmfPath" << d->dc[d->level].clip_id << ")\" "; d->outsvg += tmp_style.str().c_str(); } @@ -1565,7 +1622,7 @@ int Emf::myEnhMetaFileProc(char *contents, unsigned int length, PEMF_CALLBACK_DA lpEMFR = (PU_ENHMETARECORD)(contents + off); // Uncomment the following to track down toxic records -//std::cout << "record type: " << lpEMFR->iType << " length: " << lpEMFR->nSize << " offset: " << off <iType << " name " << U_emr_names(lpEMFR->iType) << " length: " << lpEMFR->nSize << " offset: " << off <nSize; SVGOStringStream tmp_outsvg; @@ -1616,7 +1673,7 @@ int Emf::myEnhMetaFileProc(char *contents, unsigned int length, PEMF_CALLBACK_DA d->dc[d->level].dirty = 0; } -//std::cout << "BEFORE DRAW logic d->mask: " << std::hex << d->mask << " emr_mask: " << emr_mask << std::dec << std::endl; +// std::cout << "BEFORE DRAW logic d->mask: " << std::hex << d->mask << " emr_mask: " << emr_mask << std::dec << std::endl; /* std::cout << "BEFORE DRAW" << " test0 " << ( d->mask & U_DRAW_VISIBLE) @@ -1643,7 +1700,7 @@ std::cout << "BEFORE DRAW" ) ) ){ -// std::cout << "PATH DRAW at TOP" << std::endl; +// std::cout << "PATH DRAW at TOP path" << *(d->path) << std::endl; d->outsvg += " drawtype){ // explicit draw type EMR record output_style(d, d->drawtype); @@ -2115,7 +2172,24 @@ std::cout << "BEFORE DRAW" } break; } - case U_EMR_OFFSETCLIPRGN: dbg_str << "\n"; break; + case U_EMR_OFFSETCLIPRGN: + { + dbg_str << "\n"; + if (d->dc[d->level].clip_id) { // can only offsetan existing clipping path + PU_EMROFFSETCLIPRGN pEmr = (PU_EMROFFSETCLIPRGN) lpEMFR; + U_POINTL off = pEmr->ptlOffset; + unsigned int real_idx = d->dc[d->level].clip_id - 1; + Geom::PathVector tmp_vect = sp_svg_read_pathv(d->clips.strings[real_idx]); + double ox = pix_to_x_point(d, off.x, off.y) - pix_to_x_point(d, 0, 0); // take into account all active transforms + double oy = pix_to_y_point(d, off.x, off.y) - pix_to_y_point(d, 0, 0); + Geom::Affine tf = Geom::Translate(ox,oy); + tmp_vect *= tf; + char *tmp_path = sp_svg_write_path(tmp_vect); + add_clips(d, tmp_path, U_RGN_COPY); + free(tmp_path); + } + break; + } case U_EMR_MOVETOEX: { dbg_str << "\n"; @@ -2131,36 +2205,52 @@ std::cout << "BEFORE DRAW" break; } case U_EMR_SETMETARGN: dbg_str << "\n"; break; - case U_EMR_EXCLUDECLIPRECT: dbg_str << "\n"; break; + case U_EMR_EXCLUDECLIPRECT: + { + dbg_str << "\n"; + + PU_EMREXCLUDECLIPRECT pEmr = (PU_EMREXCLUDECLIPRECT) lpEMFR; + U_RECTL rc = pEmr->rclClip; + + SVGOStringStream tmp_path; + float faraway = 10000000; // hopefully well outside any real drawing! + //outer rect, clockwise + tmp_path << "M " << faraway << "," << faraway << " "; + tmp_path << "L " << faraway << "," << -faraway << " "; + tmp_path << "L " << -faraway << "," << -faraway << " "; + tmp_path << "L " << -faraway << "," << faraway << " "; + tmp_path << "z "; + //inner rect, counterclockwise (sign of Y is reversed) + tmp_path << "M " << pix_to_xy( d, rc.left , rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.bottom ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.left, rc.bottom ) << " "; + tmp_path << "z"; + + add_clips(d, tmp_path.str().c_str(), U_RGN_AND); + + d->path = ""; + d->drawtype = 0; + break; + } case U_EMR_INTERSECTCLIPRECT: { dbg_str << "\n"; PU_EMRINTERSECTCLIPRECT pEmr = (PU_EMRINTERSECTCLIPRECT) lpEMFR; U_RECTL rc = pEmr->rclClip; - clipset = true; - if ((rc.left == rc_old.left) && (rc.top == rc_old.top) && (rc.right == rc_old.right) && (rc.bottom == rc_old.bottom)) - break; - rc_old = rc; - double dx = pix_to_x_point( d, rc.left, rc.top ); - double dy = pix_to_y_point( d, rc.left, rc.top ); - double dw = pix_to_abs_size( d, rc.right - rc.left + 1); - double dh = pix_to_abs_size( d, rc.bottom - rc.top + 1); + SVGOStringStream tmp_path; + tmp_path << "M " << pix_to_xy( d, rc.left , rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.bottom ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.left, rc.bottom ) << " "; + tmp_path << "z"; + + add_clips(d, tmp_path.str().c_str(), U_RGN_AND); - SVGOStringStream tmp_rectangle; - tmp_rectangle << "\nid) << "\" >"; - tmp_rectangle << "\n\n"; - - d->outdef += tmp_rectangle.str().c_str(); d->path = ""; + d->drawtype = 0; break; } case U_EMR_SCALEVIEWPORTEXTEX: dbg_str << "\n"; break; @@ -2171,7 +2261,7 @@ std::cout << "BEFORE DRAW" if (d->level < EMF_MAX_DC) { d->dc[d->level + 1] = d->dc[d->level]; if(d->dc[d->level].font_name){ - d->dc[d->level + 1].font_name = strdup(d->dc[d->level].font_name); // or memory access problems because font name pointer duplicated + d->dc[d->level + 1].font_name = strdup(d->dc[d->level].font_name); // or memory access problems because font name pointer duplicated } d->level = d->level + 1; } @@ -2727,7 +2817,18 @@ std::cout << "BEFORE DRAW" } case U_EMR_FLATTENPATH: dbg_str << "\n"; break; case U_EMR_WIDENPATH: dbg_str << "\n"; break; - case U_EMR_SELECTCLIPPATH: dbg_str << "\n"; break; + case U_EMR_SELECTCLIPPATH: + { + dbg_str << "\n"; + PU_EMRSELECTCLIPPATH pEmr = (PU_EMRSELECTCLIPPATH) lpEMFR; + int logic = pEmr->iMode; + + if ((logic < U_RGN_MIN) || (logic > U_RGN_MAX)){ break; } + add_clips(d, d->path.c_str(), logic); // finds an existing one or stores this, sets clip_id + d->path = ""; + d->drawtype = 0; + break; + } case U_EMR_ABORTPATH: { dbg_str << "\n"; @@ -2770,8 +2871,10 @@ std::cout << "BEFORE DRAW" dbg_str << "\n"; PU_EMREXTSELECTCLIPRGN pEmr = (PU_EMREXTSELECTCLIPRGN) lpEMFR; - if (pEmr->iMode == U_RGN_COPY) - clipset = false; + // the only mode we implement - this clears the clipping region + if (pEmr->iMode == U_RGN_COPY) { + d->dc[d->level].clip_id = 0; + } break; } case U_EMR_BITBLT: @@ -3334,6 +3437,8 @@ void Emf::free_emf_strings(EMF_STRINGS name){ for(int i=0; i< name.count; i++){ free(name.strings[i]); } free(name.strings); } + name.count = 0; + name.size = 0; } SPDocument * @@ -3381,6 +3486,7 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) free_emf_strings(d.hatches); free_emf_strings(d.images); free_emf_strings(d.gradients); + free_emf_strings(d.clips); if (d.emf_obj) { int i; diff --git a/src/extension/internal/emf-inout.h b/src/extension/internal/emf-inout.h index f15db5518..302d5c474 100644 --- a/src/extension/internal/emf-inout.h +++ b/src/extension/internal/emf-inout.h @@ -53,6 +53,7 @@ typedef struct emf_device_context { emf_device_context() : // SPStyle: class with constructor font_name(NULL), + clip_id(0), stroke_set(false), stroke_mode(0), stroke_idx(0), stroke_recidx(0), fill_set(false), fill_mode(0), fill_idx(0), fill_recidx(0), dirty(0), @@ -81,6 +82,7 @@ typedef struct emf_device_context { }; SPStyle style; char *font_name; + int clip_id; // 0 if none, else 1 + index into clips bool stroke_set; int stroke_mode; // enumeration from drawmode, not used if fill_set is not True int stroke_idx; // used with DRAW_PATTERN and DRAW_IMAGE to return the appropriate fill @@ -122,7 +124,7 @@ typedef struct emf_callback_data { arcdir(U_AD_COUNTERCLOCKWISE), dwRop2(U_R2_COPYPEN), dwRop3(0), MMX(0),MMY(0), - id(0), drawtype(0), + drawtype(0), pDesc(NULL), // hatches, images, gradients, struct w/ constructor tri(NULL), @@ -154,13 +156,13 @@ typedef struct emf_callback_data { float MMX; float MMY; - unsigned int id; unsigned int drawtype; // one of 0 or U_EMR_FILLPATH, U_EMR_STROKEPATH, U_EMR_STROKEANDFILLPATH char *pDesc; // both of these end up in under the names shown here. These structures allow duplicates to be avoided. EMF_STRINGS hatches; // hold pattern names, all like EMFhatch#_$$$$$$ where # is the EMF hatch code and $$$$$$ is the color EMF_STRINGS images; // hold images, all like Image#, where # is the slot the image lives. EMF_STRINGS gradients; // hold gradient names, all like EMF[HV]_$$$$$$_$$$$$$ where $$$$$$ are the colors + EMF_STRINGS clips; // hold clipping paths, referred to be the slot where the clipping path lives TR_INFO *tri; // Text Reassembly data structure @@ -199,12 +201,17 @@ protected: static int in_hatches(PEMF_CALLBACK_DATA d, char *test); static uint32_t add_hatch(PEMF_CALLBACK_DATA d, uint32_t hatchType, U_COLORREF hatchColor); static void enlarge_images(PEMF_CALLBACK_DATA d); - static int in_images(PEMF_CALLBACK_DATA d, char *test); + static int in_images(PEMF_CALLBACK_DATA d, const char *test); static uint32_t add_image(PEMF_CALLBACK_DATA d, void *pEmr, uint32_t cbBits, uint32_t cbBmi, uint32_t iUsage, uint32_t offBits, uint32_t offBmi); static void enlarge_gradients(PEMF_CALLBACK_DATA d); - static int in_gradients(PEMF_CALLBACK_DATA d, char *test); + static int in_gradients(PEMF_CALLBACK_DATA d, const char *test); static uint32_t add_gradient(PEMF_CALLBACK_DATA d, uint32_t gradientType, U_TRIVERTEX tv1, U_TRIVERTEX tv2); + + static void enlarge_clips(PEMF_CALLBACK_DATA d); + static int in_clips(PEMF_CALLBACK_DATA d, const char *test); + static void add_clips(PEMF_CALLBACK_DATA d, const char *clippath, unsigned int logic); + static void output_style(PEMF_CALLBACK_DATA d, int iType); static double _pix_x_to_point(PEMF_CALLBACK_DATA d, double px); static double _pix_y_to_point(PEMF_CALLBACK_DATA d, double py); diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 8b80fec1c..9c68e40a4 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -34,6 +34,7 @@ #include <2geom/pathvector.h> #include <2geom/rect.h> #include <2geom/curves.h> +#include #include "helper/geom.h" #include "helper/geom-curves.h" @@ -975,6 +976,9 @@ unsigned int PrintEmf::fill( { using Geom::X; using Geom::Y; + + SPItem *item = SP_ITEM(style->object); + SPClipPath *scp = (item->clip_ref ? item->clip_ref->getObject() : NULL); Geom::Affine tf = m_tr_stack.top(); diff --git a/src/extension/internal/metafile-inout.cpp b/src/extension/internal/metafile-inout.cpp index 53bb86d24..162ad8b7d 100644 --- a/src/extension/internal/metafile-inout.cpp +++ b/src/extension/internal/metafile-inout.cpp @@ -179,28 +179,6 @@ void Metafile::toPNG(PMEMPNG accum, int width, int height, const char *px){ } - -/* convert an EMF RGB(A) color to 0RGB -inverse of gethexcolor() in emf-print.cpp -*/ -uint32_t Metafile::sethexcolor(U_COLORREF color){ - - uint32_t out; - out = (U_RGBAGetR(color) << 16) + - (U_RGBAGetG(color) << 8 ) + - (U_RGBAGetB(color) ); - return(out); -} - -/* Return the base64 encoded png which is shown for all bad images. -Currently a random 3x4 blotch. -Caller must free. -*/ -gchar *Metafile::bad_image_png(void){ - gchar *gstring = g_strdup("iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAA3NCSVQICAjb4U/gAAAALElEQVQImQXBQQ2AMAAAsUJQMSWI2H8qME1yMshojwrvGB8XcHKvR1XtOTc/8HENumHCsOMAAAAASUVORK5CYII="); - return(gstring); -} - /* If the viewBox is missing, set one */ void Metafile::setViewBoxIfMissing(SPDocument *doc) { @@ -257,6 +235,55 @@ void Metafile::setViewBoxIfMissing(SPDocument *doc) { } } +/** + \fn Convert EMF/WMF region combining ops to livarot region combining ops + \return combination operators in livarot enumeration, or -1 on no match + \param ops (int) combination operator (Inkscape) +*/ +int Metafile::combine_ops_to_livarot(const int op) +{ + int ret = -1; + switch(op) { + case U_RGN_AND: + ret = bool_op_inters; + break; + case U_RGN_OR: + ret = bool_op_union; + break; + case U_RGN_XOR: + ret = bool_op_symdiff; + break; + case U_RGN_DIFF: + ret = bool_op_diff; + break; + } + return(ret); +} + + + +/* convert an EMF RGB(A) color to 0RGB +inverse of gethexcolor() in emf-print.cpp +*/ +uint32_t Metafile::sethexcolor(U_COLORREF color){ + + uint32_t out; + out = (U_RGBAGetR(color) << 16) + + (U_RGBAGetG(color) << 8 ) + + (U_RGBAGetB(color) ); + return(out); +} + +/* Return the base64 encoded png which is shown for all bad images. +Currently a random 3x4 blotch. +Caller must free. +*/ +gchar *Metafile::bad_image_png(void){ + gchar *gstring = g_strdup("iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAA3NCSVQICAjb4U/gAAAALElEQVQImQXBQQ2AMAAAsUJQMSWI2H8qME1yMshojwrvGB8XcHKvR1XtOTc/8HENumHCsOMAAAAASUVORK5CYII="); + return(gstring); +} + + } // namespace Internal } // namespace Extension diff --git a/src/extension/internal/metafile-inout.h b/src/extension/internal/metafile-inout.h index 2f7001cf2..b3efee2a6 100644 --- a/src/extension/internal/metafile-inout.h +++ b/src/extension/internal/metafile-inout.h @@ -72,6 +72,7 @@ protected: static void toPNG(PMEMPNG accum, int width, int height, const char *px); static gchar *bad_image_png(void); static void setViewBoxIfMissing(SPDocument *doc); + static int combine_ops_to_livarot(const int op); private: diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index 5d7fc29d0..85060470b 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -44,6 +44,7 @@ #include "display/drawing.h" #include "display/drawing-item.h" #include "clear-n_.h" +#include "svg/svg.h" #include "util/units.h" // even though it is included indirectly by wmf-inout.h #include "inkscape.h" // even though it is included indirectly by wmf-inout.h @@ -626,6 +627,67 @@ uint32_t Wmf::add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char * return(idx-1); } +/* Add another 100 blank slots to the clips array. +*/ +void Wmf::enlarge_clips(PWMF_CALLBACK_DATA d){ + d->clips.size += 100; + d->clips.strings = (char **) realloc(d->clips.strings,d->clips.size * sizeof(char *)); +} + +/* See if the pattern name is already in the list. If it is return its position (1->n, not 1-n-1) +*/ +int Wmf::in_clips(PWMF_CALLBACK_DATA d, const char *test){ + int i; + for(i=0; iclips.count; i++){ + if(strcmp(test,d->clips.strings[i])==0)return(i+1); + } + return(0); +} + +/* (Conditionally) add a clip. + If a matching clip already exists nothing happens + If one does exist it is added to the clips list, entered into . +*/ +void Wmf::add_clips(PWMF_CALLBACK_DATA d, const char *clippath, unsigned int logic){ + int op = combine_ops_to_livarot(logic); + Geom::PathVector combined_vect; + char *combined = NULL; + if (op >= 0 && d->dc[d->level].clip_id) { + unsigned int real_idx = d->dc[d->level].clip_id - 1; + Geom::PathVector old_vect = sp_svg_read_pathv(d->clips.strings[real_idx]); + Geom::PathVector new_vect = sp_svg_read_pathv(clippath); + combined_vect = sp_pathvector_boolop(new_vect, old_vect, (bool_op) op , (FillRule) fill_oddEven, (FillRule) fill_oddEven); + combined = sp_svg_write_path(combined_vect); + } + else { + combined = strdup(clippath); // COPY operation, erases everything and starts a new one + } + + uint32_t idx = in_clips(d, combined); + if(!idx){ // add clip if not already present + if(d->clips.count == d->clips.size){ enlarge_clips(d); } + d->clips.strings[d->clips.count++]=strdup(combined); + d->dc[d->level].clip_id = d->clips.count; // one more than the slot where it is actually stored + SVGOStringStream tmp_clippath; + tmp_clippath << "\ndc[d->level].clip_id << "\""; + tmp_clippath << " >"; + tmp_clippath << "\n\t"; + tmp_clippath << "\n"; + d->outdef += tmp_clippath.str().c_str(); + } + else { + d->dc[d->level].clip_id = idx; + } + free(combined); +} + + + void Wmf::output_style(PWMF_CALLBACK_DATA d) { @@ -833,9 +895,8 @@ Wmf::output_style(PWMF_CALLBACK_DATA d) tmp_style << "stroke-opacity:1;"; } tmp_style << "\" "; - if (clipset) - tmp_style << "\n\tclip-path=\"url(#clipWmfPath" << d->id << ")\" "; - clipset = false; + if (d->dc[d->level].clip_id) + tmp_style << "\n\tclip-path=\"url(#clipEmfPath" << d->dc[d->level].clip_id << ")\" "; d->outsvg += tmp_style.str().c_str(); } @@ -1913,34 +1974,51 @@ std::cout << "BEFORE DRAW" "\n\tM " << pix_to_xy( d, pt16.x, pt16.y ) << " "; break; } - case U_WMR_EXCLUDECLIPRECT: dbg_str << "\n"; break; + case U_WMR_EXCLUDECLIPRECT: + { + dbg_str << "\n"; + + U_RECT16 rc; + nSize = U_WMREXCLUDECLIPRECT_get(contents, &rc); + + SVGOStringStream tmp_path; + float faraway = 10000000; // hopefully well outside any real drawing! + //outer rect, clockwise + tmp_path << "M " << faraway << "," << faraway << " "; + tmp_path << "L " << faraway << "," << -faraway << " "; + tmp_path << "L " << -faraway << "," << -faraway << " "; + tmp_path << "L " << -faraway << "," << faraway << " "; + tmp_path << "z "; + //inner rect, counterclockwise (sign of Y is reversed) + tmp_path << "M " << pix_to_xy( d, rc.left , rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.bottom ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.left, rc.bottom ) << " "; + tmp_path << "z"; + + add_clips(d, tmp_path.str().c_str(), U_RGN_AND); + + d->path = ""; + d->drawtype = 0; + break; + } case U_WMR_INTERSECTCLIPRECT: { dbg_str << "\n"; nSize = U_WMRINTERSECTCLIPRECT_get(contents, &rc); - clipset = true; - if ((rc.left == rc_old.left) && (rc.top == rc_old.top) && (rc.right == rc_old.right) && (rc.bottom == rc_old.bottom)) - break; - rc_old = rc; - double dx = pix_to_x_point( d, rc.left, rc.top ); - double dy = pix_to_y_point( d, rc.left, rc.top ); - double dw = pix_to_abs_size( d, rc.right - rc.left + 1); - double dh = pix_to_abs_size( d, rc.bottom - rc.top + 1); + SVGOStringStream tmp_path; + tmp_path << "M " << pix_to_xy( d, rc.left , rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.top ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.right, rc.bottom ) << " "; + tmp_path << "L " << pix_to_xy( d, rc.left, rc.bottom ) << " "; + tmp_path << "z"; + + add_clips(d, tmp_path.str().c_str(), U_RGN_AND); - SVGOStringStream tmp_rectangle; - tmp_rectangle << "\nid) << "\" >"; - tmp_rectangle << "\n"; - tmp_rectangle << "\n"; - - d->outdef += tmp_rectangle.str().c_str(); d->path = ""; + d->drawtype = 0; break; } case U_WMR_ARC: @@ -2134,7 +2212,24 @@ std::cout << "BEFORE DRAW" break; } case U_WMR_SETPIXEL: dbg_str << "\n"; break; - case U_WMR_OFFSETCLIPRGN: dbg_str << "\n"; break; + case U_WMR_OFFSETCLIPRGN: + { + dbg_str << "\n"; + U_POINT16 off; + nSize = U_WMROFFSETCLIPRGN_get(contents,&off); + if (d->dc[d->level].clip_id) { // can only offset an existing clipping path + unsigned int real_idx = d->dc[d->level].clip_id - 1; + Geom::PathVector tmp_vect = sp_svg_read_pathv(d->clips.strings[real_idx]); + double ox = pix_to_x_point(d, off.x, off.y) - pix_to_x_point(d, 0, 0); // take into account all active transforms + double oy = pix_to_y_point(d, off.x, off.y) - pix_to_y_point(d, 0, 0); + Geom::Affine tf = Geom::Translate(ox,oy); + tmp_vect *= tf; + char *tmp_path = sp_svg_write_path(tmp_vect); + add_clips(d, tmp_path, U_RGN_COPY); + free(tmp_path); + } + break; + } // U_WMR_TEXTOUT should be here, but has been moved down to merge with U_WMR_EXTTEXTOUT case U_WMR_BITBLT: { @@ -2922,6 +3017,8 @@ void Wmf::free_wmf_strings(WMF_STRINGS name){ for(int i=0; i< name.count; i++){ free(name.strings[i]); } free(name.strings); } + name.count = 0; + name.size = 0; } SPDocument * @@ -2981,6 +3078,7 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) free_wmf_strings(d.hatches); free_wmf_strings(d.images); + free_wmf_strings(d.clips); if (d.wmf_obj) { int i; diff --git a/src/extension/internal/wmf-inout.h b/src/extension/internal/wmf-inout.h index 6006479c7..27ec14358 100644 --- a/src/extension/internal/wmf-inout.h +++ b/src/extension/internal/wmf-inout.h @@ -52,6 +52,7 @@ typedef struct wmf_device_context { wmf_device_context() : // SPStyle: class with constructor font_name(NULL), + clip_id(0), stroke_set(false), stroke_mode(0), stroke_idx(0), stroke_recidx(0), fill_set(false), fill_mode(0), fill_idx(0), fill_recidx(0), dirty(0), @@ -75,6 +76,7 @@ typedef struct wmf_device_context { }; SPStyle style; char *font_name; + int clip_id; // 0 if none, else 1 + index into clips bool stroke_set; int stroke_mode; // enumeration from drawmode, not used if fill_set is not True int stroke_idx; // used with DRAW_PATTERN and DRAW_IMAGE to return the appropriate fill @@ -155,6 +157,7 @@ typedef struct wmf_callback_data { // both of these end up in under the names shown here. These structures allow duplicates to be avoided. WMF_STRINGS hatches; // hold pattern names, all like WMFhatch#_$$$$$$ where # is the WMF hatch code and $$$$$$ is the color WMF_STRINGS images; // hold images, all like Image#, where # is the slot the image lives. + WMF_STRINGS clips; // hold clipping paths, referred to be the slot where the clipping path lives TR_INFO *tri; // Text Reassembly data structure @@ -195,6 +198,11 @@ protected: static int in_images(PWMF_CALLBACK_DATA d, char *test); static uint32_t add_dib_image(PWMF_CALLBACK_DATA d, const char *dib, uint32_t iUsage); static uint32_t add_bm16_image(PWMF_CALLBACK_DATA d, U_BITMAP16 Bm16, const char *px); + + static void enlarge_clips(PWMF_CALLBACK_DATA d); + static int in_clips(PWMF_CALLBACK_DATA d, const char *test); + static void add_clips(PWMF_CALLBACK_DATA d, const char *clippath, unsigned int logic); + static void output_style(PWMF_CALLBACK_DATA d); static double _pix_x_to_point(PWMF_CALLBACK_DATA d, double px); static double _pix_y_to_point(PWMF_CALLBACK_DATA d, double py); diff --git a/src/libuemf/uemf.c b/src/libuemf/uemf.c index 069cf901b..1d417dece 100644 --- a/src/libuemf/uemf.c +++ b/src/libuemf/uemf.c @@ -16,8 +16,8 @@ /* File: uemf.c -Version: 0.0.26 -Date: 24-MAR-2014 +Version: 0.0.28 +Date: 04-APR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) @@ -417,7 +417,7 @@ uint32_t emr_properties(uint32_t type){ table[ 64] = 0x90; // U_EMRSTROKEPATH 1 0 0 1 0 0 0 0 table[ 65] = 0xA0; // U_EMRFLATTENPATH 1 0 1 0 0 0 0 0 table[ 66] = 0xA0; // U_EMRWIDENPATH 1 0 1 0 0 0 0 0 - table[ 67] = 0xA0; // U_EMRSELECTCLIPPATH 1 0 1 0 0 0 0 0 + table[ 67] = 0x80; // U_EMRSELECTCLIPPATH 1 0 0 0 0 0 0 0 consumes the path, draws nothing table[ 68] = 0xA0; // U_EMRABORTPATH 1 0 1 0 0 0 0 0 table[ 69] = 0xA0; // U_EMRUNDEF69 1 0 1 0 0 0 0 0 table[ 70] = 0x00; // U_EMRCOMMENT 0 0 0 0 0 0 0 0 diff --git a/src/libuemf/uemf.h b/src/libuemf/uemf.h index cde1b6c85..a792a65de 100644 --- a/src/libuemf/uemf.h +++ b/src/libuemf/uemf.h @@ -95,8 +95,8 @@ these WMF enumerations is by referencing the following table: /* File: uemf.h -Version: 0.0.26 -Date: 27-MAR-2014 +Version: 0.0.27 +Date: 28-MAR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) @@ -1167,6 +1167,7 @@ typedef struct { EMF manual 2.1.29 @{ */ +#define U_RGN_NONE 0 //!< not part of EMF standard, may be used by others #define U_RGN_AND 1 //!< Region becomes intersection of existing region and new region. #define U_RGN_OR 2 //!< Region becomes union of existing region and new region. #define U_RGN_XOR 3 //!< Region becomes XOR of existing and new regions. diff --git a/src/libuemf/uwmf.c b/src/libuemf/uwmf.c index b4a1dfc52..b378e587f 100644 --- a/src/libuemf/uwmf.c +++ b/src/libuemf/uwmf.c @@ -19,8 +19,8 @@ /* File: uwmf.c -Version: 0.0.14 -Date: 24-MAR-2014 +Version: 0.0.15 +Date: 11-APR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) @@ -3019,7 +3019,7 @@ char *U_WMRESCAPE_set(uint16_t Escape, uint16_t Length, const void *Data){ \param DC Drawing Context to restore. (negative is relative to current, positive is absolute) */ char *U_WMRRESTOREDC_set(int16_t DC){ - return U_WMRCORE_1U16_set(U_WMR_SETMAPMODE, DC); + return U_WMRCORE_1U16_set(U_WMR_RESTOREDC, DC); } /** -- cgit v1.2.3 From d4c92eb19b82184433aee3f941fb97b2f4818027 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 29 Apr 2014 19:22:37 -0400 Subject: Fix bug #1290573 and #1310802 (bzr r13323) --- src/splivarot.cpp | 16 ++++++++++------ src/verbs.cpp | 4 ++++ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 40f3f174a..8bb2a7150 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -1457,13 +1457,21 @@ sp_selected_path_outline(SPDesktop *desktop) g_repr, xml_doc, doc ); } } + //bug lp:1290573 : completely destroy the old object first + curve->unref(); + selection->remove(item); + item->deleteObject(false); selection->add(g_repr); Inkscape::GC::release(g_repr); - - } else { + } else + { + //lp:1290573 + curve->unref(); + selection->remove(item); + item->deleteObject(false); // add the new repr to the parent parent->appendChild(repr); @@ -1489,10 +1497,6 @@ sp_selected_path_outline(SPDesktop *desktop) Inkscape::GC::release(repr); - curve->unref(); - selection->remove(item); - item->deleteObject(false); - } if (title) { g_free(title); diff --git a/src/verbs.cpp b/src/verbs.cpp index ab6c25973..eee7aef75 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1372,6 +1372,10 @@ void LayerVerb::perform(SPAction *action, void *data) survivor = Inkscape::previous_layer(dt->currentRoot(), old_layer); } + if (survivor == old_layer->lastChild()) { + //oops: layer_fns messed up. BADLY. + survivor = NULL; + } // Deleting the old layer before switching layers is a hack to trigger the // listeners of the deletion event (as happens when old_layer is deleted using the // xml editor). See -- cgit v1.2.3 From 2a5ab3d65249a8a7dde08097c87562d5bca598f2 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 29 Apr 2014 19:55:14 -0400 Subject: Fix a small issue with Attach Path (bzr r13090.1.69) --- src/live_effects/effect.cpp | 1 + src/sp-lpe-item.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 4b48ce68c..d8e057ab7 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -386,6 +386,7 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast(lpeitem); + //printf("(SPLPEITEM*) %p\n", sp_lpe_item); sp_curve = SP_SHAPE(sp_lpe_item)->getCurve(); pathvector_before_effect = sp_curve->get_pathvector(); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index b5dd74fc6..19a688ca5 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -242,7 +242,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { // Groups have their doBeforeEffect called elsewhere if (!SP_IS_GROUP(this)) { - lpe->doBeforeEffect(this); + lpe->doBeforeEffect_impl(this); } try { @@ -256,6 +256,9 @@ bool SPLPEItem::performPathEffect(SPCurve *curve) { } return false; } + if (!SP_IS_GROUP(this)) { + lpe->doAfterEffect(this); + } } } } -- cgit v1.2.3 From c09ed645a932d79d68eded5ee7f3fdc427b80ab5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Apr 2014 13:53:43 +0200 Subject: Style rewrite: fix typo. (bzr r13324) --- src/style-internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/style-internal.h b/src/style-internal.h index d1a331acf..1e878f1f6 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -166,7 +166,7 @@ class SPIFloat : public SPIBase { SPIFloat& operator=(const SPIFloat& rhs) { SPIBase::operator=(rhs); value = rhs.value; - value_default = value_default; + value_default = rhs.value_default; return *this; } -- cgit v1.2.3 From 33da924cabc1b580cca04ea77023e6a1e3e669c3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Apr 2014 14:05:25 +0200 Subject: Style rewrite: fix two more buglets. (bzr r13325) --- src/style-internal.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/style-internal.h b/src/style-internal.h index 1e878f1f6..0901cc0bc 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -229,7 +229,8 @@ class SPIScale24 : public SPIBase { SPIScale24& operator=(const SPIScale24& rhs) { SPIBase::operator=(rhs); - value = rhs.value; + value = rhs.value; + value_default = rhs.value_default; return *this; } @@ -400,6 +401,7 @@ class SPIString : public SPIBase { SPIString& operator=(const SPIString& rhs) { SPIBase::operator=(rhs); value = rhs.value?g_strdup(rhs.value):NULL; + value_default = rhs.value_default?g_strdup(rhs.value_default):NULL; return *this; } -- cgit v1.2.3 From a4d440c162b02f2fe2099a0ac1c7796609a686e7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Apr 2014 20:40:20 +0200 Subject: Enable 'mix-blend-mode' property (rendering only). (bzr r13326) --- src/display/drawing-item.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src') diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index ccf905e81..938330b02 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -23,7 +23,6 @@ namespace Inkscape { -#ifdef WITH_CSSBLEND void set_cairo_blend_operator( DrawingContext &dc, unsigned blend_mode ) { // All of the blend modes are implemented in Cairo as of 1.10. @@ -81,7 +80,6 @@ void set_cairo_blend_operator( DrawingContext &dc, unsigned blend_mode ) { break; } } -#endif /** * @class DrawingItem @@ -594,9 +592,8 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag if (_cached) { if (_cache) { _cache->prepare(); -#ifdef WITH_CSSBLEND set_cairo_blend_operator( dc, _blend_mode ); -#endif + _cache->paintFromCache(dc, carea); if (!carea) return RENDER_OK; } else { @@ -625,10 +622,8 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag nir |= (_filter != NULL && render_filters); // 3. it has a filter nir |= needs_opacity; // 4. it is non-opaque nir |= (_cache != NULL); // 5. it is cached -#ifdef WITH_CSSBLEND nir |= (_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal nir |= (_isolation == SP_CSS_ISOLATION_ISOLATE); // 7. Explicit isolatiom -#endif /* How the rendering is done. * @@ -740,9 +735,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag } dc.rectangle(*carea); dc.setSource(&intermediate); -#ifdef WITH_CSSBLEND set_cairo_blend_operator( dc, _blend_mode ); -#endif dc.fill(); dc.setSource(0,0,0,0); // the call above is to clear a ref on the intermediate surface held by dc -- cgit v1.2.3 From 399042e2de8699490b9d03d1920ceb4eb53ab37c Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Wed, 30 Apr 2014 14:48:20 -0400 Subject: do not allow ellipse arc segment greater than 90 degrees. (Bug 1312333) Fixed bugs: - https://launchpad.net/bugs/1312333 (bzr r13327) --- src/sp-ellipse.cpp | 73 +++++++++++++++++------------------------------------- 1 file changed, 23 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 25e4c07d7..cda59e057 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -419,62 +419,35 @@ void SPGenericEllipse::set_shape() // For simplicity, we use a circle with center (0, 0) and radius 1 for our calculations. Geom::Circle circle(0, 0, 1); - if (this->_isSlice()) { - Geom::Point center(0, 0); - Geom::Point start_point = Geom::Point::polar(start); - Geom::Point end_point = Geom::Point::polar(end); - Geom::Point middle_point = make_angle_bisector_ray(Geom::Ray(center, start), Geom::Ray(center, end)).versor(); - - Geom::EllipticalArc *arc = circle.arc(start_point, middle_point, end_point); - - Geom::Path path(start_point); - path.append(*arc); - - delete arc; - - Geom::PathBuilder pb; - pb.append(path); - - if (this->_closed) { - // "pizza slice" - pb.lineTo(center); - pb.closePath(); - } else { - // arc only - pb.flush(); - } - - curve = new SPCurve(pb.peek()); - } else { - // Full ellipse - // This code converts the circle to four elliptical arcs explicitly. - // Circle::getPath currently creates cubic bezier curves, these are not suitable here - // as a circle should have four mid markers at 0, 90, 180, 270 degrees. - Geom::Path path(Geom::Point::polar(0)); - Geom::EllipticalArc* arc; - - arc = circle.arc(Geom::Point::polar(0), Geom::Point::polar(M_PI / 4.0), Geom::Point::polar(M_PI / 2.0)); - path.append(*arc); - delete arc; - - arc = circle.arc(Geom::Point::polar(M_PI / 2.0), Geom::Point::polar(3.0 * M_PI / 4.0), Geom::Point::polar(M_PI)); - path.append(*arc); - delete arc; + if (!this->_isSlice()) { + start = 0.0; + end = 2.0*M_PI; + } + double incr = end - start; // arc angle + if (incr < 0.0) incr += 2.0*M_PI; - arc = circle.arc(Geom::Point::polar(M_PI), Geom::Point::polar(5.0 * M_PI / 4.0), Geom::Point::polar(3.0 * M_PI / 2.0)); - path.append(*arc); - delete arc; + int numsegs = 1 + int(incr*2.0/M_PI); // number of arc segments + if (numsegs > 4) numsegs = 4; - arc = circle.arc(Geom::Point::polar(3.0 * M_PI / 2.0), Geom::Point::polar(7.0 * M_PI / 4.0), Geom::Point::polar(2.0 * M_PI)); + incr = incr/numsegs; // limit arc angle to less than 90 degrees + Geom::Path path(Geom::Point::polar(start)); + Geom::EllipticalArc* arc; + for (int seg = 0; seg < numsegs; seg++) { + arc = circle.arc(Geom::Point::polar(start + seg*incr), Geom::Point::polar(start + (seg + 0.5)*incr), Geom::Point::polar(start + (seg + 1.0)*incr)); path.append(*arc); delete arc; - - Geom::PathBuilder pb; - pb.append(path); + } + Geom::PathBuilder pb; + pb.append(path); + if (this->_isSlice() && this->_closed) { + pb.lineTo(Geom::Point(0, 0)); + } + if (this->_closed) { pb.closePath(); - - curve = new SPCurve(pb.peek()); + } else { + pb.flush(); } + curve = new SPCurve(pb.peek()); // gchar *str = sp_svg_write_path(curve->get_pathvector()); // std::cout << " path: " << str << std::endl; -- cgit v1.2.3 From 8e0bf92c1af34564684c7f1b4a03003e643216e1 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Apr 2014 21:21:51 +0200 Subject: Style rewrite: more buglets squashed (thanks Johan). (bzr r13328) --- src/style-internal.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/style-internal.h b/src/style-internal.h index 0901cc0bc..e9cf6e604 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -128,6 +128,7 @@ class SPIBase { set = rhs.set; inherit = rhs.inherit; style_att = rhs.style_att; + style = rhs.style; return *this; } @@ -390,7 +391,7 @@ class SPIString : public SPIBase { SPIBase( name ) , value(NULL) , value_default(NULL) { value_default = value_default_in?g_strdup(value_default_in):NULL; }; - virtual ~SPIString() { g_free(value); }; + virtual ~SPIString() { g_free(value); g_free(value_default); }; virtual void read( gchar const *str ); virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, SPIBase const *const base = NULL ) const; @@ -400,6 +401,8 @@ class SPIString : public SPIBase { SPIString& operator=(const SPIString& rhs) { SPIBase::operator=(rhs); + g_free(value); + g_free(value_default); value = rhs.value?g_strdup(rhs.value):NULL; value_default = rhs.value_default?g_strdup(rhs.value_default):NULL; return *this; @@ -430,7 +433,8 @@ class SPIColor : public SPIBase { SPIColor& operator=(const SPIColor& rhs) { SPIBase::operator=(rhs); - value.color = rhs.value.color; + currentcolor = rhs.currentcolor; + value.color = rhs.value.color; return *this; } @@ -558,6 +562,7 @@ class SPIPaintOrder : public SPIBase { layer[i] = rhs.layer[i]; layer_set[i] = rhs.layer_set[i]; } + g_free(value); value = g_strdup(rhs.value); return *this; } -- cgit v1.2.3 From 5cd0a6e6d8f397d3cfd56868d1ebe74ab7c6d583 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 1 May 2014 11:16:33 +0200 Subject: Enable support for 'paint-order', rendering only. (bzr r13329) --- src/display/drawing-shape.cpp | 7 +------ src/display/drawing-text.cpp | 9 +++------ 2 files changed, 4 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index 92d71fad3..1a41bdb3a 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -149,7 +149,6 @@ DrawingShape::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u return STATE_ALL; } -#ifdef WITH_SVG2 void DrawingShape::_renderFill(DrawingContext &dc) { @@ -183,7 +182,6 @@ DrawingShape::_renderStroke(DrawingContext &dc) dc.newPath(); // clear path } } -#endif void DrawingShape::_renderMarkers(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at) @@ -222,10 +220,9 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne } -#ifdef WITH_SVG2 if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL ) { // This is the most common case, special case so we don't call get_pathvector(), etc. twice -#endif + { // we assume the context has no path Inkscape::DrawingContext::Save save(dc); @@ -255,7 +252,6 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne _renderMarkers(dc, area, flags, stop_at); return RENDER_OK; -#ifdef WITH_SVG2 } // Handle different paint orders @@ -276,7 +272,6 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne } } return RENDER_OK; -#endif } void DrawingShape::_clipItem(DrawingContext &dc, Geom::IntRect const & /*area*/) diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index a280e221a..4178cb1d8 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -451,7 +451,6 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); -#ifdef WITH_SVG2 // Text doesn't have markers, we can do paint-order quick and dirty. bool fill_first = false; if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || @@ -461,22 +460,20 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are } // Won't get "stroke fill stroke" but that isn't 'valid' if (has_fill && fill_first) { -#else - if (has_fill) { -#endif _nrstyle.applyFill(dc); dc.fillPreserve(); } + if (has_stroke) { _nrstyle.applyStroke(dc); dc.strokePreserve(); } -#ifdef WITH_SVG2 + if (has_fill && !fill_first) { _nrstyle.applyFill(dc); dc.fillPreserve(); } -#endif + dc.newPath(); // clear path // draw text decoration -- cgit v1.2.3 From 7723d455c0daf1e07da9eba75b362c1d0a8556a5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 1 May 2014 21:46:40 +0200 Subject: Enable 'paint-order', (rendering only)... missing changes. (bzr r13330) --- src/display/drawing-shape.h | 2 -- src/display/nr-style.cpp | 4 ---- src/display/nr-style.h | 2 -- 3 files changed, 8 deletions(-) (limited to 'src') diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h index f37de9ce7..9d93a642f 100644 --- a/src/display/drawing-shape.h +++ b/src/display/drawing-shape.h @@ -39,10 +39,8 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); -#ifdef WITH_SVG2 void _renderFill(DrawingContext &dc); void _renderStroke(DrawingContext &dc); -#endif void _renderMarkers(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at); diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 3d2d36483..09a28e63c 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -69,9 +69,7 @@ NRStyle::NRStyle() , line_through_position(0) , font_size(0) { -#ifdef WITH_SVG2 paint_order_layer[0] = PAINT_ORDER_NORMAL; -#endif } NRStyle::~NRStyle() @@ -165,7 +163,6 @@ void NRStyle::set(SPStyle *style) } -#ifdef WITH_SVG2 for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i) { switch (style->paint_order.layer[i]) { case SP_CSS_PAINT_ORDER_NORMAL: @@ -182,7 +179,6 @@ void NRStyle::set(SPStyle *style) break; } } -#endif text_decoration_line = TEXT_DECORATION_LINE_CLEAR; if(style->text_decoration_line.inherit ){ text_decoration_line |= TEXT_DECORATION_LINE_INHERIT; } diff --git a/src/display/nr-style.h b/src/display/nr-style.h index 8b5a0ee3d..ca880c00b 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -68,7 +68,6 @@ struct NRStyle { cairo_pattern_t *fill_pattern; cairo_pattern_t *stroke_pattern; -#ifdef WITH_SVG2 enum PaintOrderType { PAINT_ORDER_NORMAL, PAINT_ORDER_FILL, @@ -78,7 +77,6 @@ struct NRStyle { static const size_t PAINT_ORDER_LAYERS = 3; PaintOrderType paint_order_layer[PAINT_ORDER_LAYERS]; -#endif #define TEXT_DECORATION_LINE_CLEAR 0x00 #define TEXT_DECORATION_LINE_SET 0x01 -- cgit v1.2.3 From e838d370cf1d9e4176dbee7a950df4482f951d02 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 2 May 2014 14:09:23 +0200 Subject: Removing the old SP_VERB_FILE_EXPORT (replaced with SP_VERB_DIALOG_EXPORT). (bzr r13331) --- src/verbs.cpp | 3 +-- src/verbs.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/verbs.cpp b/src/verbs.cpp index eee7aef75..0c329cab8 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2368,8 +2368,7 @@ Verb *Verb::_base_verbs[] = { INKSCAPE_ICON("document-cleanup") ), new FileVerb(SP_VERB_FILE_IMPORT, "FileImport", N_("_Import..."), N_("Import a bitmap or SVG image into this document"), INKSCAPE_ICON("document-import")), - new FileVerb(SP_VERB_FILE_EXPORT, "FileExport", N_("_Export Bitmap..."), - N_("Export this document or a selection as a bitmap image"), INKSCAPE_ICON("document-export")), +// new FileVerb(SP_VERB_FILE_EXPORT, "FileExport", N_("_Export Bitmap..."), N_("Export this document or a selection as a bitmap image"), INKSCAPE_ICON("document-export")), new FileVerb(SP_VERB_FILE_IMPORT_FROM_OCAL, "FileImportFromOCAL", N_("Import Clip Art..."), N_("Import clipart from Open Clip Art Library"), INKSCAPE_ICON("document-import-ocal")), // new FileVerb(SP_VERB_FILE_EXPORT_TO_OCAL, "FileExportToOCAL", N_("Export To Open Clip Art Library"), N_("Export this document to Open Clip Art Library"), INKSCAPE_ICON_DOCUMENT_EXPORT_OCAL), diff --git a/src/verbs.h b/src/verbs.h index 297ef1655..6ad4d0fee 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -52,7 +52,7 @@ enum { SP_VERB_FILE_PRINT, SP_VERB_FILE_VACUUM, SP_VERB_FILE_IMPORT, - SP_VERB_FILE_EXPORT, +// SP_VERB_FILE_EXPORT, SP_VERB_FILE_IMPORT_FROM_OCAL, /**< Import the file from Open Clip Art Library */ // SP_VERB_FILE_EXPORT_TO_OCAL, /**< Export the file to Open Clip Art Library */ SP_VERB_FILE_NEXT_DESKTOP, -- cgit v1.2.3 From 8f373840d0a408d43d2a6712c638463637890e97 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 3 May 2014 23:37:36 +0200 Subject: Fix bounding box cache issues in general, and prevent the selector tool from updating anything in case of identity affines (which prevents the bounding box from being invalidated) Fixed bugs: - https://launchpad.net/bugs/1256597 (bzr r13333) --- src/display/canvas-arena.cpp | 2 +- src/display/drawing-item.cpp | 2 +- src/seltrans.cpp | 71 +++++++++++++++++++++++++++----------------- 3 files changed, 45 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 404a94828..25d35fc6b 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -227,7 +227,7 @@ sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_ { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK); + arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK | DrawingItem::STATE_BBOX); DrawingItem *picked = arena->drawing.pick(p, arena->drawing.delta, arena->sticky); arena->picked = picked; diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 938330b02..0bfb00b62 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -407,7 +407,7 @@ DrawingItem::setItemBounds(Geom::OptRect const &bounds) * @param reset State fields that should be reset before processing them. This is * a means to force a recomputation of internal data even if the item * considers it up to date. Mainly for internal use, such as - * propagating bunding box recomputation to children when the item's + * propagating bounding box recomputation to children when the item's * transform changes. */ void diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 60a0bfa11..7708c999e 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -377,6 +377,12 @@ void Inkscape::SelTrans::transform(Geom::Affine const &rel_affine, Geom::Point c g_return_if_fail(_grabbed); g_return_if_fail(!_empty); + // E.g. scaling a perfectly vertical line in horizontal direction will not work, and will produce an identity affine + + if (rel_affine.isIdentity()) { + return; + } + Geom::Affine const affine( Geom::Translate(-norm) * rel_affine * Geom::Translate(norm) ); if (_show == SHOW_CONTENT) { @@ -389,6 +395,7 @@ void Inkscape::SelTrans::transform(Geom::Affine const &rel_affine, Geom::Point c } Geom::Affine const &prev_transform = _items_affines[i]; item.set_i2d_affine(prev_transform * affine); + // The new affine will only have been applied if the transformation is different from the previous one, see SPItem::set_item_transform } } else { if (_bbox) { @@ -439,21 +446,25 @@ void Inkscape::SelTrans::ungrab() _message_context.clear(); if (!_empty && _changed) { - sp_selection_apply_affine(selection, _current_relative_affine, (_show == SHOW_OUTLINE)? true : false); - if (_center) { - *_center *= _current_relative_affine; - _center_is_set = true; - } + if (!_current_relative_affine.isIdentity()) { // we can have a identity affine + // when trying to stretch a perfectly vertical line in horizontal direction, which will not be allowed by the handles; -// If dragging showed content live, sp_selection_apply_affine cannot change the centers -// appropriately - it does not know the original positions of the centers (all objects already have -// the new bboxes). So we need to reset the centers from our saved array. - if (_show != SHOW_OUTLINE && !_current_relative_affine.isTranslation()) { - for (unsigned i = 0; i < _items_centers.size(); i++) { - SPItem *currentItem = _items[i]; - if (currentItem->isCenterSet()) { // only if it's already set - currentItem->setCenter (_items_centers[i] * _current_relative_affine); - currentItem->updateRepr(); + sp_selection_apply_affine(selection, _current_relative_affine, (_show == SHOW_OUTLINE)? true : false); + if (_center) { + *_center *= _current_relative_affine; + _center_is_set = true; + } + + // If dragging showed content live, sp_selection_apply_affine cannot change the centers + // appropriately - it does not know the original positions of the centers (all objects already have + // the new bboxes). So we need to reset the centers from our saved array. + if (_show != SHOW_OUTLINE && !_current_relative_affine.isTranslation()) { + for (unsigned i = 0; i < _items_centers.size(); i++) { + SPItem *currentItem = _items[i]; + if (currentItem->isCenterSet()) { // only if it's already set + currentItem->setCenter (_items_centers[i] * _current_relative_affine); + currentItem->updateRepr(); + } } } } @@ -463,18 +474,22 @@ void Inkscape::SelTrans::ungrab() _items_affines.clear(); _items_centers.clear(); - if (_current_relative_affine.isTranslation()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, - _("Move")); - } else if (_current_relative_affine.withoutTranslation().isScale()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, - _("Scale")); - } else if (_current_relative_affine.withoutTranslation().isRotation()) { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, - _("Rotate")); - } else { - DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, - _("Skew")); + if (!_current_relative_affine.isIdentity()) { // we can have a identity affine + // when trying to stretch a perfectly vertical line in horizontal direction, which will not be allowed + // by the handles; this would be identified as a (zero) translation by isTranslation() + if (_current_relative_affine.isTranslation()) { + DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Move")); + } else if (_current_relative_affine.withoutTranslation().isScale()) { + DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Scale")); + } else if (_current_relative_affine.withoutTranslation().isRotation()) { + DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Rotate")); + } else { + DocumentUndo::done(sp_desktop_document(_desktop), SP_VERB_CONTEXT_SELECT, + _("Skew")); + } } } else { @@ -506,7 +521,7 @@ void Inkscape::SelTrans::stamp() bool fixup = !_grabbed; if ( fixup && _stamp_cache ) { - // TODO - give a proper fix. Simple temproary work-around for the grab() issue + // TODO - give a proper fix. Simple temporary work-around for the grab() issue g_slist_free(_stamp_cache); _stamp_cache = NULL; } @@ -565,7 +580,7 @@ void Inkscape::SelTrans::stamp() } if ( fixup && _stamp_cache ) { - // TODO - give a proper fix. Simple temproary work-around for the grab() issue + // TODO - give a proper fix. Simple temporary work-around for the grab() issue g_slist_free(_stamp_cache); _stamp_cache = NULL; } -- cgit v1.2.3 From 5a8b00f027b9eb3d4abb290d2ddf26d36d71cf80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20dos=20Santos=20Oliveira?= Date: Mon, 5 May 2014 04:13:35 -0300 Subject: Enabling path manipulator to comunicate if paths are bspline when accessing const objects. This change was required to correctly show on the GUI whether or not a node was a bspline. (bzr r11950.8.1) --- src/live_effects/effect.h | 1 + src/sp-lpe-item.cpp | 16 ++++++++++++++++ src/sp-lpe-item.h | 1 + src/ui/tool/node.cpp | 8 +------- src/ui/tool/node.h | 6 ++++++ src/ui/tool/path-manipulator.cpp | 12 ++++++++---- src/ui/tool/path-manipulator.h | 3 ++- 7 files changed, 35 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 1da9b4cc9..940770616 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -101,6 +101,7 @@ public: Inkscape::XML::Node * getRepr(); SPDocument * getSPDoc(); LivePathEffectObject * getLPEObj() {return lpeobj;}; + LivePathEffectObject const * getLPEObj() const {return lpeobj;}; Parameter * getParameter(const char * key); void readallParameters(Inkscape::XML::Node const* repr); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index f59bc33ee..33359727a 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -606,6 +606,22 @@ SPLPEItem::getPathEffectOfType(int type) return NULL; } +Inkscape::LivePathEffect::Effect const* +SPLPEItem::getPathEffectOfType(int type) const +{ + std::list::const_iterator i; + for (i = path_effect_list->begin(); i != path_effect_list->end(); ++i) { + LivePathEffectObject const *lpeobj = (*i)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect const *lpe = lpeobj->get_lpe(); + if (lpe && (lpe->effectType() == type)) { + return lpe; + } + } + } + return NULL; +} + void SPLPEItem::editNextParamOncanvas(SPDesktop *dt) { Inkscape::LivePathEffect::LPEObjectReference *lperef = this->getCurrentLPEReference(); diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index cd72ac55b..85878a95b 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -77,6 +77,7 @@ public: bool hasPathEffectOfType(int const type) const; bool hasPathEffectRecursive() const; Inkscape::LivePathEffect::Effect* getPathEffectOfType(int type); + Inkscape::LivePathEffect::Effect const* getPathEffectOfType(int type) const; bool hasBrokenPathEffect() const; PathEffectList getEffectList(); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 7ba69b039..6cb254b7f 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1421,13 +1421,7 @@ Node *Node::nodeAwayFrom(Handle *h) Glib::ustring Node::_getTip(unsigned state) const { - - /* if the node doesnt have strength, it marks it as bspline, we'll use it later - to show the appropiate messages. We cannot do it in any other way, because the - function is constant */ - bool isBSpline = false; - //if( this->bsplineWeight != 0.0000) - // isBSpline = true; + bool isBSpline = _pm().isBSpline(); if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 202dbb3cd..415563a7d 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -217,6 +217,7 @@ public: Node *nodeAwayFrom(Handle *h); NodeList &nodeList() { return *(static_cast(this)->ln_list); } + NodeList &nodeList() const { return *(static_cast(this)->ln_list); } /** * Move the node to the bottom of its canvas group. @@ -263,6 +264,7 @@ private: Inkscape::SnapSourceType _snapSourceType() const; Inkscape::SnapTargetType _snapTargetType() const; inline PathManipulator &_pm(); + inline PathManipulator &_pm() const; /** Determine whether two nodes are joined by a linear segment. */ static bool _is_line_segment(Node *first, Node *second); @@ -494,6 +496,10 @@ inline PathManipulator &Node::_pm() { return nodeList().subpathList().pm(); } +inline PathManipulator &Node::_pm() const { + return nodeList().subpathList().pm(); +} + // definitions for node iterator template NodeIterator::operator bool() const { diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 487c31b10..3beeed049 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1181,14 +1181,14 @@ void PathManipulator::_createControlPointsFromGeometry() } //determines if the trace has a bspline effect and the number of steps that it takes -int PathManipulator::BSplineGetSteps(){ +int PathManipulator::BSplineGetSteps() const { - LivePathEffect::LPEBSpline *lpe_bsp = NULL; + LivePathEffect::LPEBSpline const *lpe_bsp = NULL; if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); + Inkscape::LivePathEffect::Effect const *thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::BSPLINE); if(thisEffect){ - lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + lpe_bsp = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); } } int steps = 0; @@ -1206,6 +1206,10 @@ bool PathManipulator::isBSpline(bool recalculate){ return _is_bspline; } +bool PathManipulator::isBSpline() const { + return BSplineGetSteps() > 0; +} + // returns the corresponding strength to the position of the handlers double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ using Geom::X; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index a85664ddf..151805c83 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -96,7 +96,7 @@ public: NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); - int BSplineGetSteps(); + int BSplineGetSteps() const; // this is necessary for Tab-selection in MultiPathManipulator SubpathList &subpathList() { return _subpaths; } @@ -108,6 +108,7 @@ private: void _createControlPointsFromGeometry(); bool isBSpline(bool recalculate = false); + bool isBSpline() const; double BSplineHandlePosition(Handle *h, Handle *h2 = NULL); Geom::Point BSplineHandleReposition(Handle *h, Handle *h2 = NULL); Geom::Point BSplineHandleReposition(Handle *h, double pos); -- cgit v1.2.3 From e2f2dfac4f2c54eef41c4b7429fe5fb6bc5eb1d2 Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 5 May 2014 01:40:12 -0700 Subject: Make experimental feature enabling more unified/easy. (bzr r13336) --- src/live_effects/effect.cpp | 2 -- src/widgets/toolbox.cpp | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 12990ee24..4c5e21194 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -5,8 +5,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -//#define LPE_ENABLE_TEST_EFFECTS - #ifdef HAVE_CONFIG_H # include "config.h" #endif diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 02da805bf..3d6f73ef1 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -1301,8 +1301,9 @@ void setup_tool_toolbox(GtkWidget *toolbox, SPDesktop *desktop) " " " " - -// " " +#ifdef WITH_LPETOOL + " " +#endif " " ""; -- cgit v1.2.3 From 77ec197912229a64495bda39ac0b0943580baaaf Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 5 May 2014 11:50:39 +0200 Subject: adding const _pathmanipulatos staff to handles (handles also have tips) (bzr r11950.1.341) --- src/ui/tool/node.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 415563a7d..5971956e1 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -131,6 +131,7 @@ protected: private: inline PathManipulator &_pm(); + inline PathManipulator &_pm() const; Node *_parent; // the handle's lifetime does not extend beyond that of the parent node, // so a naked pointer is OK and allows setting it during Node's construction SPCtrlLine *_handle_line; @@ -492,6 +493,9 @@ inline double Handle::length() const { inline PathManipulator &Handle::_pm() { return _parent->_pm(); } +inline PathManipulator &Handle::_pm() const { + return _parent->_pm(); +} inline PathManipulator &Node::_pm() { return nodeList().subpathList().pm(); } -- cgit v1.2.3 From 1fd4e3f17b3d591c56d0a50b877909791cd6c05e Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 5 May 2014 11:22:35 -0700 Subject: Add one more ifdef for LPETool prefs. Thanks suv! (bzr r13337) --- src/ui/dialog/inkscape-preferences.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 559398a84..e757bf702 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -500,10 +500,12 @@ void InkscapePreferences::initPageTools() _page_connector.add_line(false, "", _connector_ignore_text, "", _("If on, connector attachment points will not be shown for text objects")); +#ifdef WITH_LPETOOL //LPETool - // commented out, because the LPETool is not finished yet. + //disabled, because the LPETool is not finished yet. //this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); //this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); +#endif // WITH_LPETOOL } void InkscapePreferences::initPageUI() -- cgit v1.2.3 From 65c7b8f3c893e681b5d395cbef9a8b37d17e07a8 Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 5 May 2014 11:29:46 -0700 Subject: Apparently I didn't look twice before committing. Thanks suv! (bzr r13338) --- src/ui/dialog/inkscape-preferences.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index e757bf702..b6095fa8b 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -503,8 +503,8 @@ void InkscapePreferences::initPageTools() #ifdef WITH_LPETOOL //LPETool //disabled, because the LPETool is not finished yet. - //this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); - //this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); + this->AddPage(_page_lpetool, _("LPE Tool"), iter_tools, PREFS_PAGE_TOOLS_LPETOOL); + this->AddNewObjectsStyle(_page_lpetool, "/tools/lpetool"); #endif // WITH_LPETOOL } -- cgit v1.2.3 From d762533f6b091d1af8b71b9694078179ff72dd32 Mon Sep 17 00:00:00 2001 From: Mohamed Ikbel Boulabiar Date: Tue, 6 May 2014 14:44:42 +0200 Subject: Fix a small copy-paste typo. (Get position Y returns X) (bzr r13338.1.1) --- src/extension/dbus/document-interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index 221a3e879..e3452f4ce 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -169,7 +169,7 @@ selection_get_center_x (Inkscape::Selection *sel){ gdouble selection_get_center_y (Inkscape::Selection *sel){ Geom::OptRect box = sel->documentBounds(SPItem::GEOMETRIC_BBOX); - return box ? box->midpoint()[Geom::X] : 0; + return box ? box->midpoint()[Geom::Y] : 0; } /* -- cgit v1.2.3 From e4f2903c77e176f38e3700454266d9183fb774fa Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 7 May 2014 14:06:26 +0200 Subject: Style rewrite: prevent crash when fill/stroke set to "currentColor". (bzr r13342) --- src/style-internal.cpp | 122 ++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index df08d0adf..c74683a7a 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -65,13 +65,13 @@ SPIFloat::read( gchar const *str ) { if( !str ) return; if ( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { gfloat value_tmp; if (sp_svg_number_read_f(str, &value_tmp)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value = value_tmp; } } @@ -140,13 +140,13 @@ SPIScale24::read( gchar const *str ) { if( !str ) return; if ( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { gfloat value_in; if (sp_svg_number_read_f(str, &value_in)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value_in = CLAMP(value_in, 0.0, 1.0); value = SP_SCALE24_FROM_FLOAT( value_in ); } @@ -228,8 +228,8 @@ SPILength::read( gchar const *str ) { if( !str ) return; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; unit = SP_CSS_UNIT_NONE; value = computed = 0.0; } else { @@ -291,8 +291,8 @@ SPILength::read( gchar const *str ) { /* Invalid */ return; } - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; } } } @@ -439,11 +439,11 @@ SPILengthOrNormal::read( gchar const *str ) { if( !str ) return; if ( !strcmp(str, "normal") ) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; unit = SP_CSS_UNIT_NONE; value = computed = 0.0; - normal = TRUE; + normal = true; } else { SPILength::read( str ); normal = false; @@ -501,13 +501,13 @@ SPIEnum::read( gchar const *str ) { if( !str ) return; if( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { for (unsigned i = 0; enums[i].key; i++) { if (!strcmp(str, enums[i].key)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value = enums[i].value; /* Save copying for values not needing it */ computed = value; @@ -651,12 +651,12 @@ SPIString::read( gchar const *str ) { g_free(value); if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; value = NULL; } else { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value = g_strdup(str); } } @@ -762,13 +762,13 @@ void SPIColor::read( gchar const *str ) { if( name.compare( "color") == 0 ) { inherit = true; // CSS3 } else { - value.color = style->color.value.color; + setColor( style->color.value.color ); } } else { guint32 const rgb0 = sp_svg_read_color(str, 0xff); if (rgb0 != 0xff) { setColor(rgb0); - set = TRUE; + set = true; } } } @@ -821,7 +821,7 @@ SPIColor::cascade( const SPIBase* const parent ) { if( const SPIColor* p = dynamic_cast(parent) ) { if( (inherits && !set) || inherit) { // FIXME verify for 'color' if( !(inherit && currentcolor) ) currentcolor = p->currentcolor; - value.color = p->value.color; + setColor( p->value.color ); } else { // Add CSS4 Color: Lighter, Darker } @@ -910,8 +910,8 @@ SPIPaint::read( gchar const *str ) { } if (streq(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { // Read any URL first. The other values can be stand-alone or backup to the URL. @@ -924,7 +924,7 @@ SPIPaint::read( gchar const *str ) { } else if (!style ) { std::cerr << "SPIPaint::read: url with empty SPStyle pointer" << std::endl; } else { - set = TRUE; + set = true; SPDocument *document = (style->object) ? style->object->document : NULL; // Create href if not done already @@ -946,17 +946,17 @@ SPIPaint::read( gchar const *str ) { } if (streq(str, "currentColor")) { - set = TRUE; - currentcolor = TRUE; - value.color = style->color.value.color; + set = true; + currentcolor = true; + setColor( style->color.value.color ); } else if (streq(str, "none")) { - set = TRUE; - noneSet = TRUE; + set = true; + noneSet = true; } else { guint32 const rgb0 = sp_svg_read_color(str, &str, 0xff); if (rgb0 != 0xff) { setColor( rgb0 ); - set = TRUE; + set = true; while (g_ascii_isspace(*str)) { ++str; @@ -1076,7 +1076,7 @@ SPIPaint::reset( bool init ) { setColor(0.0, 0.0, 0.0); } if( name.compare( "text-decoration-color" ) == 0 ) { - currentcolor = true; + // currentcolor = true; } } } @@ -1100,10 +1100,10 @@ SPIPaint::cascade( const SPIBase* const parent ) { } else if( p->isColor() ) { setColor( p->value.color ); } else if( p->isNoneSet() ) { - noneSet = TRUE; + noneSet = true; } else if( p->currentcolor ) { - currentcolor = TRUE; - value.color = style->color.value.color; + currentcolor = true; + setColor( style->color.value.color ); } else if( isNone() ) { // } else { @@ -1112,7 +1112,7 @@ SPIPaint::cascade( const SPIBase* const parent ) { } else { if( currentcolor ) { // Update in case color value changed. - value.color = style->color.value.color; + setColor( style->color.value.color ); } } @@ -1179,14 +1179,14 @@ SPIPaintOrder::read( gchar const *str ) { if( !str ) return; g_free(value); - set = FALSE; - inherit = FALSE; + set = false; + inherit = false; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { - set = TRUE; + set = true; value = g_strdup(str); if (!strcmp(value, "normal")) { @@ -1347,10 +1347,10 @@ SPIFilter::read( gchar const *str ) { clear(); if ( streq(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else if(streq(str, "none")) { - set = TRUE; + set = true; } else if (strneq(str, "url", 3)) { gchar *uri = extract_uri(str); if(uri == NULL || uri[0] == '\0') { @@ -1360,7 +1360,7 @@ SPIFilter::read( gchar const *str ) { std::cerr << "SPIFilter::read: url with empty SPStyle pointer" << std::endl; return; } - set = TRUE; + set = true; // Create href if not already done. if (!href && style->object) { @@ -1592,14 +1592,14 @@ SPIFontSize::read( gchar const *str ) { if( !str ) return; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else if ((*str == 'x') || (*str == 's') || (*str == 'm') || (*str == 'l')) { // xx-small, x-small, etc. for (unsigned i = 0; enum_font_size[i].key; i++) { if (!strcmp(str, enum_font_size[i].key)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; type = SP_FONT_SIZE_LITERAL; literal = enum_font_size[i].value; return; @@ -1609,10 +1609,10 @@ SPIFontSize::read( gchar const *str ) { return; } else { SPILength length("temp"); - length.set = FALSE; + length.set = false; length.read( str ); if( length.set ) { - set = TRUE; + set = true; inherit = length.inherit; unit = length.unit; value = length.value; @@ -1824,8 +1824,8 @@ SPIFont::read( gchar const *str ) { } if ( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { // Break string into white space separated tokens @@ -1957,14 +1957,14 @@ SPIBaselineShift::read( gchar const *str ) { if( !str ) return; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else if ((*str == 'b') || (*str == 's')) { // baseline or sub or super for (unsigned i = 0; enum_baseline_shift[i].key; i++) { if (!strcmp(str, enum_baseline_shift[i].key)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; type = SP_BASELINE_SHIFT_LITERAL; literal = enum_baseline_shift[i].value; return; -- cgit v1.2.3 From 6a0c44e21967ec8f4170993b7ec7506e3c0c5e5e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 7 May 2014 14:25:58 +0200 Subject: Style rewrite: prevent crash when fill/stroke set to "currentColor". (bzr r13341.1.1) --- src/style-internal.cpp | 122 ++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index df08d0adf..c74683a7a 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -65,13 +65,13 @@ SPIFloat::read( gchar const *str ) { if( !str ) return; if ( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { gfloat value_tmp; if (sp_svg_number_read_f(str, &value_tmp)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value = value_tmp; } } @@ -140,13 +140,13 @@ SPIScale24::read( gchar const *str ) { if( !str ) return; if ( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { gfloat value_in; if (sp_svg_number_read_f(str, &value_in)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value_in = CLAMP(value_in, 0.0, 1.0); value = SP_SCALE24_FROM_FLOAT( value_in ); } @@ -228,8 +228,8 @@ SPILength::read( gchar const *str ) { if( !str ) return; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; unit = SP_CSS_UNIT_NONE; value = computed = 0.0; } else { @@ -291,8 +291,8 @@ SPILength::read( gchar const *str ) { /* Invalid */ return; } - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; } } } @@ -439,11 +439,11 @@ SPILengthOrNormal::read( gchar const *str ) { if( !str ) return; if ( !strcmp(str, "normal") ) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; unit = SP_CSS_UNIT_NONE; value = computed = 0.0; - normal = TRUE; + normal = true; } else { SPILength::read( str ); normal = false; @@ -501,13 +501,13 @@ SPIEnum::read( gchar const *str ) { if( !str ) return; if( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { for (unsigned i = 0; enums[i].key; i++) { if (!strcmp(str, enums[i].key)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value = enums[i].value; /* Save copying for values not needing it */ computed = value; @@ -651,12 +651,12 @@ SPIString::read( gchar const *str ) { g_free(value); if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; value = NULL; } else { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; value = g_strdup(str); } } @@ -762,13 +762,13 @@ void SPIColor::read( gchar const *str ) { if( name.compare( "color") == 0 ) { inherit = true; // CSS3 } else { - value.color = style->color.value.color; + setColor( style->color.value.color ); } } else { guint32 const rgb0 = sp_svg_read_color(str, 0xff); if (rgb0 != 0xff) { setColor(rgb0); - set = TRUE; + set = true; } } } @@ -821,7 +821,7 @@ SPIColor::cascade( const SPIBase* const parent ) { if( const SPIColor* p = dynamic_cast(parent) ) { if( (inherits && !set) || inherit) { // FIXME verify for 'color' if( !(inherit && currentcolor) ) currentcolor = p->currentcolor; - value.color = p->value.color; + setColor( p->value.color ); } else { // Add CSS4 Color: Lighter, Darker } @@ -910,8 +910,8 @@ SPIPaint::read( gchar const *str ) { } if (streq(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { // Read any URL first. The other values can be stand-alone or backup to the URL. @@ -924,7 +924,7 @@ SPIPaint::read( gchar const *str ) { } else if (!style ) { std::cerr << "SPIPaint::read: url with empty SPStyle pointer" << std::endl; } else { - set = TRUE; + set = true; SPDocument *document = (style->object) ? style->object->document : NULL; // Create href if not done already @@ -946,17 +946,17 @@ SPIPaint::read( gchar const *str ) { } if (streq(str, "currentColor")) { - set = TRUE; - currentcolor = TRUE; - value.color = style->color.value.color; + set = true; + currentcolor = true; + setColor( style->color.value.color ); } else if (streq(str, "none")) { - set = TRUE; - noneSet = TRUE; + set = true; + noneSet = true; } else { guint32 const rgb0 = sp_svg_read_color(str, &str, 0xff); if (rgb0 != 0xff) { setColor( rgb0 ); - set = TRUE; + set = true; while (g_ascii_isspace(*str)) { ++str; @@ -1076,7 +1076,7 @@ SPIPaint::reset( bool init ) { setColor(0.0, 0.0, 0.0); } if( name.compare( "text-decoration-color" ) == 0 ) { - currentcolor = true; + // currentcolor = true; } } } @@ -1100,10 +1100,10 @@ SPIPaint::cascade( const SPIBase* const parent ) { } else if( p->isColor() ) { setColor( p->value.color ); } else if( p->isNoneSet() ) { - noneSet = TRUE; + noneSet = true; } else if( p->currentcolor ) { - currentcolor = TRUE; - value.color = style->color.value.color; + currentcolor = true; + setColor( style->color.value.color ); } else if( isNone() ) { // } else { @@ -1112,7 +1112,7 @@ SPIPaint::cascade( const SPIBase* const parent ) { } else { if( currentcolor ) { // Update in case color value changed. - value.color = style->color.value.color; + setColor( style->color.value.color ); } } @@ -1179,14 +1179,14 @@ SPIPaintOrder::read( gchar const *str ) { if( !str ) return; g_free(value); - set = FALSE; - inherit = FALSE; + set = false; + inherit = false; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { - set = TRUE; + set = true; value = g_strdup(str); if (!strcmp(value, "normal")) { @@ -1347,10 +1347,10 @@ SPIFilter::read( gchar const *str ) { clear(); if ( streq(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else if(streq(str, "none")) { - set = TRUE; + set = true; } else if (strneq(str, "url", 3)) { gchar *uri = extract_uri(str); if(uri == NULL || uri[0] == '\0') { @@ -1360,7 +1360,7 @@ SPIFilter::read( gchar const *str ) { std::cerr << "SPIFilter::read: url with empty SPStyle pointer" << std::endl; return; } - set = TRUE; + set = true; // Create href if not already done. if (!href && style->object) { @@ -1592,14 +1592,14 @@ SPIFontSize::read( gchar const *str ) { if( !str ) return; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else if ((*str == 'x') || (*str == 's') || (*str == 'm') || (*str == 'l')) { // xx-small, x-small, etc. for (unsigned i = 0; enum_font_size[i].key; i++) { if (!strcmp(str, enum_font_size[i].key)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; type = SP_FONT_SIZE_LITERAL; literal = enum_font_size[i].value; return; @@ -1609,10 +1609,10 @@ SPIFontSize::read( gchar const *str ) { return; } else { SPILength length("temp"); - length.set = FALSE; + length.set = false; length.read( str ); if( length.set ) { - set = TRUE; + set = true; inherit = length.inherit; unit = length.unit; value = length.value; @@ -1824,8 +1824,8 @@ SPIFont::read( gchar const *str ) { } if ( !strcmp(str, "inherit") ) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else { // Break string into white space separated tokens @@ -1957,14 +1957,14 @@ SPIBaselineShift::read( gchar const *str ) { if( !str ) return; if (!strcmp(str, "inherit")) { - set = TRUE; - inherit = TRUE; + set = true; + inherit = true; } else if ((*str == 'b') || (*str == 's')) { // baseline or sub or super for (unsigned i = 0; enum_baseline_shift[i].key; i++) { if (!strcmp(str, enum_baseline_shift[i].key)) { - set = TRUE; - inherit = FALSE; + set = true; + inherit = false; type = SP_BASELINE_SHIFT_LITERAL; literal = enum_baseline_shift[i].value; return; -- cgit v1.2.3 From 8968a706971ba63e91ffe3704ee9a594d7a9b189 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 9 May 2014 15:05:08 +0200 Subject: Style rewrite: correct 'text-decoration' CSS2 vs CSS3 behavior. (bzr r13344) --- src/style-internal.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index c74683a7a..bfe708e7a 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -2425,11 +2425,21 @@ SPITextDecoration::read( gchar const *str ) { free(frag); if( style->text_decoration_color.set ) break; style->text_decoration_color.read( "currentColor" ); // Default value + style->text_decoration_color.set = false; if( *str == '\0' )break; hstr = str + 1; } str++; } + + // If we read a style or color then we have CSS3 which require any non-set values to be + // set to their default values. + if( style->text_decoration_style.set == true || + style->text_decoration_style.set == true ) { + style->text_decoration_line.set = true; + style->text_decoration_style.set = true; + style->text_decoration_color.set = true; + } } // Returns CSS2 'text-decoration' (using settings in SPTextDecorationLine) -- cgit v1.2.3 From d9496e287b19b63ad567b2ef95bc97f5b3100f6f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 9 May 2014 15:06:22 +0200 Subject: Style rewrite: Correct 'text-decoration' CSS2 vs. CSS3 behavior. (bzr r13341.1.3) --- src/style-internal.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index c74683a7a..bfe708e7a 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -2425,11 +2425,21 @@ SPITextDecoration::read( gchar const *str ) { free(frag); if( style->text_decoration_color.set ) break; style->text_decoration_color.read( "currentColor" ); // Default value + style->text_decoration_color.set = false; if( *str == '\0' )break; hstr = str + 1; } str++; } + + // If we read a style or color then we have CSS3 which require any non-set values to be + // set to their default values. + if( style->text_decoration_style.set == true || + style->text_decoration_style.set == true ) { + style->text_decoration_line.set = true; + style->text_decoration_style.set = true; + style->text_decoration_color.set = true; + } } // Returns CSS2 'text-decoration' (using settings in SPTextDecorationLine) -- cgit v1.2.3 From 7e2ba3db2f8ff62444843af7983d59eff629151c Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sat, 10 May 2014 10:11:01 +0200 Subject: Adding new INKSCAPE_PROFILE_DIR environment variable (see bug #1247448, environment variable INKSCAPE_PORTABLE_PROFILE_DIR should be documented in man page). Fixed bugs: - https://launchpad.net/bugs/1247448 (bzr r13346) --- src/inkscape.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 54451aba4..4b4c8c678 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -1445,6 +1445,11 @@ profile_path(const char *filename) if (val) { prefdir = g_strdup(val); } + // Then check for a custom user environment variable + gchar const *userenv = g_getenv("INKSCAPE_PROFILE_DIR"); + if (userenv) { + prefdir = g_strdup(userenv); + } #ifdef HAS_SHGetSpecialFolderLocation // prefer c:\Documents and Settings\UserName\Application Data\ to -- cgit v1.2.3 From 9a1a8cfc1dd26f094a6c2dce291b50ba00fe2e5b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 10 May 2014 12:19:43 +0200 Subject: Style rewrite: 'text-decoration' requires access to style of ancestor element which set property. (bzr r13348) --- src/style-internal.cpp | 20 ++++++++++++++++---- src/style-internal.h | 12 ++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index bfe708e7a..508fb677c 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -2440,6 +2440,11 @@ SPITextDecoration::read( gchar const *str ) { style->text_decoration_style.set = true; style->text_decoration_color.set = true; } + + // If we set text_decoration_line, then update style_td (for CSS2 text-decoration) + if( style->text_decoration_line.set == true ) { + style_td = style; + } } // Returns CSS2 'text-decoration' (using settings in SPTextDecorationLine) @@ -2474,10 +2479,17 @@ SPITextDecoration::write( guint const flags, SPIBase const *const base) const { return Glib::ustring(""); } -// Done in SPITextDecorationLine -// void -// SPITextDecoration::cascade( const SPIBase* const parent ) { -// } +void +SPITextDecoration::cascade( const SPIBase* const parent ) { + if( const SPITextDecoration* p = dynamic_cast(parent) ) { + if( style_td == NULL ) { + style_td = p->style_td; + } + } else { + std::cerr << "SPITextDecoration::cascade(): Incorrect parent type" << std::endl; + } + +} // void // SPITextDecoration::merge( const SPIBase* const parent ) { diff --git a/src/style-internal.h b/src/style-internal.h index e9cf6e604..a806afc81 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -837,19 +837,20 @@ class SPITextDecorationStyle : public SPIBase { // the right style. (See http://www.w3.org/TR/css-text-decor-3/#text-decoration-property ) /// Text decoration type internal to SPStyle. -class SPITextDecoration: public SPIBase { +class SPITextDecoration : public SPIBase { public: - SPITextDecoration() : SPIBase( "text-decoration" ) {}; + SPITextDecoration() : SPIBase( "text-decoration" ), style_td( NULL ) {}; virtual ~SPITextDecoration() {}; virtual void read( gchar const *str ); virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, SPIBase const *const base = NULL ) const; virtual void clear() { SPIBase::clear(); + style_td = NULL; }; - virtual void cascade( const SPIBase* const parent ) {}; // Done in SPITextDecorationLine - virtual void merge( const SPIBase* const parent ) {}; // Done in SPITextDecorationLine + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ) {}; // FIX ME SPITextDecoration& operator=(const SPITextDecoration& rhs) { SPIBase::operator=(rhs); @@ -859,6 +860,9 @@ class SPITextDecoration: public SPIBase { // Use CSS2 value virtual bool operator==(const SPIBase& rhs); virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + public: + SPStyle* style_td; // Style to be used for drawing CSS2 text decorations }; -- cgit v1.2.3 From 4302660fe98b575843bde77a0d7ded72920a701c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 10 May 2014 12:32:28 +0200 Subject: Style rewrite: 'text-decoration' requires access to style of ancestor element which set property. (bzr r13341.1.4) --- src/style-internal.cpp | 20 ++++++++++++++++---- src/style-internal.h | 12 ++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index bfe708e7a..508fb677c 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -2440,6 +2440,11 @@ SPITextDecoration::read( gchar const *str ) { style->text_decoration_style.set = true; style->text_decoration_color.set = true; } + + // If we set text_decoration_line, then update style_td (for CSS2 text-decoration) + if( style->text_decoration_line.set == true ) { + style_td = style; + } } // Returns CSS2 'text-decoration' (using settings in SPTextDecorationLine) @@ -2474,10 +2479,17 @@ SPITextDecoration::write( guint const flags, SPIBase const *const base) const { return Glib::ustring(""); } -// Done in SPITextDecorationLine -// void -// SPITextDecoration::cascade( const SPIBase* const parent ) { -// } +void +SPITextDecoration::cascade( const SPIBase* const parent ) { + if( const SPITextDecoration* p = dynamic_cast(parent) ) { + if( style_td == NULL ) { + style_td = p->style_td; + } + } else { + std::cerr << "SPITextDecoration::cascade(): Incorrect parent type" << std::endl; + } + +} // void // SPITextDecoration::merge( const SPIBase* const parent ) { diff --git a/src/style-internal.h b/src/style-internal.h index e9cf6e604..a806afc81 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -837,19 +837,20 @@ class SPITextDecorationStyle : public SPIBase { // the right style. (See http://www.w3.org/TR/css-text-decor-3/#text-decoration-property ) /// Text decoration type internal to SPStyle. -class SPITextDecoration: public SPIBase { +class SPITextDecoration : public SPIBase { public: - SPITextDecoration() : SPIBase( "text-decoration" ) {}; + SPITextDecoration() : SPIBase( "text-decoration" ), style_td( NULL ) {}; virtual ~SPITextDecoration() {}; virtual void read( gchar const *str ); virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, SPIBase const *const base = NULL ) const; virtual void clear() { SPIBase::clear(); + style_td = NULL; }; - virtual void cascade( const SPIBase* const parent ) {}; // Done in SPITextDecorationLine - virtual void merge( const SPIBase* const parent ) {}; // Done in SPITextDecorationLine + virtual void cascade( const SPIBase* const parent ); + virtual void merge( const SPIBase* const parent ) {}; // FIX ME SPITextDecoration& operator=(const SPITextDecoration& rhs) { SPIBase::operator=(rhs); @@ -859,6 +860,9 @@ class SPITextDecoration: public SPIBase { // Use CSS2 value virtual bool operator==(const SPIBase& rhs); virtual bool operator!=(const SPIBase& rhs) { return !(*this == rhs); }; + + public: + SPStyle* style_td; // Style to be used for drawing CSS2 text decorations }; -- cgit v1.2.3 From 0a3de4794a6fa71b4c6b4217d42115001503013e Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 10 May 2014 09:47:56 -0400 Subject: Fix stubborn bug 1299948 Fixed bugs: - https://launchpad.net/bugs/1299948 (bzr r13090.1.74) --- src/live_effects/parameter/path.cpp | 5 +++++ src/sp-path.cpp | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index cdbbef1db..44d414942 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -118,6 +118,11 @@ PathParam::param_readSVGValue(const gchar * strvalue) // Now do the attaching, which emits the changed signal. try { ref.attach(Inkscape::URI(href)); + //lp:1299948 + SPItem* i = ref.getObject(); + if (i) { + linked_modified_callback(i, SP_OBJECT_MODIFIED_FLAG); + } // else: document still processing new events. Repr of the linked object not created yet. } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); ref.detach(); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index cbb61b0f6..d1fb850e1 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -140,7 +140,22 @@ void SPPath::build(SPDocument *document, Inkscape::XML::Node *repr) { SPShape::build(document, repr); - this->readAttr( "inkscape:original-d" ); + //this->readAttr( "inkscape:original-d" ); //lp1299948 + if (gchar const* s = this->getRepr()->attribute("inkscape:original-d")) + { + //write it to XML, and to my curve, but don't update patheffects + Geom::PathVector pv = sp_svg_read_pathv(s); + SPCurve *curve = new SPCurve(pv); + + if (_curve_before_lpe) { + _curve_before_lpe = _curve_before_lpe->unref(); + } + + if (curve) { + _curve_before_lpe = curve->ref(); + } + //this->getRepr()->setAttribute("inkscape:original-d", s); + } this->readAttr( "d" ); /* d is a required attribute */ @@ -314,7 +329,6 @@ g_message("sp_path_update_patheffect"); #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); #endif - if (_curve) { gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); repr->setAttribute("d", str); -- cgit v1.2.3 From 4038de8b4763974c97aa8fcb9d87b83c1a5daac7 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 10 May 2014 15:16:24 -0400 Subject: Add selection sets (bzr r13090.1.75) --- src/Makefile_insert | 3 + src/attributes.cpp | 1 + src/attributes.h | 1 + src/menus-skeleton.h | 1 + src/sp-tag-use-reference.cpp | 156 +++++ src/sp-tag-use-reference.h | 77 +++ src/sp-tag-use.cpp | 205 +++++++ src/sp-tag-use.h | 54 ++ src/sp-tag.cpp | 154 +++++ src/sp-tag.h | 57 ++ src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/dialog-manager.cpp | 6 +- src/ui/dialog/tags.cpp | 1155 ++++++++++++++++++++++++++++++++++++++ src/ui/dialog/tags.h | 181 ++++++ src/verbs.cpp | 86 ++- src/verbs.h | 4 +- 16 files changed, 2134 insertions(+), 9 deletions(-) create mode 100644 src/sp-tag-use-reference.cpp create mode 100644 src/sp-tag-use-reference.h create mode 100644 src/sp-tag-use.cpp create mode 100644 src/sp-tag-use.h create mode 100644 src/sp-tag.cpp create mode 100644 src/sp-tag.h create mode 100644 src/ui/dialog/tags.cpp create mode 100644 src/ui/dialog/tags.h (limited to 'src') diff --git a/src/Makefile_insert b/src/Makefile_insert index 6d0d6b08c..810f706ac 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -199,6 +199,9 @@ ink_common_sources += \ sp-style-elem.cpp sp-style-elem.h \ sp-switch.cpp sp-switch.h \ sp-symbol.cpp sp-symbol.h \ + sp-tag.cpp sp-tag.h \ + sp-tag-use.cpp sp-tag-use.h \ + sp-tag-use-reference.cpp sp-tag-use-reference.h \ sp-text.cpp sp-text.h \ sp-textpath.h \ sp-title.cpp sp-title.h \ diff --git a/src/attributes.cpp b/src/attributes.cpp index 4e39b648e..2dc0d8071 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -52,6 +52,7 @@ static SPStyleProp const props[] = { {SP_ATTR_XLINK_ACTUATE, "xlink:actuate"}, {SP_ATTR_TARGET, "target"}, {SP_ATTR_INKSCAPE_GROUPMODE, "inkscape:groupmode"}, + {SP_ATTR_INKSCAPE_EXPANDED, "inkscape:expanded"}, /* SPRoot */ {SP_ATTR_VERSION, "version"}, {SP_ATTR_WIDTH, "width"}, diff --git a/src/attributes.h b/src/attributes.h index d1c93b819..270296c9a 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -52,6 +52,7 @@ enum SPAttributeEnum { SP_ATTR_TARGET, /* SPGroup */ SP_ATTR_INKSCAPE_GROUPMODE, + SP_ATTR_INKSCAPE_EXPANDED, /* SPRoot */ SP_ATTR_VERSION, SP_ATTR_WIDTH, diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index 67e600edf..18a26d82c 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -179,6 +179,7 @@ static char const menus_skeleton[] = " \n" " \n" " \n" +" \n" " \n" " \n" " \n" diff --git a/src/sp-tag-use-reference.cpp b/src/sp-tag-use-reference.cpp new file mode 100644 index 000000000..50c011812 --- /dev/null +++ b/src/sp-tag-use-reference.cpp @@ -0,0 +1,156 @@ +/* + * The reference corresponding to href of element. + * + * Copyright (C) Theodore Janeczko 2012-2014 + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include +#include +#include + +#include "enums.h" +#include "sp-tag-use-reference.h" + +#include "display/curve.h" +#include "livarot/Path.h" +#include "preferences.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "uri.h" + +#if 0 +namespace { + SPObject* createTagUseReference() { + return new SPTag(); + } + bool tagUseReferencesRegistered = SPFactory::instance().registerObject("inkscape:tag", createTag); +} +// this SPObject doesn't need to be registered +#endif + + +bool SPTagUseReference::_acceptObject(SPObject * const obj) const +{ + if (SP_IS_ITEM(obj)) { + SPObject * const owner = getOwner(); + // Refuse references to us or to an ancestor. + for ( SPObject *iter = owner ; iter ; iter = iter->parent ) { + if ( iter == obj ) { + return false; + } + } + return true; + } else { + return false; + } +} + + +static void sp_usepath_href_changed(SPObject *old_ref, SPObject *ref, SPTagUsePath *offset); +static void sp_usepath_delete_self(SPObject *deleted, SPTagUsePath *offset); + +SPTagUsePath::SPTagUsePath(SPObject* i_owner):SPTagUseReference(i_owner) +{ + owner=i_owner; + originalPath = NULL; + sourceDirty=false; + sourceHref = NULL; + sourceRepr = NULL; + sourceObject = NULL; + _changed_connection = changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_usepath_href_changed), this)); // listening to myself, this should be virtual instead + + user_unlink = NULL; +} + +SPTagUsePath::~SPTagUsePath(void) +{ + delete originalPath; + originalPath = NULL; + + _changed_connection.disconnect(); // to do before unlinking + + quit_listening(); + unlink(); +} + +void +SPTagUsePath::link(char *to) +{ + if ( to == NULL ) { + quit_listening(); + unlink(); + } else { + if ( !sourceHref || ( strcmp(to, sourceHref) != 0 ) ) { + g_free(sourceHref); + sourceHref = g_strdup(to); + try { + attach(Inkscape::URI(to)); + } catch (Inkscape::BadURIException &e) { + /* TODO: Proper error handling as per + * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. + */ + g_warning("%s", e.what()); + detach(); + } + } + } +} + +void +SPTagUsePath::unlink(void) +{ + g_free(sourceHref); + sourceHref = NULL; + detach(); +} + +void +SPTagUsePath::start_listening(SPObject* to) +{ + if ( to == NULL ) { + return; + } + sourceObject = to; + sourceRepr = to->getRepr(); + _delete_connection = to->connectDelete(sigc::bind(sigc::ptr_fun(&sp_usepath_delete_self), this)); +} + +void +SPTagUsePath::quit_listening(void) +{ + if ( sourceObject == NULL ) { + return; + } + _delete_connection.disconnect(); + sourceRepr = NULL; + sourceObject = NULL; +} + +static void +sp_usepath_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPTagUsePath *offset) +{ + offset->quit_listening(); + SPItem *refobj = offset->getObject(); + if ( refobj ) { + offset->start_listening(refobj); + } +} + +static void +sp_usepath_delete_self(SPObject */*deleted*/, SPTagUsePath *offset) +{ + offset->owner->deleteObject(); +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use-reference.h b/src/sp-tag-use-reference.h new file mode 100644 index 000000000..b38e45837 --- /dev/null +++ b/src/sp-tag-use-reference.h @@ -0,0 +1,77 @@ +#ifndef SEEN_SP_TAG_USE_REFERENCE_H +#define SEEN_SP_TAG_USE_REFERENCE_H + +/* + * The reference corresponding to href of element. + * + * Copyright (C) Theodore Janeczko 2012-2014 + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include "sp-object.h" +#include "sp-item.h" +#include +#include +#include + +class Path; + +namespace Inkscape { +namespace XML { + struct Node; +} +} + + +class SPTagUseReference : public Inkscape::URIReference { +public: + SPTagUseReference(SPObject *owner) : URIReference(owner) {} + + SPItem *getObject() const { + return static_cast(URIReference::getObject()); + } + +protected: + virtual bool _acceptObject(SPObject * const obj) const; + +}; + + +class SPTagUsePath : public SPTagUseReference { +public: + Path *originalPath; + bool sourceDirty; + + SPObject *owner; + gchar *sourceHref; + Inkscape::XML::Node *sourceRepr; + SPObject *sourceObject; + + sigc::connection _delete_connection; + sigc::connection _changed_connection; + + SPTagUsePath(SPObject* i_owner); + ~SPTagUsePath(void); + + void link(char* to); + void unlink(void); + void start_listening(SPObject* to); + void quit_listening(void); + void refresh_source(void); + + void (*user_unlink) (SPObject *user); +}; + +#endif /* !SEEN_SP_USE_REFERENCE_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use.cpp b/src/sp-tag-use.cpp new file mode 100644 index 000000000..ffcfcee3e --- /dev/null +++ b/src/sp-tag-use.cpp @@ -0,0 +1,205 @@ +/* + * SVG implementation + * + * Authors: + * Theodore Janeczko + * Liam P White + * + * Copyright (C) Theodore Janeczko 2012-2014 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include +#include "display/drawing-group.h" +#include "attributes.h" +#include "document.h" +#include "uri.h" +#include "xml/repr.h" +#include "preferences.h" +#include "style.h" +#include "sp-factory.h" +#include "sp-symbol.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +namespace { + SPObject* createTagUse() { + return new SPTagUse(); + } + bool tagUseRegistered = SPFactory::instance().registerObject("inkscape:tagref", createTagUse); +} + +SPTagUse::SPTagUse() +{ + href = NULL; + //new (_changed_connection) sigc::connection; + ref = new SPTagUseReference(this); + + _changed_connection = ref->changedSignal().connect(sigc::mem_fun(*this, &SPTagUse::href_changed)); +} + +SPTagUse::~SPTagUse() +{ + + if (child) { + detach(child); + child = NULL; + } + + ref->detach(); + delete ref; + ref = 0; + + _changed_connection.~connection(); //FIXME why? +} + +void +SPTagUse::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + SPObject::build(document, repr); + readAttr( "xlink:href" ); + + // We don't need to create child here: + // reading xlink:href will attach ref, and that will cause the changed signal to be emitted, + // which will call sp_tag_use_href_changed, and that will take care of the child +} + +void +SPTagUse::release() +{ + + if (child) { + detach(child); + child = NULL; + } + + _changed_connection.disconnect(); + + g_free(href); + href = NULL; + + ref->detach(); + + SPObject::release(); +} + +void +SPTagUse::set(unsigned key, gchar const *value) +{ + + switch (key) { + case SP_ATTR_XLINK_HREF: { + if ( value && href && ( strcmp(value, href) == 0 ) ) { + /* No change, do nothing. */ + } else { + g_free(href); + href = NULL; + if (value) { + // First, set the href field, because sp_tag_use_href_changed will need it. + href = g_strdup(value); + + // Now do the attaching, which emits the changed signal. + try { + ref->attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + ref->detach(); + } + } else { + ref->detach(); + } + } + break; + } + + default: + SPObject::set(key, value); + break; + } +} + +Inkscape::XML::Node * +SPTagUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("inkscape:tagref"); + } + + SPObject::write(xml_doc, repr, flags); + + if (ref->getURI()) { + gchar *uri_string = ref->getURI()->toString(); + repr->setAttribute("xlink:href", uri_string); + g_free(uri_string); + } + + return repr; +} + +/** + * Returns the ultimate original of a SPTagUse (i.e. the first object in the chain of its originals + * which is not an SPTagUse). If no original is found, NULL is returned (it is the responsibility + * of the caller to make sure that this is handled correctly). + * + * Note that the returned is the clone object, i.e. the child of an SPTagUse (of the argument one for + * the trivial case) and not the "true original". + */ + +SPItem * SPTagUse::root() +{ + SPObject *orig = child; + while (orig && SP_IS_TAG_USE(orig)) { + orig = SP_TAG_USE(orig)->child; + } + if (!orig || !SP_IS_ITEM(orig)) + return NULL; + return SP_ITEM(orig); +} + +void +SPTagUse::href_changed(SPObject */*old_ref*/, SPObject */*ref*/) +{ + if (href) { + SPItem *refobj = ref->getObject(); + if (refobj) { + Inkscape::XML::Node *childrepr = refobj->getRepr(); + const std::string typeString = NodeTraits::get_type_string(*childrepr); + + SPObject* child_ = SPFactory::instance().createObject(typeString); + if (child_) { + attach(child_, lastChild()); + sp_object_unref(child_, 0); + child_->invoke_build(this->document, childrepr, TRUE); + + } + } + } +} + +SPItem * SPTagUse::get_original() +{ + SPItem *ref_ = NULL; + if (ref) { + ref_ = ref->getObject(); + } + return ref_; +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-tag-use.h b/src/sp-tag-use.h new file mode 100644 index 000000000..8a0c3e7fb --- /dev/null +++ b/src/sp-tag-use.h @@ -0,0 +1,54 @@ +#ifndef __SP_TAG_USE_H__ +#define __SP_TAG_USE_H__ + +/* + * SVG implementation + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "svg/svg-length.h" +#include "sp-object.h" + + +#define SP_TAG_USE(obj) (dynamic_cast (obj)) +#define SP_IS_TAG_USE(obj) (dynamic_cast (obj) != NULL) + +class SPTagUse; +class SPTagUseReference; + +class SPTagUse : public SPObject { + +public: + // item built from the original's repr (the visible clone) + // relative to the SPUse itself, it is treated as a child, similar to a grouped item relative to its group + SPObject *child; + gchar *href; +public: + SPTagUse(); + virtual ~SPTagUse(); + + virtual void build(SPDocument *doc, Inkscape::XML::Node *repr); + virtual void set(unsigned key, gchar const *value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual void release(); + + virtual void href_changed(SPObject* old_ref, SPObject* ref); + + //virtual SPItem* unlink(); + virtual SPItem* get_original(); + virtual SPItem* root(); + + // the reference to the original object + SPTagUseReference *ref; + sigc::connection _changed_connection; +}; + +#endif diff --git a/src/sp-tag.cpp b/src/sp-tag.cpp new file mode 100644 index 000000000..c4b40417f --- /dev/null +++ b/src/sp-tag.cpp @@ -0,0 +1,154 @@ +/** \file + * SVG implementation + * + * Authors: + * Theodore Janeczko + * Liam P. White + * + * Copyright (C) Theodore Janeczko 2012-2014 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "attributes.h" +#include "sp-factory.h" +#include "sp-tag.h" +#include "xml/repr.h" +#include + +namespace { + SPObject* createTag() { + return new SPTag(); + } + bool tagsRegistered = SPFactory::instance().registerObject("inkscape:tag", createTag); +} + +/* + * Move this SPItem into or after another SPItem in the doc + * \param target - the SPItem to move into or after + * \param intoafter - move to after the target (false), move inside (sublayer) of the target (true) + */ +void SPTag::moveTo(SPObject *target, gboolean intoafter) { + + Inkscape::XML::Node *target_ref = ( target ? target->getRepr() : NULL ); + Inkscape::XML::Node *our_ref = getRepr(); + gboolean first = FALSE; + + if (target_ref == our_ref) { + // Move to ourself ignore + return; + } + + if (!target_ref) { + // Assume move to the "first" in the top node, find the top node + target_ref = our_ref; + while (target_ref->parent() != target_ref->root()) { + target_ref = target_ref->parent(); + } + first = TRUE; + } + + if (intoafter) { + // Move this inside of the target at the end + our_ref->parent()->removeChild(our_ref); + target_ref->addChild(our_ref, NULL); + } else if (target_ref->parent() != our_ref->parent()) { + // Change in parent, need to remove and add + our_ref->parent()->removeChild(our_ref); + target_ref->parent()->addChild(our_ref, target_ref); + } else if (!first) { + // Same parent, just move + our_ref->parent()->changeOrder(our_ref, target_ref); + } +} + +/** + * Reads the Inkscape::XML::Node, and initializes SPTag variables. For this to get called, + * our name must be associated with a repr via "sp_object_type_register". Best done through + * sp-object-repr.cpp's repr_name_entries array. + */ +void +SPTag::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + readAttr( "inkscape:expanded" ); + SPObject::build(document, repr); +} + +/** + * Sets a specific value in the SPTag. + */ +void +SPTag::set(unsigned int key, gchar const *value) +{ + + switch (key) + { + case SP_ATTR_INKSCAPE_EXPANDED: + if ( value && !strcmp(value, "true") ) { + setExpanded(true); + } + break; + default: + SPObject::set(key, value); + break; + } +} + +void SPTag::setExpanded(bool isexpanded) { + //if ( _expanded != isexpanded ){ + _expanded = isexpanded; + //} +} + +/** + * Receives update notifications. + */ +void +SPTag::update(SPCtx *ctx, guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + + /* do something to trigger redisplay, updates? */ + + } + SPObject::update(ctx, flags); +} + +/** + * Writes its settings to an incoming repr object, if any. + */ +Inkscape::XML::Node * +SPTag::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) +{ + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = doc->createElement("inkscape:tag"); + } + + // Inkscape-only object, not copied during an "plain SVG" dump: + if (flags & SP_OBJECT_WRITE_EXT) { + if (_expanded) { + repr->setAttribute("inkscape:expanded", "true"); + } else { + repr->setAttribute("inkscape:expanded", NULL); + } + } + SPObject::write(doc, repr, flags); + return repr; +} + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-tag.h b/src/sp-tag.h new file mode 100644 index 000000000..927bb45d1 --- /dev/null +++ b/src/sp-tag.h @@ -0,0 +1,57 @@ +#ifndef SP_TAG_H_SEEN +#define SP_TAG_H_SEEN + +/** \file + * SVG implementation + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" + +/* Skeleton base class */ + +#define SP_TAG(o) (dynamic_cast(o)) +#define SP_IS_TAG(o) (dynamic_cast(o) != NULL) + +class SPTag; + +class SPTag : public SPObject { +public: + SPTag() {} + virtual ~SPTag() {} + + virtual void build(SPDocument * doc, Inkscape::XML::Node *repr); + //virtual void release(); + virtual void set(unsigned key, const gchar* value); + virtual void update(SPCtx * ctx, unsigned flags); + + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + + bool expanded() const { return _expanded; } + void setExpanded(bool isexpanded); + + void moveTo(SPObject *target, gboolean intoafter); + +private: + bool _expanded; +}; + + +#endif /* !SP_SKELETON_H_SEEN */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 8a7a4a5dd..1aa73dc5b 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -100,6 +100,8 @@ ink_common_sources += \ ui/dialog/template-load-tab.h \ ui/dialog/template-widget.cpp \ ui/dialog/template-widget.h \ + ui/dialog/tags.cpp \ + ui/dialpg/tags.h \ ui/dialog/text-edit.cpp \ ui/dialog/text-edit.h \ ui/dialog/tile.cpp \ diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 22c41d75e..bd2f1eb12 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -55,7 +55,7 @@ #include "ui/dialog/clonetiler.h" #include "ui/dialog/svg-fonts-dialog.h" #include "ui/dialog/objects.h" -//#include "ui/dialog/tags.h" +#include "ui/dialog/tags.h" namespace Inkscape { namespace UI { @@ -113,7 +113,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); -// registerFactory("TagsPanel", &create); + registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); @@ -148,7 +148,7 @@ DialogManager::DialogManager() { registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); -// registerFactory("TagsPanel", &create); + registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp new file mode 100644 index 000000000..7fdd2e906 --- /dev/null +++ b/src/ui/dialog/tags.cpp @@ -0,0 +1,1155 @@ +/* + * A simple panel for tags + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "tags.h" +#include +#include +#include +#include + +#include + +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" +#include "inkscape.h" +#include "layer-fns.h" +#include "layer-manager.h" +#include "preferences.h" +#include "sp-item.h" +#include "sp-object.h" +#include "sp-shape.h" +#include "svg/css-ostringstream.h" +#include "ui/icon-names.h" +#include "ui/widget/layertypeicon.h" +#include "ui/widget/addtoicon.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/node.h" +#include "xml/node-observer.h" +#include "xml/repr.h" +#include "sp-root.h" +#include "ui/tools/tool-base.h" //"event-context.h" +#include "selection.h" +#include "dialogs/dialog-events.h" +#include "widgets/sp-color-notebook.h" +#include "style.h" +#include "filter-chemistry.h" +#include "filters/blend.h" +#include "filters/gaussian-blur.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-tag.h" +#include "sp-defs.h" +#include "sp-tag-use.h" +#include "sp-tag-use-reference.h" + +//#define DUMP_LAYERS 1 + +namespace Inkscape { +namespace UI { +namespace Dialog { + +using Inkscape::XML::Node; + +TagsPanel& TagsPanel::getInstance() +{ + return *new TagsPanel(); +} + +enum { + COL_ADD = 1 +}; + +enum { + BUTTON_NEW = 0, + BUTTON_TOP, + BUTTON_BOTTOM, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_DELETE, + DRAGNDROP +}; + +class TagsPanel::ObjectWatcher : public Inkscape::XML::NodeObserver { +public: + ObjectWatcher(TagsPanel* pnl, SPObject* obj, Inkscape::XML::Node * repr) : + _pnl(pnl), + _obj(obj), + _repr(repr), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + ObjectWatcher(TagsPanel* pnl, SPObject* obj) : + _pnl(pnl), + _obj(obj), + _repr(obj->getRepr()), + _labelAttr(g_quark_from_string("inkscape:label")) + {} + + virtual void notifyChildAdded( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildRemoved( Node &/*node*/, Node &/*child*/, Node */*prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyChildOrderChanged( Node &/*node*/, Node &/*child*/, Node */*old_prev*/, Node */*new_prev*/ ) + { + if ( _pnl && _obj ) { + _pnl->_objectsChanged( _obj ); + } + } + virtual void notifyContentChanged( Node &/*node*/, Util::ptr_shared /*old_content*/, Util::ptr_shared /*new_content*/ ) {} + virtual void notifyAttributeChanged( Node &/*node*/, GQuark name, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) { + if ( _pnl && _obj ) { + if ( name == _labelAttr ) { + _pnl->_updateObject( _obj); + } + } + } + + TagsPanel* _pnl; + SPObject* _obj; + Inkscape::XML::Node* _repr; + GQuark _labelAttr; +}; + +class TagsPanel::InternalUIBounce +{ +public: + int _actionCode; +}; + +void TagsPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ) +{ + bool set = false; + + if ( iconName ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + btn.set_relief(Gtk::RELIEF_NONE); + set = true; + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !set && action && action->image ) { + GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); + gtk_widget_show( child ); + btn.add( *manage(Glib::wrap(child)) ); + set = true; + } + } + } + + btn.set_tooltip_text (tooltip); +} + + +Gtk::MenuItem& TagsPanel::_addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ) +{ + GtkWidget* iconWidget = 0; + const char* label = 0; + + if ( iconName ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, iconName ); + } + + if ( desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(desktop); + if ( !iconWidget && action && action->image ) { + iconWidget = sp_icon_new( Inkscape::ICON_SIZE_MENU, action->image ); + } + + if ( action ) { + label = action->name; + } + } + } + + if ( !label && fallback ) { + label = fallback; + } + + Gtk::Widget* wrapped = 0; + if ( iconWidget ) { + wrapped = manage(Glib::wrap(iconWidget)); + wrapped->show(); + } + + + Gtk::MenuItem* item = 0; + + if (wrapped) { + item = Gtk::manage(new Gtk::ImageMenuItem(*wrapped, label, true)); + } else { + item = Gtk::manage(new Gtk::MenuItem(label, true)); + } + + item->signal_activate().connect(sigc::bind(sigc::mem_fun(*this, &TagsPanel::_takeAction), id)); + _popupMenu.append(*item); + + return *item; +} + +void TagsPanel::_fireAction( unsigned int code ) +{ + if ( _desktop ) { + Verb *verb = Verb::get( code ); + if ( verb ) { + SPAction *action = verb->get_action(_desktop); + if ( action ) { + sp_action_perform( action, NULL ); + } + } + } +} + +void TagsPanel::_takeAction( int val ) +{ + if ( !_pending ) { + _pending = new InternalUIBounce(); + _pending->_actionCode = val; + Glib::signal_timeout().connect( sigc::mem_fun(*this, &TagsPanel::_executeAction), 0 ); + } +} + +bool TagsPanel::_executeAction() +{ + // Make sure selected layer hasn't changed since the action was triggered + if ( _pending) + { + int val = _pending->_actionCode; +// SPObject* target = _pending->_target; + bool empty = _desktop->selection->isEmpty(); + + switch ( val ) { + case BUTTON_NEW: + { + _fireAction( SP_VERB_TAG_NEW ); + } + break; + case BUTTON_TOP: + { + _fireAction( empty ? SP_VERB_LAYER_TO_TOP : SP_VERB_SELECTION_TO_FRONT); + } + break; + case BUTTON_BOTTOM: + { + _fireAction( empty ? SP_VERB_LAYER_TO_BOTTOM : SP_VERB_SELECTION_TO_BACK ); + } + break; + case BUTTON_UP: + { + _fireAction( empty ? SP_VERB_LAYER_RAISE : SP_VERB_SELECTION_RAISE ); + } + break; + case BUTTON_DOWN: + { + _fireAction( empty ? SP_VERB_LAYER_LOWER : SP_VERB_SELECTION_LOWER ); + } + break; + case BUTTON_DELETE: + { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + break; + case DRAGNDROP: + { + _doTreeMove( ); + } + break; + } + + delete _pending; + _pending = 0; + } + + return false; +} + + +class TagsPanel::ModelColumns : public Gtk::TreeModel::ColumnRecord +{ +public: + + ModelColumns() + { + add(_colParentObject); + add(_colObject); + add(_colLabel); + add(_colAddRemove); + add(_colAllowAddRemove); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn _colParentObject; + Gtk::TreeModelColumn _colObject; + Gtk::TreeModelColumn _colLabel; + Gtk::TreeModelColumn _colAddRemove; + Gtk::TreeModelColumn _colAllowAddRemove; +}; + +void TagsPanel::_checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete) +{ + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && obj->parent) { + todelete->push_back(obj); + } +} + +void TagsPanel::_updateObject( SPObject *obj ) { + _store->foreach( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_checkForUpdated), obj) ); +} + +bool TagsPanel::_checkForUpdated(const Gtk::TreePath &/*path*/, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + if ( obj == row[_model->_colObject] ) + { + /* + * We get notified of layer update here (from layer->setLabel()) before layer->label() is set + * with the correct value (sp-object bug?). So use the inkscape:label attribute instead which + * has the correct value (bug #168351) + */ + //row[_model->_colLabel] = layer->label() ? layer->label() : layer->getId(); + gchar const *label; + SPTagUse * use = SP_IS_TAG_USE(obj) ? SP_TAG_USE(obj) : 0; + if (use && use->ref->isAttached()) { + label = use->ref->getObject()->getAttribute("inkscape:label"); + } else { + label = obj->getAttribute("inkscape:label"); + } + row[_model->_colLabel] = label ? label : obj->getId(); + row[_model->_colAddRemove] = SP_IS_TAG(obj); + } + + return false; +} + +void TagsPanel::_objectsSelected( Selection *sel ) { + + _selectedConnection.block(); + _tree.get_selection()->unselect_all(); + for (const GSList * iter = sel->list(); iter != NULL; iter = iter->next) + { + SPObject *obj = reinterpret_cast(iter->data); + _store->foreach(sigc::bind( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); + } + _selectedConnection.unblock(); + _checkTreeSelection(); +} + +bool TagsPanel::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj) +{ + Gtk::TreeModel::Row row = *iter; + SPObject * it = row[_model->_colObject]; + if ( it && SP_IS_TAG_USE(it) && SP_TAG_USE(it)->ref->getObject() == obj ) + { + Glib::RefPtr select = _tree.get_selection(); + + select->select(iter); + } + return false; +} + +void TagsPanel::_objectsChanged(SPObject* root) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_desktop) { + SPDocument* document = _desktop->doc(); + SPDefs* root = document->getDefs(); + if ( root ) { + _selectedConnection.block(); + _store->clear(); + _addObject( document, root, 0 ); + _selectedConnection.unblock(); + _objectsSelected(_desktop->selection); + _checkTreeSelection(); + } + } +} + +void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) +{ + if ( _desktop && obj ) { + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG(child)) + { + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colAddRemove] = true; + row[_model->_colAllowAddRemove] = true; + + _tree.expand_to_path( _store->get_path(iter) ); + + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); + child->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + _addObject( doc, child, &row ); + } + } + if (SP_IS_TAG(obj) && obj->children) + { + Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row rowitems = *iteritems; + rowitems[_model->_colObject] = NULL; + rowitems[_model->_colParentObject] = obj; + rowitems[_model->_colLabel] = _("Items"); + rowitems[_model->_colAddRemove] = false; + rowitems[_model->_colAllowAddRemove] = false; + + _tree.expand_to_path( _store->get_path(iteritems) ); + + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child)) + { + SPItem *item = SP_TAG_USE(child)->ref->getObject(); + Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colParentObject] = NULL; + row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; + row[_model->_colAddRemove] = false; + row[_model->_colAllowAddRemove] = true; + + if (SP_TAG(obj)->expanded()) { + _tree.expand_to_path( _store->get_path(iter) ); + } + + if (item) { + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); + item->getRepr()->addObserver(*w); + _objectWatchers.push_back(w); + } + } + } + } + } +} + +void TagsPanel::_select_tag( SPTag * tag ) +{ + for (SPObject * child = tag->children; child != NULL; child = child->next) + { + if (SP_IS_TAG(child)) { + _select_tag(SP_TAG(child)); + } else if (SP_IS_TAG_USE(child)) { + SPObject * obj = SP_TAG_USE(child)->ref->getObject(); + if (obj) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); + _desktop->selection->add(obj); + } + } + } +} + +void TagsPanel::_selected_row_callback( const Gtk::TreeModel::iterator& iter ) +{ + if (iter) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _select_tag(SP_TAG(obj)); + } else if (SP_IS_TAG_USE(obj)) { + SPObject * item = SP_TAG_USE(obj)->ref->getObject(); + if (item) { + if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(item->parent); + _desktop->selection->add(item); + } + } + } + } +} + +void TagsPanel::_pushTreeSelectionToCurrent() +{ + _selectionChangedConnection.block(); + // TODO hunt down the possible API abuse in getting NULL + if ( _desktop && _desktop->currentRoot() ) { + _desktop->selection->clear(); + _tree.get_selection()->selected_foreach_iter( sigc::mem_fun(*this, &TagsPanel::_selected_row_callback)); + } + _selectionChangedConnection.unblock(); + + _checkTreeSelection(); +} + +void TagsPanel::_checkTreeSelection() +{ + bool sensitive = _tree.get_selection()->count_selected_rows() > 0; + bool sensitiveNonTop = true; + bool sensitiveNonBottom = true; +// if ( _tree.get_selection()->count_selected_rows() > 0 ) { +// sensitive = true; +// +// SPObject* inTree = _selectedLayer(); +// if ( inTree ) { +// +// sensitiveNonTop = (Inkscape::Nex(inTree->parent, inTree) != 0); +// sensitiveNonBottom = (Inkscape::previous_layer(inTree->parent, inTree) != 0); +// +// } +// } + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( sensitive ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonTop ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( sensitiveNonBottom ); + } +} + +bool TagsPanel::_handleKeyEvent(GdkEventKey *event) +{ + + switch (Inkscape::UI::Tools::get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + case GDK_KEY_F2: { + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if (iter && !_text_renderer->property_editable()) { + Gtk::TreeRow row = *iter; + SPObject * obj = row[_model->_colObject]; + if (obj && SP_IS_TAG(obj)) { + Gtk::TreeModel::Path *path = new Gtk::TreeModel::Path(iter); + // Edit the layer label + _text_renderer->property_editable() = true; + _tree.set_cursor(*path, *_name_column, true); + grab_focus(); + return true; + } + } + } + case GDK_KEY_Delete: { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * obj = *iter; + if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + return true; + } + break; + } + return false; +} + +bool TagsPanel::_handleButtonEvent(GdkEventButton* event) +{ + static unsigned doubleclick = 0; + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 3) ) { + // TODO - fix to a better is-popup function + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + if ( _tree.get_path_at_pos( x, y, path ) ) { + _checkTreeSelection(); + _popupMenu.popup(event->button, event->time); + if (_tree.get_selection()->is_selected(path)) { + return true; + } + } + } + + if ( (event->type == GDK_BUTTON_PRESS) && (event->button == 1)) { + // Alt left click on the visible/lock columns - eat this event to keep row selection + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (col == _tree.get_column(COL_ADD-1)) { + down_at_add = true; + return true; + } else if ( !(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) & _tree.get_selection()->is_selected(path) ) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_noSelection)); + _defer_target = path; + } else { + down_at_add = false; + } + } else { + down_at_add = false; + } + } + + if ( event->type == GDK_BUTTON_RELEASE) { + _tree.get_selection()->set_select_function(sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction)); + } + + // TODO - ImageToggler doesn't seem to handle Shift/Alt clicks - so we deal with them here. + if ( (event->type == GDK_BUTTON_RELEASE) && (event->button == 1)) { + + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) ) { + if (_defer_target) { + if (_defer_target == path && !(event->x == 0 && event->y == 0)) + { + _tree.set_cursor(path, *col, false); + } + _defer_target = Gtk::TreeModel::Path(); + } else { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + + if (obj) { + if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { + if (SP_IS_TAG(obj)) { + bool wasadded = false; + for (const GSList * iter = _desktop->selection->itemList(); iter != NULL; iter = iter->next) + { + SPObject *newobj = reinterpret_cast(iter->data); + bool addchild = true; + for ( SPObject *child = obj->children; child != NULL; child = child->next) { + if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { + addchild = false; + } + } + if (addchild) { + Inkscape::XML::Node *clone = _document->getReprDoc()->createElement("inkscape:tagref"); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", newobj->getRepr()->attribute("id")), false); + obj->appendChild(clone); + wasadded = true; + } + } + if (wasadded) { + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Add selection to set")); + } + } else { + std::vector todelete; + _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); + if (!todelete.empty()) { + for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { + SPObject * tobj = *iter; + if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { + tobj->parent->getRepr()->removeChild(tobj->getRepr()); + } + } + } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { + obj->parent->getRepr()->removeChild(obj->getRepr()); + } + DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); + } + } + } + } + } + } + + + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + doubleclick = 1; + } + + if ( event->type == GDK_BUTTON_RELEASE && doubleclick) { + doubleclick = 0; + Gtk::TreeModel::Path path; + Gtk::TreeViewColumn* col = 0; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + if ( _tree.get_path_at_pos( x, y, path, col, x2, y2 ) && col == _name_column) { + Gtk::TreeModel::Children::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colObject]; + if (obj && (SP_IS_TAG(obj) || (SP_IS_TAG_USE(obj) && SP_TAG_USE(obj)->ref->getObject()))) { + // Double click on the Layer name, enable editing + _text_renderer->property_editable() = true; + _tree.set_cursor (path, *_name_column, true); + grab_focus(); + } + } + } + + return false; +} + +void TagsPanel::_storeDragSource(const Gtk::TreeModel::iterator& iter) +{ + Gtk::TreeModel::Row row = *iter; + SPObject* obj = row[_model->_colObject]; + SPTag* item = ( obj && SP_IS_TAG(obj) ) ? SP_TAG(obj) : 0; + if (item) + { + _dnd_source.push_back(item); + } +} + +/* + * Drap and drop within the tree + * Save the drag source and drop target SPObjects and if its a drag between layers or into (sublayer) a layer + */ +bool TagsPanel::_handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time) +{ + int cell_x = 0, cell_y = 0; + Gtk::TreeModel::Path target_path; + Gtk::TreeView::Column *target_column; + + _dnd_into = true; + _dnd_target = _document->getDefs(); + _dnd_source.clear(); + _tree.get_selection()->selected_foreach_iter(sigc::mem_fun(*this, &TagsPanel::_storeDragSource)); + + if (_dnd_source.empty()) { + return true; + } + + if (_tree.get_path_at_pos (x, y, target_path, target_column, cell_x, cell_y)) { + // Are we before, inside or after the drop layer + Gdk::Rectangle rect; + _tree.get_background_area (target_path, *target_column, rect); + int cell_height = rect.get_height(); + _dnd_into = (cell_y > (int)(cell_height * 1/3) && cell_y <= (int)(cell_height * 2/3)); + if (cell_y > (int)(cell_height * 2/3)) { + Gtk::TreeModel::Path next_path = target_path; + next_path.next(); + if (_store->iter_is_valid(_store->get_iter(next_path))) { + target_path = next_path; + } else { + // Dragging to the "end" + Gtk::TreeModel::Path up_path = target_path; + up_path.up(); + if (_store->iter_is_valid(_store->get_iter(up_path))) { + // Drop into parent + target_path = up_path; + _dnd_into = true; + } else { + // Drop into the top level + _dnd_target = _document->getDefs(); + _dnd_into = true; + } + } + } + Gtk::TreeModel::iterator iter = _store->get_iter(target_path); + if (_store->iter_is_valid(iter)) { + Gtk::TreeModel::Row row = *iter; + SPObject *obj = row[_model->_colObject]; + SPObject *pobj = row[_model->_colParentObject]; + if (obj) { + if (SP_IS_TAG(obj)) { + _dnd_target = SP_TAG(obj); + } else if (SP_IS_TAG(obj->parent)) { + _dnd_target = SP_TAG(obj->parent); + _dnd_into = true; + } + } else if (pobj && SP_IS_TAG(pobj)) { + _dnd_target = SP_TAG(pobj); + _dnd_into = true; + } else { + return true; + } + } + } + + _takeAction(DRAGNDROP); + + return false; +} + +/* + * Move a layer in response to a drag & drop action + */ +void TagsPanel::_doTreeMove( ) +{ + if (_dnd_target) { + for (std::vector::iterator iter = _dnd_source.begin(); iter != _dnd_source.end(); ++iter) + { + SPTag *src = *iter; + if (src != _dnd_target) { + src->moveTo(_dnd_target, _dnd_into); + } + } + _desktop->selection->clear(); + while (!_dnd_source.empty()) + { + SPTag *src = _dnd_source.back(); + _select_tag(src); + _dnd_source.pop_back(); + } + DocumentUndo::done( _desktop->doc() , SP_VERB_DIALOG_TAGS, + _("Moved sets")); + } +} + + +void TagsPanel::_handleEdited(const Glib::ustring& path, const Glib::ustring& new_text) +{ + Gtk::TreeModel::iterator iter = _tree.get_model()->get_iter(path); + Gtk::TreeModel::Row row = *iter; + + _renameObject(row, new_text); + _text_renderer->property_editable() = false; +} + +void TagsPanel::_handleEditingCancelled() +{ + _text_renderer->property_editable() = false; +} + +void TagsPanel::_renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name) +{ + if ( row && _desktop) { + SPObject* obj = row[_model->_colObject]; + if ( obj ) { + if (SP_IS_TAG(obj)) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } else if (SP_IS_TAG_USE(obj) && (obj = SP_TAG_USE(obj)->ref->getObject())) { + gchar const* oldLabel = obj->label(); + if ( !name.empty() && (!oldLabel || name != oldLabel) ) { + obj->setLabel(name.c_str()); + DocumentUndo::done( _desktop->doc() , SP_VERB_NONE, + _("Rename object")); + } + } + } + } +} + +bool TagsPanel::_noSelection( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + return false; +} + +bool TagsPanel::_rowSelectFunction( Glib::RefPtr const & /*model*/, Gtk::TreeModel::Path const & /*path*/, bool currentlySelected ) +{ + bool val = true; + if ( !currentlySelected && _toggleEvent ) + { + GdkEvent* event = gtk_get_current_event(); + if ( event ) { + // (keep these checks separate, so we know when to call gdk_event_free() + if ( event->type == GDK_BUTTON_PRESS ) { + GdkEventButton const* target = reinterpret_cast(_toggleEvent); + GdkEventButton const* evtb = reinterpret_cast(event); + + if ( (evtb->window == target->window) + && (evtb->send_event == target->send_event) + && (evtb->time == target->time) + && (evtb->state == target->state) + ) + { + // Ooooh! It's a magic one + val = false; + } + } + gdk_event_free(event); + } + } + return val; +} + +void TagsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& /*path*/, bool isexpanded) +{ + Gtk::TreeModel::Row row = *iter; + + SPObject* obj = row[_model->_colParentObject]; + if (obj && SP_IS_TAG(obj)) + { + SP_TAG(obj)->setExpanded(isexpanded); + obj->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); + } +} + +/** + * Constructor + */ +TagsPanel::TagsPanel() : + UI::Widget::Panel("", "/dialogs/tags", SP_VERB_DIALOG_TAGS), + _rootWatcher(0), + deskTrack(), + _desktop(0), + _document(0), + _model(0), + _pending(0), + _toggleEvent(0), + _defer_target(), + desktopChangeConn() +{ + //Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + + _store = Gtk::TreeStore::create( *zoop ); + + _tree.set_model( _store ); + _tree.set_headers_visible(false); + _tree.set_reorderable(true); + _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); + + Inkscape::UI::Widget::AddToIcon * addRenderer = manage( new Inkscape::UI::Widget::AddToIcon()); + int addColNum = _tree.append_column("type", *addRenderer) - 1; + Gtk::TreeViewColumn *col = _tree.get_column(addColNum); + if ( col ) { + col->add_attribute( addRenderer->property_active(), _model->_colAddRemove ); + col->add_attribute( addRenderer->property_visible(), _model->_colAllowAddRemove ); + } + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + + _tree.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectedConnection = _tree.get_selection()->signal_changed().connect( sigc::mem_fun(*this, &TagsPanel::_pushTreeSelectionToCurrent) ); + _tree.get_selection()->set_select_function( sigc::mem_fun(*this, &TagsPanel::_rowSelectFunction) ); + + _tree.signal_drag_drop().connect( sigc::mem_fun(*this, &TagsPanel::_handleDragDrop), false); + _collapsedConnection = _tree.signal_row_collapsed().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), false)); + _expandedConnection = _tree.signal_row_expanded().connect( sigc::bind(sigc::mem_fun(*this, &TagsPanel::_setExpanded), true)); + + _text_renderer->signal_edited().connect( sigc::mem_fun(*this, &TagsPanel::_handleEdited) ); + _text_renderer->signal_editing_canceled().connect( sigc::mem_fun(*this, &TagsPanel::_handleEditingCancelled) ); + + _tree.signal_button_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_button_release_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleButtonEvent), false ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &TagsPanel::_handleKeyEvent), false ); + + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + Gtk::Requisition sreq; +#if WITH_GTKMM_3_0 + Gtk::Requisition sreq_natural; + _scroller.get_preferred_size(sreq_natural, sreq); +#else + sreq = _scroller.size_request(); +#endif + int minHeight = 70; + if (sreq.height < minHeight) { + // Set a min height to see the layers when used with Ubuntu liboverlay-scrollbar + _scroller.set_size_request(sreq.width, minHeight); + } + + _layersPage.pack_start( _scroller, Gtk::PACK_EXPAND_WIDGET ); + + _layersPage.pack_end(_buttonsRow, Gtk::PACK_SHRINK); + + _getContents()->pack_start(_layersPage, Gtk::PACK_EXPAND_WIDGET); + + SPDesktop* targetDesktop = getDesktop(); + + Gtk::Button* btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_TAG_NEW, GTK_STOCK_ADD, _("Add a new selection set") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_NEW) ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + +// btn = manage( new Gtk::Button("Dup") ); +// btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); +// _buttonsRow.add( *btn ); + + btn = manage( new Gtk::Button() ); + _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, GTK_STOCK_REMOVE, _("Remove Item/Set") ); + btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &TagsPanel::_takeAction), (int)BUTTON_DELETE) ); + _watching.push_back( btn ); + _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); + + _buttonsRow.pack_start(_buttonsSecondary, Gtk::PACK_EXPAND_WIDGET); + _buttonsRow.pack_end(_buttonsPrimary, Gtk::PACK_EXPAND_WIDGET); + + // ------------------------------------------------------- + { + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + + _popupMenu.show_all_children(); + } + // ------------------------------------------------------- + + + + for ( std::vector::iterator it = _watching.begin(); it != _watching.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonTop.begin(); it != _watchingNonTop.end(); ++it ) { + (*it)->set_sensitive( false ); + } + for ( std::vector::iterator it = _watchingNonBottom.begin(); it != _watchingNonBottom.end(); ++it ) { + (*it)->set_sensitive( false ); + } + + setDesktop( targetDesktop ); + + show_all_children(); + + // restorePanelPrefs(); + + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &TagsPanel::setDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); +} + +TagsPanel::~TagsPanel() +{ + + setDesktop(NULL); + + if ( _model ) + { + delete _model; + _model = 0; + } + + if (_pending) { + delete _pending; + _pending = 0; + } + + if ( _toggleEvent ) + { + gdk_event_free( _toggleEvent ); + _toggleEvent = 0; + } + + desktopChangeConn.disconnect(); + deskTrack.disconnect(); +} + +void TagsPanel::setDocument(SPDesktop* /*desktop*/, SPDocument* document) +{ + while (!_objectWatchers.empty()) + { + TagsPanel::ObjectWatcher *w = _objectWatchers.back(); + w->_repr->removeObserver(*w); + _objectWatchers.pop_back(); + delete w; + } + + if (_rootWatcher) + { + _rootWatcher->_repr->removeObserver(*_rootWatcher); + delete _rootWatcher; + _rootWatcher = NULL; + } + + _document = document; + + if (document && document->getDefs() && document->getDefs()->getRepr()) + { + _rootWatcher = new TagsPanel::ObjectWatcher(this, document->getDefs()); + document->getDefs()->getRepr()->addObserver(*_rootWatcher); + _objectsChanged(document->getDefs()); + } +} + +void TagsPanel::setDesktop( SPDesktop* desktop ) +{ + Panel::setDesktop(desktop); + + if ( desktop != _desktop ) { + _documentChangedConnection.disconnect(); + _selectionChangedConnection.disconnect(); + if ( _desktop ) { + _desktop = 0; + } + + _desktop = Panel::getDesktop(); + if ( _desktop ) { + //setLabel( _desktop->doc()->name ); + _documentChangedConnection = _desktop->connectDocumentReplaced( sigc::mem_fun(*this, &TagsPanel::setDocument)); + _selectionChangedConnection = _desktop->selection->connectChanged( sigc::mem_fun(*this, &TagsPanel::_objectsSelected)); + + setDocument(_desktop, _desktop->doc()); + } + } +/* + GSList const *layers = _desktop->doc()->getResourceList( "layer" ); + g_message( "layers list starts at %p", layers ); + for ( GSList const *iter=layers ; iter ; iter = iter->next ) { + SPObject *layer=static_cast(iter->data); + g_message(" {%s} [%s]", layer->id, layer->label() ); + } +*/ + deskTrack.setBase(desktop); +} + + + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/tags.h b/src/ui/dialog/tags.h new file mode 100644 index 000000000..d35dfba01 --- /dev/null +++ b/src/ui/dialog/tags.h @@ -0,0 +1,181 @@ +/* + * A simple dialog for tags UI. + * + * Authors: + * Theodore Janeczko + * + * Copyright (C) Theodore Janeczko 2012 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_TAGS_PANEL_H +#define SEEN_TAGS_PANEL_H + +#include +#include +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/panel.h" +#include "ui/widget/object-composite-settings.h" +#include "desktop-tracker.h" +#include "ui/widget/style-subject.h" +#include "selection.h" +#include "ui/widget/filter-effect-chooser.h" + +class SPObject; +class SPTag; +struct SPColorSelector; + +namespace Inkscape { + +namespace UI { +namespace Dialog { + + +/** + * A panel that displays layers. + */ +class TagsPanel : public UI::Widget::Panel +{ +public: + TagsPanel(); + virtual ~TagsPanel(); + + //virtual void setOrientation( Gtk::AnchorType how ); + + static TagsPanel& getInstance(); + + void setDesktop( SPDesktop* desktop ); + void setDocument( SPDesktop* desktop, SPDocument* document); + +protected: + //virtual void _handleAction( int setId, int itemId ); + friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); +private: + class ModelColumns; + class InternalUIBounce; + class ObjectWatcher; + + TagsPanel(TagsPanel const &); // no copy + TagsPanel &operator=(TagsPanel const &); // no assign + + void _styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned int code, char const* iconName, char const* tooltip ); + void _fireAction( unsigned int code ); + Gtk::MenuItem& _addPopupItem( SPDesktop *desktop, unsigned int code, char const* iconName, char const* fallback, int id ); + + bool _handleButtonEvent(GdkEventButton *event); + bool _handleKeyEvent(GdkEventKey *event); + + void _storeDragSource(const Gtk::TreeModel::iterator& iter); + bool _handleDragDrop(const Glib::RefPtr& context, int x, int y, guint time); + void _handleEdited(const Glib::ustring& path, const Glib::ustring& new_text); + void _handleEditingCancelled(); + + void _doTreeMove(); + void _renameObject(Gtk::TreeModel::Row row, const Glib::ustring& name); + + void _pushTreeSelectionToCurrent(); + void _selected_row_callback( const Gtk::TreeModel::iterator& iter ); + void _select_tag( SPTag * tag ); + + void _checkTreeSelection(); + + void _takeAction( int val ); + bool _executeAction(); + + void _setExpanded( const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path, bool isexpanded ); + + bool _noSelection( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + bool _rowSelectFunction( Glib::RefPtr const & model, Gtk::TreeModel::Path const & path, bool b ); + + void _updateObject(SPObject *obj); + bool _checkForUpdated(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPObject* obj); + + void _objectsSelected(Selection *sel); + bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPObject* layer); + + void _objectsChanged(SPObject *root); + void _addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ); + + void _checkForDeleted(const Gtk::TreeIter& iter, std::vector* todelete); + +// std::vector groupConnections; + TagsPanel::ObjectWatcher* _rootWatcher; + std::vector _objectWatchers; + + // Hooked to the layer manager: + sigc::connection _documentChangedConnection; + sigc::connection _selectionChangedConnection; + + sigc::connection _changedConnection; + sigc::connection _addedConnection; + sigc::connection _removedConnection; + + // Internal + sigc::connection _selectedConnection; + sigc::connection _expandedConnection; + sigc::connection _collapsedConnection; + + DesktopTracker deskTrack; + SPDesktop* _desktop; + SPDocument* _document; + ModelColumns* _model; + InternalUIBounce* _pending; + gboolean _dnd_into; + std::vector _dnd_source; + SPObject* _dnd_target; + + GdkEvent* _toggleEvent; + bool down_at_add; + + Gtk::TreeModel::Path _defer_target; + + Glib::RefPtr _store; + std::vector _watching; + std::vector _watchingNonTop; + std::vector _watchingNonBottom; + + Gtk::TreeView _tree; + Gtk::CellRendererText *_text_renderer; + Gtk::TreeView::Column *_name_column; +#if WITH_GTKMM_3_0 + Gtk::Box _buttonsRow; + Gtk::Box _buttonsPrimary; + Gtk::Box _buttonsSecondary; +#else + Gtk::HBox _buttonsRow; + Gtk::HBox _buttonsPrimary; + Gtk::HBox _buttonsSecondary; +#endif + Gtk::ScrolledWindow _scroller; + Gtk::Menu _popupMenu; + Inkscape::UI::Widget::SpinButton _spinBtn; + Gtk::VBox _layersPage; + + sigc::connection desktopChangeConn; + +}; + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_OBJECTS_PANEL_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/verbs.cpp b/src/verbs.cpp index c20f48e65..e1d6c0583 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -64,6 +64,7 @@ #include "seltrans.h" #include "shape-editor.h" #include "shortcuts.h" +#include "sp-defs.h" #include "sp-flowtext.h" #include "sp-guide.h" #include "splivarot.h" @@ -214,6 +215,25 @@ public: { } }; // ObjectVerb class +/** + * A class to encompass all of the verbs which deal with operations related to tags. + */ +class TagVerb : public Verb { +private: + static void perform(SPAction *action, void *mydata); +protected: + virtual SPAction *make_action(Inkscape::ActionContext const & context); +public: + /** Use the Verb initializer with the same parameters. */ + TagVerb(unsigned int const code, + gchar const *id, + gchar const *name, + gchar const *tip, + gchar const *image) : + Verb(code, id, name, tip, image, _("Tag")) + { } +}; // TagVerb class + /** * A class to encompass all of the verbs which deal with operations relative to context. */ @@ -459,6 +479,19 @@ SPAction *ObjectVerb::make_action(Inkscape::ActionContext const & context) return make_action_helper(context, &perform); } +/** + * Create an action for a \c TagVerb. + * + * Calls \c make_action_helper with the \c vector. + * + * @param view Which view the action should be created for. + * @return The built action. + */ +SPAction *TagVerb::make_action(Inkscape::ActionContext const & context) +{ + return make_action_helper(context, &perform); +} + /** * Create an action for a \c ContextVerb. * @@ -1547,6 +1580,47 @@ void ObjectVerb::perform( SPAction *action, void *data) } // end of sp_verb_action_object_perform() +/** + * Decode the verb code and take appropriate action. + */ +void TagVerb::perform( SPAction *action, void *data) +{ + SPDesktop *dt = static_cast(sp_action_get_view(action)); + if (!dt) + return; + + //Inkscape::UI::Tools::ToolBase *ec = dt->event_context; + + Inkscape::Selection *sel = sp_desktop_selection(dt); + + Inkscape::XML::Document * doc; + Inkscape::XML::Node * repr; + gchar *id; + + switch (reinterpret_cast(data)) { + case SP_VERB_TAG_NEW: + static int tag_suffix=1; + id=NULL; + do { + g_free(id); + id = g_strdup_printf("tag%d", tag_suffix++); + } while (dt->doc()->getObjectById(id)); + + doc = dt->doc()->getReprDoc(); + repr = doc->createElement("inkscape:tag"); + repr->setAttribute("id", id); + g_free(id); + + dt->doc()->getDefs()->addChild(repr, NULL); + Inkscape::DocumentUndo::done(dt->doc(), SP_VERB_DIALOG_TAGS, _("Create new selection set")); + break; + default: + break; + } + +} // end of sp_verb_action_tag_perform() + + /** * Decode the verb code and take appropriate action. */ @@ -2040,9 +2114,9 @@ void DialogVerb::perform(SPAction *action, void *data) case SP_VERB_DIALOG_OBJECTS: dt->_dlg_mgr->showDialog("ObjectsPanel"); break; - /*case SP_VERB_DIALOG_TAGS: + case SP_VERB_DIALOG_TAGS: dt->_dlg_mgr->showDialog("TagsPanel"); - break;*/ //in a moment my dear + break; case SP_VERB_DIALOG_LIVE_PATH_EFFECT: dt->_dlg_mgr->showDialog("LivePathEffect"); break; @@ -2647,7 +2721,9 @@ Verb *Verb::_base_verbs[] = { N_("Edit clipping path"), INKSCAPE_ICON("path-clip-edit")), new ObjectVerb(SP_VERB_OBJECT_UNSET_CLIPPATH, "ObjectUnSetClipPath", N_("_Release"), N_("Remove clipping path from selection"), NULL), - + // Tag + new TagVerb(SP_VERB_TAG_NEW, "TagNew", N_("_New"), + N_("Create new selection set"), NULL), // Tools new ContextVerb(SP_VERB_CONTEXT_SELECT, "ToolSelector", NC_("ContextVerb", "Select"), N_("Select and transform objects"), INKSCAPE_ICON("tool-pointer")), @@ -2862,8 +2938,8 @@ Verb *Verb::_base_verbs[] = { N_("View Layers"), INKSCAPE_ICON("dialog-layers")), new DialogVerb(SP_VERB_DIALOG_OBJECTS, "DialogObjects", N_("Object_s..."), N_("View Objects"), INKSCAPE_ICON("dialog-layers")), - /*new DialogVerb(SP_VERB_DIALOG_TAGS, "DialogObjects", N_("Ta_gs..."), - N_("View Tags"), INKSCAPE_ICON("edit-select-all-layers")),*/ + new DialogVerb(SP_VERB_DIALOG_TAGS, "DialogTags", N_("Ta_gs..."), + N_("View Tags"), INKSCAPE_ICON("edit-select-all-layers")), new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), N_("Manage, edit, and apply path effects"), NULL), new DialogVerb(SP_VERB_DIALOG_FILTER_EFFECTS, "DialogFilterEffects", N_("Filter _Editor..."), diff --git a/src/verbs.h b/src/verbs.h index 141a9c7e9..821c9ee82 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -177,6 +177,8 @@ enum { SP_VERB_OBJECT_SET_CLIPPATH, SP_VERB_OBJECT_EDIT_CLIPPATH, SP_VERB_OBJECT_UNSET_CLIPPATH, + /* Tag */ + SP_VERB_TAG_NEW, /* Tools */ SP_VERB_CONTEXT_SELECT, SP_VERB_CONTEXT_NODE, @@ -290,7 +292,7 @@ enum { SP_VERB_DIALOG_EXTENSIONEDITOR, SP_VERB_DIALOG_LAYERS, SP_VERB_DIALOG_OBJECTS, -// SP_VERB_DIALOG_TAGS, + SP_VERB_DIALOG_TAGS, SP_VERB_DIALOG_LIVE_PATH_EFFECT, SP_VERB_DIALOG_FILTER_EFFECTS, SP_VERB_DIALOG_SVG_FONTS, -- cgit v1.2.3 From ef5f5f784221dbf04469b803c3bba265b0f93803 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 10 May 2014 16:44:06 -0400 Subject: Tentative fix for LPEs and undo Fixed bugs: - https://launchpad.net/bugs/1299948 (bzr r13341.1.5) --- src/live_effects/parameter/path.cpp | 5 +++++ src/sp-path.cpp | 18 ++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index cdbbef1db..44d414942 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -118,6 +118,11 @@ PathParam::param_readSVGValue(const gchar * strvalue) // Now do the attaching, which emits the changed signal. try { ref.attach(Inkscape::URI(href)); + //lp:1299948 + SPItem* i = ref.getObject(); + if (i) { + linked_modified_callback(i, SP_OBJECT_MODIFIED_FLAG); + } // else: document still processing new events. Repr of the linked object not created yet. } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); ref.detach(); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index cbb61b0f6..d1fb850e1 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -140,7 +140,22 @@ void SPPath::build(SPDocument *document, Inkscape::XML::Node *repr) { SPShape::build(document, repr); - this->readAttr( "inkscape:original-d" ); + //this->readAttr( "inkscape:original-d" ); //lp1299948 + if (gchar const* s = this->getRepr()->attribute("inkscape:original-d")) + { + //write it to XML, and to my curve, but don't update patheffects + Geom::PathVector pv = sp_svg_read_pathv(s); + SPCurve *curve = new SPCurve(pv); + + if (_curve_before_lpe) { + _curve_before_lpe = _curve_before_lpe->unref(); + } + + if (curve) { + _curve_before_lpe = curve->ref(); + } + //this->getRepr()->setAttribute("inkscape:original-d", s); + } this->readAttr( "d" ); /* d is a required attribute */ @@ -314,7 +329,6 @@ g_message("sp_path_update_patheffect"); #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); #endif - if (_curve) { gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); repr->setAttribute("d", str); -- cgit v1.2.3 From 6d27c0696e7c6babb2f66c81c0a1f13d1036a569 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 11 May 2014 10:20:24 +0200 Subject: Add closePath(). (bzr r13341.1.6) --- src/display/drawing-context.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/display/drawing-context.h b/src/display/drawing-context.h index d990bcb73..0d82087c3 100644 --- a/src/display/drawing-context.h +++ b/src/display/drawing-context.h @@ -61,6 +61,7 @@ public: cairo_curve_to(_ct, p1[Geom::X], p1[Geom::Y], p2[Geom::X], p2[Geom::Y], p3[Geom::X], p3[Geom::Y]); } void arc(Geom::Point const ¢er, double radius, Geom::AngleInterval const &angle); + void closePath() { cairo_close_path(_ct); } void rectangle(Geom::Rect const &r) { cairo_rectangle(_ct, r.left(), r.top(), r.width(), r.height()); } -- cgit v1.2.3 From c67d303b14e0f76754bff98cbde85368d19a4644 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 11 May 2014 10:21:34 +0200 Subject: Add closePath(). (bzr r13349) --- src/display/drawing-context.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/display/drawing-context.h b/src/display/drawing-context.h index d990bcb73..0d82087c3 100644 --- a/src/display/drawing-context.h +++ b/src/display/drawing-context.h @@ -61,6 +61,7 @@ public: cairo_curve_to(_ct, p1[Geom::X], p1[Geom::Y], p2[Geom::X], p2[Geom::Y], p3[Geom::X], p3[Geom::Y]); } void arc(Geom::Point const ¢er, double radius, Geom::AngleInterval const &angle); + void closePath() { cairo_close_path(_ct); } void rectangle(Geom::Rect const &r) { cairo_rectangle(_ct, r.left(), r.top(), r.width(), r.height()); } -- cgit v1.2.3 From fd9d44b5d3cea413da044940218f7a807dbe31db Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 11 May 2014 10:28:13 +0200 Subject: CSS2 and CSS3 text decoration rendering, most code from David Mathog. (bzr r13341.1.7) --- src/display/drawing-text.cpp | 473 ++++++++++++++++++++++++++----------------- src/display/drawing-text.h | 4 +- src/display/nr-style.cpp | 140 +++++++++++-- src/display/nr-style.h | 11 +- 4 files changed, 429 insertions(+), 199 deletions(-) (limited to 'src') diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index 4178cb1d8..366501fb0 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -67,16 +67,14 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext _pick_bbox = Geom::IntRect(); _bbox = Geom::IntRect(); -/* orignally it did the one line below, - but it did not handle ws characters at all, and it had problems with scaling for overline/underline. - Replaced with the section below, which seems to be much more stable. - - Geom::OptRect b = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); -*/ - /* Make a bounding box that is a little taller and lower (currently 10% extra) than the font's drawing box. Extra space is - to hold overline or underline, if present. All characters in a font use the same ascent and descent, - but different widths. This lets leading and trailing spaces have text decorations. If it is not done - the bounding box is limited to the box surrounding the drawn parts of visible glyphs only, and draws outside are ignored. + /* + Make a bounding box for drawing that is a little taller and lower (currently 10% extra) than + the font's drawing box. Extra space is to hold overline or underline, if present. All + characters in a font use the same ascent and descent, but different widths. This lets leading + and trailing spaces have text decorations. If it is not done the bounding box is limited to + the box surrounding the drawn parts of visible glyphs only, and draws outside are ignored. + The box is also a hair wider than the text, since the glyphs do not always start or end at + the left and right edges of the box defined in the font. */ float scale_bigbox = 1.0; @@ -84,9 +82,47 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext scale_bigbox /= _transform->descrim(); } - Geom::Rect bigbox(Geom::Point(0.0, _asc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, -_dsc*scale_bigbox*1.1)); + Geom::Rect bigbox(Geom::Point(-_width*scale_bigbox*0.1, _asc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, -_dsc*scale_bigbox*1.1)); Geom::Rect b = bigbox * ctx.ctm; + /* + The pick box matches the characters as best as it can, leaving no extra space above or below + for decorations. The pathvector may include spaces, and spaces have no drawable glyph. + Catch those and do not pass them to bounds_exact_transformed(), which crashes Inkscape if it + sees a nondrawable glyph. Instead mock up a pickbox for them using font characteristics. + There may also be some other similar white space characters in some other unforeseen context + which should be handled by this code as well.. + */ + + Geom::OptRect pb; + bool fallback = true; + if(_drawable){ + pb = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); + if(pb) fallback = false; + } + if(fallback){ + Geom::Rect pbigbox(Geom::Point(0.0, _asc*scale_bigbox*0.66),Geom::Point(_width*scale_bigbox, 0.0)); + pb = pbigbox * ctx.ctm; + } + +#if 0 + /* FIXME if this is commented out then not even an approximation of pick on decorations */ + /* adjust the pick box up or down to include the decorations. + This is only approximate since at this point we don't know how wide that line is, if it has + an unusual offset, and so forth. The selection point is set at what is roughly the center of + the decoration (vertically) for the wide ones, like wavy and double line. + The text decorations are not actually selectable. + */ + if (_decorations.overline || _decorations.underline) { + double top = _asc*scale_bigbox*0.66; + double bot = 0; + if (_decorations.overline) { top = _asc * scale_bigbox * 1.025; } + if (_decorations.underline) { bot = -_dsc * scale_bigbox * 0.2; } + Geom::Rect padjbox(Geom::Point(0.0, top),Geom::Point(_width*scale_bigbox, bot)); + pb.unionWith(padjbox * ctx.ctm); + } +#endif + if (ggroup->_nrstyle.stroke.type != NRStyle::PAINT_NONE) { // this expands the selection box for cases where the stroke is "thick" float scale = ctx.ctm.descrim(); @@ -96,10 +132,11 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext float width = MAX(0.125, ggroup->_nrstyle.stroke_width * scale); if ( fabs(ggroup->_nrstyle.stroke_width * scale) > 0.01 ) { // FIXME: this is always true b.expandBy(0.5 * width); + pb->expandBy(0.5 * width); } // save bbox without miters for picking - _pick_bbox = b.roundOutwards(); + _pick_bbox = pb->roundOutwards(); float miterMax = width * ggroup->_nrstyle.miter_limit; if ( miterMax > 0.01 ) { @@ -110,14 +147,8 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext _bbox = b.roundOutwards(); } else { _bbox = b.roundOutwards(); - _pick_bbox = *_bbox; + _pick_bbox = pb->roundOutwards(); } -/* -std::cout << "DEBUG _bbox" -<< " { " << _bbox->min()[Geom::X] << " , " << _bbox->min()[Geom::Y] -<< " } , { " << _bbox->max()[Geom::X] << " , " << _bbox->max()[Geom::Y] -<< " }" << std::endl; -*/ return STATE_ALL; } @@ -136,7 +167,8 @@ DrawingGlyphs::_pickItem(Geom::Point const &p, double delta, unsigned /*flags*/) // With text we take a simple approach: pick if the point is in a character bbox Geom::Rect expanded(_pick_bbox); - expanded.expandBy(delta); + // FIXME, why expand by delta? When is the next line needed? + // expanded.expandBy(delta); if (expanded.contains(p)) return this; return NULL; } @@ -195,7 +227,7 @@ DrawingText::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, un return DrawingGroup::_updateItem(area, ctx, flags, reset); } -void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2) +void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2, double thickness) { double wave[16]={ 0.000000, 0.382499, 0.706825, 0.923651, 1.000000, 0.923651, 0.706825, 0.382499, @@ -213,7 +245,6 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas 4, 3, 2, 1, -4, -3, -2, -1 }; - Geom::Point p3,p4,ps,pf; double step = vextent/32.0; unsigned i = 15 & (unsigned) round(xphase/step); // xphase is >= 0.0 @@ -221,26 +252,19 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas This allows decoration continuity within the line, and does not step outside the clip box off the end For the first/last section on the line though, stay well clear of the edge, or when the text is dragged it may "spray" pixels. - if(_nrstyle.tspan_line_end){ pf = p2 - Geom::Point(2*step, 0.0); } - else { pf = p2; } - if(_nrstyle.tspan_line_start){ ps = p1 + Geom::Point(2*step, 0.0); - i = 15 & (i + 2); - } - else { ps = p1; } */ /* snap to nearest step in X */ -ps = Geom::Point(step * round(p1[Geom::X]/step),p1[Geom::Y]); -pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); + Geom::Point ps = Geom::Point(step * round(p1[Geom::X]/step),p1[Geom::Y]); + Geom::Point pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); + Geom::Point poff = Geom::Point(0,thickness/2.0); if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_ISDOUBLE){ ps -= Geom::Point(0, vextent/12.0); pf -= Geom::Point(0, vextent/12.0); - dc.moveTo(ps); - dc.lineTo(pf); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); ps += Geom::Point(0, vextent/6.0); pf += Geom::Point(0, vextent/6.0); - dc.moveTo(ps); - dc.lineTo(pf); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); } /* The next three have a problem in that they are phase dependent. The bits of a line are not necessarily passing through this routine in order, so we have to use the xphase information @@ -248,43 +272,52 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); Huge possitive offset should keep the phase calculation from ever being negative. */ else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_DOTTED){ + // FIXME: Per spec, this should produce round dots. + Geom::Point pv = ps; while(1){ + Geom::Point pvlast = pv; if(dots[i]>0){ - if(ps[Geom::X]> pf[Geom::X])break; - dc.moveTo(ps); - ps += Geom::Point(step * (double)dots[i], 0.0); - if(ps[Geom::X]>= pf[Geom::X]){ - dc.lineTo(pf); + if(pv[Geom::X] > pf[Geom::X]) break; + + pv += Geom::Point(step * (double)dots[i], 0.0); + + if(pv[Geom::X]>= pf[Geom::X]){ + // Last dot + dc.rectangle( Geom::Rect(pvlast + poff, pf - poff)); break; + } else { + dc.rectangle( Geom::Rect(pvlast + poff, pv - poff)); } - else { - dc.lineTo(ps); - } - ps += Geom::Point(step * 4.0, 0.0); - } - else { - ps += Geom::Point(step * -(double)dots[i], 0.0); + + pv += Geom::Point(step * 4.0, 0.0); + + } else { + pv += Geom::Point(step * -(double)dots[i], 0.0); } i = 0; // once in phase, it stays in phase } } else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_DASHED){ + Geom::Point pv = ps; while(1){ + Geom::Point pvlast = pv; if(dashes[i]>0){ - if(ps[Geom::X]> pf[Geom::X])break; - dc.moveTo(ps); - ps += Geom::Point(step * (double)dashes[i], 0.0); - if(ps[Geom::X]>= pf[Geom::X]){ - dc.lineTo(pf); + if(pv[Geom::X]> pf[Geom::X]) break; + + pv += Geom::Point(step * (double)dashes[i], 0.0); + + if(pv[Geom::X]>= pf[Geom::X]){ + // Last dash + dc.rectangle( Geom::Rect(pvlast + poff, pf - poff)); break; + } else { + dc.rectangle( Geom::Rect(pvlast + poff, pv - poff)); } - else { - dc.lineTo(ps); - } - ps += Geom::Point(step * 8.0, 0.0); - } - else { - ps += Geom::Point(step * -(double)dashes[i], 0.0); + + pv += Geom::Point(step * 8.0, 0.0); + + } else { + pv += Geom::Point(step * -(double)dashes[i], 0.0); } i = 0; // once in phase, it stays in phase } @@ -292,7 +325,7 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_WAVY){ double amp = vextent/10.0; double x = ps[Geom::X]; - double y = ps[Geom::Y]; + double y = ps[Geom::Y] + poff[Geom::Y]; dc.moveTo(Geom::Point(x, y + amp * wave[i])); while(1){ i = ((i + 1) & 15); @@ -300,17 +333,25 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); dc.lineTo(Geom::Point(x, y + amp * wave[i])); if(x >= pf[Geom::X])break; } - } + y = ps[Geom::Y] - poff[Geom::Y]; + dc.lineTo(Geom::Point(x, y + amp * wave[i])); + while(1){ + i = ((i - 1) & 15); + x -= step; + dc.lineTo(Geom::Point(x, y + amp * wave[i])); + if(x <= ps[Geom::X])break; + } + dc.closePath(); + } else { // TEXT_DECORATION_STYLE_SOLID, also default in case it was not set for some reason - dc.moveTo(ps); - dc.lineTo(pf); -// dc.revrectangle(Geom::Rect(ps,pf)); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); } } /* returns scaled line thickness */ -double DrawingText::decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length) +void DrawingText::decorateItem(DrawingContext &dc, double phase_length, bool under) { + if (_nrstyle.font_size < 1.0e-32)return; // would cause a divide by zero and nothing would be visible anyway double tsp_width_adj = _nrstyle.tspan_width / _nrstyle.font_size; double tsp_asc_adj = _nrstyle.ascender / _nrstyle.font_size; double tsp_size_adj = (_nrstyle.ascender + _nrstyle.descender) / _nrstyle.font_size; @@ -318,49 +359,54 @@ double DrawingText::decorateItem(DrawingContext &dc, Geom::Affine const &aff, do double final_underline_thickness = CLAMP(_nrstyle.underline_thickness, tsp_size_adj/30.0, tsp_size_adj/10.0); double final_line_through_thickness = CLAMP(_nrstyle.line_through_thickness, tsp_size_adj/30.0, tsp_size_adj/10.0); - double scale = aff.descrim(); double xphase = phase_length/ _nrstyle.font_size; // used to figure out phase of patterns - Inkscape::DrawingContext::Save save(dc); - dc.transform(aff); // must be leftmost affine in span - Geom::Point p1; Geom::Point p2; // All lines must be the same thickness, in combinations, line_through trumps underline double thickness = final_underline_thickness; - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_UNDERLINE){ - p1 = Geom::Point(0.0, -_nrstyle.underline_position); - p2 = Geom::Point(tsp_width_adj,-_nrstyle.underline_position); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_OVERLINE){ - p1 = Geom::Point(0.0, tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); - p2 = Geom::Point(tsp_width_adj,tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_LINETHROUGH){ - thickness = final_line_through_thickness; - p1 = Geom::Point(0.0, _nrstyle.line_through_position); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - // Obviously this does not blink, but it does indicate which text has been set with that attribute - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_BLINK){ - thickness = final_line_through_thickness; - p1 = Geom::Point(0.0, _nrstyle.line_through_position - 2*final_line_through_thickness); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position - 2*final_line_through_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - p1 = Geom::Point(0.0, _nrstyle.line_through_position + 2*final_line_through_thickness); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position + 2*final_line_through_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); + dc.setTolerance(0.5); // Is this really necessary... could effect dots. + + if( under ) { + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_UNDERLINE){ + p1 = Geom::Point(0.0, -_nrstyle.underline_position); + p2 = Geom::Point(tsp_width_adj,-_nrstyle.underline_position); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_OVERLINE){ + p1 = Geom::Point(0.0, tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); + p2 = Geom::Point(tsp_width_adj,tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + } else { + // Over + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_LINETHROUGH){ + thickness = final_line_through_thickness; + p1 = Geom::Point(0.0, _nrstyle.line_through_position); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + // Obviously this does not blink, but it does indicate which text has been set with that attribute + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_BLINK){ + thickness = final_line_through_thickness; + p1 = Geom::Point(0.0, _nrstyle.line_through_position - 2*final_line_through_thickness); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position - 2*final_line_through_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + p1 = Geom::Point(0.0, _nrstyle.line_through_position + 2*final_line_through_thickness); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position + 2*final_line_through_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } } - thickness *= scale; - return(thickness); } unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*area*/, unsigned /*flags*/, DrawingItem * /*stop_at*/) { - if (_drawing.outline()) { + if (_drawing.outline()) { guint32 rgba = _drawing.outlinecolor; Inkscape::DrawingContext::Save save(dc); dc.setSource(rgba); @@ -382,124 +428,187 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are return RENDER_OK; } - // NOTE: this is very similar to drawing-shape.cpp; the only difference is in path feeding - double leftmost = DBL_MAX; - double phase_length = 0.0; - bool firsty = true; - bool decorate = true; - double starty = 0.0; - Geom::Affine aff; - using Geom::X; - using Geom::Y; - - // NOTE: + // NOTE: This is very similar to drawing-shape.cpp; the only differences are in path feeding + // and in applying text decorations. + + + // Do we have text decorations? + bool decorate = (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR ); + // prepareFill / prepareStroke need to be called with _ctm in effect. // However, we might need to apply a different ctm for glyphs. // Therefore, only apply this ctm temporarily. - bool has_stroke, has_fill; + bool has_stroke = false; + bool has_fill = false; + bool has_td_fill = false; + bool has_td_stroke = false; { Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); - has_fill = _nrstyle.prepareFill( dc, _item_bbox); - has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); + has_fill = _nrstyle.prepareFill( dc, _item_bbox); + has_stroke = _nrstyle.prepareStroke( dc, _item_bbox); + + // Avoid creating patterns if not needed + if( decorate ) { + has_td_fill = _nrstyle.prepareTextDecorationFill( dc, _item_bbox); + has_td_stroke = _nrstyle.prepareTextDecorationStroke(dc, _item_bbox); + } } - if (has_fill || has_stroke) { - Geom::Affine rotinv; - bool invset = false; + if (has_fill || has_stroke || has_td_fill || has_td_stroke) { - // accumulate the path that represents the glyphs - for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { - DrawingGlyphs *g = dynamic_cast(&*i); - if (!g) throw InvalidItemException(); - if (!invset) { - rotinv = g->_ctm.withoutTranslation().inverse(); - invset = true; - } + // Determine order for fill and stroke. + // Text doesn't have markers, we can do paint-order quick and dirty. + bool fill_first = false; + if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || + _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_FILL || + _nrstyle.paint_order_layer[2] == NRStyle::PAINT_ORDER_STROKE ) { + fill_first = true; + } // Won't get "stroke fill stroke" but that isn't 'valid' + + + // Determine geometry of text decoration + double phase_length = 0.0; + Geom::Affine aff; + if( decorate ) { + + Geom::Affine rotinv; + bool invset = false; + double leftmost = DBL_MAX; + bool first_y = true; + double start_y = 0.0; + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + + DrawingGlyphs *g = dynamic_cast(&*i); + if (!g) throw InvalidItemException(); + + if (!invset) { + rotinv = g->_ctm.withoutTranslation().inverse(); + invset = true; + } - Inkscape::DrawingContext::Save save(dc); - if (g->_ctm.isSingular()) continue; - dc.transform(g->_ctm); - if (g->_drawable) { - dc.path(*g->_font->PathVector(g->_glyph)); - } - // get the leftmost affine transform (leftmost defined with respect to the x axis of the first transform). - // That way the decoration will work no matter what mix of L->R, R->L text is in the span. - if (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR) { Geom::Point pt = g->_ctm.translation() * rotinv; - if (pt[X] < leftmost) { - leftmost = pt[X]; + if (pt[Geom::X] < leftmost) { + leftmost = pt[Geom::X]; aff = g->_ctm; phase_length = g->_pl; } - /* If the text has been mapped onto a path, which causes y to vary, drop the text decorations. - To handle that properly would need a conformal map - */ - if (firsty) { - firsty = false; - starty = pt[Y]; + + // Check for text on a path. FIXME: This needs better test (and probably not here). + if (first_y) { + first_y = false; + start_y = pt[Geom::Y]; } - else if (fabs(pt[Y] - starty) > 1.0e-6) { + else if (fabs(pt[Geom::Y] - start_y) > 1.0e-6) { + // If the text has been mapped onto a path, which causes y to vary, drop the + // text decorations. To handle that properly would need a conformal map. decorate = false; } } } - // draw the text itself - // we need to apply this object's ctm again - Inkscape::DrawingContext::Save save(dc); - dc.transform(_ctm); + // Draw text decorations that go UNDER the text (underline, over-line) + if( decorate ) { - // Text doesn't have markers, we can do paint-order quick and dirty. - bool fill_first = false; - if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || - _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_FILL || - _nrstyle.paint_order_layer[2] == NRStyle::PAINT_ORDER_STROKE ) { - fill_first = true; - } // Won't get "stroke fill stroke" but that isn't 'valid' + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(aff); // must be leftmost affine in span + decorateItem(dc, phase_length, true); + } + + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); // Needed so that fill pattern rotates with text + + if (has_td_fill && fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + + if (has_td_stroke) { + _nrstyle.applyTextDecorationStroke(dc); + dc.strokePreserve(); + } + + if (has_td_fill && !fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } - if (has_fill && fill_first) { - _nrstyle.applyFill(dc); - dc.fillPreserve(); + } + + dc.newPath(); // Clear text-decoration path } - if (has_stroke) { - _nrstyle.applyStroke(dc); - dc.strokePreserve(); + // accumulate the path that represents the glyphs + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingGlyphs *g = dynamic_cast(&*i); + if (!g) throw InvalidItemException(); + + Inkscape::DrawingContext::Save save(dc); + if (g->_ctm.isSingular()) continue; + dc.transform(g->_ctm); + if (g->_drawable) { + dc.path(*g->_font->PathVector(g->_glyph)); + } } - if (has_fill && !fill_first) { - _nrstyle.applyFill(dc); - dc.fillPreserve(); + // Draw the glyphs. + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); + + if (has_fill && fill_first) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } + + if (has_stroke) { + _nrstyle.applyStroke(dc); + dc.strokePreserve(); + } + + if (has_fill && !fill_first) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } } + dc.newPath(); // Clear glyphs path + + // Draw text decorations that go OVER the text (line through, blink) + if (decorate) { - dc.newPath(); // clear path - - // draw text decoration - if (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR && decorate) { - guint32 ergba; - if (_nrstyle.text_decoration_useColor) { // color different from the glyph - ergba = SP_RGBA32_F_COMPOSE( - _nrstyle.text_decoration_color.color.v.c[0], - _nrstyle.text_decoration_color.color.v.c[1], - _nrstyle.text_decoration_color.color.v.c[2], - 1.0); + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(aff); // must be leftmost affine in span + decorateItem(dc, phase_length, false); } - else { // whatever the current fill color is - ergba = SP_RGBA32_F_COMPOSE( - _nrstyle.fill.color.v.c[0], - _nrstyle.fill.color.v.c[1], - _nrstyle.fill.color.v.c[2], - 1.0); + + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); // Needed so that fill pattern rotates with text + + if (has_td_fill && fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + + if (has_td_stroke) { + _nrstyle.applyTextDecorationStroke(dc); + dc.strokePreserve(); + } + + if (has_td_fill && !fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + } - dc.setSource(ergba); - dc.setTolerance(0.5); - double thickness = decorateItem(dc, aff, phase_length); - dc.setLineWidth(thickness); - dc.strokePreserve(); - dc.newPath(); // clear path + + dc.newPath(); // Clear text-decoration path } + } return RENDER_OK; } diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h index 41039d85d..4453a3db4 100644 --- a/src/display/drawing-text.h +++ b/src/display/drawing-text.h @@ -68,8 +68,8 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); - double decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length); - void decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2); + void decorateItem(DrawingContext &dc, double phase_length, bool under); + void decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2, double thickness); NRStyle _nrstyle; friend class DrawingGlyphs; diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 09a28e63c..ec3117079 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -54,8 +54,13 @@ NRStyle::NRStyle() , line_join(CAIRO_LINE_JOIN_MITER) , fill_pattern(NULL) , stroke_pattern(NULL) + , text_decoration_fill_pattern(NULL) + , text_decoration_stroke_pattern(NULL) , text_decoration_line(TEXT_DECORATION_LINE_CLEAR) , text_decoration_style(TEXT_DECORATION_STYLE_CLEAR) + , text_decoration_fill() + , text_decoration_stroke() + , text_decoration_stroke_width(0.0) , phase_length(0.0) , tspan_line_start(false) , tspan_line_end(false) @@ -76,11 +81,15 @@ NRStyle::~NRStyle() { if (fill_pattern) cairo_pattern_destroy(fill_pattern); if (stroke_pattern) cairo_pattern_destroy(stroke_pattern); + if (text_decoration_fill_pattern) cairo_pattern_destroy(text_decoration_fill_pattern); + if (text_decoration_stroke_pattern) cairo_pattern_destroy(text_decoration_stroke_pattern); if (dash){ delete [] dash; } fill.clear(); stroke.clear(); + text_decoration_fill.clear(); + text_decoration_stroke.clear(); } void NRStyle::set(SPStyle *style) @@ -195,15 +204,65 @@ void NRStyle::set(SPStyle *style) if(style->text_decoration_style.dashed ){ text_decoration_style |= TEXT_DECORATION_STYLE_DASHED + TEXT_DECORATION_STYLE_SET; } if(style->text_decoration_style.wavy ){ text_decoration_style |= TEXT_DECORATION_STYLE_WAVY + TEXT_DECORATION_STYLE_SET; } + /* FIXME + The meaning of text-decoration-color in CSS3 for SVG is ambiguous (2014-05-06). Set + it for fill, for stroke, for both? Both would seem like the obvious choice but what happens + is that for text which is just fill (very common) it makes the lines fatter because it + enables stroke on the decorations when it wasn't present on the text. That contradicts the + usual behavior where the text and decorations by default have the same fill/stroke. + + The behavior here is that if color is defined it is applied to text_decoration_fill/stroke + ONLY if the corresponding fill/stroke is also present. + + Hopefully the standard will be clarified to resolve this issue. + */ + + SPStyle* style_td = style; + if ( style->text_decoration.style_td ) style_td = style->text_decoration.style_td; + text_decoration_stroke.opacity = SP_SCALE24_TO_FLOAT(style_td->stroke_opacity.value); + text_decoration_stroke_width = style_td->stroke_width.computed; + if( style->text_decoration_color.set || style->text_decoration_color.inherit || - style->text_decoration_color.currentcolor ){ - text_decoration_color.set(style->text_decoration_color.value.color); - text_decoration_useColor = true; - } - else { - text_decoration_color.clear(); - text_decoration_useColor = false; + style->text_decoration_color.currentcolor ) { + + if(style->fill.isPaintserver() || style->fill.isColor()) { + // SVG sets color specifically + text_decoration_fill.set(style->text_decoration_color.value.color); + } else { + // No decoration fill because no text fill + text_decoration_fill.clear(); + } + + if(style->stroke.isPaintserver() || style->stroke.isColor()) { + // SVG sets color specifically + text_decoration_stroke.set(style->text_decoration_color.value.color); + } else { + // No decoration stroke because no text stroke + text_decoration_stroke.clear(); + } + + } else { + // Pick color/pattern from text + if ( style_td->fill.isPaintserver() ) { + text_decoration_fill.set(style_td->getFillPaintServer()); + } else if ( style_td->fill.isColor() ) { + text_decoration_fill.set(style_td->fill.value.color); + } else if ( style_td->fill.isNone() ) { + text_decoration_fill.clear(); + } else { + g_assert_not_reached(); + } + + if ( style_td->stroke.isPaintserver() ) { + text_decoration_stroke.set(style_td->getStrokePaintServer()); + } else if ( style_td->stroke.isColor() ) { + text_decoration_stroke.set(style_td->stroke.value.color); + } else if ( style_td->stroke.isNone() ) { + text_decoration_stroke.clear(); + } else { + g_assert_not_reached(); + } } if(text_decoration_line != TEXT_DECORATION_LINE_CLEAR){ @@ -232,10 +291,8 @@ bool NRStyle::prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &pai if (!fill_pattern) { switch (fill.type) { case PAINT_SERVER: { - //fill_pattern = sp_paint_server_create_pattern(fill.server, dc.raw(), paintbox, fill.opacity); - fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); - - } break; + fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); + } break; case PAINT_COLOR: { SPColor const &c = fill.color; fill_pattern = cairo_pattern_create_rgba( @@ -254,14 +311,38 @@ void NRStyle::applyFill(Inkscape::DrawingContext &dc) dc.setFillRule(fill_rule); } +bool NRStyle::prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) +{ + // update text decoration pattern + if (!text_decoration_fill_pattern) { + switch (text_decoration_fill.type) { + case PAINT_SERVER: { + text_decoration_fill_pattern = text_decoration_fill.server->pattern_new(dc.raw(), paintbox, text_decoration_fill.opacity); + } break; + case PAINT_COLOR: { + SPColor const &c = text_decoration_fill.color; + text_decoration_fill_pattern = cairo_pattern_create_rgba( + c.v.c[0], c.v.c[1], c.v.c[2], text_decoration_fill.opacity); + } break; + default: break; + } + } + if (!text_decoration_fill_pattern) return false; + return true; +} + +void NRStyle::applyTextDecorationFill(Inkscape::DrawingContext &dc) +{ + dc.setSource(text_decoration_fill_pattern); + // Fill rule does not matter, no intersections. +} + bool NRStyle::prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) { if (!stroke_pattern) { switch (stroke.type) { case PAINT_SERVER: { - //stroke_pattern = sp_paint_server_create_pattern(stroke.server, dc.raw(), paintbox, stroke.opacity); stroke_pattern = stroke.server->pattern_new(dc.raw(), paintbox, stroke.opacity); - } break; case PAINT_COLOR: { SPColor const &c = stroke.color; @@ -285,13 +366,46 @@ void NRStyle::applyStroke(Inkscape::DrawingContext &dc) cairo_set_dash(dc.raw(), dash, n_dash, dash_offset); // fixme } +bool NRStyle::prepareTextDecorationStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) +{ + if (!text_decoration_stroke_pattern) { + switch (text_decoration_stroke.type) { + case PAINT_SERVER: { + text_decoration_stroke_pattern = text_decoration_stroke.server->pattern_new(dc.raw(), paintbox, text_decoration_stroke.opacity); + } break; + case PAINT_COLOR: { + SPColor const &c = text_decoration_stroke.color; + text_decoration_stroke_pattern = cairo_pattern_create_rgba( + c.v.c[0], c.v.c[1], c.v.c[2], text_decoration_stroke.opacity); + } break; + default: break; + } + } + if (!text_decoration_stroke_pattern) return false; + return true; +} + +void NRStyle::applyTextDecorationStroke(Inkscape::DrawingContext &dc) +{ + dc.setSource(text_decoration_stroke_pattern); + dc.setLineWidth(text_decoration_stroke_width); + dc.setLineCap(CAIRO_LINE_CAP_BUTT); + dc.setLineJoin(CAIRO_LINE_JOIN_MITER); + dc.setMiterLimit(miter_limit); + cairo_set_dash(dc.raw(), 0, 0, 0.0); // fixme (no dash) +} + void NRStyle::update() { // force pattern update if (fill_pattern) cairo_pattern_destroy(fill_pattern); if (stroke_pattern) cairo_pattern_destroy(stroke_pattern); + if (text_decoration_fill_pattern) cairo_pattern_destroy(text_decoration_fill_pattern); + if (text_decoration_stroke_pattern) cairo_pattern_destroy(text_decoration_stroke_pattern); fill_pattern = NULL; stroke_pattern = NULL; + text_decoration_fill_pattern = NULL; + text_decoration_stroke_pattern = NULL; } /* diff --git a/src/display/nr-style.h b/src/display/nr-style.h index ca880c00b..83bcb1ab7 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -30,8 +30,12 @@ struct NRStyle { void set(SPStyle *); bool prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); bool prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); + bool prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); + bool prepareTextDecorationStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); void applyFill(Inkscape::DrawingContext &dc); void applyStroke(Inkscape::DrawingContext &dc); + void applyTextDecorationFill(Inkscape::DrawingContext &dc); + void applyTextDecorationStroke(Inkscape::DrawingContext &dc); void update(); enum PaintType { @@ -67,6 +71,8 @@ struct NRStyle { cairo_pattern_t *fill_pattern; cairo_pattern_t *stroke_pattern; + cairo_pattern_t *text_decoration_fill_pattern; + cairo_pattern_t *text_decoration_stroke_pattern; enum PaintOrderType { PAINT_ORDER_NORMAL, @@ -97,8 +103,9 @@ struct NRStyle { int text_decoration_line; int text_decoration_style; - Paint text_decoration_color; - bool text_decoration_useColor; // if false, use whatever the glyph color was + Paint text_decoration_fill; + Paint text_decoration_stroke; + float text_decoration_stroke_width; // These are the same as in style.h float phase_length; bool tspan_line_start; -- cgit v1.2.3 From f9b46a56e41c1fb0d743ae381394b2245f264fc8 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 11 May 2014 13:57:14 +0200 Subject: i18n. Fix for bug #1318289 (preferences > bitmap > rendering shows po file headers). Fixed bugs: - https://launchpad.net/bugs/1318289 (bzr r13350) --- src/ui/dialog/inkscape-preferences.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index b6095fa8b..f1a29e971 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1468,7 +1468,7 @@ void InkscapePreferences::initPageBitmaps() _page_bitmaps.add_group_header( _("Render")); // rendering outlines for pixmap image tags _rendering_image_outline.init( _("Images in Outline Mode"), "/options/rendering/imageinoutlinemode", false); - _page_bitmaps.add_line(false, _(""), _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); + _page_bitmaps.add_line(false, "", _rendering_image_outline, "", _("When active will render images while in outline mode instead of a red box with an x. This is useful for manual tracing.")); this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } -- cgit v1.2.3 From 1fb28d6c7a8d030542ab5bcdf6ed6228356e213d Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 11 May 2014 16:04:42 +0200 Subject: i18n. Fix for bug #1318345 (untranslatable strings in trunk-r13348). Fixed bugs: - https://launchpad.net/bugs/1318345 (bzr r13352) --- src/ui/dialog/grid-arrange-tab.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 8c0a4dc66..72217c729 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -708,7 +708,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1); // Anchor selection widget - AlignLabel.set_label("Alignment:"); + AlignLabel.set_label(_("Alignment:")); AlignLabel.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); AlignmentSelector.setAlignment(HorizAlign, VertAlign); AlignmentSelector.on_selectionChanged().connect(sigc::mem_fun(*this, &GridArrangeTab::Align_changed)); -- cgit v1.2.3 From 1f1932ae4592c8f316e3a68ac86874bf87f321c4 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 11 May 2014 14:23:10 -0400 Subject: Stabilize the selection set system a bit (bzr r13090.1.76) --- src/sp-tag-use.cpp | 1 + src/ui/dialog/tags.cpp | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sp-tag-use.cpp b/src/sp-tag-use.cpp index ffcfcee3e..5851598f2 100644 --- a/src/sp-tag-use.cpp +++ b/src/sp-tag-use.cpp @@ -175,6 +175,7 @@ SPTagUse::href_changed(SPObject */*old_ref*/, SPObject */*ref*/) SPObject* child_ = SPFactory::instance().createObject(typeString); if (child_) { + child = child_; attach(child_, lastChild()); sp_object_unref(child_, 0); child_->invoke_build(this->document, childrepr, TRUE); diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 7fdd2e906..14ad5b8cc 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -280,7 +280,8 @@ bool TagsPanel::_executeAction() for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * obj = *iter; if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); + //obj->parent->getRepr()->removeChild(obj->getRepr()); + obj->deleteObject(true, true); } } DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); @@ -576,7 +577,8 @@ bool TagsPanel::_handleKeyEvent(GdkEventKey *event) for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * obj = *iter; if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { - obj->parent->getRepr()->removeChild(obj->getRepr()); + //obj->parent->getRepr()->removeChild(obj->getRepr()); + obj->deleteObject(true, true); } } DocumentUndo::done(_document, SP_VERB_DIALOG_TAGS, _("Remove from selection set")); @@ -680,12 +682,14 @@ bool TagsPanel::_handleButtonEvent(GdkEventButton* event) } } else { std::vector todelete; + // FIXME unnecessary use of XML tree _tree.get_selection()->selected_foreach_iter(sigc::bind*>(sigc::mem_fun(*this, &TagsPanel::_checkForDeleted), &todelete)); if (!todelete.empty()) { for (std::vector::iterator iter = todelete.begin(); iter != todelete.end(); ++iter) { SPObject * tobj = *iter; if (tobj && tobj->parent && tobj->getRepr() && tobj->parent->getRepr()) { - tobj->parent->getRepr()->removeChild(tobj->getRepr()); + //tobj->parent->getRepr()->removeChild(tobj->getRepr()); + tobj->deleteObject(true, true); } } } else if (obj && obj->parent && obj->getRepr() && obj->parent->getRepr()) { -- cgit v1.2.3 From fd9836417427340b4d140aaac9663060c571ebb7 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Sun, 11 May 2014 12:00:54 -0700 Subject: make: Order our dist headers before installed package headers src/Makefile.am has a fragile AM_CPPFLAGS order: various -I$(top_srcdir)/* are after various $(*_CFLAGS), so a header file supplied by some other installed package on the system could mask the intended one in the dist itself. Best to put all local flags before globals. Patch from Fink via Daniel Macks. (bzr r13353) --- src/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index d5439f0ea..bb34047a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,6 +64,8 @@ BUILT_SOURCES = EXTRA_DIST = AM_CPPFLAGS = \ + -I$(top_srcdir)/cxxtest \ + -I$(builddir)/extension/dbus \ $(EXIF_CFLAGS) \ $(FREETYPE_CFLAGS) \ $(GNOME_PRINT_CFLAGS) \ @@ -80,9 +82,7 @@ AM_CPPFLAGS = \ $(POPPLER_GLIB_CFLAGS) \ -DPOTRACE=\"potrace\" \ $(INKSCAPE_CFLAGS) \ - -I$(top_srcdir)/cxxtest \ $(WIN32_CFLAGS) \ - -I$(builddir)/extension/dbus \ $(X11_CFLAGS) CXXTEST_TEMPLATE = $(srcdir)/cxxtest-template.tpl -- cgit v1.2.3 From 0dc8b506fe92a6f4a57d6412db69c3fea420d67a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 11 May 2014 15:08:59 -0400 Subject: Rename "Tags" to "Selection sets" to avoid confusion with a global tagging system (bzr r13090.1.77) --- src/ui/dialog/tags.cpp | 2 +- src/verbs.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 14ad5b8cc..1b5dd9400 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -1025,7 +1025,7 @@ TagsPanel::TagsPanel() : // ------------------------------------------------------- { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "New", (int)BUTTON_NEW ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_TAG_NEW, 0, "Add a new selection set", (int)BUTTON_NEW ) ); _popupMenu.show_all_children(); } diff --git a/src/verbs.cpp b/src/verbs.cpp index e1d6c0583..73613ab9e 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1603,7 +1603,7 @@ void TagVerb::perform( SPAction *action, void *data) id=NULL; do { g_free(id); - id = g_strdup_printf("tag%d", tag_suffix++); + id = g_strdup_printf("Set %d", tag_suffix++); } while (dt->doc()->getObjectById(id)); doc = dt->doc()->getReprDoc(); @@ -2938,7 +2938,7 @@ Verb *Verb::_base_verbs[] = { N_("View Layers"), INKSCAPE_ICON("dialog-layers")), new DialogVerb(SP_VERB_DIALOG_OBJECTS, "DialogObjects", N_("Object_s..."), N_("View Objects"), INKSCAPE_ICON("dialog-layers")), - new DialogVerb(SP_VERB_DIALOG_TAGS, "DialogTags", N_("Ta_gs..."), + new DialogVerb(SP_VERB_DIALOG_TAGS, "DialogTags", N_("Selection se_ts..."), N_("View Tags"), INKSCAPE_ICON("edit-select-all-layers")), new DialogVerb(SP_VERB_DIALOG_LIVE_PATH_EFFECT, "DialogLivePathEffect", N_("Path E_ffects ..."), N_("Manage, edit, and apply path effects"), NULL), -- cgit v1.2.3 From c8162ae7a5692e0aa91de4c08fa4bd8a47cc54a8 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 11 May 2014 23:13:23 +0200 Subject: fix 2geom build for newer compilers (assert can be disabled/overridden, i suppose) (bzr r13355) --- src/2geom/toposweep.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/2geom/toposweep.cpp b/src/2geom/toposweep.cpp index cfb91857c..9316669f5 100644 --- a/src/2geom/toposweep.cpp +++ b/src/2geom/toposweep.cpp @@ -53,6 +53,7 @@ TopoGraph::Edge TopoGraph::remove_edge(unsigned ix, unsigned jx) { } } assert(0); + return Edge; // if assert is disabled, return empty Edge. } void TopoGraph::cannonize() { -- cgit v1.2.3 From a596a3e08e0f11e3d8d6a3107fc897c2cd729b1d Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 11 May 2014 23:18:22 +0200 Subject: correctly fix rev. 13355 (bzr r13356) --- src/2geom/toposweep.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/2geom/toposweep.cpp b/src/2geom/toposweep.cpp index 9316669f5..4da3f6922 100644 --- a/src/2geom/toposweep.cpp +++ b/src/2geom/toposweep.cpp @@ -53,7 +53,7 @@ TopoGraph::Edge TopoGraph::remove_edge(unsigned ix, unsigned jx) { } } assert(0); - return Edge; // if assert is disabled, return empty Edge. + return v[0]; // if assert is disabled, return first Edge. } void TopoGraph::cannonize() { -- cgit v1.2.3 From 3ef365a9d42823ded18fb31aa2c36c39005cb0ee Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 11 May 2014 23:38:10 +0200 Subject: fix build for some (windows 64 bit devlibs attempt) specifically, fixes this build error: .../include/glibmm-2.4/glibmm/threads.h:201:11: error: field 'gobject_' has incomplete type 'GThread {aka _GThread}' (bzr r13357) --- src/libdepixelize/kopftracer2011.cpp | 2 ++ src/ui/dialog/filedialogimpl-win32.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src') diff --git a/src/libdepixelize/kopftracer2011.cpp b/src/libdepixelize/kopftracer2011.cpp index e2f387c86..1e769b0c9 100644 --- a/src/libdepixelize/kopftracer2011.cpp +++ b/src/libdepixelize/kopftracer2011.cpp @@ -26,6 +26,8 @@ # include #endif +#include + // Build fix under Inkscape build tree #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index 29bcb9a45..a71ee1ad0 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -13,6 +13,8 @@ # include "config.h" #endif +#include + #ifdef WIN32 #if WITH_GLIBMM_2_32 #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -- cgit v1.2.3 From 8e46606ce757e07874cde51fe0ad21ec0078094f Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 11 May 2014 23:59:26 +0200 Subject: fix build on Windows with newer gcc / other Windows headers. redefining NULL is terrible, perhaps we can remove these lines for all build platforms? (bzr r13358) --- src/prefix.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/prefix.cpp b/src/prefix.cpp index 99e20171f..126d16a72 100644 --- a/src/prefix.cpp +++ b/src/prefix.cpp @@ -44,8 +44,11 @@ extern "C" { #endif /* __cplusplus */ -#undef NULL -#define NULL ((void *) 0) + // Why is NULL being redefined?! This breaks compilation on Windows, as it disables the safe assignment of NULL to other pointer types. +#ifndef __WIN32__ +# undef NULL +# define NULL ((void *) 0) +#endif #ifdef __GNUC__ #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;} -- cgit v1.2.3 From 8be92f2c327b30cb3c2127d2b501fa50c8ac4cbf Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 12 May 2014 19:41:12 +0200 Subject: small logic improvement (bzr r13341.1.8) --- src/display/drawing-text.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index 366501fb0..05a2c3c2a 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -95,12 +95,10 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext */ Geom::OptRect pb; - bool fallback = true; if(_drawable){ pb = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); - if(pb) fallback = false; } - if(fallback){ + if(!pb){ // Fallback Geom::Rect pbigbox(Geom::Point(0.0, _asc*scale_bigbox*0.66),Geom::Point(_width*scale_bigbox, 0.0)); pb = pbigbox * ctx.ctm; } -- cgit v1.2.3 From 5a16d98495719cf201a03c36246c75072c97b596 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Mon, 12 May 2014 21:34:58 +0200 Subject: Fix snapping issue in selector tool Fixed bugs: - https://launchpad.net/bugs/1255764 (bzr r13361) --- src/display/snap-indicator.cpp | 6 ++-- src/seltrans.cpp | 64 +++++++++++++++++++++++++----------------- src/snap.cpp | 10 +++---- 3 files changed, 48 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 627bfb2ab..3a8358174 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -73,6 +73,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap switch (p.getTarget()) { case SNAPTARGET_UNDEFINED: target_name = _("UNDEFINED"); + g_warning("Snap target has not been specified"); break; case SNAPTARGET_GRID: target_name = _("grid line"); @@ -172,7 +173,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap target_name = _("constraint"); break; default: - g_warning("Snap target has not yet been defined!"); + g_warning("Snap target not in SnapTargetType enum"); break; } @@ -180,6 +181,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap switch (p.getSource()) { case SNAPSOURCE_UNDEFINED: source_name = _("UNDEFINED"); + g_warning("Snap source has not been specified"); break; case SNAPSOURCE_BBOX_CORNER: source_name = _("Bounding box corner"); @@ -235,7 +237,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap source_name = _("Multiple of grid spacing"); break; default: - g_warning("Snap source has not yet been defined!"); + g_warning("Snap source not in SnapSourceType enum"); break; } //std::cout << "Snapped " << source_name << " to " << target_name << std::endl; diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 7708c999e..fa2441847 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -929,23 +929,29 @@ gboolean Inkscape::SelTrans::scaleRequest(Geom::Point &pt, guint state) sn = m.freeSnapScale(_snap_points, _point, geom_scale, _origin_for_specpoints); } - if (!(bb.getSnapped() || sn.getSnapped())) { + std::cout << bb.getSnapped() << " | " << sn.getSnapped() << std::endl; + // These lines below are duplicated in stretchRequest + if (bb.getSnapped() || sn.getSnapped()) { + if (bb.getSnapped()) { + if (!bb.isOtherSnapBetter(sn, false)) { + // We snapped the bbox (which is either visual or geometric) + _desktop->snapindicator->set_new_snaptarget(bb); + default_scale = Geom::Scale(bb.getTransformation()); + // Calculate the new transformation and update the handle position + pt = _calcAbsAffineDefault(default_scale); + } + } else if (sn.getSnapped()) { + _desktop->snapindicator->set_new_snaptarget(sn); + // We snapped the special points (e.g. nodes), which are not at the visual bbox + // The handle location however (pt) might however be at the visual bbox, so we + // will have to calculate pt taking the stroke width into account + geom_scale = Geom::Scale(sn.getTransformation()); + pt = _calcAbsAffineGeom(geom_scale); + } + } else { // We didn't snap at all! Don't update the handle position, just calculate the new transformation _calcAbsAffineDefault(default_scale); _desktop->snapindicator->remove_snaptarget(); - } else if (bb.getSnapped() && !bb.isOtherSnapBetter(sn, false)) { - // We snapped the bbox (which is either visual or geometric) - _desktop->snapindicator->set_new_snaptarget(bb); - default_scale = Geom::Scale(bb.getTransformation()); - // Calculate the new transformation and update the handle position - pt = _calcAbsAffineDefault(default_scale); - } else { - _desktop->snapindicator->set_new_snaptarget(sn); - // We snapped the special points (e.g. nodes), which are not at the visual bbox - // The handle location however (pt) might however be at the visual bbox, so we - // will have to calculate pt taking the stroke width into account - geom_scale = Geom::Scale(sn.getTransformation()); - pt = _calcAbsAffineGeom(geom_scale); } m.unSetup(); } @@ -1028,20 +1034,28 @@ gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, Geom geom_scale[perp] = fabs(geom_scale[axis]); } - if (!(bb.getSnapped() || sn.getSnapped())) { + // These lines below are duplicated in scaleRequest + if (bb.getSnapped() || sn.getSnapped()) { + if (bb.getSnapped()) { + if (!bb.isOtherSnapBetter(sn, false)) { + // We snapped the bbox (which is either visual or geometric) + _desktop->snapindicator->set_new_snaptarget(bb); + default_scale = Geom::Scale(bb.getTransformation()); + // Calculate the new transformation and update the handle position + pt = _calcAbsAffineDefault(default_scale); + } + } else if (sn.getSnapped()) { + _desktop->snapindicator->set_new_snaptarget(sn); + // We snapped the special points (e.g. nodes), which are not at the visual bbox + // The handle location however (pt) might however be at the visual bbox, so we + // will have to calculate pt taking the stroke width into account + geom_scale = Geom::Scale(sn.getTransformation()); + pt = _calcAbsAffineGeom(geom_scale); + } + } else { // We didn't snap at all! Don't update the handle position, just calculate the new transformation _calcAbsAffineDefault(default_scale); _desktop->snapindicator->remove_snaptarget(); - } else if (bb.getSnapped() && !bb.isOtherSnapBetter(sn, false)) { - _desktop->snapindicator->set_new_snaptarget(bb); - // Calculate the new transformation and update the handle position - pt = _calcAbsAffineDefault(default_scale); - } else { - _desktop->snapindicator->set_new_snaptarget(sn); - // We snapped the special points (e.g. nodes), which are not at the visual bbox - // The handle location however (pt) might however be at the visual bbox, so we - // will have to calculate pt taking the stroke width into account - pt = _calcAbsAffineGeom(geom_scale); } m.unSetup(); diff --git a/src/snap.cpp b/src/snap.cpp index ecf799cdc..ea6322e37 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -239,7 +239,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapCandidatePoint // Snapping the mouse pointer instead of the constrained position of the knot allows // to snap to things which don't intersect with the constraint line; this is basically // then just a freesnap with the constraint applied afterwards - // We'll only to this if we're dragging a single handle, and for example not when transforming an object in the selector tool + // We'll only do this if we're dragging a single handle, and for example not when transforming an object in the selector tool result = freeSnap(p, bbox_to_snap); if (result.getSnapped()) { // only change the snap indicator if we really snapped to something @@ -570,7 +570,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( // be collected. Therefore we enforce that the first SnapCandidatePoint that is to be freeSnapped always // has source_num == 0; // TODO: This is a bit ugly so fix this; do we need sourcenum for anything else? if we don't then get rid - // of it and explicitely communicate to the object snapper that this is a first point + // of it and explicitly communicate to the object snapper that this is a first point if (first_free_snap) { (*j).setSourceNum(0); first_free_snap = false; @@ -616,8 +616,8 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( // and the scaling factor for the other direction should remain // untouched (unless scaling is uniform of course) for (int index = 0; index < 2; index++) { - if (fabs(b[index]) > 1e-6) { // if SCALING CAN occur in this direction - if (fabs(fabs(a[index]/b[index]) - fabs(transformation[index])) > 1e-12) { // if SNAPPING DID occur in this direction + if (fabs(b[index]) > 1e-4) { // if SCALING CAN occur in this direction + if (fabs(fabs(a[index]/b[index]) - fabs(transformation[index])) > 1e-7) { // if SNAPPING DID occur in this direction result[index] = a[index] / b[index]; // then calculate it! } // we might have left result[1-index] = Geom::infinity() @@ -669,7 +669,7 @@ Inkscape::SnappedPoint SnapManager::_snapTransformed( case ROTATE: // a is vector to snapped point; b is vector to original point; now lets calculate angle between a and b result[0] = atan2(Geom::dot(Geom::rot90(b), a), Geom::dot(b, a)); - result[1] = result[1]; // how else should we store an angle in a point ;-) + result[1] = result[0]; // dummy value; how else should we store an angle in a point ;-) if (Geom::L2(b) < 1e-9) { // points too close to the rotation center will not move. Don't try to snap these // as they will always yield a perfect snap result if they're already snapped beforehand (e.g. // when the transformation center has been snapped to a grid intersection in the selector tool) -- cgit v1.2.3 From 11eaa0b10f1663c821dc669289f633eb6d20f80a Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 12 May 2014 22:04:46 +0200 Subject: remove unnecessary include, that is causing troubles (it is doing a bad #define in MinGW) (bzr r13363) --- src/widgets/ege-paint-def.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/widgets/ege-paint-def.cpp b/src/widgets/ege-paint-def.cpp index 542205b53..1a8ad041a 100644 --- a/src/widgets/ege-paint-def.cpp +++ b/src/widgets/ege-paint-def.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 56a433955a5472fa2762bfa828df12aacd6c96e1 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 12 May 2014 23:48:39 +0200 Subject: add Windows resource files for x64 builds (bzr r13366) --- src/inkscape-manifest-x64.xml | 10 ++++++++++ src/inkscape-x64.rc | 30 ++++++++++++++++++++++++++++++ src/inkview-x64.rc | 29 +++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/inkscape-manifest-x64.xml create mode 100644 src/inkscape-x64.rc create mode 100644 src/inkview-x64.rc (limited to 'src') diff --git a/src/inkscape-manifest-x64.xml b/src/inkscape-manifest-x64.xml new file mode 100644 index 000000000..ec8ef44d8 --- /dev/null +++ b/src/inkscape-manifest-x64.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/src/inkscape-x64.rc b/src/inkscape-x64.rc new file mode 100644 index 000000000..ce286c2ca --- /dev/null +++ b/src/inkscape-x64.rc @@ -0,0 +1,30 @@ + +APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" +1 24 DISCARDABLE "./inkscape-manifest-x64.xml" + +1 VERSIONINFO + FILEVERSION 0,48,0,9 + PRODUCTVERSION 0,48,0,9 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040901b5" + BEGIN + VALUE "Comments", "Published under the GNU GPL" + VALUE "CompanyName", "inkscape.org" + VALUE "FileDescription", "Inkscape" + VALUE "FileVersion", "0.48+devel" + VALUE "InternalName", "Inkscape" + VALUE "LegalCopyright", " 2014 Inkscape" + VALUE "ProductName", "Inkscape" + VALUE "ProductVersion", "0.48+devel" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1033, 437 + END +END + +1000 BITMAP "./show-preview.bmp" + diff --git a/src/inkview-x64.rc b/src/inkview-x64.rc new file mode 100644 index 000000000..2de16060b --- /dev/null +++ b/src/inkview-x64.rc @@ -0,0 +1,29 @@ + +APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" +1 24 DISCARDABLE "./inkview-manifest-x64.xml" + +1 VERSIONINFO + FILEVERSION 0,48,0,9 + PRODUCTVERSION 0,48,0,9 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040901b5" + BEGIN + VALUE "Comments", "Published under the GNU GPL" + VALUE "CompanyName", "inkscape.org" + VALUE "FileDescription", "Inkview" + VALUE "FileVersion", "0.48+devel" + VALUE "InternalName", "Inkview" + VALUE "LegalCopyright", " 2014 Inkscape" + VALUE "ProductName", "Inkview" + VALUE "ProductVersion", "0.48+devel" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1033, 437 + END +END + +1000 BITMAP "./show-preview.bmp" -- cgit v1.2.3 From b83d1944463950ab27b4eff6bd746e91bca32fff Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 12 May 2014 23:52:55 +0200 Subject: add x64 Windows resource file (bzr r13367) --- src/inkview-manifest-x64.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/inkview-manifest-x64.xml (limited to 'src') diff --git a/src/inkview-manifest-x64.xml b/src/inkview-manifest-x64.xml new file mode 100644 index 000000000..ec8ef44d8 --- /dev/null +++ b/src/inkview-manifest-x64.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file -- cgit v1.2.3 From 6e65bac42d427f3f34749242defdbb489f6c4c0a Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 13 May 2014 00:12:16 +0200 Subject: put correct architecture in x64 Windows resource manifests (bzr r13369) --- src/inkscape-manifest-x64.xml | 2 +- src/inkview-manifest-x64.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/inkscape-manifest-x64.xml b/src/inkscape-manifest-x64.xml index ec8ef44d8..38526cfe6 100644 --- a/src/inkscape-manifest-x64.xml +++ b/src/inkscape-manifest-x64.xml @@ -3,7 +3,7 @@ diff --git a/src/inkview-manifest-x64.xml b/src/inkview-manifest-x64.xml index ec8ef44d8..38526cfe6 100644 --- a/src/inkview-manifest-x64.xml +++ b/src/inkview-manifest-x64.xml @@ -3,7 +3,7 @@ -- cgit v1.2.3 From c1b60947d10a0455b023ae8bbe7b2b4414114ac5 Mon Sep 17 00:00:00 2001 From: Josh Andler Date: Mon, 12 May 2014 15:12:41 -0700 Subject: Patch from Jabierxto to fix a bug I reported off-tracker. (bzr r13341.3.1) --- src/ui/tool/node.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 1434a5c5b..f077bcffc 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -623,7 +623,7 @@ void Node::move(Geom::Point const &new_pos) Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - nodeWeight = _pm().BSplineHandlePosition(n->front()); + nodeWeight = fmax(_pm().BSplineHandlePosition(n->front()),_pm().BSplineHandlePosition(n->back())); if(prevNode){ if(prevNode->isEndNode()){ prevNodeWeight = _pm().BSplineHandlePosition(prevNode->front(),prevNode->front()); @@ -659,7 +659,7 @@ void Node::move(Geom::Point const &new_pos) if(nextNode->isEndNode()){ nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNodeWeight)); }else{ - nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->back())); + nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextNode->front())); } } } -- cgit v1.2.3 From 8e303a547b23758ec6c1accee912185f25718c03 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 12 May 2014 19:59:28 -0400 Subject: Commit patch for "leaned" cap. Thanks Jabiertxof! (bzr r13090.1.78) --- src/live_effects/lpe-jointype.cpp | 24 ++++++--- src/live_effects/lpe-jointype.h | 2 + src/live_effects/pathoutlineprovider.cpp | 92 ++++++++++++++++++++++++++------ src/live_effects/pathoutlineprovider.h | 14 +++-- 4 files changed, 105 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index 0c1813970..b0a6e845b 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -41,10 +41,11 @@ static const Util::EnumData JoinTypeData[] = { }; static const Util::EnumData CapTypeData[] = { - {butt_straight, N_("Butt"), "butt"}, - {butt_round, N_("Rounded"), "round"}, - {butt_square, N_("Square"), "square"}, - {butt_pointy, N_("Peak"), "peak"} + {BUTT_STRAIGHT, N_("Butt"), "butt"}, + {BUTT_ROUND, N_("Rounded"), "round"}, + {BUTT_SQUARE, N_("Square"), "square"}, + {BUTT_POINTY, N_("Peak"), "peak"}, + {BUTT_LEANED, N_("Leaned"), "leaned"} }; static const Util::EnumDataConverter CapTypeConverter(CapTypeData, sizeof(CapTypeData)/sizeof(*CapTypeData)); @@ -55,6 +56,8 @@ LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) : line_width(_("Line width"), _("Thickness of the stroke"), "line_width", &wr, this, 1.), linecap_type(_("Line cap"), _("The end shape of the stroke"), "linecap_type", CapTypeConverter, &wr, this, butt_straight), linejoin_type(_("Join:"), _("Determines the shape of the path's corners"), "linejoin_type", JoinTypeConverter, &wr, this, LINEJOIN_EXTRAPOLATED), + start_lean(_("Start path lean"), _("Start path lean"), "start_lean", &wr, this, 0.), + end_lean(_("End path lean"), _("End path lean"), "end_lean", &wr, this, 0.), miter_limit(_("Miter limit:"), _("Maximum length of the miter join (in units of stroke width)"), "miter_limit", &wr, this, 100.), attempt_force_join(_("Force miter"), _("Overrides the miter limit and forces a join."), "attempt_force_join", &wr, this, true) { @@ -62,9 +65,17 @@ LPEJoinType::LPEJoinType(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&linecap_type) ); registerParameter( dynamic_cast(&line_width) ); registerParameter( dynamic_cast(&linejoin_type) ); + registerParameter( dynamic_cast(&start_lean) ); + registerParameter( dynamic_cast(&end_lean) ); registerParameter( dynamic_cast(&miter_limit) ); registerParameter( dynamic_cast(&attempt_force_join) ); was_initialized = false; + start_lean.param_set_range(-1,1); + start_lean.param_set_increments(0.1, 0.1); + start_lean.param_set_digits(4); + end_lean.param_set_range(-1,1); + end_lean.param_set_increments(0.1, 0.1); + end_lean.param_set_digits(4); } LPEJoinType::~LPEJoinType() @@ -163,9 +174,10 @@ void LPEJoinType::doOnRemove(SPLPEItem const* lpeitem) //wrapper around it. std::vector LPEJoinType::doEffect_path(std::vector const & path_in) { - return Outline::PathVectorOutline(path_in, line_width, static_cast(linecap_type.get_value()), + return Outline::PathVectorOutline(path_in, line_width, static_cast(linecap_type.get_value()), static_cast(linejoin_type.get_value()), - (attempt_force_join ? std::numeric_limits::max() : miter_limit)); + (attempt_force_join ? std::numeric_limits::max() : miter_limit), + start_lean/2 ,end_lean/2); } } //namespace LivePathEffect diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h index db113c66a..7ebce1c7e 100755 --- a/src/live_effects/lpe-jointype.h +++ b/src/live_effects/lpe-jointype.h @@ -32,6 +32,8 @@ private: ScalarParam line_width; EnumParam linecap_type; EnumParam linejoin_type; + ScalarParam start_lean; + ScalarParam end_lean; ScalarParam miter_limit; BoolParam attempt_force_join; bool was_initialized; diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index 9ff896f84..d6e0ce7ea 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -586,7 +586,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double } Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, - ButtType butt, double miter_lim, bool extrapolate) + ButtTypeMod butt, double miter_lim, bool extrapolate, double start_lean, double end_lean) { Geom::PathVector path_out; @@ -610,13 +610,13 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, //add in our line caps if (!path_in[i].closed()) { switch (butt) { - case butt_straight: + case BUTT_STRAIGHT: pb.lineTo(against_direction.initialPoint()); break; - case butt_round: + case BUTT_ROUND: pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, against_direction.initialPoint() ); break; - case butt_pointy: { + case BUTT_POINTY: { Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.); double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint()); Geom::Point midpoint = 0.5 * (with_direction.finalPoint() + against_direction.initialPoint()) + radius*end_deriv; @@ -624,7 +624,7 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, pb.lineTo(against_direction.initialPoint()); break; } - case butt_square: { + case BUTT_SQUARE: { Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.); double radius = 0.5 * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint()); pb.lineTo(with_direction.finalPoint() + radius*end_deriv); @@ -632,6 +632,15 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, pb.lineTo(against_direction.initialPoint()); break; } + case BUTT_LEANED: { + Geom::Point end_deriv = -Geom::unitTangentAt(Geom::reverse(path_in[i].back().toSBasis()), 0.); + double maxRadius = (end_lean+0.5) * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint()); + double minRadius = ((end_lean*-1)+0.5) * Geom::distance(with_direction.finalPoint(), against_direction.initialPoint()); + pb.lineTo(with_direction.finalPoint() + maxRadius*end_deriv); + pb.lineTo(against_direction.initialPoint() + minRadius*end_deriv); + pb.lineTo(against_direction.initialPoint()); + break; + } } } else { pb.moveTo(against_direction.initialPoint()); @@ -642,13 +651,13 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, //cap (if necessary) if (!path_in[i].closed()) { switch (butt) { - case butt_straight: + case BUTT_STRAIGHT: pb.lineTo(with_direction.initialPoint()); break; - case butt_round: + case BUTT_ROUND: pb.arcTo((-line_width) / 2, (-line_width) / 2, 0., true, true, with_direction.initialPoint() ); break; - case butt_pointy: { + case BUTT_POINTY: { Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.); double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint()); Geom::Point midpoint = 0.5 * (against_direction.finalPoint() + with_direction.initialPoint()) + radius*end_deriv; @@ -656,7 +665,7 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, pb.lineTo(with_direction.initialPoint()); break; } - case butt_square: { + case BUTT_SQUARE: { Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.); double radius = 0.5 * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint()); pb.lineTo(against_direction.finalPoint() + radius*end_deriv); @@ -664,6 +673,15 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, pb.lineTo(with_direction.initialPoint()); break; } + case BUTT_LEANED: { + Geom::Point end_deriv = -Geom::unitTangentAt(path_in[i].front().toSBasis(), 0.); + double maxRadius = (start_lean+0.5) * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint()); + double minRadius = ((start_lean*-1)+0.5) * Geom::distance(against_direction.finalPoint(), with_direction.initialPoint()); + pb.lineTo(against_direction.finalPoint() + minRadius*end_deriv); + pb.lineTo(with_direction.initialPoint() + maxRadius*end_deriv); + pb.lineTo(with_direction.initialPoint()); + break; + } } } pb.flush(); @@ -674,9 +692,29 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, } else { Path p = Path(); Path outlinepath = Path(); - + ButtType original_butt; + switch (butt) { + case BUTT_STRAIGHT: + original_butt = butt_straight; + break; + case BUTT_ROUND: + original_butt = butt_round; + break; + case butt_pointy: { + original_butt = butt_pointy; + break; + } + case BUTT_SQUARE: { + original_butt = butt_square; + break; + } + case BUTT_LEANED: { + original_butt = butt_straight; + break; + } + } p.LoadPath(path_in[i], Geom::Affine(), false, false); - p.Outline(&outlinepath, line_width / 2, static_cast(join), butt, miter_lim); + p.Outline(&outlinepath, line_width / 2, static_cast(join), original_butt, miter_lim); Geom::PathVector *pv_p = outlinepath.MakePathVector(); //somewhat hack-ish path_out.push_back( (*pv_p)[0].reverse() ); @@ -686,8 +724,8 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, return path_out; } -Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtType linecap_type, - LineJoinType linejoin_type, double miter_limit) +Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtTypeMod linecap_type, + LineJoinType linejoin_type, double miter_limit, double start_lean, double end_lean) { std::vector path_out = std::vector(); if (path_in.empty()) { @@ -702,9 +740,30 @@ Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line #define miter_lim fabs(line_width * miter_limit) //magic! + ButtType original_butt; + switch (linecap_type) { + case BUTT_STRAIGHT: + original_butt = butt_straight; + break; + case BUTT_ROUND: + original_butt = butt_round; + break; + case butt_pointy: { + original_butt = butt_pointy; + break; + } + case BUTT_SQUARE: { + original_butt = butt_square; + break; + } + case BUTT_LEANED: { + original_butt = butt_straight; + break; + } + } if (linejoin_type <= 2) { p.Outline(&outlinepath, line_width / 2, static_cast(linejoin_type), - linecap_type, miter_lim); + original_butt, miter_lim); //fix memory leak std::vector *pv_p = outlinepath.MakePathVector(); path_out = *pv_p; @@ -713,12 +772,11 @@ Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line } else if (linejoin_type == 3) { //reflected arc join path_out = outlinePath(path_in, line_width, static_cast(linejoin_type), - linecap_type , miter_lim, false); + linecap_type , miter_lim, false, start_lean, end_lean); } else if (linejoin_type == 4) { //extrapolated arc join - path_out = outlinePath(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim, true); - + path_out = outlinePath(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim, true, start_lean, end_lean); } #undef miter_lim diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h index 0ee0f261e..272c93a49 100644 --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -11,7 +11,13 @@ enum LineJoinType { LINEJOIN_REFLECTED, LINEJOIN_EXTRAPOLATED }; - +enum ButtTypeMod { + BUTT_STRAIGHT, + BUTT_ROUND, + BUTT_SQUARE, + BUTT_POINTY, + BUTT_LEANED +}; namespace Geom { Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in); @@ -21,11 +27,11 @@ namespace Geom namespace Outline { unsigned bezierOrder (const Geom::Curve* curve_in); - std::vector PathVectorOutline(std::vector const & path_in, double line_width, ButtType linecap_type, - LineJoinType linejoin_type, double miter_limit); + std::vector PathVectorOutline(std::vector const & path_in, double line_width, ButtTypeMod linecap_type, + LineJoinType linejoin_type, double miter_limit, double start_lean = 0, double end_lean = 0); /*Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, - ButtType butt, double miter_lim, bool extrapolate = false);*/ + ButtTypeMod butt, double miter_lim, bool extrapolate = false);*/ Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit); } -- cgit v1.2.3 From 8dbf7bd73db6bb549b3e0be3fba91cddfcb589b8 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 May 2014 07:35:50 +0200 Subject: Fixed a bug in bspline with snaps and 1 sice segments. Pointed by LiamW (bzr r13341.1.12) --- src/live_effects/lpe-bspline.cpp | 22 +++++++++++++++++++--- src/ui/tool/node.cpp | 2 +- src/ui/tools/pen-tool.cpp | 22 +++++++++++++++++++--- 3 files changed, 39 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index edf19d1e5..454924d2b 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -96,7 +96,7 @@ void LPEBSpline::createAndApply(const char *name, SPDocument *doc, } void LPEBSpline::doEffect(SPCurve *curve) { - if (curve->get_segment_count() < 2) + if (curve->get_segment_count() < 1) return; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); @@ -216,10 +216,26 @@ void LPEBSpline::doEffect(SPCurve *curve) { ++curve_it1; ++curve_it2; } + SPCurve *out = new SPCurve(); + out->moveto(curve_it1->initialPoint()); + out->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2], *out->first_segment())); + nextPointAt3 = out->first_segment()->finalPoint(); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + } + out->reset(); + delete out; //Si está cerrada la curva, la cerramos sobre el valor guardado //previamente //Si no finalizamos en el punto final - Geom::Point startNode(0, 0); + Geom::Point startNode = path_it->begin()->initialPoint(); if (path_it->closed()) { SPCurve *start = new SPCurve(); start->moveto(path_it->begin()->initialPoint()); @@ -421,7 +437,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { } } //bool hasNodesSelected = LPEBspline::hasNodesSelected(); - if (curve->get_segment_count() < 2) + if (curve->get_segment_count() < 1) return; // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index f077bcffc..ed0843b65 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -371,7 +371,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) std::vector unselected; //if the snap adjustment is activated and it is not bspline - if (snap && !_pm().isBSpline()) { + if (snap && !_pm().isBSpline(false)) { ControlPointSelection::Set &nodes = _parent->_selection.allPoints(); for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { Node *n = static_cast(*i); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 9e4df5031..386dc43e9 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1811,9 +1811,9 @@ void PenTool::_bspline_spiro_build() void PenTool::_bspline_doEffect(SPCurve * curve) { // commenting the function doEffect in src/live_effects/lpe-bspline.cpp - if(curve->get_segment_count() < 2) - return; Geom::PathVector const original_pathv = curve->get_pathvector(); + if (curve->get_segment_count() < 1) + return; curve->reset(); for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -1890,9 +1890,25 @@ void PenTool::_bspline_doEffect(SPCurve * curve) ++curve_it1; ++curve_it2; } + SPCurve *out = new SPCurve(); + out->moveto(curve_it1->initialPoint()); + out->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2], *out->first_segment())); + nextPointAt3 = out->first_segment()->finalPoint(); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + } + out->reset(); + delete out; SPCurve *curveHelper = new SPCurve(); curveHelper->moveto(node); - Geom::Point startNode(0,0); + Geom::Point startNode = path_it->begin()->initialPoint(); if (path_it->closed()) { SPCurve * start = new SPCurve(); start->moveto(path_it->begin()->initialPoint()); -- cgit v1.2.3 From 9cd50c94d560a2372a755bdf58ccf7feb7afe083 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 May 2014 08:50:42 +0200 Subject: Add Simplify LPE (bzr r13341.1.13) --- src/live_effects/CMakeLists.txt | 4 +++ src/live_effects/Makefile_insert | 2 ++ src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 14 ++++++-- src/live_effects/parameter/Makefile_insert | 2 ++ src/ui/tools/node-tool.cpp | 48 +++++++++++++++++++++++++-- src/ui/tools/node-tool.h | 2 ++ src/ui/widget/registered-widget.cpp | 53 ++++++++++++++++++++++++++++++ src/ui/widget/registered-widget.h | 25 ++++++++++++++ 9 files changed, 145 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 7aeb911b0..5979cd028 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -29,6 +29,7 @@ set(live_effects_SRC lpe-recursiveskeleton.cpp lpe-rough-hatches.cpp lpe-ruler.cpp + lpe-simplify.cpp # lpe-skeleton.cpp lpe-sketch.cpp lpe-spiro.cpp @@ -53,6 +54,7 @@ set(live_effects_SRC parameter/powerstrokepointarray.cpp parameter/random.cpp parameter/text.cpp + parameter/togglebutton.cpp parameter/unit.cpp parameter/vector.cpp @@ -90,6 +92,7 @@ set(live_effects_SRC lpe-recursiveskeleton.h lpe-rough-hatches.h lpe-ruler.h + lpe-simplify.h lpe-skeleton.h lpe-sketch.h lpe-spiro.h @@ -115,6 +118,7 @@ set(live_effects_SRC parameter/powerstrokepointarray.h parameter/random.h parameter/text.h + parameter/togglebutton.h parameter/unit.h parameter/vector.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 248030e8c..a9da81d5b 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -42,6 +42,8 @@ ink_common_sources += \ live_effects/lpe-bspline.h \ live_effects/lpe-lattice.cpp \ live_effects/lpe-lattice.h \ + live_effects/lpe-simplify.cpp \ + live_effects/lpe-simplify.h \ live_effects/lpe-envelope.cpp \ live_effects/lpe-envelope.h \ live_effects/lpe-spiro.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 342a2c849..cacb1190f 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -28,6 +28,7 @@ enum EffectType { PERSPECTIVE_PATH, SPIRO, LATTICE, + SIMPLIFY, ENVELOPE, CONSTRUCT_GRID, PERP_BISECTOR, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 9006e5359..66bce9c1d 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -26,6 +26,7 @@ #include "live_effects/lpe-perspective_path.h" #include "live_effects/lpe-spiro.h" #include "live_effects/lpe-lattice.h" +#include "live_effects/lpe-simplify.h" #include "live_effects/lpe-envelope.h" #include "live_effects/lpe-constructgrid.h" #include "live_effects/lpe-perp_bisector.h" @@ -122,6 +123,7 @@ const Util::EnumData LPETypeData[] = { {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, {BSPLINE, N_("BSpline"), "bspline"}, + {SIMPLIFY, N_("Simplify"), "simplify"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -248,6 +250,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case CLONE_ORIGINAL: neweffect = static_cast ( new LPECloneOriginal(lpeobj) ); break; + case SIMPLIFY: + neweffect = static_cast ( new LPESimplify(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; @@ -499,9 +504,12 @@ Effect::getCanvasIndicators(SPLPEItem const* lpeitem) { std::vector hp_vec; - if (!SP_IS_SHAPE(lpeitem)) { -// g_print ("How to handle helperpaths for non-shapes?\n"); // non-shapes are for example SPGroups. - return hp_vec; + // TODO: we can probably optimize this by using a lot more references + // rather than copying PathVectors all over the place + if (SP_IS_SHAPE(lpeitem) && show_orig_path) { + // add original path to helperpaths + SPCurve* curve = SP_SHAPE(lpeitem)->getCurve (); + hp_vec.push_back(curve->get_pathvector()); } // add indicators provided by the effect itself diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index efdda686a..30f1f510b 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -22,6 +22,8 @@ ink_common_sources += \ live_effects/parameter/powerstrokepointarray.h \ live_effects/parameter/text.cpp \ live_effects/parameter/text.h \ + live_effects/parameter/togglebutton.cpp \ + live_effects/parameter/togglebutton.h \ live_effects/parameter/unit.cpp \ live_effects/parameter/unit.h \ live_effects/parameter/vector.cpp \ diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index b1e11bd66..ce487831d 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -23,6 +23,8 @@ #include "message-context.h" #include "selection.h" #include "shape-editor.h" // temporary! +#include "live_effects/effect.h" +#include "display/curve.h" #include "sp-clippath.h" #include "sp-item-group.h" #include "sp-mask.h" @@ -167,6 +169,10 @@ NodeTool::~NodeTool() { this->desktop->remove_temporary_canvasitem(this->flash_tempitem); } + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + } + this->_selection_changed_connection.disconnect(); //this->_selection_modified_connection.disconnect(); this->_mouseover_changed_connection.disconnect(); @@ -252,6 +258,7 @@ void NodeTool::setup() { this->flash_tempitem = NULL; this->flashed_item = NULL; this->_last_over = NULL; + this->helperpath_tmpitem = NULL; // read prefs before adding items to selection to prevent momentarily showing the outline sp_event_context_read(this, "show_handles"); @@ -278,6 +285,41 @@ void NodeTool::setup() { } this->desktop->emitToolSubselectionChanged(NULL); // sets the coord entry fields to inactive + this->update_helperpath(); +} + +void NodeTool::update_helperpath(){ + Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + this->helperpath_tmpitem = NULL; + } + if (SP_IS_LPE_ITEM(selection->singleItem())) { + Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); + if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { + if (lpe) { + SPCurve *c = new SPCurve(); + SPCurve *cc = new SPCurve(); + std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); + for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { + cc->set_pathvector(*p); + c->append(cc, false); + cc->reset(); + } + if (!c->is_empty()) { + c->transform(selection->singleItem()->i2dt_affine()); + SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), + 0x0000ff9A, 1.0, + SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); + this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0); + } + c->unref(); + cc->unref(); + } + } + } } void NodeTool::set(const Inkscape::Preferences::Entry& value) { @@ -392,7 +434,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { for (std::set::iterator i = shapes.begin(); i != shapes.end(); ++i) { ShapeRecord const &r = *i; - if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item)) && + if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item) || SP_IS_GROUP(r.item) || SP_IS_OBJECTGROUP(r.item)) && this->_shape_editors.find(r.item) == this->_shape_editors.end()) { ShapeEditor *si = new ShapeEditor(this->desktop); @@ -416,7 +458,7 @@ bool NodeTool::root_handler(GdkEvent* event) { Inkscape::Selection *selection = desktop->selection; static Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - + if (this->_multipath->event(this, event)) { return true; } @@ -433,6 +475,7 @@ bool NodeTool::root_handler(GdkEvent* event) { { case GDK_MOTION_NOTIFY: { combine_motion_events(desktop->canvas, event->motion, 0); + this->update_helperpath(); SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button), FALSE, TRUE); @@ -441,7 +484,6 @@ bool NodeTool::root_handler(GdkEvent* event) { //ink_node_tool_update_tip(nt, event); this->update_tip(event); } - // create pathflash outline if (prefs->getBool("/tools/nodes/pathflash_enabled")) { if (over_item == this->flashed_item) { diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 42f89cd1c..9f0c40aa8 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -54,6 +54,7 @@ public: static const std::string prefsPath; virtual void setup(); + virtual void update_helperpath(); virtual void set(const Inkscape::Preferences::Entry& val); virtual bool root_handler(GdkEvent* event); @@ -66,6 +67,7 @@ private: SPItem *flashed_item; Inkscape::Display::TemporaryItem *flash_tempitem; + Inkscape::Display::TemporaryItem *helperpath_tmpitem; Inkscape::UI::Selector* _selector; Inkscape::UI::PathSharedData* _path_data; SPCanvasGroup *_transform_handle_group; diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 92cb3f03d..83da1a6d6 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -99,6 +99,59 @@ RegisteredCheckButton::on_toggled() _wr->setUpdating (false); } +/*######################################### + * Registered TOGGLEBUTTON + */ + +RegisteredToggleButton::~RegisteredToggleButton() +{ + _toggled_connection.disconnect(); +} + +RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) + : RegisteredWidget(label) + , _active_str(active_str) + , _inactive_str(inactive_str) +{ + init_parent(key, wr, repr_in, doc_in); + setProgrammatically = false; + set_tooltip_text (tip); + set_alignment (right? 1.0 : 0.0, 0.5); + _toggled_connection = signal_toggled().connect (sigc::mem_fun (*this, &RegisteredToggleButton::on_toggled)); +} + +void +RegisteredToggleButton::setActive (bool b) +{ + setProgrammatically = true; + set_active (b); + //The slave button is greyed out if the master button is untoggled + for (std::list::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { + (*i)->set_sensitive(b); + } + setProgrammatically = false; +} + +void +RegisteredToggleButton::on_toggled() +{ + if (setProgrammatically) { + setProgrammatically = false; + return; + } + + if (_wr->isUpdating()) + return; + _wr->setUpdating (true); + + write_to_xml(get_active() ? _active_str : _inactive_str); + //The slave button is greyed out if the master button is untoggled + for (std::list::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { + (*i)->set_sensitive(get_active()); + } + + _wr->setUpdating (false); +} /*######################################### * Registered UNITMENU diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index d64c09c16..d8c0e6602 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -163,6 +163,31 @@ protected: void on_toggled(); }; +class RegisteredToggleButton : public RegisteredWidget { +public: + virtual ~RegisteredToggleButton(); + RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right=true, Inkscape::XML::Node* repr_in=NULL, SPDocument *doc_in=NULL, char const *active_str = "true", char const *inactive_str = "false"); + + void setActive (bool); + + std::list _slavewidgets; + + // a slave button is only sensitive when the master button is active + // i.e. a slave button is greyed-out when the master button is not checked + + void setSlaveWidgets(std::list btns) { + _slavewidgets = btns; + } + + bool setProgrammatically; // true if the value was set by setActive, not changed by the user; + // if a callback checks it, it must reset it back to false + +protected: + char const *_active_str, *_inactive_str; + sigc::connection _toggled_connection; + void on_toggled(); +}; + class RegisteredUnitMenu : public RegisteredWidget { public: ~RegisteredUnitMenu(); -- cgit v1.2.3 From d516a941370f10590ad305b9fcbe1a4a7622df90 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 May 2014 09:44:27 +0200 Subject: Added Latice2 deformation LPE (bzr r13341.1.14) --- src/live_effects/Makefile_insert | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 5 + src/live_effects/lpe-lattice.h | 1 - src/live_effects/lpe-lattice2.cpp | 496 +++++++++++++++++++++++++ src/live_effects/lpe-lattice2.h | 92 +++++ src/live_effects/parameter/Makefile_insert | 2 + src/live_effects/parameter/pointreseteable.cpp | 210 +++++++++++ src/live_effects/parameter/pointreseteable.h | 74 ++++ 9 files changed, 882 insertions(+), 1 deletion(-) create mode 100644 src/live_effects/lpe-lattice2.cpp create mode 100644 src/live_effects/lpe-lattice2.h create mode 100644 src/live_effects/parameter/pointreseteable.cpp create mode 100644 src/live_effects/parameter/pointreseteable.h (limited to 'src') diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index a9da81d5b..aa6a372a8 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -42,6 +42,8 @@ ink_common_sources += \ live_effects/lpe-bspline.h \ live_effects/lpe-lattice.cpp \ live_effects/lpe-lattice.h \ + live_effects/lpe-lattice2.cpp \ + live_effects/lpe-lattice2.h \ live_effects/lpe-simplify.cpp \ live_effects/lpe-simplify.h \ live_effects/lpe-envelope.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index cacb1190f..bd7f6cf23 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -28,6 +28,7 @@ enum EffectType { PERSPECTIVE_PATH, SPIRO, LATTICE, + LATTICE2, SIMPLIFY, ENVELOPE, CONSTRUCT_GRID, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 66bce9c1d..76546c093 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -26,6 +26,7 @@ #include "live_effects/lpe-perspective_path.h" #include "live_effects/lpe-spiro.h" #include "live_effects/lpe-lattice.h" +#include "live_effects/lpe-lattice2.h" #include "live_effects/lpe-simplify.h" #include "live_effects/lpe-envelope.h" #include "live_effects/lpe-constructgrid.h" @@ -124,6 +125,7 @@ const Util::EnumData LPETypeData[] = { {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, {BSPLINE, N_("BSpline"), "bspline"}, {SIMPLIFY, N_("Simplify"), "simplify"}, + {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -253,6 +255,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case SIMPLIFY: neweffect = static_cast ( new LPESimplify(lpeobj) ); break; + case LATTICE2: + neweffect = static_cast ( new LPELattice2(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-lattice.h b/src/live_effects/lpe-lattice.h index a44dda3fd..5eb48909b 100644 --- a/src/live_effects/lpe-lattice.h +++ b/src/live_effects/lpe-lattice.h @@ -58,7 +58,6 @@ private: PointParam grid_point13; PointParam grid_point14; PointParam grid_point15; - LPELattice(const LPELattice&); LPELattice& operator=(const LPELattice&); }; diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp new file mode 100644 index 000000000..db609c9e1 --- /dev/null +++ b/src/live_effects/lpe-lattice2.cpp @@ -0,0 +1,496 @@ +/** \file + * LPE implementation + + */ +/* + * Authors: + * Johan Engelen + * Steren Giannini + * No Falzon + * Victor Navez + * ~suv + * Jabiertxo Arraiza +* +* Copyright (C) 2007-2008 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-lattice2.h" + +#include "sp-shape.h" +#include "sp-item.h" +#include "sp-path.h" +#include "display/curve.h" +#include "svg/svg.h" + +#include <2geom/sbasis.h> +#include <2geom/sbasis-2d.h> +#include <2geom/sbasis-geometric.h> +#include <2geom/bezier-to-sbasis.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/d2.h> +#include <2geom/piecewise.h> +#include <2geom/transforms.h> +#include + +#include "desktop.h" // TODO: should be factored out (see below) + +using namespace Geom; + +namespace Inkscape { +namespace LivePathEffect { + +LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + // initialise your parameters here: + grid_point0(_("Control handle 0:"), _("Control handle 0 - Ctrl+Alt+Click to reset"), "gridpoint0", &wr, this), + grid_point1(_("Control handle 1:"), _("Control handle 1 - Ctrl+Alt+Click to reset"), "gridpoint1", &wr, this), + grid_point2(_("Control handle 2:"), _("Control handle 2 - Ctrl+Alt+Click to reset"), "gridpoint2", &wr, this), + grid_point3(_("Control handle 3:"), _("Control handle 3 - Ctrl+Alt+Click to reset"), "gridpoint3", &wr, this), + grid_point4(_("Control handle 4:"), _("Control handle 4 - Ctrl+Alt+Click to reset"), "gridpoint4", &wr, this), + grid_point5(_("Control handle 5:"), _("Control handle 5 - Ctrl+Alt+Click to reset"), "gridpoint5", &wr, this), + grid_point6(_("Control handle 6:"), _("Control handle 6 - Ctrl+Alt+Click to reset"), "gridpoint6", &wr, this), + grid_point7(_("Control handle 7:"), _("Control handle 7 - Ctrl+Alt+Click to reset"), "gridpoint7", &wr, this), + grid_point8x9(_("Control handle 8x9:"), _("Control handle 8x9 - Ctrl+Alt+Click to reset"), "gridpoint8x9", &wr, this), + grid_point10x11(_("Control handle 10x11:"), _("Control handle 10x11 - Ctrl+Alt+Click to reset"), "gridpoint10x11", &wr, this), + grid_point12(_("Control handle 12:"), _("Control handle 12 - Ctrl+Alt+Click to reset"), "gridpoint12", &wr, this), + grid_point13(_("Control handle 13:"), _("Control handle 13 - Ctrl+Alt+Click to reset"), "gridpoint13", &wr, this), + grid_point14(_("Control handle 14:"), _("Control handle 14 - Ctrl+Alt+Click to reset"), "gridpoint14", &wr, this), + grid_point15(_("Control handle 15:"), _("Control handle 15 - Ctrl+Alt+Click to reset"), "gridpoint15", &wr, this), + grid_point16(_("Control handle 16:"), _("Control handle 16 - Ctrl+Alt+Click to reset"), "gridpoint16", &wr, this), + grid_point17(_("Control handle 17:"), _("Control handle 17 - Ctrl+Alt+Click to reset"), "gridpoint17", &wr, this), + grid_point18(_("Control handle 18:"), _("Control handle 18 - Ctrl+Alt+Click to reset"), "gridpoint18", &wr, this), + grid_point19(_("Control handle 19:"), _("Control handle 19 - Ctrl+Alt+Click to reset"), "gridpoint19", &wr, this), + grid_point20x21(_("Control handle 20x21:"), _("Control handle 20x21 - Ctrl+Alt+Click to reset"), "gridpoint20x21", &wr, this), + grid_point22x23(_("Control handle 22x23:"), _("Control handle 22x23 - Ctrl+Alt+Click to reset"), "gridpoint22x23", &wr, this), + grid_point24x26(_("Control handle 24x26:"), _("Control handle 24x26 - Ctrl+Alt+Click to reset"), "gridpoint24x26", &wr, this), + grid_point25x27(_("Control handle 25x27:"), _("Control handle 25x27 - Ctrl+Alt+Click to reset"), "gridpoint25x27", &wr, this), + grid_point28x30(_("Control handle 28x30:"), _("Control handle 28x30 - Ctrl+Alt+Click to reset"), "gridpoint28x30", &wr, this), + grid_point29x31(_("Control handle 29x31:"), _("Control handle 29x31 - Ctrl+Alt+Click to reset"), "gridpoint29x31", &wr, this), + grid_point32x33x34x35(_("Control handle 32x33x34x35:"), _("Control handle 32x33x34x35 - Ctrl+Alt+Click to reset"), "gridpoint32x33x34x35", &wr, this) + + +{ + // register all your parameters here, so Inkscape knows which parameters this effect has: + registerParameter( dynamic_cast(&grid_point0) ); + registerParameter( dynamic_cast(&grid_point1) ); + registerParameter( dynamic_cast(&grid_point2) ); + registerParameter( dynamic_cast(&grid_point3) ); + registerParameter( dynamic_cast(&grid_point4) ); + registerParameter( dynamic_cast(&grid_point5) ); + registerParameter( dynamic_cast(&grid_point6) ); + registerParameter( dynamic_cast(&grid_point7) ); + registerParameter( dynamic_cast(&grid_point8x9) ); + registerParameter( dynamic_cast(&grid_point10x11) ); + registerParameter( dynamic_cast(&grid_point12) ); + registerParameter( dynamic_cast(&grid_point13) ); + registerParameter( dynamic_cast(&grid_point14) ); + registerParameter( dynamic_cast(&grid_point15) ); + registerParameter( dynamic_cast(&grid_point16) ); + registerParameter( dynamic_cast(&grid_point17) ); + registerParameter( dynamic_cast(&grid_point18) ); + registerParameter( dynamic_cast(&grid_point19) ); + registerParameter( dynamic_cast(&grid_point20x21) ); + registerParameter( dynamic_cast(&grid_point22x23) ); + registerParameter( dynamic_cast(&grid_point24x26) ); + registerParameter( dynamic_cast(&grid_point25x27) ); + registerParameter( dynamic_cast(&grid_point28x30) ); + registerParameter( dynamic_cast(&grid_point29x31) ); + registerParameter( dynamic_cast(&grid_point32x33x34x35) ); +} + +LPELattice2::~LPELattice2() +{ +} + +Geom::Piecewise > +LPELattice2::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) +{ + D2 sb2; + + //Initialisation of the sb2 + for(unsigned dim = 0; dim < 2; dim++) { + sb2[dim].us = 3; + sb2[dim].vs = 3; + const int depth = sb2[dim].us*sb2[dim].vs; + sb2[dim].resize(depth, Linear2d(0)); + } + + //Grouping the point params in a convenient vector + std::vector handles(36); + + handles[0] = &grid_point0; + handles[1] = &grid_point1; + handles[2] = &grid_point2; + handles[3] = &grid_point3; + handles[4] = &grid_point4; + handles[5] = &grid_point5; + handles[6] = &grid_point6; + handles[7] = &grid_point7; + handles[8] = &grid_point8x9; + handles[9] = &grid_point8x9; + handles[10] = &grid_point10x11; + handles[11] = &grid_point10x11; + handles[12] = &grid_point12; + handles[13] = &grid_point13; + handles[14] = &grid_point14; + handles[15] = &grid_point15; + handles[16] = &grid_point16; + handles[17] = &grid_point17; + handles[18] = &grid_point18; + handles[19] = &grid_point19; + handles[20] = &grid_point20x21; + handles[21] = &grid_point20x21; + handles[22] = &grid_point22x23; + handles[23] = &grid_point22x23; + handles[24] = &grid_point24x26; + handles[25] = &grid_point25x27; + handles[26] = &grid_point24x26; + handles[27] = &grid_point25x27; + handles[28] = &grid_point28x30; + handles[29] = &grid_point29x31; + handles[30] = &grid_point28x30; + handles[31] = &grid_point29x31; + handles[32] = &grid_point32x33x34x35; + handles[33] = &grid_point32x33x34x35; + handles[34] = &grid_point32x33x34x35; + handles[35] = &grid_point32x33x34x35; + + Geom::Point origin = Geom::Point(boundingbox_X.min(),boundingbox_Y.min()); + + double width = boundingbox_X.extent(); + double height = boundingbox_Y.extent(); + + //numbering is based on 4 rectangles.16 + for(unsigned dim = 0; dim < 2; dim++) { + Geom::Point dir(0,0); + dir[dim] = 1; + for(unsigned vi = 0; vi < sb2[dim].vs; vi++) { + for(unsigned ui = 0; ui < sb2[dim].us; ui++) { + for(unsigned iv = 0; iv < 2; iv++) { + for(unsigned iu = 0; iu < 2; iu++) { + unsigned corner = iu + 2*iv; + unsigned i = ui + vi*sb2[dim].us; + + //This is the offset from the Upperleft point + Geom::Point base( (ui + iu*(4-2*ui))*width/4., + (vi + iv*(4-2*vi))*height/4.); + + //Special action for corners + if(vi == 0 && ui == 0) { + base = Geom::Point(0,0); + } + + // i = Upperleft corner of the considerated rectangle + // corner = actual corner of the rectangle + // origin = Upperleft point + double dl = dot((*handles[corner+4*i] - (base + origin)), dir)/dot(dir,dir); + sb2[dim][i][corner] = dl/( dim ? height : width )*pow(4.0,ui+vi); + } + } + } + } + } + + Piecewise > output; + output.push_cut(0.); + for(unsigned i = 0; i < pwd2_in.size(); i++) { + D2 B = pwd2_in[i]; + B[Geom::X] -= origin[Geom::X]; + B[Geom::X]*= 1/width; + B[Geom::Y] -= origin[Geom::Y]; + B[Geom::Y]*= 1/height; + //Here comes the magic + D2 tB = compose_each(sb2,B); + tB[Geom::X] = tB[Geom::X] * width + origin[Geom::X]; + tB[Geom::Y] = tB[Geom::Y] * height + origin[Geom::Y]; + + output.push(tB,i+1); + } + return output; +} + +Gtk::Widget * +LPELattice2::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + + vbox->set_border_width(5); + Gtk::Button* resetButton = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset grid")))); + resetButton->set_alignment(0.0, 0.5); + resetButton->signal_clicked().connect(sigc::mem_fun (*this,&LPELattice2::resetGrid)); + Gtk::Widget* resetButtonWidget = dynamic_cast(resetButton); + resetButtonWidget->set_tooltip_text("Reset grid"); + vbox->pack_start(*resetButtonWidget, true, true,2); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); + if(param->param_key == "grid"){ + widg = NULL; + } + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + +void +LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem) +{ + original_bbox(lpeitem); + setDefaults(); +} + +void +LPELattice2::setDefaults() +{ + Geom::Point gp0((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min()); + + Geom::Point gp1((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min()); + + Geom::Point gp2((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min()); + + Geom::Point gp3((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min()); + + Geom::Point gp4((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min()); + + Geom::Point gp5((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min()); + + Geom::Point gp6((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min()); + + Geom::Point gp7((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min()); + + Geom::Point gp8x9((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*0+boundingbox_Y.min()); + + Geom::Point gp10x11((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*4+boundingbox_Y.min()); + + Geom::Point gp12((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min()); + + Geom::Point gp13((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min()); + + Geom::Point gp14((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min()); + + Geom::Point gp15((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min()); + + Geom::Point gp16((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min()); + + Geom::Point gp17((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min()); + + Geom::Point gp18((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min()); + + Geom::Point gp19((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min()); + + Geom::Point gp20x21((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*1+boundingbox_Y.min()); + + Geom::Point gp22x23((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*3+boundingbox_Y.min()); + + Geom::Point gp24x26((boundingbox_X.max()-boundingbox_X.min())/4*0+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min()); + + Geom::Point gp25x27((boundingbox_X.max()-boundingbox_X.min())/4*4+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min()); + + Geom::Point gp28x30((boundingbox_X.max()-boundingbox_X.min())/4*1+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min()); + + Geom::Point gp29x31((boundingbox_X.max()-boundingbox_X.min())/4*3+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min()); + + Geom::Point gp32x33x34x35((boundingbox_X.max()-boundingbox_X.min())/4*2+boundingbox_X.min(), + (boundingbox_Y.max()-boundingbox_Y.min())/4*2+boundingbox_Y.min()); + + grid_point0.param_update_default(gp0); + grid_point1.param_update_default(gp1); + grid_point2.param_update_default(gp2); + grid_point3.param_update_default(gp3); + grid_point4.param_update_default(gp4); + grid_point5.param_update_default(gp5); + grid_point6.param_update_default(gp6); + grid_point7.param_update_default(gp7); + grid_point8x9.param_update_default(gp8x9); + grid_point10x11.param_update_default(gp10x11); + grid_point12.param_update_default(gp12); + grid_point13.param_update_default(gp13); + grid_point14.param_update_default(gp14); + grid_point15.param_update_default(gp15); + grid_point16.param_update_default(gp16); + grid_point17.param_update_default(gp17); + grid_point18.param_update_default(gp18); + grid_point19.param_update_default(gp19); + grid_point20x21.param_update_default(gp20x21); + grid_point22x23.param_update_default(gp22x23); + grid_point24x26.param_update_default(gp24x26); + grid_point25x27.param_update_default(gp25x27); + grid_point28x30.param_update_default(gp28x30); + grid_point29x31.param_update_default(gp29x31); + grid_point32x33x34x35.param_update_default(gp32x33x34x35); +} + +void +LPELattice2::resetGrid() +{ + grid_point0.param_set_and_write_default(); + grid_point1.param_set_and_write_default(); + grid_point2.param_set_and_write_default(); + grid_point3.param_set_and_write_default(); + grid_point4.param_set_and_write_default(); + grid_point5.param_set_and_write_default(); + grid_point6.param_set_and_write_default(); + grid_point7.param_set_and_write_default(); + grid_point8x9.param_set_and_write_default(); + grid_point10x11.param_set_and_write_default(); + grid_point12.param_set_and_write_default(); + grid_point13.param_set_and_write_default(); + grid_point14.param_set_and_write_default(); + grid_point15.param_set_and_write_default(); + grid_point16.param_set_and_write_default(); + grid_point17.param_set_and_write_default(); + grid_point18.param_set_and_write_default(); + grid_point19.param_set_and_write_default(); + grid_point20x21.param_set_and_write_default(); + grid_point22x23.param_set_and_write_default(); + grid_point24x26.param_set_and_write_default(); + grid_point25x27.param_set_and_write_default(); + grid_point28x30.param_set_and_write_default(); + grid_point29x31.param_set_and_write_default(); + grid_point32x33x34x35.param_set_and_write_default(); + //todo:this hack is only to reposition the knots on reser grid button + //Better update path effect in LPEITEM + SPDesktop * desktop = inkscape_active_desktop(); + tools_switch(desktop, TOOLS_SELECT); + tools_switch(desktop, TOOLS_NODES); +} + +void +LPELattice2::resetDefaults(SPItem const* item) +{ + Effect::resetDefaults(item); + original_bbox(SP_LPE_ITEM(item)); + setDefaults(); + resetGrid(); +} + +void +LPELattice2::calculateCurve(Geom::Point a,Geom::Point b, SPCurve* c, bool horizontal, bool move) +{ + using Geom::X; + using Geom::Y; + if(move) c->moveto(a); + Geom::Point cubic1 = a + (1./3)* (b - a); + Geom::Point cubic2 = b + (1./3)* (a - b); + if(horizontal) c->curveto(Geom::Point(cubic1[X],a[Y]),Geom::Point(cubic2[X],b[Y]),b); + else c->curveto(Geom::Point(a[X],cubic1[Y]),Geom::Point(b[X],cubic2[Y]),b); +} + +void +LPELattice2::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.clear(); + + SPCurve *c = new SPCurve(); + calculateCurve(grid_point0,grid_point4, c,true, true); + calculateCurve(grid_point4,grid_point8x9, c,true, false); + calculateCurve(grid_point8x9,grid_point5, c,true, false); + calculateCurve(grid_point5,grid_point1, c,true, false); + + calculateCurve(grid_point12,grid_point16, c,true, true); + calculateCurve(grid_point16,grid_point20x21, c,true, false); + calculateCurve(grid_point20x21,grid_point17, c,true, false); + calculateCurve(grid_point17,grid_point13, c,true, false); + + calculateCurve(grid_point24x26,grid_point28x30, c,true, true); + calculateCurve(grid_point28x30,grid_point32x33x34x35, c,true, false); + calculateCurve(grid_point32x33x34x35,grid_point29x31, c,true, false); + calculateCurve(grid_point29x31,grid_point25x27, c,true, false); + + calculateCurve(grid_point14,grid_point18, c,true, true); + calculateCurve(grid_point18,grid_point22x23, c,true, false); + calculateCurve(grid_point22x23,grid_point19, c,true, false); + calculateCurve(grid_point19,grid_point15, c,true, false); + + calculateCurve(grid_point2,grid_point6, c,true, true); + calculateCurve(grid_point6,grid_point10x11, c,true, false); + calculateCurve(grid_point10x11,grid_point7, c,true, false); + calculateCurve(grid_point7,grid_point3, c,true, false); + + calculateCurve(grid_point0,grid_point12, c,false, true); + calculateCurve(grid_point12,grid_point24x26, c,false, false); + calculateCurve(grid_point24x26,grid_point14, c,false, false); + calculateCurve(grid_point14,grid_point2, c,false, false); + + calculateCurve(grid_point4,grid_point16, c,false, true); + calculateCurve(grid_point16,grid_point28x30, c,false, false); + calculateCurve(grid_point28x30,grid_point18, c,false, false); + calculateCurve(grid_point18,grid_point6, c,false, false); + + calculateCurve(grid_point8x9,grid_point20x21, c,false, true); + calculateCurve(grid_point20x21,grid_point32x33x34x35, c,false, false); + calculateCurve(grid_point32x33x34x35,grid_point22x23, c,false, false); + calculateCurve(grid_point22x23,grid_point10x11, c,false, false); + + calculateCurve(grid_point5,grid_point17, c, false, true); + calculateCurve(grid_point17,grid_point29x31, c,false, false); + calculateCurve(grid_point29x31,grid_point19, c,false, false); + calculateCurve(grid_point19,grid_point7, c,false, false); + + calculateCurve(grid_point1,grid_point13, c, false, true); + calculateCurve(grid_point13,grid_point25x27, c,false, false); + calculateCurve(grid_point25x27,grid_point15, c,false, false); + calculateCurve(grid_point15,grid_point3, c, false, false); + hp_vec.push_back(c->get_pathvector()); +} + + +/* ######################## */ + +} //namespace LivePathEffect +} /* namespace Inkscape */ + + + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-lattice2.h b/src/live_effects/lpe-lattice2.h new file mode 100644 index 000000000..461f835c6 --- /dev/null +++ b/src/live_effects/lpe-lattice2.h @@ -0,0 +1,92 @@ +#ifndef INKSCAPE_LPE_LATTICE2_H +#define INKSCAPE_LPE_LATTICE2_H + +/** \file + * LPE implementation, see lpe-lattice2.cpp. + */ + +/* + * Authors: + * Johan Engelen + * Steren Giannini + * No Falzon + * Victor Navez + * ~suv + * Jabiertxo Arraiza +* +* Copyright (C) Johan Engelen 2007 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/enum.h" +#include "live_effects/effect.h" +#include "live_effects/parameter/pointreseteable.h" +#include "live_effects/lpegroupbbox.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPELattice2 : public Effect, GroupBBoxEffect { +public: + + LPELattice2(LivePathEffectObject *lpeobject); + virtual ~LPELattice2(); + + virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + + virtual void resetDefaults(SPItem const* item); + + virtual void doBeforeEffect(SPLPEItem const* lpeitem); + + virtual Gtk::Widget * newWidget(); + + virtual void calculateCurve(Geom::Point a,Geom::Point b, SPCurve *c, bool horizontal, bool move); + + virtual void setDefaults(); + + virtual void resetGrid(); + + //virtual void original_bbox(SPLPEItem const* lpeitem, bool absolute = false); + + //virtual void addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector &/*hp_vec*/); + + //virtual std::vector getHelperPaths(SPLPEItem const* lpeitem); +protected: + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); +private: + + PointReseteableParam grid_point0; + PointReseteableParam grid_point1; + PointReseteableParam grid_point2; + PointReseteableParam grid_point3; + PointReseteableParam grid_point4; + PointReseteableParam grid_point5; + PointReseteableParam grid_point6; + PointReseteableParam grid_point7; + PointReseteableParam grid_point8x9; + PointReseteableParam grid_point10x11; + PointReseteableParam grid_point12; + PointReseteableParam grid_point13; + PointReseteableParam grid_point14; + PointReseteableParam grid_point15; + PointReseteableParam grid_point16; + PointReseteableParam grid_point17; + PointReseteableParam grid_point18; + PointReseteableParam grid_point19; + PointReseteableParam grid_point20x21; + PointReseteableParam grid_point22x23; + PointReseteableParam grid_point24x26; + PointReseteableParam grid_point25x27; + PointReseteableParam grid_point28x30; + PointReseteableParam grid_point29x31; + PointReseteableParam grid_point32x33x34x35; + + LPELattice2(const LPELattice2&); + LPELattice2& operator=(const LPELattice2&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index 30f1f510b..1026cf11c 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -11,6 +11,8 @@ ink_common_sources += \ live_effects/parameter/random.h \ live_effects/parameter/point.cpp \ live_effects/parameter/point.h \ + live_effects/parameter/pointreseteable.cpp \ + live_effects/parameter/pointreseteable.h \ live_effects/parameter/enum.h \ live_effects/parameter/path-reference.cpp \ live_effects/parameter/path-reference.h \ diff --git a/src/live_effects/parameter/pointreseteable.cpp b/src/live_effects/parameter/pointreseteable.cpp new file mode 100644 index 000000000..ec36fc035 --- /dev/null +++ b/src/live_effects/parameter/pointreseteable.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) Johan Engelen 2007 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "ui/widget/registered-widget.h" +#include "live_effects/parameter/pointreseteable.h" +#include "live_effects/effect.h" +#include "svg/svg.h" +#include "svg/stringstream.h" +#include "ui/widget/point.h" +#include "widgets/icon.h" +#include "inkscape.h" +#include "verbs.h" +#include "knotholder.h" +#include +#include "tools-switch.h" +#include "ui/tools/node-tool.h" + +// needed for on-canvas editting: +#include "desktop.h" + +namespace Inkscape { + +namespace LivePathEffect { + +PointReseteableParam::PointReseteableParam( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, + Effect* effect, const gchar *htip, Geom::Point default_value) + : Geom::Point(default_value), Parameter(label, tip, key, wr, effect), defvalue(default_value) +{ + knot_shape = SP_KNOT_SHAPE_DIAMOND; + knot_mode = SP_KNOT_MODE_XOR; + knot_color = 0xffffff00; + handle_tip = g_strdup(htip); +} + +PointReseteableParam::~PointReseteableParam() +{ + if (handle_tip) + g_free(handle_tip); +} + +void +PointReseteableParam::param_set_default() +{ + param_setValue(defvalue); +} + +void +PointReseteableParam::param_set_and_write_default() +{ + param_set_and_write_new_value(defvalue); +} + +void +PointReseteableParam::param_update_default(Geom::Point newpoint) +{ + this->defvalue = newpoint; +} + +bool +PointReseteableParam::param_readSVGValue(const gchar * strvalue) +{ + gchar ** strarray = g_strsplit(strvalue, ",", 2); + double newx, newy; + unsigned int success = sp_svg_number_read_d(strarray[0], &newx); + success += sp_svg_number_read_d(strarray[1], &newy); + g_strfreev (strarray); + if (success == 2) { + param_setValue( Geom::Point(newx, newy) ); + return true; + } + return false; +} + +gchar * +PointReseteableParam::param_getSVGValue() const +{ + Inkscape::SVGOStringStream os; + os << *dynamic_cast( this ); + gchar * str = g_strdup(os.str().c_str()); + return str; +} + +Gtk::Widget * +PointReseteableParam::param_newWidget() +{ + Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = Gtk::manage( + new Inkscape::UI::Widget::RegisteredTransformedPoint( param_label, + param_tooltip, + param_key, + *param_wr, + param_effect->getRepr(), + param_effect->getSPDoc() ) ); + // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Geom::Affine transf = desktop->doc2dt(); + pointwdg->setTransform(transf); + pointwdg->setValue( *this ); + pointwdg->clearProgrammatically(); + pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter")); + + Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); + static_cast(hbox)->pack_start(*pointwdg, true, true); + static_cast(hbox)->show_all_children(); + + return dynamic_cast (hbox); +} + +void +PointReseteableParam::param_setValue(Geom::Point newpoint) +{ + *dynamic_cast( this ) = newpoint; + if(SP_ACTIVE_DESKTOP){ + SPDesktop* desktop = SP_ACTIVE_DESKTOP; + if (tools_isactive( desktop, TOOLS_NODES)) { + Inkscape::UI::Tools::NodeTool *nt = static_cast( desktop->event_context); + nt->update_helperpath(); + } + } +} + +void +PointReseteableParam::param_set_and_write_new_value (Geom::Point newpoint) +{ + Inkscape::SVGOStringStream os; + os << newpoint; + gchar * str = g_strdup(os.str().c_str()); + param_write_to_repr(str); + g_free(str); +} + +void +PointReseteableParam::param_transform_multiply(Geom::Affine const& postmul, bool /*set*/) +{ + param_set_and_write_new_value( (*this) * postmul ); +} + + +void +PointReseteableParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color) +{ + knot_shape = shape; + knot_mode = mode; + knot_color = color; +} + +class PointReseteableParamKnotHolderEntity : public KnotHolderEntity { +public: + PointReseteableParamKnotHolderEntity(PointReseteableParam *p) { this->pparam = p; } + virtual ~PointReseteableParamKnotHolderEntity() {} + + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + virtual void knot_click(guint state); + +private: + PointReseteableParam *pparam; +}; + +void +PointReseteableParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +{ + Geom::Point const s = snap_knot_position(p, state); + pparam->param_setValue(s); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); +} + +Geom::Point +PointReseteableParamKnotHolderEntity::knot_get() const +{ + return *pparam; +} + +void +PointReseteableParamKnotHolderEntity::knot_click(guint state) +{ + if (state & GDK_CONTROL_MASK) { + if (state & GDK_MOD1_MASK) { + this->pparam->param_set_default(); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + } + } +} + +void +PointReseteableParam::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + PointReseteableParamKnotHolderEntity *e = new PointReseteableParamKnotHolderEntity(this); + // TODO: can we ditch handleTip() etc. because we have access to handle_tip etc. itself??? + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, handleTip(), knot_shape, knot_mode, knot_color); + knotholder->add(e); +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/pointreseteable.h b/src/live_effects/parameter/pointreseteable.h new file mode 100644 index 000000000..5ae1fdf02 --- /dev/null +++ b/src/live_effects/parameter/pointreseteable.h @@ -0,0 +1,74 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_RESETEABLE_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_POINT_RESETEABLE_H + +/* + * Inkscape::LivePathEffectParameters + * +* Copyright (C) Johan Engelen 2007 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include <2geom/point.h> + +#include "live_effects/parameter/parameter.h" + +#include "knot-holder-entity.h" + +namespace Inkscape { + +namespace LivePathEffect { + +class PointReseteableParamKnotHolderEntity; + +class PointReseteableParam : public Geom::Point, public Parameter { +public: + PointReseteableParam( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + const gchar *handle_tip = NULL, + Geom::Point default_value = Geom::Point(0,0) ); // tip for automatically associated on-canvas handle + virtual ~PointReseteableParam(); + + virtual Gtk::Widget * param_newWidget(); + + bool param_readSVGValue(const gchar * strvalue); + gchar * param_getSVGValue() const; + inline const gchar *handleTip() const { return handle_tip ? handle_tip : param_tooltip.c_str(); } + + void param_setValue(Geom::Point newpoint); + void param_set_default(); + void param_set_and_write_default(); + void param_update_default(Geom::Point newpoint); + + void param_set_and_write_new_value(Geom::Point newpoint); + + virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/); + + void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color); + + virtual bool providesKnotHolderEntities() const { return true; } + virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); + + friend class PointReseteableParamKnotHolderEntity; +private: + PointReseteableParam(const PointReseteableParam&); + PointReseteableParam& operator=(const PointReseteableParam&); + + Geom::Point defvalue; + + SPKnotShapeType knot_shape; + SPKnotModeType knot_mode; + guint32 knot_color; + gchar *handle_tip; +}; + + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif -- cgit v1.2.3 From b15c7af34a2c4e440211006b4ea9d687be754525 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 13 May 2014 15:21:10 +0200 Subject: Style rewrite: prevent CSS2 'text-decoration' from overwriting CSS3 'text-decoration-xxx' values. Fix some unused variable warnings. (bzr r13371) --- src/style-internal.cpp | 55 +++++++++++++++++++++++++++++++++++++------------- src/style-internal.h | 10 ++++----- 2 files changed, 46 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 508fb677c..2c488105b 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -2405,27 +2405,47 @@ SPITextDecoration::read( gchar const *str ) { if( !str ) return; - style->text_decoration_line.read( str ); - style->text_decoration_style.read( str ); + bool is_css3 = false; + + SPITextDecorationLine test_line; + test_line.read( str ); + if( test_line.set ) { + style->text_decoration_line = test_line; + } + + SPITextDecorationStyle test_style; + test_style.read( str ); + if( test_style.set ) { + style->text_decoration_style = test_style; + is_css3 = true; + } + // the color routine must be fed one token at a time - if multiple colors are found the LAST // one is used ???? then why break on set? - const gchar *hstr = str; - style->text_decoration_color.read( "currentColor" ); // Default value - style->text_decoration_color.set = false; + // This could certainly be designed better + SPIColor test_color("text-decoration-color"); + test_color.setStylePointer( style ); + test_color.read( "currentColor" ); // Default value + test_color.set = false; + const gchar *hstr = str; while (1) { if (*str == ' ' || *str == ',' || *str == '\0'){ int slen = str - hstr; gchar *frag = g_strndup(hstr,slen+1); // only send one piece at a time, since keywords may be intermixed if( strcmp( frag, "none" ) != 0 ) { // 'none' not allowed - style->text_decoration_color.read( frag ); + test_color.read( frag ); } free(frag); - if( style->text_decoration_color.set ) break; - style->text_decoration_color.read( "currentColor" ); // Default value - style->text_decoration_color.set = false; + if( test_color.set ) { + style->text_decoration_color = test_color; + is_css3 = true; + break; + } + test_color.read( "currentColor" ); // Default value + test_color.set = false; if( *str == '\0' )break; hstr = str + 1; } @@ -2434,8 +2454,7 @@ SPITextDecoration::read( gchar const *str ) { // If we read a style or color then we have CSS3 which require any non-set values to be // set to their default values. - if( style->text_decoration_style.set == true || - style->text_decoration_style.set == true ) { + if( is_css3 ) { style->text_decoration_line.set = true; style->text_decoration_style.set = true; style->text_decoration_color.set = true; @@ -2491,9 +2510,17 @@ SPITextDecoration::cascade( const SPIBase* const parent ) { } -// void -// SPITextDecoration::merge( const SPIBase* const parent ) { -// } +void +SPITextDecoration::merge( const SPIBase* const parent ) { + if( const SPITextDecoration* p = dynamic_cast(parent) ) { + if( style_td == NULL ) { + style_td = p->style_td; + } + } else { + std::cerr << "SPITextDecoration::merge(): Incorrect parent type" << std::endl; + } + +} // Use CSS2 value bool diff --git a/src/style-internal.h b/src/style-internal.h index a806afc81..e76f9faaf 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -116,8 +116,8 @@ class SPIBase { virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, SPIBase const *const base = NULL ) const = 0; virtual void clear() { set = false, inherit = false; }; - virtual void cascade( const SPIBase* const parent ) {}; - virtual void merge( const SPIBase* const parent ) {}; // To do: Set to 0 + virtual void cascade( const SPIBase* const parent ) = 0; + virtual void merge( const SPIBase* const parent ) = 0; virtual void setStylePointer( SPStyle *style_in ) { style = style_in; }; @@ -698,8 +698,8 @@ class SPIFont : public SPIBase { virtual void clear() { SPIBase::clear(); }; - virtual void cascade( const SPIBase* const parent ) {}; // Done in dependent properties - virtual void merge( const SPIBase* const parent ) {}; + virtual void cascade( const SPIBase* const parent ) { (void)parent; }; // Done in dependent properties + virtual void merge( const SPIBase* const parent ) { (void)parent; }; SPIFont& operator=(const SPIFont& rhs) { SPIBase::operator=(rhs); @@ -850,7 +850,7 @@ class SPITextDecoration : public SPIBase { style_td = NULL; }; virtual void cascade( const SPIBase* const parent ); - virtual void merge( const SPIBase* const parent ) {}; // FIX ME + virtual void merge( const SPIBase* const parent ); SPITextDecoration& operator=(const SPITextDecoration& rhs) { SPIBase::operator=(rhs); -- cgit v1.2.3 From fe03965ac74349efcc592bee4a9b05542de613eb Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 13 May 2014 15:32:45 +0200 Subject: Style rewrite: Prevent CSS2 'text-decoration' from overwriting CSS3 'text-decoration-xxx'. Suppress unused variable warnings. (bzr r13341.1.15) --- src/style-internal.cpp | 55 +++++++++++++++++++++++++++++++++++++------------- src/style-internal.h | 10 ++++----- 2 files changed, 46 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 508fb677c..2c488105b 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -2405,27 +2405,47 @@ SPITextDecoration::read( gchar const *str ) { if( !str ) return; - style->text_decoration_line.read( str ); - style->text_decoration_style.read( str ); + bool is_css3 = false; + + SPITextDecorationLine test_line; + test_line.read( str ); + if( test_line.set ) { + style->text_decoration_line = test_line; + } + + SPITextDecorationStyle test_style; + test_style.read( str ); + if( test_style.set ) { + style->text_decoration_style = test_style; + is_css3 = true; + } + // the color routine must be fed one token at a time - if multiple colors are found the LAST // one is used ???? then why break on set? - const gchar *hstr = str; - style->text_decoration_color.read( "currentColor" ); // Default value - style->text_decoration_color.set = false; + // This could certainly be designed better + SPIColor test_color("text-decoration-color"); + test_color.setStylePointer( style ); + test_color.read( "currentColor" ); // Default value + test_color.set = false; + const gchar *hstr = str; while (1) { if (*str == ' ' || *str == ',' || *str == '\0'){ int slen = str - hstr; gchar *frag = g_strndup(hstr,slen+1); // only send one piece at a time, since keywords may be intermixed if( strcmp( frag, "none" ) != 0 ) { // 'none' not allowed - style->text_decoration_color.read( frag ); + test_color.read( frag ); } free(frag); - if( style->text_decoration_color.set ) break; - style->text_decoration_color.read( "currentColor" ); // Default value - style->text_decoration_color.set = false; + if( test_color.set ) { + style->text_decoration_color = test_color; + is_css3 = true; + break; + } + test_color.read( "currentColor" ); // Default value + test_color.set = false; if( *str == '\0' )break; hstr = str + 1; } @@ -2434,8 +2454,7 @@ SPITextDecoration::read( gchar const *str ) { // If we read a style or color then we have CSS3 which require any non-set values to be // set to their default values. - if( style->text_decoration_style.set == true || - style->text_decoration_style.set == true ) { + if( is_css3 ) { style->text_decoration_line.set = true; style->text_decoration_style.set = true; style->text_decoration_color.set = true; @@ -2491,9 +2510,17 @@ SPITextDecoration::cascade( const SPIBase* const parent ) { } -// void -// SPITextDecoration::merge( const SPIBase* const parent ) { -// } +void +SPITextDecoration::merge( const SPIBase* const parent ) { + if( const SPITextDecoration* p = dynamic_cast(parent) ) { + if( style_td == NULL ) { + style_td = p->style_td; + } + } else { + std::cerr << "SPITextDecoration::merge(): Incorrect parent type" << std::endl; + } + +} // Use CSS2 value bool diff --git a/src/style-internal.h b/src/style-internal.h index a806afc81..e76f9faaf 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -116,8 +116,8 @@ class SPIBase { virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET, SPIBase const *const base = NULL ) const = 0; virtual void clear() { set = false, inherit = false; }; - virtual void cascade( const SPIBase* const parent ) {}; - virtual void merge( const SPIBase* const parent ) {}; // To do: Set to 0 + virtual void cascade( const SPIBase* const parent ) = 0; + virtual void merge( const SPIBase* const parent ) = 0; virtual void setStylePointer( SPStyle *style_in ) { style = style_in; }; @@ -698,8 +698,8 @@ class SPIFont : public SPIBase { virtual void clear() { SPIBase::clear(); }; - virtual void cascade( const SPIBase* const parent ) {}; // Done in dependent properties - virtual void merge( const SPIBase* const parent ) {}; + virtual void cascade( const SPIBase* const parent ) { (void)parent; }; // Done in dependent properties + virtual void merge( const SPIBase* const parent ) { (void)parent; }; SPIFont& operator=(const SPIFont& rhs) { SPIBase::operator=(rhs); @@ -850,7 +850,7 @@ class SPITextDecoration : public SPIBase { style_td = NULL; }; virtual void cascade( const SPIBase* const parent ); - virtual void merge( const SPIBase* const parent ) {}; // FIX ME + virtual void merge( const SPIBase* const parent ); SPITextDecoration& operator=(const SPITextDecoration& rhs) { SPIBase::operator=(rhs); -- cgit v1.2.3 From 291262ed193a4f2b3252967f8673290cdc94e173 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 13 May 2014 18:02:25 +0200 Subject: adding missing files from LPE simplify (bzr r13341.1.16) --- src/live_effects/lpe-simplify.cpp | 287 ++++++++++++++++++++++++++++ src/live_effects/lpe-simplify.h | 59 ++++++ src/live_effects/parameter/togglebutton.cpp | 92 +++++++++ src/live_effects/parameter/togglebutton.h | 56 ++++++ 4 files changed, 494 insertions(+) create mode 100644 src/live_effects/lpe-simplify.cpp create mode 100644 src/live_effects/lpe-simplify.h create mode 100644 src/live_effects/parameter/togglebutton.cpp create mode 100644 src/live_effects/parameter/togglebutton.h (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp new file mode 100644 index 000000000..d010e75a2 --- /dev/null +++ b/src/live_effects/lpe-simplify.cpp @@ -0,0 +1,287 @@ +#define INKSCAPE_LPE_SIMPLIFY_C +/* + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include +#include +#include "live_effects/lpe-simplify.h" +#include "display/curve.h" +#include "live_effects/parameter/parameter.h" +#include +#include "helper/geom.h" +#include "livarot/Path.h" +#include "splivarot.h" +#include <2geom/svg-path-parser.h> +#include "desktop.h" +#include "inkscape.h" +#include "svg/svg.h" +#include "ui/tools/node-tool.h" +#include <2geom/d2.h> +#include <2geom/generic-rect.h> +#include <2geom/interval.h> + + +namespace Inkscape { +namespace LivePathEffect { + +LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), + threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), + helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 2.), + nodes(_("Helper nodes"), _("Show helper nodes"), "nodes", &wr, this, false), + handles(_("Helper handles"), _("Show helper handles"), "handles", &wr, this, false), + simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false), + simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false) + { + registerParameter(dynamic_cast(&steps)); + registerParameter(dynamic_cast(&threshold)); + registerParameter(dynamic_cast(&helper_size)); + registerParameter(dynamic_cast(&nodes)); + registerParameter(dynamic_cast(&handles)); + registerParameter(dynamic_cast(&simplifyindividualpaths)); + registerParameter(dynamic_cast(&simplifyJustCoalesce)); + threshold.param_set_range(0., Geom::infinity()); + threshold.param_set_increments(0.0001, 0.0001); + threshold.param_set_digits(6); + steps.param_set_range(0, 100); + steps.param_set_increments(1, 1); + steps.param_set_digits(0); + helper_size.param_set_range(0.1, 100); + helper_size.param_set_increments(1, 1); + helper_size.param_set_digits(1); +} + +LPESimplify::~LPESimplify() {} + +void +LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) +{ + if(!hp.empty()){ + hp.clear(); + } + bbox = SP_ITEM(lpeitem)->visualBounds(); + +} + +Gtk::Widget * +LPESimplify::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + std::vector::iterator it = param_vector.begin(); + Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * buttonsTwo = Gtk::manage(new Gtk::HBox(true,0)); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "simplifyindividualpaths" || + param->param_key == "simplifyJustCoalesce") + { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + buttonsTwo->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } else if (param->param_key == "nodes" || + param->param_key == "handles") + { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + buttons->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + }else{ + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + Gtk::HBox * scalarParameter = dynamic_cast(widg); + std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); + Gtk::Entry* entryWidg = dynamic_cast(childList[1]); + entryWidg->set_width_chars(8); + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + } + + ++it; + } + vbox->pack_start(*buttons,true, true, 2); + vbox->pack_start(*buttonsTwo,true, true, 2); + return dynamic_cast(vbox); +} + +void +LPESimplify::doEffect(SPCurve *curve) { + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); + gdouble size = Geom::L2(bbox->dimensions()); + //size /= Geom::Affine(0,0,0,0,0,0).descrim(); + Path* pathliv = Path_for_pathvector(original_pathv); + if(simplifyindividualpaths){ + size = Geom::L2(Geom::bounds_fast(original_pathv)->dimensions()); + } + for (int unsigned i = 0; i < steps; i++){ + if ( simplifyJustCoalesce ) { + pathliv->Coalesce(threshold * size); + }else{ + pathliv->ConvertEvenLines(threshold * size); + pathliv->Simplify(threshold * size); + } + } + Geom::PathVector outres = Geom::parse_svg_path(pathliv->svg_dump_path()); + generateHelperPath(outres); + curve->set_pathvector(outres); + if(SP_ACTIVE_DESKTOP && INK_IS_NODE_TOOL(SP_ACTIVE_DESKTOP->event_context)){ + SPDesktop* desktop = SP_ACTIVE_DESKTOP; + Inkscape::UI::Tools::NodeTool *nt = static_cast(desktop->event_context); + nt->update_helperpath(); + } +} + +void +LPESimplify::generateHelperPath(Geom::PathVector result) +{ + if(!handles && !nodes){ + return; + } + + if(steps < 1){ + return; + } + + Geom::CubicBezier const *cubic = NULL; + for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) { + //Si está vacío... + if (path_it->empty()){ + continue; + } + //Itreadores + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = + ++(path_it->begin()); // outgoing curve + Geom::Path::const_iterator curve_endit = + path_it->end_default(); // this determines when the loop has to stop + + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + if(nodes){ + drawNode(curve_it1->initialPoint()); + } + while (curve_it2 != curve_endit) { + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + if(handles){ + drawHandle((*cubic)[1]); + drawHandle((*cubic)[2]); + drawHandleLine((*cubic)[0],(*cubic)[1]); + drawHandleLine((*cubic)[2],(*cubic)[3]); + } + } + if(nodes){ + drawNode(curve_it1->finalPoint()); + } + ++curve_it1; + ++curve_it2; + } + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + if(handles){ + drawHandle((*cubic)[1]); + drawHandle((*cubic)[2]); + drawHandleLine((*cubic)[0],(*cubic)[1]); + drawHandleLine((*cubic)[2],(*cubic)[3]); + } + } + if(nodes){ + drawNode(curve_it1->finalPoint()); + } + } +} + +void +LPESimplify::drawNode(Geom::Point p) +{ + double r = helper_size/0.67; + char const * svgd; + svgd = "M 0.999993,0.5 C 1.000065,0.7757576 0.7761859,1 0.4999926,1 0.2237994,1 -7.933901e-5,0.7757576 -7.339015e-6,0.5 -7.933901e-5,0.2242424 0.2237994,0 0.4999926,0 0.7761859,0 1.000065,0.2242424 0.999993,0.5 Z m -0.058561,0 C 0.9414949,0.74327 0.7438375,0.9416286 0.4999928,0.9416286 0.2561481,0.9416286 0.0584908,0.74327 0.0585543,0.5 0.0584908,0.25673 0.2561481,0.0583714 0.4999928,0.0583714 0.7438375,0.0583714 0.9414949,0.25673 0.9414313,0.5 Z m -0.3828447,0 c 8.5e-6,0.030303 -0.026228,0.060606 -0.058593,0.060606 -0.032366,0 -0.058603,-0.030303 -0.058593,-0.060606 -8.5e-6,-0.030303 0.026227,-0.060606 0.058593,-0.060606 0.032366,0 0.058603,0.030303 0.058593,0.060606 z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + pathv *= Geom::Affine(r,0,0,r,0,0); + pathv += p - Geom::Point(0.5*r,0.5*r); + hp.push_back(pathv[0]); + hp.push_back(pathv[1]); + hp.push_back(pathv[2]); +} + +void +LPESimplify::drawHandle(Geom::Point p) +{ + double r = helper_size/0.67; + char const * svgd; + svgd = "M 0.6999623,0.35 C 0.7000128,0.5430303 0.5433044,0.7 0.3499775,0.7 0.1566506,0.7 -5.778776e-5,0.5430303 -7.344202e-6,0.35 -5.778776e-5,0.1569697 0.1566506,0 0.3499775,0 0.5433044,0 0.7000128,0.1569697 0.6999623,0.35 Z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + pathv *= Geom::Affine(r,0,0,r,0,0); + pathv += p - Geom::Point(0.35*r,0.35*r); + hp.push_back(pathv[0]); +} + + +void +LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2) +{ + Geom::Path path; + path.start( p ); + path.appendNew( p2 ); + hp.push_back(path); +} + +void +LPESimplify::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(hp); +} + + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-simplify.h b/src/live_effects/lpe-simplify.h new file mode 100644 index 000000000..6acf2f2d4 --- /dev/null +++ b/src/live_effects/lpe-simplify.h @@ -0,0 +1,59 @@ +#ifndef INKSCAPE_LPE_SIMPLIFY_H +#define INKSCAPE_LPE_SIMPLIFY_H + +/* + * Inkscape::LPESimplify + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/togglebutton.h" +#include "live_effects/lpegroupbbox.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPESimplify : public Effect , GroupBBoxEffect{ + +public: + LPESimplify(LivePathEffectObject *lpeobject); + virtual ~LPESimplify(); + + virtual void doEffect(SPCurve *curve); + + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + + virtual void generateHelperPath(Geom::PathVector result); + + virtual Gtk::Widget * newWidget(); + + virtual void drawNode(Geom::Point p); + + virtual void drawHandle(Geom::Point p); + + virtual void drawHandleLine(Geom::Point p,Geom::Point p2); + +protected: + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); + +private: + ScalarParam steps; + ScalarParam threshold; + ScalarParam helper_size; + ToggleButtonParam nodes; + ToggleButtonParam handles; + ToggleButtonParam simplifyindividualpaths; + ToggleButtonParam simplifyJustCoalesce; + + Geom::PathVector hp; + Geom::OptRect bbox; + + LPESimplify(const LPESimplify &); + LPESimplify &operator=(const LPESimplify &); + +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape +#endif diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp new file mode 100644 index 000000000..03238f935 --- /dev/null +++ b/src/live_effects/parameter/togglebutton.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) Johan Engelen 2007 + * Copyright (C) Jabiertxo Arraiza Cenoz 2014 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "ui/widget/registered-widget.h" +#include "live_effects/parameter/togglebutton.h" +#include "live_effects/effect.h" +#include "svg/svg.h" +#include "svg/stringstream.h" +#include "widgets/icon.h" +#include "inkscape.h" +#include "verbs.h" +#include "helper-fns.h" +#include + +namespace Inkscape { + +namespace LivePathEffect { + +ToggleButtonParam::ToggleButtonParam( const Glib::ustring& label, const Glib::ustring& tip, + const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, + Effect* effect, bool default_value ) + : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value) +{ +} + +ToggleButtonParam::~ToggleButtonParam() +{ +} + +void +ToggleButtonParam::param_set_default() +{ + param_setValue(defvalue); +} + +bool +ToggleButtonParam::param_readSVGValue(const gchar * strvalue) +{ + param_setValue(helperfns_read_bool(strvalue, defvalue)); + return true; // not correct: if value is unacceptable, should return false! +} + +gchar * +ToggleButtonParam::param_getSVGValue() const +{ + gchar * str = g_strdup(value ? "true" : "false"); + return str; +} + +Gtk::Widget * +ToggleButtonParam::param_newWidget() +{ + Inkscape::UI::Widget::RegisteredToggleButton * checkwdg = Gtk::manage( + new Inkscape::UI::Widget::RegisteredToggleButton( param_label, + param_tooltip, + param_key, + *param_wr, + false, + param_effect->getRepr(), + param_effect->getSPDoc()) ); + + checkwdg->setActive(value); + checkwdg->setProgrammatically = false; + checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change togglebutton parameter")); + + return dynamic_cast (checkwdg); +} + +void +ToggleButtonParam::param_setValue(bool newvalue) +{ + value = newvalue; +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/togglebutton.h b/src/live_effects/parameter/togglebutton.h new file mode 100644 index 000000000..9b1c71185 --- /dev/null +++ b/src/live_effects/parameter/togglebutton.h @@ -0,0 +1,56 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_PARAMETER_TOGGLEBUTTON_H +#define INKSCAPE_LIVEPATHEFFECT_PARAMETER_TOGGLEBUTTON_H + +/* + * Inkscape::LivePathEffectParameters + * +* Copyright (C) Johan Engelen 2007 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "live_effects/parameter/parameter.h" + +namespace Inkscape { + +namespace LivePathEffect { + + +class ToggleButtonParam : public Parameter { +public: + ToggleButtonParam( const Glib::ustring& label, + const Glib::ustring& tip, + const Glib::ustring& key, + Inkscape::UI::Widget::Registry* wr, + Effect* effect, + bool default_value = false); + virtual ~ToggleButtonParam(); + + virtual Gtk::Widget * param_newWidget(); + + virtual bool param_readSVGValue(const gchar * strvalue); + virtual gchar * param_getSVGValue() const; + + void param_setValue(bool newvalue); + virtual void param_set_default(); + + bool get_value() const { return value; }; + + inline operator bool() const { return value; }; + +private: + ToggleButtonParam(const ToggleButtonParam&); + ToggleButtonParam& operator=(const ToggleButtonParam&); + + bool value; + bool defvalue; +}; + + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif -- cgit v1.2.3 From cd0d2dbafee362548176b6d9cf7e369967e04460 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 13 May 2014 19:48:34 +0200 Subject: CSS2 and CSS3 text decoration rendering, most code from David Mathog. (bzr r13372) --- src/display/drawing-text.cpp | 471 ++++++++++++++++++++++++++----------------- src/display/drawing-text.h | 4 +- src/display/nr-style.cpp | 140 +++++++++++-- src/display/nr-style.h | 11 +- 4 files changed, 427 insertions(+), 199 deletions(-) (limited to 'src') diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index 4178cb1d8..05a2c3c2a 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -67,16 +67,14 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext _pick_bbox = Geom::IntRect(); _bbox = Geom::IntRect(); -/* orignally it did the one line below, - but it did not handle ws characters at all, and it had problems with scaling for overline/underline. - Replaced with the section below, which seems to be much more stable. - - Geom::OptRect b = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); -*/ - /* Make a bounding box that is a little taller and lower (currently 10% extra) than the font's drawing box. Extra space is - to hold overline or underline, if present. All characters in a font use the same ascent and descent, - but different widths. This lets leading and trailing spaces have text decorations. If it is not done - the bounding box is limited to the box surrounding the drawn parts of visible glyphs only, and draws outside are ignored. + /* + Make a bounding box for drawing that is a little taller and lower (currently 10% extra) than + the font's drawing box. Extra space is to hold overline or underline, if present. All + characters in a font use the same ascent and descent, but different widths. This lets leading + and trailing spaces have text decorations. If it is not done the bounding box is limited to + the box surrounding the drawn parts of visible glyphs only, and draws outside are ignored. + The box is also a hair wider than the text, since the glyphs do not always start or end at + the left and right edges of the box defined in the font. */ float scale_bigbox = 1.0; @@ -84,9 +82,45 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext scale_bigbox /= _transform->descrim(); } - Geom::Rect bigbox(Geom::Point(0.0, _asc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, -_dsc*scale_bigbox*1.1)); + Geom::Rect bigbox(Geom::Point(-_width*scale_bigbox*0.1, _asc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, -_dsc*scale_bigbox*1.1)); Geom::Rect b = bigbox * ctx.ctm; + /* + The pick box matches the characters as best as it can, leaving no extra space above or below + for decorations. The pathvector may include spaces, and spaces have no drawable glyph. + Catch those and do not pass them to bounds_exact_transformed(), which crashes Inkscape if it + sees a nondrawable glyph. Instead mock up a pickbox for them using font characteristics. + There may also be some other similar white space characters in some other unforeseen context + which should be handled by this code as well.. + */ + + Geom::OptRect pb; + if(_drawable){ + pb = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); + } + if(!pb){ // Fallback + Geom::Rect pbigbox(Geom::Point(0.0, _asc*scale_bigbox*0.66),Geom::Point(_width*scale_bigbox, 0.0)); + pb = pbigbox * ctx.ctm; + } + +#if 0 + /* FIXME if this is commented out then not even an approximation of pick on decorations */ + /* adjust the pick box up or down to include the decorations. + This is only approximate since at this point we don't know how wide that line is, if it has + an unusual offset, and so forth. The selection point is set at what is roughly the center of + the decoration (vertically) for the wide ones, like wavy and double line. + The text decorations are not actually selectable. + */ + if (_decorations.overline || _decorations.underline) { + double top = _asc*scale_bigbox*0.66; + double bot = 0; + if (_decorations.overline) { top = _asc * scale_bigbox * 1.025; } + if (_decorations.underline) { bot = -_dsc * scale_bigbox * 0.2; } + Geom::Rect padjbox(Geom::Point(0.0, top),Geom::Point(_width*scale_bigbox, bot)); + pb.unionWith(padjbox * ctx.ctm); + } +#endif + if (ggroup->_nrstyle.stroke.type != NRStyle::PAINT_NONE) { // this expands the selection box for cases where the stroke is "thick" float scale = ctx.ctm.descrim(); @@ -96,10 +130,11 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext float width = MAX(0.125, ggroup->_nrstyle.stroke_width * scale); if ( fabs(ggroup->_nrstyle.stroke_width * scale) > 0.01 ) { // FIXME: this is always true b.expandBy(0.5 * width); + pb->expandBy(0.5 * width); } // save bbox without miters for picking - _pick_bbox = b.roundOutwards(); + _pick_bbox = pb->roundOutwards(); float miterMax = width * ggroup->_nrstyle.miter_limit; if ( miterMax > 0.01 ) { @@ -110,14 +145,8 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext _bbox = b.roundOutwards(); } else { _bbox = b.roundOutwards(); - _pick_bbox = *_bbox; + _pick_bbox = pb->roundOutwards(); } -/* -std::cout << "DEBUG _bbox" -<< " { " << _bbox->min()[Geom::X] << " , " << _bbox->min()[Geom::Y] -<< " } , { " << _bbox->max()[Geom::X] << " , " << _bbox->max()[Geom::Y] -<< " }" << std::endl; -*/ return STATE_ALL; } @@ -136,7 +165,8 @@ DrawingGlyphs::_pickItem(Geom::Point const &p, double delta, unsigned /*flags*/) // With text we take a simple approach: pick if the point is in a character bbox Geom::Rect expanded(_pick_bbox); - expanded.expandBy(delta); + // FIXME, why expand by delta? When is the next line needed? + // expanded.expandBy(delta); if (expanded.contains(p)) return this; return NULL; } @@ -195,7 +225,7 @@ DrawingText::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, un return DrawingGroup::_updateItem(area, ctx, flags, reset); } -void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2) +void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2, double thickness) { double wave[16]={ 0.000000, 0.382499, 0.706825, 0.923651, 1.000000, 0.923651, 0.706825, 0.382499, @@ -213,7 +243,6 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas 4, 3, 2, 1, -4, -3, -2, -1 }; - Geom::Point p3,p4,ps,pf; double step = vextent/32.0; unsigned i = 15 & (unsigned) round(xphase/step); // xphase is >= 0.0 @@ -221,26 +250,19 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas This allows decoration continuity within the line, and does not step outside the clip box off the end For the first/last section on the line though, stay well clear of the edge, or when the text is dragged it may "spray" pixels. - if(_nrstyle.tspan_line_end){ pf = p2 - Geom::Point(2*step, 0.0); } - else { pf = p2; } - if(_nrstyle.tspan_line_start){ ps = p1 + Geom::Point(2*step, 0.0); - i = 15 & (i + 2); - } - else { ps = p1; } */ /* snap to nearest step in X */ -ps = Geom::Point(step * round(p1[Geom::X]/step),p1[Geom::Y]); -pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); + Geom::Point ps = Geom::Point(step * round(p1[Geom::X]/step),p1[Geom::Y]); + Geom::Point pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); + Geom::Point poff = Geom::Point(0,thickness/2.0); if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_ISDOUBLE){ ps -= Geom::Point(0, vextent/12.0); pf -= Geom::Point(0, vextent/12.0); - dc.moveTo(ps); - dc.lineTo(pf); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); ps += Geom::Point(0, vextent/6.0); pf += Geom::Point(0, vextent/6.0); - dc.moveTo(ps); - dc.lineTo(pf); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); } /* The next three have a problem in that they are phase dependent. The bits of a line are not necessarily passing through this routine in order, so we have to use the xphase information @@ -248,43 +270,52 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); Huge possitive offset should keep the phase calculation from ever being negative. */ else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_DOTTED){ + // FIXME: Per spec, this should produce round dots. + Geom::Point pv = ps; while(1){ + Geom::Point pvlast = pv; if(dots[i]>0){ - if(ps[Geom::X]> pf[Geom::X])break; - dc.moveTo(ps); - ps += Geom::Point(step * (double)dots[i], 0.0); - if(ps[Geom::X]>= pf[Geom::X]){ - dc.lineTo(pf); + if(pv[Geom::X] > pf[Geom::X]) break; + + pv += Geom::Point(step * (double)dots[i], 0.0); + + if(pv[Geom::X]>= pf[Geom::X]){ + // Last dot + dc.rectangle( Geom::Rect(pvlast + poff, pf - poff)); break; + } else { + dc.rectangle( Geom::Rect(pvlast + poff, pv - poff)); } - else { - dc.lineTo(ps); - } - ps += Geom::Point(step * 4.0, 0.0); - } - else { - ps += Geom::Point(step * -(double)dots[i], 0.0); + + pv += Geom::Point(step * 4.0, 0.0); + + } else { + pv += Geom::Point(step * -(double)dots[i], 0.0); } i = 0; // once in phase, it stays in phase } } else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_DASHED){ + Geom::Point pv = ps; while(1){ + Geom::Point pvlast = pv; if(dashes[i]>0){ - if(ps[Geom::X]> pf[Geom::X])break; - dc.moveTo(ps); - ps += Geom::Point(step * (double)dashes[i], 0.0); - if(ps[Geom::X]>= pf[Geom::X]){ - dc.lineTo(pf); + if(pv[Geom::X]> pf[Geom::X]) break; + + pv += Geom::Point(step * (double)dashes[i], 0.0); + + if(pv[Geom::X]>= pf[Geom::X]){ + // Last dash + dc.rectangle( Geom::Rect(pvlast + poff, pf - poff)); break; + } else { + dc.rectangle( Geom::Rect(pvlast + poff, pv - poff)); } - else { - dc.lineTo(ps); - } - ps += Geom::Point(step * 8.0, 0.0); - } - else { - ps += Geom::Point(step * -(double)dashes[i], 0.0); + + pv += Geom::Point(step * 8.0, 0.0); + + } else { + pv += Geom::Point(step * -(double)dashes[i], 0.0); } i = 0; // once in phase, it stays in phase } @@ -292,7 +323,7 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_WAVY){ double amp = vextent/10.0; double x = ps[Geom::X]; - double y = ps[Geom::Y]; + double y = ps[Geom::Y] + poff[Geom::Y]; dc.moveTo(Geom::Point(x, y + amp * wave[i])); while(1){ i = ((i + 1) & 15); @@ -300,17 +331,25 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); dc.lineTo(Geom::Point(x, y + amp * wave[i])); if(x >= pf[Geom::X])break; } - } + y = ps[Geom::Y] - poff[Geom::Y]; + dc.lineTo(Geom::Point(x, y + amp * wave[i])); + while(1){ + i = ((i - 1) & 15); + x -= step; + dc.lineTo(Geom::Point(x, y + amp * wave[i])); + if(x <= ps[Geom::X])break; + } + dc.closePath(); + } else { // TEXT_DECORATION_STYLE_SOLID, also default in case it was not set for some reason - dc.moveTo(ps); - dc.lineTo(pf); -// dc.revrectangle(Geom::Rect(ps,pf)); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); } } /* returns scaled line thickness */ -double DrawingText::decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length) +void DrawingText::decorateItem(DrawingContext &dc, double phase_length, bool under) { + if (_nrstyle.font_size < 1.0e-32)return; // would cause a divide by zero and nothing would be visible anyway double tsp_width_adj = _nrstyle.tspan_width / _nrstyle.font_size; double tsp_asc_adj = _nrstyle.ascender / _nrstyle.font_size; double tsp_size_adj = (_nrstyle.ascender + _nrstyle.descender) / _nrstyle.font_size; @@ -318,49 +357,54 @@ double DrawingText::decorateItem(DrawingContext &dc, Geom::Affine const &aff, do double final_underline_thickness = CLAMP(_nrstyle.underline_thickness, tsp_size_adj/30.0, tsp_size_adj/10.0); double final_line_through_thickness = CLAMP(_nrstyle.line_through_thickness, tsp_size_adj/30.0, tsp_size_adj/10.0); - double scale = aff.descrim(); double xphase = phase_length/ _nrstyle.font_size; // used to figure out phase of patterns - Inkscape::DrawingContext::Save save(dc); - dc.transform(aff); // must be leftmost affine in span - Geom::Point p1; Geom::Point p2; // All lines must be the same thickness, in combinations, line_through trumps underline double thickness = final_underline_thickness; - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_UNDERLINE){ - p1 = Geom::Point(0.0, -_nrstyle.underline_position); - p2 = Geom::Point(tsp_width_adj,-_nrstyle.underline_position); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_OVERLINE){ - p1 = Geom::Point(0.0, tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); - p2 = Geom::Point(tsp_width_adj,tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_LINETHROUGH){ - thickness = final_line_through_thickness; - p1 = Geom::Point(0.0, _nrstyle.line_through_position); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - // Obviously this does not blink, but it does indicate which text has been set with that attribute - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_BLINK){ - thickness = final_line_through_thickness; - p1 = Geom::Point(0.0, _nrstyle.line_through_position - 2*final_line_through_thickness); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position - 2*final_line_through_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - p1 = Geom::Point(0.0, _nrstyle.line_through_position + 2*final_line_through_thickness); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position + 2*final_line_through_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); + dc.setTolerance(0.5); // Is this really necessary... could effect dots. + + if( under ) { + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_UNDERLINE){ + p1 = Geom::Point(0.0, -_nrstyle.underline_position); + p2 = Geom::Point(tsp_width_adj,-_nrstyle.underline_position); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_OVERLINE){ + p1 = Geom::Point(0.0, tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); + p2 = Geom::Point(tsp_width_adj,tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + } else { + // Over + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_LINETHROUGH){ + thickness = final_line_through_thickness; + p1 = Geom::Point(0.0, _nrstyle.line_through_position); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + // Obviously this does not blink, but it does indicate which text has been set with that attribute + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_BLINK){ + thickness = final_line_through_thickness; + p1 = Geom::Point(0.0, _nrstyle.line_through_position - 2*final_line_through_thickness); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position - 2*final_line_through_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + p1 = Geom::Point(0.0, _nrstyle.line_through_position + 2*final_line_through_thickness); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position + 2*final_line_through_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } } - thickness *= scale; - return(thickness); } unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*area*/, unsigned /*flags*/, DrawingItem * /*stop_at*/) { - if (_drawing.outline()) { + if (_drawing.outline()) { guint32 rgba = _drawing.outlinecolor; Inkscape::DrawingContext::Save save(dc); dc.setSource(rgba); @@ -382,124 +426,187 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are return RENDER_OK; } - // NOTE: this is very similar to drawing-shape.cpp; the only difference is in path feeding - double leftmost = DBL_MAX; - double phase_length = 0.0; - bool firsty = true; - bool decorate = true; - double starty = 0.0; - Geom::Affine aff; - using Geom::X; - using Geom::Y; - - // NOTE: + // NOTE: This is very similar to drawing-shape.cpp; the only differences are in path feeding + // and in applying text decorations. + + + // Do we have text decorations? + bool decorate = (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR ); + // prepareFill / prepareStroke need to be called with _ctm in effect. // However, we might need to apply a different ctm for glyphs. // Therefore, only apply this ctm temporarily. - bool has_stroke, has_fill; + bool has_stroke = false; + bool has_fill = false; + bool has_td_fill = false; + bool has_td_stroke = false; { Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); - has_fill = _nrstyle.prepareFill( dc, _item_bbox); - has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); + has_fill = _nrstyle.prepareFill( dc, _item_bbox); + has_stroke = _nrstyle.prepareStroke( dc, _item_bbox); + + // Avoid creating patterns if not needed + if( decorate ) { + has_td_fill = _nrstyle.prepareTextDecorationFill( dc, _item_bbox); + has_td_stroke = _nrstyle.prepareTextDecorationStroke(dc, _item_bbox); + } } - if (has_fill || has_stroke) { - Geom::Affine rotinv; - bool invset = false; + if (has_fill || has_stroke || has_td_fill || has_td_stroke) { - // accumulate the path that represents the glyphs - for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { - DrawingGlyphs *g = dynamic_cast(&*i); - if (!g) throw InvalidItemException(); - if (!invset) { - rotinv = g->_ctm.withoutTranslation().inverse(); - invset = true; - } + // Determine order for fill and stroke. + // Text doesn't have markers, we can do paint-order quick and dirty. + bool fill_first = false; + if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || + _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_FILL || + _nrstyle.paint_order_layer[2] == NRStyle::PAINT_ORDER_STROKE ) { + fill_first = true; + } // Won't get "stroke fill stroke" but that isn't 'valid' + + + // Determine geometry of text decoration + double phase_length = 0.0; + Geom::Affine aff; + if( decorate ) { + + Geom::Affine rotinv; + bool invset = false; + double leftmost = DBL_MAX; + bool first_y = true; + double start_y = 0.0; + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + + DrawingGlyphs *g = dynamic_cast(&*i); + if (!g) throw InvalidItemException(); + + if (!invset) { + rotinv = g->_ctm.withoutTranslation().inverse(); + invset = true; + } - Inkscape::DrawingContext::Save save(dc); - if (g->_ctm.isSingular()) continue; - dc.transform(g->_ctm); - if (g->_drawable) { - dc.path(*g->_font->PathVector(g->_glyph)); - } - // get the leftmost affine transform (leftmost defined with respect to the x axis of the first transform). - // That way the decoration will work no matter what mix of L->R, R->L text is in the span. - if (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR) { Geom::Point pt = g->_ctm.translation() * rotinv; - if (pt[X] < leftmost) { - leftmost = pt[X]; + if (pt[Geom::X] < leftmost) { + leftmost = pt[Geom::X]; aff = g->_ctm; phase_length = g->_pl; } - /* If the text has been mapped onto a path, which causes y to vary, drop the text decorations. - To handle that properly would need a conformal map - */ - if (firsty) { - firsty = false; - starty = pt[Y]; + + // Check for text on a path. FIXME: This needs better test (and probably not here). + if (first_y) { + first_y = false; + start_y = pt[Geom::Y]; } - else if (fabs(pt[Y] - starty) > 1.0e-6) { + else if (fabs(pt[Geom::Y] - start_y) > 1.0e-6) { + // If the text has been mapped onto a path, which causes y to vary, drop the + // text decorations. To handle that properly would need a conformal map. decorate = false; } } } - // draw the text itself - // we need to apply this object's ctm again - Inkscape::DrawingContext::Save save(dc); - dc.transform(_ctm); + // Draw text decorations that go UNDER the text (underline, over-line) + if( decorate ) { - // Text doesn't have markers, we can do paint-order quick and dirty. - bool fill_first = false; - if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || - _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_FILL || - _nrstyle.paint_order_layer[2] == NRStyle::PAINT_ORDER_STROKE ) { - fill_first = true; - } // Won't get "stroke fill stroke" but that isn't 'valid' + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(aff); // must be leftmost affine in span + decorateItem(dc, phase_length, true); + } + + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); // Needed so that fill pattern rotates with text + + if (has_td_fill && fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + + if (has_td_stroke) { + _nrstyle.applyTextDecorationStroke(dc); + dc.strokePreserve(); + } + + if (has_td_fill && !fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } - if (has_fill && fill_first) { - _nrstyle.applyFill(dc); - dc.fillPreserve(); + } + + dc.newPath(); // Clear text-decoration path } - if (has_stroke) { - _nrstyle.applyStroke(dc); - dc.strokePreserve(); + // accumulate the path that represents the glyphs + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingGlyphs *g = dynamic_cast(&*i); + if (!g) throw InvalidItemException(); + + Inkscape::DrawingContext::Save save(dc); + if (g->_ctm.isSingular()) continue; + dc.transform(g->_ctm); + if (g->_drawable) { + dc.path(*g->_font->PathVector(g->_glyph)); + } } - if (has_fill && !fill_first) { - _nrstyle.applyFill(dc); - dc.fillPreserve(); + // Draw the glyphs. + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); + + if (has_fill && fill_first) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } + + if (has_stroke) { + _nrstyle.applyStroke(dc); + dc.strokePreserve(); + } + + if (has_fill && !fill_first) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } } + dc.newPath(); // Clear glyphs path + + // Draw text decorations that go OVER the text (line through, blink) + if (decorate) { - dc.newPath(); // clear path - - // draw text decoration - if (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR && decorate) { - guint32 ergba; - if (_nrstyle.text_decoration_useColor) { // color different from the glyph - ergba = SP_RGBA32_F_COMPOSE( - _nrstyle.text_decoration_color.color.v.c[0], - _nrstyle.text_decoration_color.color.v.c[1], - _nrstyle.text_decoration_color.color.v.c[2], - 1.0); + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(aff); // must be leftmost affine in span + decorateItem(dc, phase_length, false); } - else { // whatever the current fill color is - ergba = SP_RGBA32_F_COMPOSE( - _nrstyle.fill.color.v.c[0], - _nrstyle.fill.color.v.c[1], - _nrstyle.fill.color.v.c[2], - 1.0); + + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); // Needed so that fill pattern rotates with text + + if (has_td_fill && fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + + if (has_td_stroke) { + _nrstyle.applyTextDecorationStroke(dc); + dc.strokePreserve(); + } + + if (has_td_fill && !fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + } - dc.setSource(ergba); - dc.setTolerance(0.5); - double thickness = decorateItem(dc, aff, phase_length); - dc.setLineWidth(thickness); - dc.strokePreserve(); - dc.newPath(); // clear path + + dc.newPath(); // Clear text-decoration path } + } return RENDER_OK; } diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h index 41039d85d..4453a3db4 100644 --- a/src/display/drawing-text.h +++ b/src/display/drawing-text.h @@ -68,8 +68,8 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); - double decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length); - void decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2); + void decorateItem(DrawingContext &dc, double phase_length, bool under); + void decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2, double thickness); NRStyle _nrstyle; friend class DrawingGlyphs; diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 09a28e63c..ec3117079 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -54,8 +54,13 @@ NRStyle::NRStyle() , line_join(CAIRO_LINE_JOIN_MITER) , fill_pattern(NULL) , stroke_pattern(NULL) + , text_decoration_fill_pattern(NULL) + , text_decoration_stroke_pattern(NULL) , text_decoration_line(TEXT_DECORATION_LINE_CLEAR) , text_decoration_style(TEXT_DECORATION_STYLE_CLEAR) + , text_decoration_fill() + , text_decoration_stroke() + , text_decoration_stroke_width(0.0) , phase_length(0.0) , tspan_line_start(false) , tspan_line_end(false) @@ -76,11 +81,15 @@ NRStyle::~NRStyle() { if (fill_pattern) cairo_pattern_destroy(fill_pattern); if (stroke_pattern) cairo_pattern_destroy(stroke_pattern); + if (text_decoration_fill_pattern) cairo_pattern_destroy(text_decoration_fill_pattern); + if (text_decoration_stroke_pattern) cairo_pattern_destroy(text_decoration_stroke_pattern); if (dash){ delete [] dash; } fill.clear(); stroke.clear(); + text_decoration_fill.clear(); + text_decoration_stroke.clear(); } void NRStyle::set(SPStyle *style) @@ -195,15 +204,65 @@ void NRStyle::set(SPStyle *style) if(style->text_decoration_style.dashed ){ text_decoration_style |= TEXT_DECORATION_STYLE_DASHED + TEXT_DECORATION_STYLE_SET; } if(style->text_decoration_style.wavy ){ text_decoration_style |= TEXT_DECORATION_STYLE_WAVY + TEXT_DECORATION_STYLE_SET; } + /* FIXME + The meaning of text-decoration-color in CSS3 for SVG is ambiguous (2014-05-06). Set + it for fill, for stroke, for both? Both would seem like the obvious choice but what happens + is that for text which is just fill (very common) it makes the lines fatter because it + enables stroke on the decorations when it wasn't present on the text. That contradicts the + usual behavior where the text and decorations by default have the same fill/stroke. + + The behavior here is that if color is defined it is applied to text_decoration_fill/stroke + ONLY if the corresponding fill/stroke is also present. + + Hopefully the standard will be clarified to resolve this issue. + */ + + SPStyle* style_td = style; + if ( style->text_decoration.style_td ) style_td = style->text_decoration.style_td; + text_decoration_stroke.opacity = SP_SCALE24_TO_FLOAT(style_td->stroke_opacity.value); + text_decoration_stroke_width = style_td->stroke_width.computed; + if( style->text_decoration_color.set || style->text_decoration_color.inherit || - style->text_decoration_color.currentcolor ){ - text_decoration_color.set(style->text_decoration_color.value.color); - text_decoration_useColor = true; - } - else { - text_decoration_color.clear(); - text_decoration_useColor = false; + style->text_decoration_color.currentcolor ) { + + if(style->fill.isPaintserver() || style->fill.isColor()) { + // SVG sets color specifically + text_decoration_fill.set(style->text_decoration_color.value.color); + } else { + // No decoration fill because no text fill + text_decoration_fill.clear(); + } + + if(style->stroke.isPaintserver() || style->stroke.isColor()) { + // SVG sets color specifically + text_decoration_stroke.set(style->text_decoration_color.value.color); + } else { + // No decoration stroke because no text stroke + text_decoration_stroke.clear(); + } + + } else { + // Pick color/pattern from text + if ( style_td->fill.isPaintserver() ) { + text_decoration_fill.set(style_td->getFillPaintServer()); + } else if ( style_td->fill.isColor() ) { + text_decoration_fill.set(style_td->fill.value.color); + } else if ( style_td->fill.isNone() ) { + text_decoration_fill.clear(); + } else { + g_assert_not_reached(); + } + + if ( style_td->stroke.isPaintserver() ) { + text_decoration_stroke.set(style_td->getStrokePaintServer()); + } else if ( style_td->stroke.isColor() ) { + text_decoration_stroke.set(style_td->stroke.value.color); + } else if ( style_td->stroke.isNone() ) { + text_decoration_stroke.clear(); + } else { + g_assert_not_reached(); + } } if(text_decoration_line != TEXT_DECORATION_LINE_CLEAR){ @@ -232,10 +291,8 @@ bool NRStyle::prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &pai if (!fill_pattern) { switch (fill.type) { case PAINT_SERVER: { - //fill_pattern = sp_paint_server_create_pattern(fill.server, dc.raw(), paintbox, fill.opacity); - fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); - - } break; + fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); + } break; case PAINT_COLOR: { SPColor const &c = fill.color; fill_pattern = cairo_pattern_create_rgba( @@ -254,14 +311,38 @@ void NRStyle::applyFill(Inkscape::DrawingContext &dc) dc.setFillRule(fill_rule); } +bool NRStyle::prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) +{ + // update text decoration pattern + if (!text_decoration_fill_pattern) { + switch (text_decoration_fill.type) { + case PAINT_SERVER: { + text_decoration_fill_pattern = text_decoration_fill.server->pattern_new(dc.raw(), paintbox, text_decoration_fill.opacity); + } break; + case PAINT_COLOR: { + SPColor const &c = text_decoration_fill.color; + text_decoration_fill_pattern = cairo_pattern_create_rgba( + c.v.c[0], c.v.c[1], c.v.c[2], text_decoration_fill.opacity); + } break; + default: break; + } + } + if (!text_decoration_fill_pattern) return false; + return true; +} + +void NRStyle::applyTextDecorationFill(Inkscape::DrawingContext &dc) +{ + dc.setSource(text_decoration_fill_pattern); + // Fill rule does not matter, no intersections. +} + bool NRStyle::prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) { if (!stroke_pattern) { switch (stroke.type) { case PAINT_SERVER: { - //stroke_pattern = sp_paint_server_create_pattern(stroke.server, dc.raw(), paintbox, stroke.opacity); stroke_pattern = stroke.server->pattern_new(dc.raw(), paintbox, stroke.opacity); - } break; case PAINT_COLOR: { SPColor const &c = stroke.color; @@ -285,13 +366,46 @@ void NRStyle::applyStroke(Inkscape::DrawingContext &dc) cairo_set_dash(dc.raw(), dash, n_dash, dash_offset); // fixme } +bool NRStyle::prepareTextDecorationStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) +{ + if (!text_decoration_stroke_pattern) { + switch (text_decoration_stroke.type) { + case PAINT_SERVER: { + text_decoration_stroke_pattern = text_decoration_stroke.server->pattern_new(dc.raw(), paintbox, text_decoration_stroke.opacity); + } break; + case PAINT_COLOR: { + SPColor const &c = text_decoration_stroke.color; + text_decoration_stroke_pattern = cairo_pattern_create_rgba( + c.v.c[0], c.v.c[1], c.v.c[2], text_decoration_stroke.opacity); + } break; + default: break; + } + } + if (!text_decoration_stroke_pattern) return false; + return true; +} + +void NRStyle::applyTextDecorationStroke(Inkscape::DrawingContext &dc) +{ + dc.setSource(text_decoration_stroke_pattern); + dc.setLineWidth(text_decoration_stroke_width); + dc.setLineCap(CAIRO_LINE_CAP_BUTT); + dc.setLineJoin(CAIRO_LINE_JOIN_MITER); + dc.setMiterLimit(miter_limit); + cairo_set_dash(dc.raw(), 0, 0, 0.0); // fixme (no dash) +} + void NRStyle::update() { // force pattern update if (fill_pattern) cairo_pattern_destroy(fill_pattern); if (stroke_pattern) cairo_pattern_destroy(stroke_pattern); + if (text_decoration_fill_pattern) cairo_pattern_destroy(text_decoration_fill_pattern); + if (text_decoration_stroke_pattern) cairo_pattern_destroy(text_decoration_stroke_pattern); fill_pattern = NULL; stroke_pattern = NULL; + text_decoration_fill_pattern = NULL; + text_decoration_stroke_pattern = NULL; } /* diff --git a/src/display/nr-style.h b/src/display/nr-style.h index ca880c00b..83bcb1ab7 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -30,8 +30,12 @@ struct NRStyle { void set(SPStyle *); bool prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); bool prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); + bool prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); + bool prepareTextDecorationStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); void applyFill(Inkscape::DrawingContext &dc); void applyStroke(Inkscape::DrawingContext &dc); + void applyTextDecorationFill(Inkscape::DrawingContext &dc); + void applyTextDecorationStroke(Inkscape::DrawingContext &dc); void update(); enum PaintType { @@ -67,6 +71,8 @@ struct NRStyle { cairo_pattern_t *fill_pattern; cairo_pattern_t *stroke_pattern; + cairo_pattern_t *text_decoration_fill_pattern; + cairo_pattern_t *text_decoration_stroke_pattern; enum PaintOrderType { PAINT_ORDER_NORMAL, @@ -97,8 +103,9 @@ struct NRStyle { int text_decoration_line; int text_decoration_style; - Paint text_decoration_color; - bool text_decoration_useColor; // if false, use whatever the glyph color was + Paint text_decoration_fill; + Paint text_decoration_stroke; + float text_decoration_stroke_width; // These are the same as in style.h float phase_length; bool tspan_line_start; -- cgit v1.2.3 From ce664d6b69a8e67e3518116f927958edf0ff469c Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 13 May 2014 19:54:03 +0200 Subject: add 64-bit resource manifests for Windows x64 builds (bzr r13341.1.17) --- src/inkscape-manifest-x64.xml | 10 ++++++++++ src/inkscape-x64.rc | 30 ++++++++++++++++++++++++++++++ src/inkview-manifest-x64.xml | 10 ++++++++++ src/inkview-x64.rc | 29 +++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 src/inkscape-manifest-x64.xml create mode 100644 src/inkscape-x64.rc create mode 100644 src/inkview-manifest-x64.xml create mode 100644 src/inkview-x64.rc (limited to 'src') diff --git a/src/inkscape-manifest-x64.xml b/src/inkscape-manifest-x64.xml new file mode 100644 index 000000000..38526cfe6 --- /dev/null +++ b/src/inkscape-manifest-x64.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/src/inkscape-x64.rc b/src/inkscape-x64.rc new file mode 100644 index 000000000..ce286c2ca --- /dev/null +++ b/src/inkscape-x64.rc @@ -0,0 +1,30 @@ + +APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" +1 24 DISCARDABLE "./inkscape-manifest-x64.xml" + +1 VERSIONINFO + FILEVERSION 0,48,0,9 + PRODUCTVERSION 0,48,0,9 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040901b5" + BEGIN + VALUE "Comments", "Published under the GNU GPL" + VALUE "CompanyName", "inkscape.org" + VALUE "FileDescription", "Inkscape" + VALUE "FileVersion", "0.48+devel" + VALUE "InternalName", "Inkscape" + VALUE "LegalCopyright", " 2014 Inkscape" + VALUE "ProductName", "Inkscape" + VALUE "ProductVersion", "0.48+devel" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1033, 437 + END +END + +1000 BITMAP "./show-preview.bmp" + diff --git a/src/inkview-manifest-x64.xml b/src/inkview-manifest-x64.xml new file mode 100644 index 000000000..38526cfe6 --- /dev/null +++ b/src/inkview-manifest-x64.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/src/inkview-x64.rc b/src/inkview-x64.rc new file mode 100644 index 000000000..2de16060b --- /dev/null +++ b/src/inkview-x64.rc @@ -0,0 +1,29 @@ + +APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" +1 24 DISCARDABLE "./inkview-manifest-x64.xml" + +1 VERSIONINFO + FILEVERSION 0,48,0,9 + PRODUCTVERSION 0,48,0,9 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040901b5" + BEGIN + VALUE "Comments", "Published under the GNU GPL" + VALUE "CompanyName", "inkscape.org" + VALUE "FileDescription", "Inkview" + VALUE "FileVersion", "0.48+devel" + VALUE "InternalName", "Inkview" + VALUE "LegalCopyright", " 2014 Inkscape" + VALUE "ProductName", "Inkview" + VALUE "ProductVersion", "0.48+devel" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 1033, 437 + END +END + +1000 BITMAP "./show-preview.bmp" -- cgit v1.2.3 From 41ab3bd526807e0a092466e7d4e979f12bab81ff Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 13 May 2014 21:17:06 +0200 Subject: fix windows 64bit build. (changes already committed to trunk) (bzr r13341.1.19) --- src/2geom/toposweep.cpp | 1 + src/libdepixelize/kopftracer2011.cpp | 4 +++- src/libdepixelize/kopftracer2011.h | 1 + src/prefix.cpp | 3 --- src/ui/dialog/filedialogimpl-win32.h | 2 ++ src/widgets/ege-paint-def.cpp | 1 - 6 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/2geom/toposweep.cpp b/src/2geom/toposweep.cpp index cfb91857c..4da3f6922 100644 --- a/src/2geom/toposweep.cpp +++ b/src/2geom/toposweep.cpp @@ -53,6 +53,7 @@ TopoGraph::Edge TopoGraph::remove_edge(unsigned ix, unsigned jx) { } } assert(0); + return v[0]; // if assert is disabled, return first Edge. } void TopoGraph::cannonize() { diff --git a/src/libdepixelize/kopftracer2011.cpp b/src/libdepixelize/kopftracer2011.cpp index e2f387c86..bbb73d445 100644 --- a/src/libdepixelize/kopftracer2011.cpp +++ b/src/libdepixelize/kopftracer2011.cpp @@ -26,13 +26,15 @@ # include #endif + +#include "kopftracer2011.h" + // Build fix under Inkscape build tree #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include #endif #include -#include "kopftracer2011.h" #include "priv/colorspace.h" #include "priv/homogeneoussplines.h" #include "priv/branchless.h" diff --git a/src/libdepixelize/kopftracer2011.h b/src/libdepixelize/kopftracer2011.h index 598f6c79c..c60d0a61a 100644 --- a/src/libdepixelize/kopftracer2011.h +++ b/src/libdepixelize/kopftracer2011.h @@ -27,6 +27,7 @@ #include +#include // Contains exception definitions #include #include diff --git a/src/prefix.cpp b/src/prefix.cpp index 99e20171f..630d6caa8 100644 --- a/src/prefix.cpp +++ b/src/prefix.cpp @@ -44,9 +44,6 @@ extern "C" { #endif /* __cplusplus */ -#undef NULL -#define NULL ((void *) 0) - #ifdef __GNUC__ #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;} #else diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index 29bcb9a45..a71ee1ad0 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -13,6 +13,8 @@ # include "config.h" #endif +#include + #ifdef WIN32 #if WITH_GLIBMM_2_32 #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H diff --git a/src/widgets/ege-paint-def.cpp b/src/widgets/ege-paint-def.cpp index 542205b53..1a8ad041a 100644 --- a/src/widgets/ege-paint-def.cpp +++ b/src/widgets/ege-paint-def.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 4fd60580e1dd021f5a16845ff9e580044835cbb0 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 14 May 2014 18:57:01 +0200 Subject: i18n. Fix for Bug #1318929 (untranslatable string in trunk-r13370). Translations. PO template update. Translations. French translation update. (bzr r13374) --- src/selection-describer.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index 88450dfdf..1cb96fed0 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -56,6 +56,21 @@ char* collect_terms (GSList *items) return g_strdup(ss.str().c_str()); } +// Returns the number of terms in the list +static int count_terms (GSList *items) +{ + GSList *check = NULL; + int count=0; + for (GSList *i = (GSList *)items; i != NULL; i = i->next) { + const char *term = SP_ITEM(i->data)->displayName(); + if (term != NULL && g_slist_find (check, term) == NULL) { + check = g_slist_prepend (check, (void *) term); + count++; + } + } + return count; +} + // Returns the number of filtered items in the list static int count_filtered (GSList *items) { @@ -194,9 +209,12 @@ void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *select } else { // multiple items int objcount = g_slist_length((GSList *)items); char *terms = collect_terms ((GSList *)items); - - gchar *objects_str = g_strdup_printf( - "%i objects selected of types %s", objcount, terms); + int n_terms = count_terms((GSList *)items); + + gchar *objects_str = g_strdup_printf(ngettext( + "%i objects selected of type %s", + "%i objects selected of types %s", n_terms), + objcount, terms); g_free(terms); -- cgit v1.2.3 From 39f6feb2f4297f5460be4b7a0f711f19af5dfc9a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 12:18:08 +0200 Subject: Style rewrite: Unquote strings from libcroco. Fixes 1303422. Fixed bugs: - https://launchpad.net/bugs/1303422 (bzr r13377) --- src/style-internal.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 2c488105b..b15892128 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -648,7 +648,8 @@ SPIString::read( gchar const *str ) { if( !str ) return; - g_free(value); + // libcroco puts quotes around some strings... remove + gchar *str_unquoted = attribute_unquote(str); if (!strcmp(str, "inherit")) { set = true; @@ -657,8 +658,10 @@ SPIString::read( gchar const *str ) { } else { set = true; inherit = false; - value = g_strdup(str); + value = g_strdup(str_unquoted); } + + g_free( str_unquoted ); } -- cgit v1.2.3 From d1022d88770ba85ab55285f8d59e0d3ee94ec153 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 12:22:12 +0200 Subject: Style rewrite: Unquote strings from libcroco. Fixes 1303422. Fixed bugs: - https://launchpad.net/bugs/1303422 (bzr r13341.1.23) --- src/style-internal.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 2c488105b..b15892128 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -648,7 +648,8 @@ SPIString::read( gchar const *str ) { if( !str ) return; - g_free(value); + // libcroco puts quotes around some strings... remove + gchar *str_unquoted = attribute_unquote(str); if (!strcmp(str, "inherit")) { set = true; @@ -657,8 +658,10 @@ SPIString::read( gchar const *str ) { } else { set = true; inherit = false; - value = g_strdup(str); + value = g_strdup(str_unquoted); } + + g_free( str_unquoted ); } -- cgit v1.2.3 From 779a151867babce787dbd06ff1e40d54d3b9443d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 16:13:07 +0200 Subject: Fix Pango markup used in Text and Font dialog. (bzr r13378) --- src/ui/dialog/text-edit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 17c29c69f..c1ebb32e0 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -404,12 +404,12 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt"); // Pango font size is in 1024ths of a point - // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + // C++11: Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) ); std::ostringstream size_st; - size_st << pt_size * PANGO_SCALE; + size_st << int(pt_size * PANGO_SCALE); // Markup code expects integers - Glib::ustring markup = "" + phrase_escaped + ""; + Glib::ustring markup = "" + phrase_escaped + ""; preview_label.set_markup(markup.c_str()); } -- cgit v1.2.3 From 16262c5a24e91309c4c762ffbb0e82b05026c9b6 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 15 May 2014 16:14:19 +0200 Subject: Fix Pango markup in Text and Font dialog. (bzr r13341.1.25) --- src/ui/dialog/text-edit.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 17c29c69f..c1ebb32e0 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -404,12 +404,12 @@ void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) double pt_size = Inkscape::Util::Quantity::convert(sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit), "px", "pt"); // Pango font size is in 1024ths of a point - // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + // C++11: Glib::ustring size = std::to_string( int(pt_size * PANGO_SCALE) ); std::ostringstream size_st; - size_st << pt_size * PANGO_SCALE; + size_st << int(pt_size * PANGO_SCALE); // Markup code expects integers - Glib::ustring markup = "" + phrase_escaped + ""; + Glib::ustring markup = "" + phrase_escaped + ""; preview_label.set_markup(markup.c_str()); } -- cgit v1.2.3 From bdc1f59ae6a11600ba11e848b4e5a76bf5cc92a5 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 15 May 2014 22:12:29 +0200 Subject: Remove debugging output (bzr r13379) --- src/seltrans.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/seltrans.cpp b/src/seltrans.cpp index fa2441847..d6f31f073 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -929,7 +929,6 @@ gboolean Inkscape::SelTrans::scaleRequest(Geom::Point &pt, guint state) sn = m.freeSnapScale(_snap_points, _point, geom_scale, _origin_for_specpoints); } - std::cout << bb.getSnapped() << " | " << sn.getSnapped() << std::endl; // These lines below are duplicated in stretchRequest if (bb.getSnapped() || sn.getSnapped()) { if (bb.getSnapped()) { -- cgit v1.2.3 From 11bb6f3d4fedd1d22637f00a480dea54d505c23c Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:07:31 +0200 Subject: make windows filedialog's code more portable for different mingw versions (failed on 64bit) (bzr r13380) --- src/ui/dialog/filedialogimpl-win32.cpp | 11 ++--------- src/ui/dialog/filedialogimpl-win32.h | 6 +++++- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 9d91f5d56..1eeee0592 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -72,13 +72,6 @@ const unsigned long MaxPreviewFileSize = 10240; // kB #define IDC_SHOW_PREVIEW 1000 -// Windows 2000 version of OPENFILENAMEW -struct OPENFILENAMEEXW : public OPENFILENAMEW { - void * pvReserved; - DWORD dwReserved; - DWORD FlagsEx; -}; - struct Filter { gunichar2* name; @@ -483,7 +476,7 @@ void FileOpenDialogImplWin32::createFilterMenu() void FileOpenDialogImplWin32::GetOpenFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_mutex != NULL); @@ -1829,7 +1822,7 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt void FileSaveDialogImplWin32::GetSaveFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_main_loop != NULL); diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index a71ee1ad0..c523f041d 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -20,9 +20,13 @@ #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H # include #endif - #endif + #include "gc-core.h" + // define WINVER high enough so we get the correct OPENFILENAMEW size +#ifndef WINVER +#define WINVER 0x0500 +#endif #include #include "filedialogimpl-gtkmm.h" -- cgit v1.2.3 From 639540b57f19cce10e6b37df3475c252455a1b28 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:08:12 +0200 Subject: make windows filedialog's code more portable for different mingw versions (failed on 64bit) (bzr r13341.1.26) --- src/ui/dialog/filedialogimpl-win32.cpp | 12 ++---------- src/ui/dialog/filedialogimpl-win32.h | 6 +++++- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 9d91f5d56..06153a2d8 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -72,13 +72,6 @@ const unsigned long MaxPreviewFileSize = 10240; // kB #define IDC_SHOW_PREVIEW 1000 -// Windows 2000 version of OPENFILENAMEW -struct OPENFILENAMEEXW : public OPENFILENAMEW { - void * pvReserved; - DWORD dwReserved; - DWORD FlagsEx; -}; - struct Filter { gunichar2* name; @@ -483,7 +476,7 @@ void FileOpenDialogImplWin32::createFilterMenu() void FileOpenDialogImplWin32::GetOpenFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_mutex != NULL); @@ -1829,7 +1822,7 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt void FileSaveDialogImplWin32::GetSaveFileName_thread() { - OPENFILENAMEEXW ofn; + OPENFILENAMEW ofn; g_assert(this != NULL); g_assert(_main_loop != NULL); @@ -1860,7 +1853,6 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread() ofn.nFilterIndex = _filter_index; ofn.lpfnHook = GetSaveFileName_hookproc; ofn.lCustData = (LPARAM)this; - _result = GetSaveFileNameW(&ofn) != 0; g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count); diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index a71ee1ad0..c523f041d 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -20,9 +20,13 @@ #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H # include #endif - #endif + #include "gc-core.h" + // define WINVER high enough so we get the correct OPENFILENAMEW size +#ifndef WINVER +#define WINVER 0x0500 +#endif #include #include "filedialogimpl-gtkmm.h" -- cgit v1.2.3 From 7287cb711c0409f59eb0e43648b9b3ee29e4864f Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:50:29 +0200 Subject: fix compile warning (bzr r13341.1.29) --- src/desktop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/desktop.h b/src/desktop.h index be2bf891f..ec240dd40 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -442,7 +442,7 @@ private: prefs->addObserver(*this); } private: - void notify(Inkscape::Preferences::Entry const &val) { + void notify(Inkscape::Preferences::Entry const &) { _desktop->redrawDesktop(); } SPDesktop *_desktop; -- cgit v1.2.3 From 6931a268d2eb4c7d2e7f84fd4fe826b88bdc75a2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 15 May 2014 23:51:32 +0200 Subject: fix compile warning (bzr r13384) --- src/desktop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/desktop.h b/src/desktop.h index be2bf891f..ec240dd40 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -442,7 +442,7 @@ private: prefs->addObserver(*this); } private: - void notify(Inkscape::Preferences::Entry const &val) { + void notify(Inkscape::Preferences::Entry const &) { _desktop->redrawDesktop(); } SPDesktop *_desktop; -- cgit v1.2.3 From 76e9bb52fbd6a39e68cd8e34559762e2b2d1806b Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 16 May 2014 00:17:53 +0200 Subject: fix C++11 compilation (bzr r13341.1.30) --- src/live_effects/lpe-vonkoch.cpp | 3 +-- src/ui/tool/node.h | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index c0050fa60..8b0b716fe 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -4,11 +4,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include "live_effects/lpe-vonkoch.h" #include -#include "live_effects/lpe-vonkoch.h" #include <2geom/transforms.h> //using std::vector; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 5971956e1..101af4817 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -41,6 +41,7 @@ template class NodeIterator; } } +/* #if HAVE_TR1_UNORDERED_SET namespace std { namespace tr1 { @@ -48,6 +49,8 @@ template struct hash< Inkscape::UI::NodeIterator >; } } #endif +#endif +*/ namespace Inkscape { namespace UI { -- cgit v1.2.3 From c9bc38e7eadc17562c0348d12fe58cf5fa114bd3 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 16 May 2014 00:18:42 +0200 Subject: fix C++11 compilation (bzr r13385) --- src/live_effects/lpe-vonkoch.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index c0050fa60..8b0b716fe 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -4,11 +4,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include "live_effects/lpe-vonkoch.h" #include -#include "live_effects/lpe-vonkoch.h" #include <2geom/transforms.h> //using std::vector; -- cgit v1.2.3 From 165aa67187ef6e5b61515d08891ab9f42333f2c8 Mon Sep 17 00:00:00 2001 From: Tomasz Boczkowski Date: Fri, 16 May 2014 14:54:52 +0200 Subject: Fix crash in preview widget for files containing objectBoundingBox related patterns (bzr r13341.1.31) --- src/sp-pattern.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index e465565c4..9e9ce85f3 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -593,7 +593,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b double tile_y = pattern_y(this); double tile_width = pattern_width(this); double tile_height = pattern_height(this); - if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX && bbox) { tile_x *= bbox->width(); tile_y *= bbox->height(); tile_width *= bbox->width(); @@ -614,7 +614,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b } else { // Content to bbox - if (pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + if (pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX && bbox) { content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0,0); } } -- cgit v1.2.3 From a8ed8893594a2e0f609beba7dc9bee86df408b01 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 16 May 2014 19:31:40 +0200 Subject: don't rely on operator precedence (rev. 13372) (bzr r13341.1.32) --- src/sp-pattern.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 9e9ce85f3..cc82c637e 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -593,7 +593,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b double tile_y = pattern_y(this); double tile_width = pattern_width(this); double tile_height = pattern_height(this); - if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX && bbox) { + if ( bbox && (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) { tile_x *= bbox->width(); tile_y *= bbox->height(); tile_width *= bbox->width(); @@ -614,7 +614,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b } else { // Content to bbox - if (pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX && bbox) { + if (bbox && (pattern_patternContentUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) { content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0,0); } } -- cgit v1.2.3 From b4c6736390839c53251011ab5c536e020c02bda0 Mon Sep 17 00:00:00 2001 From: Tomasz Boczkowski Date: Fri, 16 May 2014 22:53:46 +0200 Subject: fix compliance test pservers-pattern-03-f - using fallback when pattern is empty (bzr r13341.1.34) --- src/display/nr-style.cpp | 18 ++++++++++++++++-- src/sp-paint-server.cpp | 5 +++++ src/sp-paint-server.h | 1 + src/sp-pattern.cpp | 10 ++++++++++ src/sp-pattern.h | 2 ++ 5 files changed, 34 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index ec3117079..a9f101f69 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -95,7 +95,14 @@ NRStyle::~NRStyle() void NRStyle::set(SPStyle *style) { if ( style->fill.isPaintserver() ) { - fill.set(style->getFillPaintServer()); + SPPaintServer* server = style->getFillPaintServer(); + if ( server && server->isValid() ) { + fill.set(server); + } else if ( style->fill.colorSet ) { + fill.set(style->fill.value.color); + } else { + fill.clear(); + } } else if ( style->fill.isColor() ) { fill.set(style->fill.value.color); } else if ( style->fill.isNone() ) { @@ -117,7 +124,14 @@ void NRStyle::set(SPStyle *style) } if ( style->stroke.isPaintserver() ) { - stroke.set(style->getStrokePaintServer()); + SPPaintServer* server = style->getStrokePaintServer(); + if ( server && server->isValid() ) { + stroke.set(server); + } else if ( style->stroke.isColor() ) { + stroke.set(style->stroke.colorSet); + } else { + stroke.clear(); + } } else if ( style->stroke.isColor() ) { stroke.set(style->stroke.value.color); } else if ( style->stroke.isNone() ) { diff --git a/src/sp-paint-server.cpp b/src/sp-paint-server.cpp index 692265bd8..77ad7a35f 100644 --- a/src/sp-paint-server.cpp +++ b/src/sp-paint-server.cpp @@ -58,6 +58,11 @@ bool SPPaintServer::isSolid() const return solid; } +bool SPPaintServer::isValid() const +{ + return true; +} + /* Local Variables: mode:c++ diff --git a/src/sp-paint-server.h b/src/sp-paint-server.h index 02e2f10ec..c1c8d651e 100644 --- a/src/sp-paint-server.h +++ b/src/sp-paint-server.h @@ -29,6 +29,7 @@ public: bool isSwatch() const; bool isSolid() const; + virtual bool isValid() const; virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity) = 0; diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index cc82c637e..9aa54eadf 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -541,6 +541,16 @@ static bool pattern_hasItemChildren (SPPattern const *pat) return hasChildren; } +bool SPPattern::isValid() const +{ + double tile_width = pattern_width(this); + double tile_height = pattern_height(this); + + if (tile_width <= 0 || tile_height <= 0) + return false; + return true; +} + cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { bool needs_opacity = (1.0 - opacity) >= 1e-3; diff --git a/src/sp-pattern.h b/src/sp-pattern.h index f69ba10b3..eb34b6714 100644 --- a/src/sp-pattern.h +++ b/src/sp-pattern.h @@ -56,6 +56,8 @@ public: sigc::connection modified_connection; + bool isValid() const; + virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); protected: -- cgit v1.2.3 From c0df405028494695ebd0b0a497c7526a2520cafd Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 16 May 2014 17:53:59 -0400 Subject: Fix GTK+ 3 build (bzr r13341.1.35) --- src/live_effects/lpe-bspline.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 454924d2b..b19b697c0 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -1,14 +1,27 @@ #define INKSCAPE_LPE_BSPLINE_C + /* * Released under GNU GPL, read the file 'COPYING' for more information */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if WITH_GLIBMM_2_32 +# include +#endif + #include #include #include #include #include + #include #include + + #include "display/curve.h" #include <2geom/bezier-curve.h> #include <2geom/point.h> -- cgit v1.2.3 From 344da57dece53a28426168c50d5802670bc9e4b9 Mon Sep 17 00:00:00 2001 From: Tomasz Boczkowski Date: Sat, 17 May 2014 11:27:41 +0200 Subject: fix compliance test pservers-pattern-04-f - inheriting pattern viewBox (bzr r13341.1.36) --- src/sp-pattern.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 9aa54eadf..9b7330a24 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -615,9 +615,10 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // Content to tile (pattern space) Geom::Affine content2ps; - if (this->viewBox_set) { + Geom::OptRect effective_view_box = pattern_viewBox(this); + if (effective_view_box) { // viewBox to pattern server (using SPViewBox) - viewBox = *pattern_viewBox(this); + viewBox = *effective_view_box; c2p.setIdentity(); apply_viewbox( pattern_tile ); content2ps = c2p; -- cgit v1.2.3 From b5d085f89b65cd28092a9548b409ac69233bb8d9 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 22 May 2014 18:27:27 +0200 Subject: i18n. Fix for Bug #1318339 (Tooltips in extensions page elements are not translated). Fixed bugs: - https://launchpad.net/bugs/1318339 (bzr r13396) --- src/extension/param/notebook.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/param/notebook.cpp b/src/extension/param/notebook.cpp index 97002e33f..9ec31ca6b 100644 --- a/src/extension/param/notebook.cpp +++ b/src/extension/param/notebook.cpp @@ -214,7 +214,7 @@ Gtk::Widget * ParamNotebookPage::get_widget(SPDocument * doc, Inkscape::XML::Nod // printf("Tip: '%s'\n", tip); vbox->pack_start(*widg, false, false, 2); if (tip) { - widg->set_tooltip_text(tip); + widg->set_tooltip_text(_(tip)); } else { widg->set_tooltip_text(""); widg->set_has_tooltip(false); -- cgit v1.2.3 From 67e3a25d12d9a273afb1b8f9f3258b232989c660 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Fri, 23 May 2014 22:52:32 +0200 Subject: Fix flakiness of measurement tool (due to issues with parallel lines, duplicate intersections, and faulty sorting of intersections) Fixed bugs: - https://launchpad.net/bugs/1022733 (bzr r13397) --- src/2geom/crossing.cpp | 20 +++++++++++++- src/2geom/crossing.h | 1 + src/2geom/path-intersection.cpp | 33 ++++++++++++++++------- src/ui/tools/measure-tool.cpp | 59 +++++++++++++++++------------------------ 4 files changed, 68 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/2geom/crossing.cpp b/src/2geom/crossing.cpp index 13affa8e9..513327271 100644 --- a/src/2geom/crossing.cpp +++ b/src/2geom/crossing.cpp @@ -154,7 +154,6 @@ Crossings reverse_tb(Crossings const &cr, unsigned split, std::vector ma Crossings ret; for(Crossings::const_iterator i = cr.begin(); i != cr.end(); ++i) { double mx = max[i->b - split]; - std::cout << i->b << "\n"; ret.push_back(Crossing(i->ta, i->tb > mx+0.01 ? (1 - (i->tb - mx) + mx) : mx - i->tb, !i->dir)); } @@ -181,6 +180,25 @@ CrossingSet reverse_tb(CrossingSet const &cr, unsigned split, std::vector max); void clean(Crossings &cr_a, Crossings &cr_b); +void delete_duplicates(Crossings &crs); } diff --git a/src/2geom/path-intersection.cpp b/src/2geom/path-intersection.cpp index ff24b92eb..63a29423d 100644 --- a/src/2geom/path-intersection.cpp +++ b/src/2geom/path-intersection.cpp @@ -164,20 +164,35 @@ void append(T &a, T const &b) { bool linear_intersect(Point A0, Point A1, Point B0, Point B1, double &tA, double &tB, double &det) { - // kramers rule as cross products + bool both_lines_non_zero = (!are_near(A0, A1)) && (!are_near(B0, B1)); + + // Cramer's rule as cross products Point Ad = A1 - A0, Bd = B1 - B0, d = B0 - A0; det = cross(Ad, Bd); - if( 1.0 + det == 1.0 ) - return false; - else - { - double detinv = 1.0 / det; - tA = cross(d, Bd) * detinv; - tB = cross(d, Ad) * detinv; - return tA >= 0. && tA <= 1. && tB >= 0. && tB <= 1.; + + double det_rel = det; // Calculate the determinant of the normalized vectors + if (both_lines_non_zero) { + det_rel /= Ad.length(); + det_rel /= Bd.length(); } + + if( fabs(det_rel) < 1e-12 ) { // If the cross product is NEARLY zero, + // Then one of the linesegments might have length zero + if (both_lines_non_zero) { + // If that's not the case, then we must have either: + // - parallel lines, with no intersections, or + // - coincident lines, with an infinite number of intersections + // Either is quite useless, so we'll just bail out + return false; + } // Else, one of the linesegments is zero, and we might still be able to calculate a single intersection point + } // Else we haven't bailed out, and we'll try to calculate the intersections + + double detinv = 1.0 / det; + tA = cross(d, Bd) * detinv; + tB = cross(d, Ad) * detinv; + return (tA >= 0.) && (tA <= 1.) && (tB >= 0.) && (tB <= 1.); } diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp index 2c85874bc..feeb68288 100644 --- a/src/ui/tools/measure-tool.cpp +++ b/src/ui/tools/measure-tool.cpp @@ -277,21 +277,13 @@ void MeasureTool::finish() { // return ret; //} -static bool GeomPointSortPredicate(const Geom::Point& p1, const Geom::Point& p2) +static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom::PathVector const &lineseg, SPCurve *curve, std::vector &intersections) { - if (p1[Geom::Y] == p2[Geom::Y]) { - return p1[Geom::X] < p2[Geom::X]; - } else { - return p1[Geom::Y] < p2[Geom::Y]; - } -} -static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom::PathVector const &lineseg, SPCurve *curve, std::vector &intersections) -{ curve->transform(item->i2doc_affine()); - // Find all intersections of the control-line with this shape Geom::CrossingSet cs = Geom::crossings(lineseg, curve->get_pathvector()); + Geom::delete_duplicates(cs[0]); // Reconstruct and store the points of intersection for (Geom::Crossings::const_iterator m = cs[0].begin(); m != cs[0].end(); ++m) { @@ -304,10 +296,11 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom: item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) || ((*m).ta + eps < 1 && item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta + eps), false, NULL)) ) { - intersections.push_back(intersection); + intersections.push_back((*m).ta); } #else - intersections.push_back(lineseg[0].pointAt((*m).ta)); + intersections.push_back((*m).ta); + #endif } } @@ -441,28 +434,20 @@ bool MeasureTool::root_handler(GdkEvent* event) { points.push_back(desktop->d2w(start_point + (i / NPOINTS) * (end_point - start_point))); } -// TODO: Felipe, why don't you simply iterate over all items, and test whether their bounding boxes intersect -// with the measurement line, instead of interpolating? E.g. bbox_of_measurement_line.intersects(*bbox_of_item). -// That's also how the object-snapper works, see _findCandidates() in object-snapper.cpp. + // TODO: Felipe, why don't you simply iterate over all items, and test whether their bounding boxes intersect + // with the measurement line, instead of interpolating over 800 points? E.g. bbox_of_measurement_line.intersects(*bbox_of_item). + // That's also how the object-snapper works, see _findCandidates() in object-snapper.cpp. + + // TODO switch to a different variable name. The single letter 'l' is easy to misread. //select elements crossed by line segment: GSList *items = sp_desktop_document(desktop)->getItemsAtPoints(desktop->dkey, points); - std::vector intersections; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool ignore_1st_and_last = prefs->getBool("/tools/measure/ignore_1st_and_last", true); - - if (!ignore_1st_and_last) { - intersections.push_back(desktop->dt2doc(start_point)); - } - - std::vector placements; - - // TODO switch to a different variable name. The single letter 'l' is easy to misread. + std::vector intersection_times; for (GSList *l = items; l != NULL; l = l->next) { SPItem *item = static_cast(l->data); if (SP_IS_SHAPE(item)) { - calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersections); + calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersection_times); } else { if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin(); @@ -486,7 +471,7 @@ bool MeasureTool::root_handler(GdkEvent* event) { curve->transform(item->i2doc_affine()); - calculate_intersections(desktop, item, lineseg, curve, intersections); + calculate_intersections(desktop, item, lineseg, curve, intersection_times); if (iter == te_get_layout(item)->end()) { break; @@ -496,13 +481,10 @@ bool MeasureTool::root_handler(GdkEvent* event) { } } - if (!ignore_1st_and_last) { - intersections.push_back(desktop->dt2doc(end_point)); - } - - //sort intersections - if (intersections.size() > 2) { - std::sort(intersections.begin(), intersections.end(), GeomPointSortPredicate); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (!prefs->getBool("/tools/measure/ignore_1st_and_last", true)) { + intersection_times.push_back(0); + intersection_times.push_back(1); } Glib::ustring unit_name = prefs->getString("/tools/measure/unit"); @@ -516,6 +498,13 @@ bool MeasureTool::root_handler(GdkEvent* event) { Geom::Point windowNormal = Geom::unit_vector(Geom::rot90(desktop->d2w(end_point - start_point))); Geom::Point normal = desktop->w2d(windowNormal); + std::vector intersections; + std::sort(intersection_times.begin(), intersection_times.end()); + for (std::vector::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) { + intersections.push_back(lineseg[0].pointAt(*iter_t)); + } + + std::vector placements; for (size_t idx = 1; idx < intersections.size(); ++idx) { LabelPlacement placement; placement.lengthVal = (intersections[idx] - intersections[idx - 1]).length(); -- cgit v1.2.3 From d2d46b5e9228a21330720e7c8ccce353ced02b72 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 26 May 2014 13:37:44 +0200 Subject: Convert from 90px to inch to 96px to inch per SVG (CSS) specification. (bzr r13341.1.39) --- src/extension/internal/gdkpixbuf-input.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index a384c7bde..da179bee0 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -87,11 +87,11 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) ir = new ImageResolution(uri); } if (ir && ir->ok()) { - xscale = 900.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi - yscale = 900.0 / floor(10.*ir->y() + .5); + xscale = 960.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi + yscale = 960.0 / floor(10.*ir->y() + .5); } else { - xscale = 90.0 / defaultxdpi; - yscale = 90.0 / defaultxdpi; + xscale = 96.0 / defaultxdpi; + yscale = 96.0 / defaultxdpi; } width *= xscale; -- cgit v1.2.3 From 2ddabce031c6c408688477544f9b16a28b7b9cb1 Mon Sep 17 00:00:00 2001 From: Fridrich Strba Date: Tue, 27 May 2014 12:35:54 +0200 Subject: Port inkscape to librevenge framework for WPG, CDR and VSD imports (bzr r13398.1.1) --- src/extension/internal/cdr-input.cpp | 20 ++++++++++-------- src/extension/internal/vsd-input.cpp | 20 ++++++++++-------- src/extension/internal/wpg-input.cpp | 41 ++++++++++++------------------------ src/ui/dialog/symbols.cpp | 10 +++++---- 4 files changed, 41 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index 0111ed626..c4f251361 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -60,7 +60,7 @@ namespace Internal { class CdrImportDialog : public Gtk::Dialog { public: - CdrImportDialog(const std::vector &vec); + CdrImportDialog(const std::vector &vec); virtual ~CdrImportDialog(); bool showDialog(); @@ -86,12 +86,12 @@ private: class Gtk::VBox * vbox2; class Gtk::Widget * _previewArea; - const std::vector &_vec; // Document to be imported + const std::vector &_vec; // Document to be imported unsigned _current_page; // Current selected page int _preview_width, _preview_height; // Size of the preview area }; -CdrImportDialog::CdrImportDialog(const std::vector &vec) +CdrImportDialog::CdrImportDialog(const std::vector &vec) : _vec(vec), _current_page(1) { int num_pages = _vec.size(); @@ -210,14 +210,16 @@ void CdrImportDialog::_setPreviewPage(unsigned page) SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - WPXFileStream input(uri); + librevenge::RVNGFileStream input(uri); if (!libcdr::CDRDocument::isSupported(&input)) { return NULL; } - libcdr::CDRStringVector output; - if (!libcdr::CDRDocument::generateSVG(&input, output)) { + librevenge::RVNGStringVector output; + librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); + + if (!libcdr::CDRDocument::parse(&input, &generator)) { return NULL; } @@ -225,9 +227,9 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } - std::vector tmpSVGOutput; + std::vector tmpSVGOutput; for (unsigned i=0; i\n\n"); + librevenge::RVNGString tmpString("\n\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 6fc79237b..b7e8669b8 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include @@ -59,7 +59,7 @@ namespace Internal { class VsdImportDialog : public Gtk::Dialog { public: - VsdImportDialog(const std::vector &vec); + VsdImportDialog(const std::vector &vec); virtual ~VsdImportDialog(); bool showDialog(); @@ -85,12 +85,12 @@ private: class Gtk::VBox * vbox2; class Gtk::Widget * _previewArea; - const std::vector &_vec; // Document to be imported + const std::vector &_vec; // Document to be imported unsigned _current_page; // Current selected page int _preview_width, _preview_height; // Size of the preview area }; -VsdImportDialog::VsdImportDialog(const std::vector &vec) +VsdImportDialog::VsdImportDialog(const std::vector &vec) : _vec(vec), _current_page(1) { int num_pages = _vec.size(); @@ -209,14 +209,16 @@ void VsdImportDialog::_setPreviewPage(unsigned page) SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - WPXFileStream input(uri); + librevenge::RVNGFileStream input(uri); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - libvisio::VSDStringVector output; - if (!libvisio::VisioDocument::generateSVG(&input, output)) { + librevenge::RVNGStringVector output; + librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); + + if (!libvisio::VisioDocument::parse(&input, &generator)) { return NULL; } @@ -224,9 +226,9 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } - std::vector tmpSVGOutput; + std::vector tmpSVGOutput; for (unsigned i=0; i\n\n"); + librevenge::RVNGString tmpString("\n\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } diff --git a/src/extension/internal/wpg-input.cpp b/src/extension/internal/wpg-input.cpp index 14ff3ec77..c10926361 100644 --- a/src/extension/internal/wpg-input.cpp +++ b/src/extension/internal/wpg-input.cpp @@ -52,17 +52,8 @@ #include "util/units.h" #include -// Take a guess and fallback to 0.1.x if no configure has run -#if !defined(WITH_LIBWPG01) && !defined(WITH_LIBWPG02) -#define WITH_LIBWPG01 1 -#endif - #include "libwpg/libwpg.h" -#if WITH_LIBWPG01 -#include "libwpg/WPGStreamImplementation.h" -#elif WITH_LIBWPG02 -#include "libwpd-stream/libwpd-stream.h" -#endif +#include "librevenge-stream/librevenge-stream.h" using namespace libwpg; @@ -73,17 +64,9 @@ namespace Internal { SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { -#if WITH_LIBWPG01 - WPXInputStream* input = new libwpg::WPGFileStream(uri); -#elif WITH_LIBWPG02 - WPXInputStream* input = new WPXFileStream(uri); -#endif - if (input->isOLEStream()) { -#if WITH_LIBWPG01 - WPXInputStream* olestream = input->getDocumentOLEStream(); -#elif WITH_LIBWPG02 - WPXInputStream* olestream = input->getDocumentOLEStream("PerfectOffice_MAIN"); -#endif + librevenge::RVNGInputStream* input = new librevenge::RVNGFileStream(uri); + if (input->isStructured()) { + librevenge::RVNGInputStream* olestream = input->getSubStreamByName("PerfectOffice_MAIN"); if (olestream) { delete input; input = olestream; @@ -98,15 +81,17 @@ SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } -#if WITH_LIBWPG01 - libwpg::WPGString output; -#elif WITH_LIBWPG02 - WPXString output; -#endif - if (!libwpg::WPGraphics::generateSVG(input, output)) { + librevenge::RVNGStringVector vec; + librevenge::RVNGSVGDrawingGenerator generator(vec, ""); + + if (!libwpg::WPGraphics::parse(input, &generator) || vec.empty() || vec[0].empty()) + { delete input; return NULL; - } + } + + librevenge::RVNGString output("\n\n"); + output.append(vec[0]); //printf("I've got a doc: \n%s", painter.document.c_str()); diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0b048ed82 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -63,7 +63,7 @@ #ifdef WITH_LIBVISIO #include -#include +#include #endif #include "verbs.h" @@ -449,14 +449,16 @@ void SymbolsDialog::iconChanged() { // Read Visio stencil files SPDocument* read_vss( gchar* fullname, gchar* filename ) { - WPXFileStream input(fullname); + librevenge::RVNGFileStream input(fullname); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - libvisio::VSDStringVector output; - if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) { + librevenge::RVNGStringVector output; + librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); + + if (!libvisio::VisioDocument::parseStencils(&input, &generator)) { return NULL; } -- cgit v1.2.3 From 6c06d19d1464f28f3a10eb4c066817a73084588b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 28 May 2014 11:05:47 +0200 Subject: Initialize style store with default styles. Fixes Gtk-CRITICAL and GLib-Gobject-CRITICAL errors. (bzr r13400) --- src/libnrtype/font-lister.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 98589d9d7..300273378 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -83,6 +83,15 @@ namespace Inkscape font_list_store->thaw_notify(); style_list_store = Gtk::ListStore::create (FontStyleList); + + // Initialize style store with defaults + style_list_store->freeze_notify(); + style_list_store->clear(); + for (GList *l=default_styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + } + style_list_store->thaw_notify(); } // Example of how to use "foreach_iter" -- cgit v1.2.3 From 45922bee145584c0161fa89735da108ece53e0f5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 28 May 2014 11:11:31 +0200 Subject: Initialize style store with default styles. Fixes Gtk-CRITICAL and GLib-Gobject-CRITICAL errors. (bzr r13341.1.40) --- src/libnrtype/font-lister.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 98589d9d7..300273378 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -83,6 +83,15 @@ namespace Inkscape font_list_store->thaw_notify(); style_list_store = Gtk::ListStore::create (FontStyleList); + + // Initialize style store with defaults + style_list_store->freeze_notify(); + style_list_store->clear(); + for (GList *l=default_styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + } + style_list_store->thaw_notify(); } // Example of how to use "foreach_iter" -- cgit v1.2.3 From f4f35a8c63d574cadaec4ad323f6c9cffa30e4c7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 29 May 2014 11:41:39 +0200 Subject: Use SPStyle value for 'font-family' rather than parse 'style' ourselves. This fixes the problem of a 'font-family' declared via the 'font' shorthand being ignored when creating the document font list. (bzr r13401) --- src/libnrtype/font-lister.cpp | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 300273378..333c4ef5b 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -240,37 +240,12 @@ namespace Inkscape font_list_store->thaw_notify(); } - // FIXME: why do we parse the style attribute instead of the object's SPStyle? void FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { - const gchar *style = r->getRepr()->attribute("style"); - if( style != NULL ) { - - std::vector tokens = Glib::Regex::split_simple(";", style ); - for( size_t i=0; i < tokens.size(); ++i ) { - - Glib::ustring token = tokens[i]; - size_t found = token.find("font-family:"); - - if( found != Glib::ustring::npos ) { - - // Remove "font-family:" - token.erase(found,12); - - // Remove any leading single or double quote - if( token[0] == '\'' || token[0] == '"' ) { - token.erase(0,1); - } - - // Remove any trailing single or double quote - if( token[token.length()-1] == '\'' || token[token.length()-1] == '"' ) { - token.erase(token.length()-1); - } - - l->push_back( token ); - } - } + const gchar *font_family = r->style->font_family.value; + if( font_family ) { + l->push_back( Glib::ustring( font_family ) ); } for (SPObject *child = r->firstChild(); child; child = child->getNext()) { -- cgit v1.2.3 From bb0190888e9c3ce7628e4662e963d115d7855b15 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 29 May 2014 11:52:45 +0200 Subject: Use SPStyle value for 'font-family' rather than parse 'style' ourselves. This fixes the problem of a 'font-family' declared via the 'font' shorthand being ignored when creating the document font list. (bzr r13341.1.41) --- src/libnrtype/font-lister.cpp | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 300273378..333c4ef5b 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -240,37 +240,12 @@ namespace Inkscape font_list_store->thaw_notify(); } - // FIXME: why do we parse the style attribute instead of the object's SPStyle? void FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { - const gchar *style = r->getRepr()->attribute("style"); - if( style != NULL ) { - - std::vector tokens = Glib::Regex::split_simple(";", style ); - for( size_t i=0; i < tokens.size(); ++i ) { - - Glib::ustring token = tokens[i]; - size_t found = token.find("font-family:"); - - if( found != Glib::ustring::npos ) { - - // Remove "font-family:" - token.erase(found,12); - - // Remove any leading single or double quote - if( token[0] == '\'' || token[0] == '"' ) { - token.erase(0,1); - } - - // Remove any trailing single or double quote - if( token[token.length()-1] == '\'' || token[token.length()-1] == '"' ) { - token.erase(token.length()-1); - } - - l->push_back( token ); - } - } + const gchar *font_family = r->style->font_family.value; + if( font_family ) { + l->push_back( Glib::ustring( font_family ) ); } for (SPObject *child = r->firstChild(); child; child = child->getNext()) { -- cgit v1.2.3 From e5004cc2ccb6d6554125552b4ef0e0b4cb23daf0 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 30 May 2014 15:29:49 +0200 Subject: Unquote names in 'font-family' lists. Partial fix for #1029080 (bzr r13402) --- src/style-internal.cpp | 17 ++++++++++----- src/style.cpp | 52 ++++++++++++++++++++++++++++---------------- src/style.h | 4 +++- src/widgets/text-toolbar.cpp | 1 + src/xml/repr-css.cpp | 20 ++++++++--------- 5 files changed, 58 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index b15892128..8b4f3c1cd 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -648,9 +648,6 @@ SPIString::read( gchar const *str ) { if( !str ) return; - // libcroco puts quotes around some strings... remove - gchar *str_unquoted = attribute_unquote(str); - if (!strcmp(str, "inherit")) { set = true; inherit = true; @@ -658,10 +655,18 @@ SPIString::read( gchar const *str ) { } else { set = true; inherit = false; - value = g_strdup(str_unquoted); - } - g_free( str_unquoted ); + // libcroco puts quotes around some strings... remove + Glib::ustring str_unquoted(str); + css_unquote( str_unquoted ); + + // Unquote individual family names, Pango always uses unquoted names. + if( name.compare( "font-family" ) == 0 ) { + css_font_family_unquote( str_unquoted ); + } + + value = g_strdup(str_unquoted.c_str()); + } } diff --git a/src/style.cpp b/src/style.cpp index 11b1dc440..8e4c89839 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -58,6 +58,8 @@ #include <2geom/math-utils.h> +#include + using Inkscape::CSSOStringStream; using std::vector; @@ -1824,31 +1826,43 @@ sp_css_attr_scale(SPCSSAttr *css, double ex) } -// Called in style.cpp, xml/repr-css.cpp +// Called in style-internal.cpp, xml/repr-css.cpp /** - * Remove quotes and escapes from a string. Returned value must be g_free'd. + * Remove paired single and double quotes from a string, changing string in place. * Note: in CSS (in style= and in stylesheets), unquoting and unescaping is done * by libcroco, our CSS parser, though it adds a new pair of "" quotes for the strings - * it parsed for us. So this function is only used to remove those quotes and for - * presentation attributes, without any unescaping. (XML unescaping - * (& etc) is done by XML parser.) + * it parsed for us. */ -gchar * -attribute_unquote(gchar const *val) +void +css_unquote(Glib::ustring &val) { - if (val) { - if (*val == '\'' || *val == '"') { - int l = strlen(val); - if (l >= 2) { - if ( ( val[0] == '"' && val[l - 1] == '"' ) || - ( val[0] == '\'' && val[l - 1] == '\'' ) ) { - return (g_strndup (val+1, l-2)); - } - } - } - } + if( val.size() > 1 && + ( (val[0] == '"' && val[val.size()-1] == '"' ) || + (val[0] == '\'' && val[val.size()-1] == '\'' ) ) ) { - return (val? g_strdup (val) : NULL); + val.erase( 0, 1 ); + val.erase( val.size()-1 ); + } +} + +// Called in style-internal.cpp, text-toolbar.cpp +/** + * Remove paired single and double quotes from font names in font-family lists, + * changing string in place. + * Pango expects unquoted font family names. We use unquoted names in interface. + */ +void +css_font_family_unquote(Glib::ustring &val) +{ + std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", val ); + + val.erase(); + for( unsigned i=0; i < tokens.size(); ++i ) { + css_unquote( tokens[i] ); + val += tokens[i] + ", "; + } + if( val.size() > 1 ) + val.erase( val.size() - 2 ); // Remove trailing ", " } // Called in style.cpp, xml/repr-css.cpp diff --git a/src/style.h b/src/style.h index 9e592b78f..506b90b44 100644 --- a/src/style.h +++ b/src/style.h @@ -292,7 +292,9 @@ void sp_style_unset_property_attrs(SPObject *o); void sp_style_set_property_url (SPObject *item, gchar const *property, SPObject *linked, bool recursive); -gchar *attribute_unquote(gchar const *val); +void css_unquote( Glib::ustring &val ); // Remove quotes from CSS values (style-internal.cpp, xml/repr-css.cpp) +void css_font_family_unquote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp + Glib::ustring css2_escape_quote(gchar const *val); #endif // SEEN_SP_STYLE_H diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 3a4f315da..64a7cd5e7 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -134,6 +134,7 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); Glib::ustring new_family = ink_comboboxentry_action_get_active_text( act ); + css_font_family_unquote( new_family ); // Remove quotes around font family names. // TODO: Think about how to handle handle multiple selections. While // the font-family may be the same for all, the styles might be different. diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 32a1e7f5d..e462f70da 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -12,7 +12,7 @@ * changing an item in the List. Utility functions are provided to go back and forth between the * two ways of representing properties (by a string or by a list). * - * Use sp_repr_write_string to go from a property list to a style string. + * Use sp_repr_css_write_string to go from a property list to a style string. * */ @@ -350,9 +350,10 @@ void sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) { guchar *const str_value_unsigned = cr_term_to_string(decl->value); - gchar *const str_value = reinterpret_cast(str_value_unsigned); - gchar *value_unquoted = attribute_unquote (str_value); // libcroco returns strings quoted in "" - Glib::ustring value_unquoted2 = value_unquoted ? value_unquoted : Glib::ustring(); + + Glib::ustring value_unquoted( reinterpret_cast(str_value_unsigned ) ); + css_unquote( value_unquoted ); // libcroco returns strings quoted in "", remove + Glib::ustring units; /* @@ -362,11 +363,11 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con * * HACK for now is to strip off em and ex units and add them back at the end */ - int le = value_unquoted2.length(); + int le = value_unquoted.length(); if (le > 2) { - units = value_unquoted2.substr(le-2, 2); + units = value_unquoted.substr(le-2, 2); if ((units == "em") || (units == "ex")) { - value_unquoted2 = value_unquoted2.substr(0, le-2); + value_unquoted = value_unquoted.substr(0, le-2); } else { units.clear(); @@ -377,7 +378,7 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con // CSSOStringStream is used here to write valid CSS (as in sp_style_write_string). This has // the additional benefit of respecting the numerical precission set in the SVG Output // preferences. We assume any numerical part comes first (if not, the whole string is copied). - std::stringstream ss( value_unquoted2 ); + std::stringstream ss( value_unquoted ); double number = 0; std::string characters; std::string temp; @@ -399,8 +400,7 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con //g_message("sp_repr_css_merge_from_decl looks like em or ex units %s --> %s", str_value, os.str().c_str()); } ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); - g_free(value_unquoted); - g_free(str_value); + g_free(str_value_unsigned); } /** -- cgit v1.2.3 From f0b0773ecf0249c576e58059864f3a0ecbac64ec Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 30 May 2014 15:38:31 +0200 Subject: Unquote names in 'font-family' lists. Partial fix for #1029080 (bzr r13341.1.42) --- src/style-internal.cpp | 17 ++++++++++----- src/style.cpp | 52 ++++++++++++++++++++++++++++---------------- src/style.h | 4 +++- src/widgets/text-toolbar.cpp | 1 + src/xml/repr-css.cpp | 20 ++++++++--------- 5 files changed, 58 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index b15892128..8b4f3c1cd 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -648,9 +648,6 @@ SPIString::read( gchar const *str ) { if( !str ) return; - // libcroco puts quotes around some strings... remove - gchar *str_unquoted = attribute_unquote(str); - if (!strcmp(str, "inherit")) { set = true; inherit = true; @@ -658,10 +655,18 @@ SPIString::read( gchar const *str ) { } else { set = true; inherit = false; - value = g_strdup(str_unquoted); - } - g_free( str_unquoted ); + // libcroco puts quotes around some strings... remove + Glib::ustring str_unquoted(str); + css_unquote( str_unquoted ); + + // Unquote individual family names, Pango always uses unquoted names. + if( name.compare( "font-family" ) == 0 ) { + css_font_family_unquote( str_unquoted ); + } + + value = g_strdup(str_unquoted.c_str()); + } } diff --git a/src/style.cpp b/src/style.cpp index 11b1dc440..8e4c89839 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -58,6 +58,8 @@ #include <2geom/math-utils.h> +#include + using Inkscape::CSSOStringStream; using std::vector; @@ -1824,31 +1826,43 @@ sp_css_attr_scale(SPCSSAttr *css, double ex) } -// Called in style.cpp, xml/repr-css.cpp +// Called in style-internal.cpp, xml/repr-css.cpp /** - * Remove quotes and escapes from a string. Returned value must be g_free'd. + * Remove paired single and double quotes from a string, changing string in place. * Note: in CSS (in style= and in stylesheets), unquoting and unescaping is done * by libcroco, our CSS parser, though it adds a new pair of "" quotes for the strings - * it parsed for us. So this function is only used to remove those quotes and for - * presentation attributes, without any unescaping. (XML unescaping - * (& etc) is done by XML parser.) + * it parsed for us. */ -gchar * -attribute_unquote(gchar const *val) +void +css_unquote(Glib::ustring &val) { - if (val) { - if (*val == '\'' || *val == '"') { - int l = strlen(val); - if (l >= 2) { - if ( ( val[0] == '"' && val[l - 1] == '"' ) || - ( val[0] == '\'' && val[l - 1] == '\'' ) ) { - return (g_strndup (val+1, l-2)); - } - } - } - } + if( val.size() > 1 && + ( (val[0] == '"' && val[val.size()-1] == '"' ) || + (val[0] == '\'' && val[val.size()-1] == '\'' ) ) ) { - return (val? g_strdup (val) : NULL); + val.erase( 0, 1 ); + val.erase( val.size()-1 ); + } +} + +// Called in style-internal.cpp, text-toolbar.cpp +/** + * Remove paired single and double quotes from font names in font-family lists, + * changing string in place. + * Pango expects unquoted font family names. We use unquoted names in interface. + */ +void +css_font_family_unquote(Glib::ustring &val) +{ + std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", val ); + + val.erase(); + for( unsigned i=0; i < tokens.size(); ++i ) { + css_unquote( tokens[i] ); + val += tokens[i] + ", "; + } + if( val.size() > 1 ) + val.erase( val.size() - 2 ); // Remove trailing ", " } // Called in style.cpp, xml/repr-css.cpp diff --git a/src/style.h b/src/style.h index 9e592b78f..506b90b44 100644 --- a/src/style.h +++ b/src/style.h @@ -292,7 +292,9 @@ void sp_style_unset_property_attrs(SPObject *o); void sp_style_set_property_url (SPObject *item, gchar const *property, SPObject *linked, bool recursive); -gchar *attribute_unquote(gchar const *val); +void css_unquote( Glib::ustring &val ); // Remove quotes from CSS values (style-internal.cpp, xml/repr-css.cpp) +void css_font_family_unquote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp + Glib::ustring css2_escape_quote(gchar const *val); #endif // SEEN_SP_STYLE_H diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 3a4f315da..64a7cd5e7 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -134,6 +134,7 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); Glib::ustring new_family = ink_comboboxentry_action_get_active_text( act ); + css_font_family_unquote( new_family ); // Remove quotes around font family names. // TODO: Think about how to handle handle multiple selections. While // the font-family may be the same for all, the styles might be different. diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index 32a1e7f5d..e462f70da 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -12,7 +12,7 @@ * changing an item in the List. Utility functions are provided to go back and forth between the * two ways of representing properties (by a string or by a list). * - * Use sp_repr_write_string to go from a property list to a style string. + * Use sp_repr_css_write_string to go from a property list to a style string. * */ @@ -350,9 +350,10 @@ void sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) { guchar *const str_value_unsigned = cr_term_to_string(decl->value); - gchar *const str_value = reinterpret_cast(str_value_unsigned); - gchar *value_unquoted = attribute_unquote (str_value); // libcroco returns strings quoted in "" - Glib::ustring value_unquoted2 = value_unquoted ? value_unquoted : Glib::ustring(); + + Glib::ustring value_unquoted( reinterpret_cast(str_value_unsigned ) ); + css_unquote( value_unquoted ); // libcroco returns strings quoted in "", remove + Glib::ustring units; /* @@ -362,11 +363,11 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con * * HACK for now is to strip off em and ex units and add them back at the end */ - int le = value_unquoted2.length(); + int le = value_unquoted.length(); if (le > 2) { - units = value_unquoted2.substr(le-2, 2); + units = value_unquoted.substr(le-2, 2); if ((units == "em") || (units == "ex")) { - value_unquoted2 = value_unquoted2.substr(0, le-2); + value_unquoted = value_unquoted.substr(0, le-2); } else { units.clear(); @@ -377,7 +378,7 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con // CSSOStringStream is used here to write valid CSS (as in sp_style_write_string). This has // the additional benefit of respecting the numerical precission set in the SVG Output // preferences. We assume any numerical part comes first (if not, the whole string is copied). - std::stringstream ss( value_unquoted2 ); + std::stringstream ss( value_unquoted ); double number = 0; std::string characters; std::string temp; @@ -399,8 +400,7 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con //g_message("sp_repr_css_merge_from_decl looks like em or ex units %s --> %s", str_value, os.str().c_str()); } ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); - g_free(value_unquoted); - g_free(str_value); + g_free(str_value_unsigned); } /** -- cgit v1.2.3 From 519d4aa4931a9ca00b6fd9874e49a863dc54a4df Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 30 May 2014 20:23:12 +0200 Subject: Added Perspective-Envelope live effect (bzr r13341.1.43) --- src/live_effects/CMakeLists.txt | 2 + src/live_effects/Makefile_insert | 4 +- src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 5 + src/live_effects/lpe-envelope-perspective.cpp | 414 ++++++++++++++++++++++++++ src/live_effects/lpe-envelope-perspective.h | 76 +++++ 6 files changed, 501 insertions(+), 1 deletion(-) create mode 100644 src/live_effects/lpe-envelope-perspective.cpp create mode 100644 src/live_effects/lpe-envelope-perspective.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 5979cd028..610d3a9bf 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -38,6 +38,7 @@ set(live_effects_SRC lpe-bspline.cpp lpe-text_label.cpp lpe-vonkoch.cpp + lpe-envelope-perspective.cpp lpegroupbbox.cpp lpeobject-reference.cpp lpeobject.cpp @@ -101,6 +102,7 @@ set(live_effects_SRC lpe-bspline.h lpe-text_label.h lpe-vonkoch.h + lpe-envelope-perspective.h lpegroupbbox.h lpeobject-reference.h lpeobject.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index aa6a372a8..c47003747 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -88,4 +88,6 @@ ink_common_sources += \ live_effects/lpe-path_length.cpp \ live_effects/lpe-path_length.h \ live_effects/lpe-line_segment.cpp \ - live_effects/lpe-line_segment.h + live_effects/lpe-line_segment.h \ + live_effects/lpe-envelope-perspective.cpp \ + live_effects/lpe-envelope-perspective.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index bd7f6cf23..4d1c1d8c1 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -53,6 +53,7 @@ enum EffectType { EXTRUDE, POWERSTROKE, CLONE_ORIGINAL, + ENVELOPE_PERSPECTIVE, INVALID_LPE // This must be last (I made it such that it is not needed anymore I think..., Don't trust on it being last. - johan) }; diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 76546c093..eef954fe2 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -48,6 +48,7 @@ #include "live_effects/lpe-extrude.h" #include "live_effects/lpe-powerstroke.h" #include "live_effects/lpe-clone-original.h" +#include "live_effects/lpe-envelope-perspective.h" #include "xml/node-event-vector.h" #include "sp-object.h" @@ -126,6 +127,7 @@ const Util::EnumData LPETypeData[] = { {BSPLINE, N_("BSpline"), "bspline"}, {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, + {ENVELOPE_PERSPECTIVE, N_("Envelope-Perspective"), "envelope-perspective"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -258,6 +260,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case LATTICE2: neweffect = static_cast ( new LPELattice2(lpeobj) ); break; + case ENVELOPE_PERSPECTIVE: + neweffect = static_cast ( new LPEEnvelopePerspective(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-envelope-perspective.cpp b/src/live_effects/lpe-envelope-perspective.cpp new file mode 100644 index 000000000..bfd6e56d7 --- /dev/null +++ b/src/live_effects/lpe-envelope-perspective.cpp @@ -0,0 +1,414 @@ +/** \file + * LPE implementation + + */ +/* + * Authors: + * Jabiertxof Code migration from python extensions envelope and perspective + * Aaron Spike, aaron@ekips.org from envelope and perspective phyton code + * Dmitry Platonov, shadowjack@mail.ru, 2006 perspective approach & math + * Jose Hevia (freon) Transform algorithm from envelope + * + * Copyright (C) 2007-2014 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-envelope-perspective.h" +#include "helper/geom.h" +#include "display/curve.h" +#include "svg/svg.h" +#include +#include +#include +#include +#include "desktop.h" + +using namespace Geom; + +namespace Inkscape { +namespace LivePathEffect { + +LPEEnvelopePerspective::LPEEnvelopePerspective(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + // initialise your parameters here: + perspective(_("Perspective"), _("Perspective"), "Perspective", &wr, this, false), + Up_Left_Point(_("Top Left:"), _("Top Left - Ctrl+Alt+Click to reset"), "Up_Left_Point", &wr, this), + Up_Right_Point(_("Top Right:"), _("Top Right - Ctrl+Alt+Click to reset"), "Up_Right_Point", &wr, this), + Down_Left_Point(_("Down Left:"), _("Down Left - Ctrl+Alt+Click to reset"), "Down_Left_Point", &wr, this), + Down_Right_Point(_("Down Right:"), _("Down Right - Ctrl+Alt+Click to reset"), "Down_Right_Point", &wr, this) +{ + // register all your parameters here, so Inkscape knows which parameters this effect has: + registerParameter( dynamic_cast(&perspective)); + registerParameter( dynamic_cast(&Up_Left_Point) ); + registerParameter( dynamic_cast(&Up_Right_Point) ); + registerParameter( dynamic_cast(&Down_Left_Point) ); + registerParameter( dynamic_cast(&Down_Right_Point) ); +} + +LPEEnvelopePerspective::~LPEEnvelopePerspective() +{ +} + +void LPEEnvelopePerspective::doEffect(SPCurve *curve) { + using Geom::X; + using Geom::Y; + double projmatrix[3][3]; + if(perspective){ + std::vector handles(4); + handles[0] = Down_Left_Point; + handles[1] = Up_Left_Point; + handles[2] = Up_Right_Point; + handles[3] = Down_Right_Point; + std::vector sourceHandles(4); + sourceHandles[0] = Geom::Point(boundingbox_X.min(), boundingbox_Y.max()); + sourceHandles[1] = Geom::Point(boundingbox_X.min(), boundingbox_Y.min()); + sourceHandles[2] = Geom::Point(boundingbox_X.max(), boundingbox_Y.min()); + sourceHandles[3] = Geom::Point(boundingbox_X.max(), boundingbox_Y.max()); + double solmatrix[8][8] = {{0}}; + double free_term[8] = {0}; + double gslSolmatrix[64]; + for(unsigned int i = 0; i < 4; ++i){ + solmatrix[i][0] = sourceHandles[i][X]; + solmatrix[i][1] = sourceHandles[i][Y]; + solmatrix[i][2] = 1; + solmatrix[i][6] = -handles[i][X] * sourceHandles[i][X]; + solmatrix[i][7] = -handles[i][X] * sourceHandles[i][Y]; + solmatrix[i+4][3] = sourceHandles[i][X]; + solmatrix[i+4][4] = sourceHandles[i][Y]; + solmatrix[i+4][5] = 1; + solmatrix[i+4][6] = -handles[i][Y] * sourceHandles[i][X]; + solmatrix[i+4][7] = -handles[i][Y] * sourceHandles[i][Y]; + free_term[i] = handles[i][X]; + free_term[i+4] = handles[i][Y]; + } + int h = 0; + for( int i = 0; i < 8; i++ ) { + for( int j = 0; j < 8; j++ ) { + gslSolmatrix[h] = solmatrix[i][j]; + h++; + } + } + //this is get by this page: + //http://www.gnu.org/software/gsl/manual/html_node/Linear-Algebra-Examples.html#Linear-Algebra-Examples + gsl_matrix_view m = gsl_matrix_view_array (gslSolmatrix, 8, 8); + gsl_vector_view b = gsl_vector_view_array (free_term, 8); + gsl_vector *x = gsl_vector_alloc (8); + int s; + gsl_permutation * p = gsl_permutation_alloc (8); + gsl_linalg_LU_decomp (&m.matrix, p, &s); + gsl_linalg_LU_solve (&m.matrix, p, &b.vector, x); + h = 0; + for( int i = 0; i < 3; i++ ) { + for( int j = 0; j < 3; j++ ) { + if(h==8){ + projmatrix[2][2] = 1.0; + continue; + } + projmatrix[i][j] = gsl_vector_get(x, h); + h++; + } + } + gsl_permutation_free (p); + gsl_vector_free (x); + } + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); + curve->reset(); + Geom::CubicBezier const *cubic = NULL; + Geom::Point pointAt1(0, 0); + Geom::Point pointAt2(0, 0); + Geom::Point pointAt3(0, 0); + for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { + //Si está vacío... + if (path_it->empty()) + continue; + //Itreadores + SPCurve *nCurve = new SPCurve(); + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = + ++(path_it->begin()); // outgoing curve + Geom::Path::const_iterator curve_endit = + path_it->end_default(); // this determines when the loop has to stop + + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + if(perspective){ + nCurve->moveto(project_point(curve_it1->initialPoint(),projmatrix)); + }else{ + nCurve->moveto(project_point(curve_it1->initialPoint())); + } + while (curve_it2 != curve_endit) { + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + pointAt1 = (*cubic)[1]; + pointAt2 = (*cubic)[2]; + } else { + pointAt1 = curve_it1->initialPoint(); + pointAt2 = curve_it1->finalPoint(); + } + pointAt3 = curve_it1->finalPoint(); + if(perspective){ + pointAt1 = project_point(pointAt1,projmatrix); + pointAt2 = project_point(pointAt2,projmatrix); + pointAt3 = project_point(pointAt3,projmatrix); + }else{ + pointAt1 = project_point(pointAt1); + pointAt2 = project_point(pointAt2); + pointAt3 = project_point(pointAt3); + } + nCurve->curveto(pointAt1, pointAt2, pointAt3); + ++curve_it1; + ++curve_it2; + } + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + pointAt1 = (*cubic)[1]; + pointAt2 = (*cubic)[2]; + } else { + pointAt1 = curve_it1->initialPoint(); + pointAt2 = curve_it1->finalPoint(); + } + pointAt3 = curve_it1->finalPoint(); + if(perspective){ + pointAt1 = project_point(pointAt1,projmatrix); + pointAt2 = project_point(pointAt2,projmatrix); + pointAt3 = project_point(pointAt3,projmatrix); + }else{ + pointAt1 = project_point(pointAt1); + pointAt2 = project_point(pointAt2); + pointAt3 = project_point(pointAt3); + } + nCurve->curveto(pointAt1, pointAt2, pointAt3); + if(perspective){ + nCurve->move_endpoints(project_point(path_it->begin()->initialPoint(),projmatrix), pointAt3); + }else{ + nCurve->move_endpoints(project_point(path_it->begin()->initialPoint()), pointAt3); + } + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); + } + curve->append(nCurve, false); + nCurve->reset(); + delete nCurve; + } +} + +Geom::Point +LPEEnvelopePerspective::project_point(Geom::Point p){ + double width = boundingbox_X.extent(); + double height = boundingbox_Y.extent(); + Geom::Coord xratio = abs(Geom::Point(boundingbox_X.min(), boundingbox_Y.max())[X]-p[X])/width; + Geom::Coord yratio = abs(Geom::Point(boundingbox_X.min(), boundingbox_Y.max())[Y]-p[Y])/height; + Geom::Line* horiz = new Geom::Line(); + Geom::Line* vert = new Geom::Line(); + vert->setPoints (pointAtRatio(yratio,Down_Left_Point,Up_Left_Point),pointAtRatio(yratio,Down_Right_Point,Up_Right_Point)); + horiz->setPoints (pointAtRatio(xratio,Down_Left_Point,Down_Right_Point),pointAtRatio(xratio,Up_Left_Point,Up_Right_Point)); + + OptCrossing crossPoint = intersection(*horiz,*vert); + if(crossPoint){ + return horiz->pointAt(Geom::Coord(crossPoint->ta)); + }else{ + return p; + } +} + +Geom::Point +LPEEnvelopePerspective::project_point(Geom::Point p, double m[][3]){ + Geom::Coord x = p[0]; + Geom::Coord y = p[1]; + return Geom::Point( + Geom::Coord((x*m[0][0] + y*m[0][1] + m[0][2])/(x*m[2][0]+y*m[2][1]+m[2][2])), + Geom::Coord((x*m[1][0] + y*m[1][1] + m[1][2])/(x*m[2][0]+y*m[2][1]+m[2][2]))); +} + +Geom::Point +LPEEnvelopePerspective::pointAtRatio(Geom::Coord ratio,Geom::Point A, Geom::Point B){ + Geom::Coord x = A[X] + (ratio * (B[X]-A[X])); + Geom::Coord y = A[Y]+ (ratio * (B[Y]-A[Y])); + return Point(x, y); +} + + +Gtk::Widget * +LPEEnvelopePerspective::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(6); + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + + Gtk::Button* resetButton = Gtk::manage(new Gtk::Button(Gtk::Stock::CLEAR)); + resetButton->signal_clicked().connect(sigc::mem_fun (*this,&LPEEnvelopePerspective::resetGrid)); + resetButton->set_size_request(140,45); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*resetButton, false, false,2); + std::vector::iterator it = param_vector.begin(); + Gtk::HBox * hboxUpHandles = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::HBox * hboxDownHandles = Gtk::manage(new Gtk::HBox(false,0)); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "Up_Left_Point" || + param->param_key == "Up_Right_Point" || + param->param_key == "Down_Left_Point" || + param->param_key == "Down_Right_Point") + { + Gtk::HBox * pointParameter = dynamic_cast(widg); + std::vector< Gtk::Widget* > childList = pointParameter->get_children(); + Gtk::HBox * pointParameterHBox = dynamic_cast(childList[0]); + std::vector< Gtk::Widget* > childList2 = pointParameterHBox->get_children(); + pointParameterHBox->remove(childList2[0][0]); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + if(param->param_key == "Up_Left_Point"){ + Gtk::Label* handles = Gtk::manage(new Gtk::Label(Glib::ustring(_("Handles:")),Gtk::ALIGN_START)); + vbox->pack_start(*handles, false, false, 2); + hboxUpHandles->pack_start(*widg, true, true, 2); + hboxUpHandles->pack_start(*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_EXPAND_WIDGET); + }else if(param->param_key == "Up_Right_Point"){ + hboxUpHandles->pack_start(*widg, true, true, 2); + }else if(param->param_key == "Down_Left_Point"){ + hboxDownHandles->pack_start(*widg, true, true, 2); + hboxDownHandles->pack_start(*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_EXPAND_WIDGET); + }else{ + hboxDownHandles->pack_start(*widg, true, true, 2); + } + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + }else{ + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + } + + ++it; + } + vbox->pack_start(*hboxUpHandles,true, true, 2); + Gtk::HBox * hboxMiddle = Gtk::manage(new Gtk::HBox(true,2)); + hboxMiddle->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); + hboxMiddle->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); + vbox->pack_start(*hboxMiddle, false, true, 2); + vbox->pack_start(*hboxDownHandles, true, true, 2); + return dynamic_cast(vbox); +} + +void +LPEEnvelopePerspective::doBeforeEffect (SPLPEItem const* lpeitem) +{ + original_bbox(lpeitem); + setDefaults(); +} + +void +LPEEnvelopePerspective::setDefaults() +{ + Geom::Point Up_Left(boundingbox_X.min(), boundingbox_Y.min()); + Geom::Point Up_Right(boundingbox_X.max(), boundingbox_Y.min()); + Geom::Point Down_Left(boundingbox_X.min(), boundingbox_Y.max()); + Geom::Point Down_Right(boundingbox_X.max(), boundingbox_Y.max()); + + Up_Left_Point.param_update_default(Up_Left); + Up_Right_Point.param_update_default(Up_Right); + Down_Right_Point.param_update_default(Down_Right); + Down_Left_Point.param_update_default(Down_Left); +} + +void +LPEEnvelopePerspective::resetGrid() +{ + Up_Left_Point.param_set_and_write_default(); + Up_Right_Point.param_set_and_write_default(); + Down_Right_Point.param_set_and_write_default(); + Down_Left_Point.param_set_and_write_default(); + //todo:this hack is only to reposition the knots on reser grid button + //Better update path effect in LPEITEM + SPDesktop * desktop = inkscape_active_desktop(); + tools_switch(desktop, TOOLS_SELECT); + tools_switch(desktop, TOOLS_NODES); +} + +void +LPEEnvelopePerspective::resetDefaults(SPItem const* item) +{ + Effect::resetDefaults(item); + original_bbox(SP_LPE_ITEM(item)); + setDefaults(); + resetGrid(); +} + +void +LPEEnvelopePerspective::calculateCurve(Geom::Point a,Geom::Point b, SPCurve* c, bool horizontal, bool move) +{ + using Geom::X; + using Geom::Y; + if(move) c->moveto(a); + Geom::Point cubic1 = a + (1./3)* (b - a); + Geom::Point cubic2 = b + (1./3)* (a - b); + if(horizontal) c->curveto(Geom::Point(cubic1[X],a[Y]),Geom::Point(cubic2[X],b[Y]),b); + else c->curveto(Geom::Point(a[X],cubic1[Y]),Geom::Point(b[X],cubic2[Y]),b); +} + +void +LPEEnvelopePerspective::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.clear(); + + SPCurve *c = new SPCurve(); + c->reset(); + c->moveto(Up_Left_Point); + c->lineto(Up_Right_Point); + c->lineto(Down_Right_Point); + c->lineto(Down_Left_Point); + c->lineto(Up_Left_Point); + hp_vec.push_back(c->get_pathvector()); +} + + +/* ######################## */ + +} //namespace LivePathEffect +} /* namespace Inkscape */ + + + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-envelope-perspective.h b/src/live_effects/lpe-envelope-perspective.h new file mode 100644 index 000000000..6aae33936 --- /dev/null +++ b/src/live_effects/lpe-envelope-perspective.h @@ -0,0 +1,76 @@ +#ifndef INKSCAPE_LPE_ENVELOPE_PERSPECTIVE_H +#define INKSCAPE_LPE_ENVELOPE_PERSPECTIVE_H + +/** \file + * LPE implementation , see lpe-envelope-perspective.cpp. + + */ +/* + * Authors: + * Jabiertxof Code migration from python extensions envelope and perspective + * Aaron Spike, aaron@ekips.org from envelope and perspective phyton code + * Dmitry Platonov, shadowjack@mail.ru, 2006 perspective approach & math + * Jose Hevia (freon) Transform algorithm from envelope + * + * Copyright (C) 2007-2014 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/enum.h" +#include "live_effects/effect.h" +#include "live_effects/parameter/pointreseteable.h" +#include "live_effects/lpegroupbbox.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEEnvelopePerspective : public Effect, GroupBBoxEffect { +public: + + LPEEnvelopePerspective(LivePathEffectObject *lpeobject); + virtual ~LPEEnvelopePerspective(); + + virtual void doEffect(SPCurve *curve); + + virtual Geom::Point project_point(Geom::Point p); + + virtual Geom::Point project_point(Geom::Point p, double m[][3]); + + Geom::Point pointAtRatio(Geom::Coord ratio,Geom::Point A, Geom::Point B); + + virtual void resetDefaults(SPItem const* item); + + virtual void doBeforeEffect(SPLPEItem const* lpeitem); + + virtual Gtk::Widget * newWidget(); + + virtual void calculateCurve(Geom::Point a,Geom::Point b, SPCurve *c, bool horizontal, bool move); + + virtual void setDefaults(); + + virtual void resetGrid(); + + //virtual void original_bbox(SPLPEItem const* lpeitem, bool absolute = false); + + //virtual void addCanvasIndicators(SPLPEItem const*/*lpeitem*/, std::vector &/*hp_vec*/); + + //virtual std::vector getHelperPaths(SPLPEItem const* lpeitem); +protected: + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); +private: + + BoolParam perspective; + PointReseteableParam Up_Left_Point; + PointReseteableParam Up_Right_Point; + PointReseteableParam Down_Left_Point; + PointReseteableParam Down_Right_Point; + + LPEEnvelopePerspective(const LPEEnvelopePerspective&); + LPEEnvelopePerspective& operator=(const LPEEnvelopePerspective&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif -- cgit v1.2.3 From 95033e5a510be941172977dc948f9c914180e359 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 1 Jun 2014 15:05:24 +0200 Subject: spellcheck.cpp: correct indenting. disable debug output. (bzr r13341.1.44) --- src/ui/dialog/spellcheck.cpp | 74 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 8a4ddc57e..a887a7355 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -347,7 +347,7 @@ SpellCheck::init(SPDesktop *d) char *slashPos = strrchr(exeName, '\\'); if (slashPos) *slashPos = '\0'; - g_print ("%s\n", exeName); + //g_print ("Aspell prefix path: %s\n", exeName); #endif _stops = 0; @@ -356,54 +356,54 @@ SpellCheck::init(SPDesktop *d) #ifdef HAVE_ASPELL { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller = to_aspell_speller(ret); } if (_lang2 != "") { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang2.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller2 = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang2.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller2 = to_aspell_speller(ret); } if (_lang3 != "") { - AspellConfig *config = new_aspell_config(); + AspellConfig *config = new_aspell_config(); #ifdef WIN32 - aspell_config_replace(config, "prefix", exeName); + aspell_config_replace(config, "prefix", exeName); #endif - aspell_config_replace(config, "lang", _lang3.c_str()); - aspell_config_replace(config, "encoding", "UTF-8"); - AspellCanHaveError *ret = new_aspell_speller(config); - delete_aspell_config(config); - if (aspell_error(ret) != 0) { - g_warning("Error: %s\n", aspell_error_message(ret)); - delete_aspell_can_have_error(ret); - return false; - } - _speller3 = to_aspell_speller(ret); + aspell_config_replace(config, "lang", _lang3.c_str()); + aspell_config_replace(config, "encoding", "UTF-8"); + AspellCanHaveError *ret = new_aspell_speller(config); + delete_aspell_config(config); + if (aspell_error(ret) != 0) { + g_warning("Error: %s\n", aspell_error_message(ret)); + delete_aspell_can_have_error(ret); + return false; + } + _speller3 = to_aspell_speller(ret); } #endif /* HAVE_ASPELL */ -- cgit v1.2.3 From fd9fa656fa1037c58963e4277c8d907a61940bd3 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 1 Jun 2014 15:40:07 +0200 Subject: remove fwd decl (a left-over, not intended for something useful) that breaks build (win64) (bzr r13404) --- src/ui/tool/node.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 4582d998a..b2f338e2c 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -41,14 +41,6 @@ template class NodeIterator; } } -#if HAVE_TR1_UNORDERED_SET -namespace std { -namespace tr1 { -template struct hash< Inkscape::UI::NodeIterator >; -} -} -#endif - namespace Inkscape { namespace UI { -- cgit v1.2.3 From 5937afd51b2ba2e826e8b1d095cd3a6b3f48e2b8 Mon Sep 17 00:00:00 2001 From: "Matthias Kilian (no public email in lp)" <> Date: Tue, 3 Jun 2014 08:38:31 -0700 Subject: Patch from comment 7. Fixes build with Poppler 0.26. Fixed bugs: - https://launchpad.net/bugs/1315142 (bzr r13405) --- src/extension/internal/pdfinput/pdf-parser.cpp | 54 +++++++++++++++++++++----- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index b398486e6..c5f03e5aa 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -866,7 +866,9 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) GBool isolated = gFalse; GBool knockout = gFalse; if (!obj4.dictLookup(const_cast("CS"), &obj5)->isNull()) { -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(&obj5, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj5, NULL); #else blendingColorSpace = GfxColorSpace::parse(&obj5); @@ -1100,7 +1102,13 @@ void PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/) res->lookupColorSpace(args[0].getName(), &obj); GfxColorSpace *colorSpace = 0; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(&obj, NULL, NULL); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL); } else { @@ -1137,7 +1145,13 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/) state->setStrokePattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(&obj, NULL, NULL); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL); } else { @@ -1231,7 +1245,13 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { builder->updateStyle(state); } GfxPattern *pattern; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL, NULL))) { + state->setFillPattern(pattern); + builder->updateStyle(state); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { state->setFillPattern(pattern); @@ -1291,7 +1311,13 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { builder->updateStyle(state); } GfxPattern *pattern; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL, NULL))) { + state->setStrokePattern(pattern); + builder->updateStyle(state); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { state->setStrokePattern(pattern); @@ -1746,7 +1772,11 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) double *matrix = NULL; GBool savedState = gFalse; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (!(shading = res->lookupShading(args[0].getName(), NULL, NULL))) { + return; + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (!(shading = res->lookupShading(args[0].getName(), NULL))) { return; } @@ -2817,7 +2847,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) } } if (!obj1.isNull()) { -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + colorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) colorSpace = GfxColorSpace::parse(&obj1, NULL); #else colorSpace = GfxColorSpace::parse(&obj1); @@ -2909,7 +2941,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) obj2.free(); } } -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL); #else GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1); @@ -3099,7 +3133,9 @@ void PdfParser::doForm(Object *str) { if (obj1.dictLookup(const_cast("S"), &obj2)->isName(const_cast("Transparency"))) { transpGroup = gTrue; if (!obj1.dictLookup(const_cast("CS"), &obj3)->isNull()) { -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(&obj3, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj3, NULL); #else blendingColorSpace = GfxColorSpace::parse(&obj3); -- cgit v1.2.3 From 2dbb379145083fe62eee32c209962c51d83b0043 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Tue, 3 Jun 2014 10:50:49 -0700 Subject: Fix for bugs 1262782 and 1262792 (bzr r13406) --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 6f4add4b1..517ba0506 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1158,6 +1158,7 @@ static int sp_process_file_list(GSList *fl) if (sp_export_text_to_path) { GSList *items = NULL; SPRoot *root = doc->getRoot(); + doc->ensureUpToDate(); for ( SPObject *iter = root->firstChild(); iter ; iter = iter->getNext()) { SPItem* item = (SPItem*) iter; if (! (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item) || SP_IS_GROUP(item))) { -- cgit v1.2.3 From 7d3e2c1904202e2979f6ba54b082439412a24192 Mon Sep 17 00:00:00 2001 From: Matthias Kilian <> Date: Wed, 4 Jun 2014 15:01:44 +0200 Subject: Fix build failure with poppler 0.26 (Bug #1315142) Fixed bugs: - https://launchpad.net/bugs/1315142 (bzr r13341.1.46) --- src/extension/internal/pdfinput/pdf-parser.cpp | 54 +++++++++++++++++++++----- 1 file changed, 45 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index b398486e6..c5f03e5aa 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -866,7 +866,9 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) GBool isolated = gFalse; GBool knockout = gFalse; if (!obj4.dictLookup(const_cast("CS"), &obj5)->isNull()) { -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(&obj5, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj5, NULL); #else blendingColorSpace = GfxColorSpace::parse(&obj5); @@ -1100,7 +1102,13 @@ void PdfParser::opSetFillColorSpace(Object args[], int /*numArgs*/) res->lookupColorSpace(args[0].getName(), &obj); GfxColorSpace *colorSpace = 0; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(&obj, NULL, NULL); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL); } else { @@ -1137,7 +1145,13 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int /*numArgs*/) state->setStrokePattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (obj.isNull()) { + colorSpace = GfxColorSpace::parse(&args[0], NULL, NULL); + } else { + colorSpace = GfxColorSpace::parse(&obj, NULL, NULL); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], NULL); } else { @@ -1231,7 +1245,13 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { builder->updateStyle(state); } GfxPattern *pattern; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL, NULL))) { + state->setFillPattern(pattern); + builder->updateStyle(state); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { state->setFillPattern(pattern); @@ -1291,7 +1311,13 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { builder->updateStyle(state); } GfxPattern *pattern; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (args[numArgs-1].isName() && + (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL, NULL))) { + state->setStrokePattern(pattern); + builder->updateStyle(state); + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (args[numArgs-1].isName() && (pattern = res->lookupPattern(args[numArgs-1].getName(), NULL))) { state->setStrokePattern(pattern); @@ -1746,7 +1772,11 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) double *matrix = NULL; GBool savedState = gFalse; -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + if (!(shading = res->lookupShading(args[0].getName(), NULL, NULL))) { + return; + } +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) if (!(shading = res->lookupShading(args[0].getName(), NULL))) { return; } @@ -2817,7 +2847,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) } } if (!obj1.isNull()) { -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + colorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) colorSpace = GfxColorSpace::parse(&obj1, NULL); #else colorSpace = GfxColorSpace::parse(&obj1); @@ -2909,7 +2941,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) obj2.free(); } } -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1, NULL); #else GfxColorSpace *maskColorSpace = GfxColorSpace::parse(&obj1); @@ -3099,7 +3133,9 @@ void PdfParser::doForm(Object *str) { if (obj1.dictLookup(const_cast("S"), &obj2)->isName(const_cast("Transparency"))) { transpGroup = gTrue; if (!obj1.dictLookup(const_cast("CS"), &obj3)->isNull()) { -#if defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) +#if defined(POPPLER_EVEN_NEWER_COLOR_SPACE_API) + blendingColorSpace = GfxColorSpace::parse(&obj3, NULL, NULL); +#elif defined(POPPLER_NEW_COLOR_SPACE_API) || defined(POPPLER_NEW_ERRORAPI) blendingColorSpace = GfxColorSpace::parse(&obj3, NULL); #else blendingColorSpace = GfxColorSpace::parse(&obj3); -- cgit v1.2.3 From 9b0db891ca0fc8ca0cfbfaa301c473f2ad3e6d68 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 5 Jun 2014 18:28:15 +0200 Subject: Make family-name comparisons case insensitive. Fix UI bug when SVG file does not have -inkscape-font-specification properties (Style drop-down list not properly updated.) (bzr r13341.1.47) --- src/ink-comboboxentry-action.cpp | 28 ++++++++++++++++++++------- src/libnrtype/font-lister.cpp | 41 ++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp index 06ccc3739..ebd238edc 100644 --- a/src/ink-comboboxentry-action.cpp +++ b/src/ink-comboboxentry-action.cpp @@ -38,7 +38,7 @@ static GtkWidget* create_tool_item( GtkAction* action ); static GtkWidget* create_menu_item( GtkAction* action ); // Internal -static gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude = false ); +static gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude = false, gboolean ignore_case = false ); static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* action ); // Callbacks @@ -732,7 +732,8 @@ void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* actio // use 3d colunm if available to exclude row from checking (useful to // skip rows added for font-families included in doc and not on // system) -gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude ) { +gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, + gboolean exclude, gboolean ignore_case ) { // Check if text in list gint row = 0; @@ -752,10 +753,23 @@ gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* ta gchar* text = 0; gtk_tree_model_get( action->model, &iter, 0, &text, -1 ); // Column 0 - // Check for match - if( strcmp( target_text, text ) == 0 ){ - found = true; - break; + if( !ignore_case ) { + // Case sensitive compare + if( strcmp( target_text, text ) == 0 ){ + found = true; + break; + } + } else { + // Case insensitive compare + gchar* target_text_casefolded = g_utf8_casefold( target_text, -1 ); + gchar* text_casefolded = g_utf8_casefold( text, -1 ); + gboolean equal = (strcmp( target_text_casefolded, text_casefolded ) == 0 ); + g_free( text_casefolded ); + g_free( target_text_casefolded ); + if( equal ) { + found = true; + break; + } } } @@ -794,7 +808,7 @@ static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* actio // Remove any surrounding white space. g_strstrip( tokens[i] ); - if( get_active_row_from_text( action, tokens[i], true ) == -1 ) { + if( get_active_row_from_text( action, tokens[i], true, true ) == -1 ) { missing += tokens[i]; missing += ", "; } diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 333c4ef5b..8ce5eccfc 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -25,6 +25,13 @@ //#define DEBUG_FONT +// CSS dictates that font family names are case insensitive. +// This should really implement full Unicode case unfolding. +bool familyNamesAreEqual( const Glib::ustring &a, const Glib::ustring &b ) { + + return( a.casefold().compare( b.casefold() ) == 0 ); +} + namespace Inkscape { FontLister::FontLister () @@ -120,7 +127,7 @@ namespace Inkscape Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); while( iter2 != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && tokens[0].compare( row[FontList.family] ) == 0 ) { + if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { styles = row[FontList.styles]; break; } @@ -197,7 +204,7 @@ namespace Inkscape Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); while( iter2 != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && tokens[0].compare( row[FontList.family] ) == 0 ) { + if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { styles = row[FontList.styles]; break; } @@ -228,7 +235,7 @@ namespace Inkscape path.push_back( row ); Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); if( iter ) { - if( current_family.compare( (*iter)[FontList.family] ) == 0 ) { + if( familyNamesAreEqual( current_family, (*iter)[FontList.family] ) ) { current_family_row = row; break; } @@ -384,6 +391,7 @@ namespace Inkscape std::pair ui = ui_from_fontspec( current_fontspec ); set_font_family( ui.first ); + set_font_style( ui.second ); #ifdef DEBUG_FONT std::cout << " family_row: :" << current_family_row << ":" << std::endl; @@ -424,7 +432,7 @@ std::pair FontLister::new_font_family (Glib::ustri #endif // No need to do anything if new family is same as old family. - if ( new_family.compare( current_family ) == 0 ) { + if ( familyNamesAreEqual( new_family, current_family ) ) { #ifdef DEBUG_FONT std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; @@ -443,7 +451,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( new_family.compare( row[FontList.family] ) == 0 ) { + if( familyNamesAreEqual( new_family, row[FontList.family] ) ) { styles = row[FontList.styles]; break; } @@ -688,18 +696,19 @@ std::pair FontLister::new_font_family (Glib::ustri fontspec = style->font_family.value; fontspec += ","; + // Use weight names as defined by Pango switch (style->font_weight.computed) { case SP_CSS_FONT_WEIGHT_100: - fontspec += " 100"; + fontspec += " Thin"; break; case SP_CSS_FONT_WEIGHT_200: - fontspec += " 200"; + fontspec += " Ultra-Light"; break; case SP_CSS_FONT_WEIGHT_300: - fontspec += " 300"; + fontspec += " Light"; break; case SP_CSS_FONT_WEIGHT_400: @@ -708,24 +717,24 @@ std::pair FontLister::new_font_family (Glib::ustri break; case SP_CSS_FONT_WEIGHT_500: - fontspec += " 500"; + fontspec += " Medium"; break; case SP_CSS_FONT_WEIGHT_600: - fontspec += " 600"; + fontspec += " Semi-Bold"; break; case SP_CSS_FONT_WEIGHT_700: case SP_CSS_FONT_WEIGHT_BOLD: - fontspec += " bold"; + fontspec += " Bold"; break; case SP_CSS_FONT_WEIGHT_800: - fontspec += " 800"; + fontspec += " Ultra-Bold"; break; case SP_CSS_FONT_WEIGHT_900: - fontspec += " 900"; + fontspec += " Heavy"; break; case SP_CSS_FONT_WEIGHT_LIGHTER: @@ -821,7 +830,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( family.compare( row[FontList.family] ) == 0 ) { + if( familyNamesAreEqual( family, row[FontList.family] ) ) { return row; } @@ -847,7 +856,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( style.compare( row[FontStyleList.styles] ) == 0 ) { + if( familyNamesAreEqual( style, row[FontStyleList.styles] ) ) { return row; } @@ -1035,7 +1044,7 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(model), &iter ) ) { gtk_tree_model_get(model, &iter, 0, &family, 2, &onSystem, -1); - if( onSystem && token.compare( family ) == 0 ) { + if( onSystem && familyNamesAreEqual( token, family ) ) { found = true; break; } -- cgit v1.2.3 From 784f4c40b1d249afaecd1b96e1590b1d930009f3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 5 Jun 2014 20:27:46 +0200 Subject: Make family-name comparisons case insensitive. Fix UI bug when SVG file does not have -inkscape-font-specification properties (Style drop-down list not properly updated.) Partial fix for bug #165521 (bzr r13408) --- src/ink-comboboxentry-action.cpp | 28 ++++++++++++++++++++------- src/libnrtype/font-lister.cpp | 41 ++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp index 06ccc3739..ebd238edc 100644 --- a/src/ink-comboboxentry-action.cpp +++ b/src/ink-comboboxentry-action.cpp @@ -38,7 +38,7 @@ static GtkWidget* create_tool_item( GtkAction* action ); static GtkWidget* create_menu_item( GtkAction* action ); // Internal -static gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude = false ); +static gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude = false, gboolean ignore_case = false ); static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* action ); // Callbacks @@ -732,7 +732,8 @@ void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* actio // use 3d colunm if available to exclude row from checking (useful to // skip rows added for font-families included in doc and not on // system) -gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, gboolean exclude ) { +gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* target_text, + gboolean exclude, gboolean ignore_case ) { // Check if text in list gint row = 0; @@ -752,10 +753,23 @@ gint get_active_row_from_text( Ink_ComboBoxEntry_Action* action, const gchar* ta gchar* text = 0; gtk_tree_model_get( action->model, &iter, 0, &text, -1 ); // Column 0 - // Check for match - if( strcmp( target_text, text ) == 0 ){ - found = true; - break; + if( !ignore_case ) { + // Case sensitive compare + if( strcmp( target_text, text ) == 0 ){ + found = true; + break; + } + } else { + // Case insensitive compare + gchar* target_text_casefolded = g_utf8_casefold( target_text, -1 ); + gchar* text_casefolded = g_utf8_casefold( text, -1 ); + gboolean equal = (strcmp( target_text_casefolded, text_casefolded ) == 0 ); + g_free( text_casefolded ); + g_free( target_text_casefolded ); + if( equal ) { + found = true; + break; + } } } @@ -794,7 +808,7 @@ static Glib::ustring check_comma_separated_text( Ink_ComboBoxEntry_Action* actio // Remove any surrounding white space. g_strstrip( tokens[i] ); - if( get_active_row_from_text( action, tokens[i], true ) == -1 ) { + if( get_active_row_from_text( action, tokens[i], true, true ) == -1 ) { missing += tokens[i]; missing += ", "; } diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 333c4ef5b..8ce5eccfc 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -25,6 +25,13 @@ //#define DEBUG_FONT +// CSS dictates that font family names are case insensitive. +// This should really implement full Unicode case unfolding. +bool familyNamesAreEqual( const Glib::ustring &a, const Glib::ustring &b ) { + + return( a.casefold().compare( b.casefold() ) == 0 ); +} + namespace Inkscape { FontLister::FontLister () @@ -120,7 +127,7 @@ namespace Inkscape Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); while( iter2 != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && tokens[0].compare( row[FontList.family] ) == 0 ) { + if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { styles = row[FontList.styles]; break; } @@ -197,7 +204,7 @@ namespace Inkscape Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); while( iter2 != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && tokens[0].compare( row[FontList.family] ) == 0 ) { + if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { styles = row[FontList.styles]; break; } @@ -228,7 +235,7 @@ namespace Inkscape path.push_back( row ); Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); if( iter ) { - if( current_family.compare( (*iter)[FontList.family] ) == 0 ) { + if( familyNamesAreEqual( current_family, (*iter)[FontList.family] ) ) { current_family_row = row; break; } @@ -384,6 +391,7 @@ namespace Inkscape std::pair ui = ui_from_fontspec( current_fontspec ); set_font_family( ui.first ); + set_font_style( ui.second ); #ifdef DEBUG_FONT std::cout << " family_row: :" << current_family_row << ":" << std::endl; @@ -424,7 +432,7 @@ std::pair FontLister::new_font_family (Glib::ustri #endif // No need to do anything if new family is same as old family. - if ( new_family.compare( current_family ) == 0 ) { + if ( familyNamesAreEqual( new_family, current_family ) ) { #ifdef DEBUG_FONT std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; @@ -443,7 +451,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( new_family.compare( row[FontList.family] ) == 0 ) { + if( familyNamesAreEqual( new_family, row[FontList.family] ) ) { styles = row[FontList.styles]; break; } @@ -688,18 +696,19 @@ std::pair FontLister::new_font_family (Glib::ustri fontspec = style->font_family.value; fontspec += ","; + // Use weight names as defined by Pango switch (style->font_weight.computed) { case SP_CSS_FONT_WEIGHT_100: - fontspec += " 100"; + fontspec += " Thin"; break; case SP_CSS_FONT_WEIGHT_200: - fontspec += " 200"; + fontspec += " Ultra-Light"; break; case SP_CSS_FONT_WEIGHT_300: - fontspec += " 300"; + fontspec += " Light"; break; case SP_CSS_FONT_WEIGHT_400: @@ -708,24 +717,24 @@ std::pair FontLister::new_font_family (Glib::ustri break; case SP_CSS_FONT_WEIGHT_500: - fontspec += " 500"; + fontspec += " Medium"; break; case SP_CSS_FONT_WEIGHT_600: - fontspec += " 600"; + fontspec += " Semi-Bold"; break; case SP_CSS_FONT_WEIGHT_700: case SP_CSS_FONT_WEIGHT_BOLD: - fontspec += " bold"; + fontspec += " Bold"; break; case SP_CSS_FONT_WEIGHT_800: - fontspec += " 800"; + fontspec += " Ultra-Bold"; break; case SP_CSS_FONT_WEIGHT_900: - fontspec += " 900"; + fontspec += " Heavy"; break; case SP_CSS_FONT_WEIGHT_LIGHTER: @@ -821,7 +830,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( family.compare( row[FontList.family] ) == 0 ) { + if( familyNamesAreEqual( family, row[FontList.family] ) ) { return row; } @@ -847,7 +856,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( style.compare( row[FontStyleList.styles] ) == 0 ) { + if( familyNamesAreEqual( style, row[FontStyleList.styles] ) ) { return row; } @@ -1035,7 +1044,7 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(model), &iter ) ) { gtk_tree_model_get(model, &iter, 0, &family, 2, &onSystem, -1); - if( onSystem && token.compare( family ) == 0 ) { + if( onSystem && familyNamesAreEqual( token, family ) ) { found = true; break; } -- cgit v1.2.3 From 4c3611844acfa101897fed00adc839f167ae75bf Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 6 Jun 2014 15:48:19 -0400 Subject: Put lpe-envelope-perspective.cpp in CMakeLists.txt (bzr r13341.1.49) --- src/live_effects/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 610d3a9bf..5d365bb21 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -12,6 +12,7 @@ set(live_effects_SRC lpe-curvestitch.cpp lpe-dynastroke.cpp lpe-envelope.cpp + lpe-envelope-perspective.cpp lpe-extrude.cpp lpe-gears.cpp lpe-interpolate.cpp -- cgit v1.2.3 From 1fd57a41383419cbeddbaef27e52d55c0d02400f Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 6 Jun 2014 17:01:38 -0400 Subject: Clean up some unnecessary pointer usage in livarot (bzr r13341.1.50) --- src/livarot/Path.h | 12 +++++------ src/livarot/PathConversion.cpp | 3 ++- src/livarot/PathCutting.cpp | 7 +++--- src/livarot/PathOutline.cpp | 9 +++++--- src/livarot/PathStroke.cpp | 3 ++- src/sp-flowregion.cpp | 3 ++- src/sp-offset.cpp | 22 +++++++++---------- src/splivarot.cpp | 48 +++++++++++++++++++++--------------------- src/ui/tools/flood-tool.cpp | 2 +- src/ui/tools/pencil-tool.cpp | 5 ++--- src/ui/tools/tweak-tool.cpp | 2 +- 11 files changed, 61 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/livarot/Path.h b/src/livarot/Path.h index 32ee71ffc..5d5a24e5a 100644 --- a/src/livarot/Path.h +++ b/src/livarot/Path.h @@ -135,26 +135,26 @@ public: // closeIfNeeded=false prevent the function from closing the path (resulting in a non-eulerian graph // pathID is a identification number for the path, and is used for recomposing curves from polylines // give each different Path a different ID, and feed the appropriate orig[] to the ConvertToForme() function - void Fill(Shape *dest, int pathID = -1, bool justAdd = false, + void Fill(Shape &dest, int pathID = -1, bool justAdd = false, bool closeIfNeeded = true, bool invert = false); // - stroke the path; usual parameters: type of cap=butt, type of join=join and miter (see LivarotDefs.h) // doClose treat the path as closed (ie a loop) - void Stroke(Shape *dest, bool doClose, double width, JoinType join, + void Stroke(Shape &dest, bool doClose, double width, JoinType join, ButtType butt, double miter, bool justAdd = false); // build a Path that is the outline of the Path instance's description (the result is stored in dest) // it doesn't compute the exact offset (it's way too complicated, but an approximation made of cubic bezier patches // and segments. the algorithm was found in a plugin for Impress (by Chris Cox), but i can't find it back... - void Outline(Path *dest, double width, JoinType join, ButtType butt, + void Outline(Path &dest, double width, JoinType join, ButtType butt, double miter); // half outline with edges having the same direction as the original - void OutsideOutline(Path *dest, double width, JoinType join, ButtType butt, + void OutsideOutline(Path &dest, double width, JoinType join, ButtType butt, double miter); // half outline with edges having the opposite direction as the original - void InsideOutline (Path * dest, double width, JoinType join, ButtType butt, + void InsideOutline (Path & dest, double width, JoinType join, ButtType butt, double miter); // polyline to cubic bezier patches @@ -184,7 +184,7 @@ public: void LoadPath(Geom::Path const &path, Geom::Affine const &tr, bool doTransformation, bool append = false); void LoadPathVector(Geom::PathVector const &pv, Geom::Affine const &tr, bool doTransformation); void LoadPathVector(Geom::PathVector const &pv); - Geom::PathVector* MakePathVector(); + Geom::PathVector MakePathVector(); void Transform(const Geom::Affine &trans); diff --git a/src/livarot/PathConversion.cpp b/src/livarot/PathConversion.cpp index 42df898e6..0ef88841a 100644 --- a/src/livarot/PathConversion.cpp +++ b/src/livarot/PathConversion.cpp @@ -1269,8 +1269,9 @@ void Path::RecBezierTo(Geom::Point const &iP, Geom::Point const &iS,Geom::Point * in a path description ( you need to have prepared the back data for that, of course) */ -void Path::Fill(Shape* dest, int pathID, bool justAdd, bool closeIfNeeded, bool invert) +void Path::Fill(Shape& destr, int pathID, bool justAdd, bool closeIfNeeded, bool invert) { + Shape* dest = &destr; if ( dest == NULL ) { return; } diff --git a/src/livarot/PathCutting.cpp b/src/livarot/PathCutting.cpp index 49b2c5a78..74653ca06 100644 --- a/src/livarot/PathCutting.cpp +++ b/src/livarot/PathCutting.cpp @@ -269,10 +269,11 @@ void Path::DashSubPath(int spL, int spP, std::vector const &orig_pt } } -Geom::PathVector * +Geom::PathVector Path::MakePathVector() { - Geom::PathVector *pv = new Geom::PathVector(); + Geom::PathVector retPv; + Geom::PathVector *pv = &retPv; Geom::Path * currentpath = NULL; Geom::Point lastP,bezSt,bezEn; @@ -380,7 +381,7 @@ Path::MakePathVector() } } - return pv; + return *pv; } void Path::AddCurve(Geom::Curve const &c) diff --git a/src/livarot/PathOutline.cpp b/src/livarot/PathOutline.cpp index 211ee31e2..f1978931a 100644 --- a/src/livarot/PathOutline.cpp +++ b/src/livarot/PathOutline.cpp @@ -21,8 +21,9 @@ // outline of a path. // computed by making 2 offsets, one of the "left" side of the path, one of the right side, and then glueing the two // the left side has to be reversed to make a contour -void Path::Outline(Path *dest, double width, JoinType join, ButtType butt, double miter) +void Path::Outline(Path &destr, double width, JoinType join, ButtType butt, double miter) { + ::Path * dest = &destr; if ( descr_flags & descr_adding_bezier ) { CancelBezier(); } @@ -198,9 +199,10 @@ void Path::Outline(Path *dest, double width, JoinType join, ButtType butt, doubl // versions for outlining closed path: they only make one side of the offset contour void -Path::OutsideOutline (Path * dest, double width, JoinType join, ButtType butt, +Path::OutsideOutline (Path & destr, double width, JoinType join, ButtType butt, double miter) { + ::Path * dest = &destr; if (descr_flags & descr_adding_bezier) { CancelBezier(); } @@ -223,9 +225,10 @@ Path::OutsideOutline (Path * dest, double width, JoinType join, ButtType butt, } void -Path::InsideOutline (Path * dest, double width, JoinType join, ButtType butt, +Path::InsideOutline (Path & destr, double width, JoinType join, ButtType butt, double miter) { + ::Path * dest = &destr; if ( descr_flags & descr_adding_bezier ) { CancelBezier(); } diff --git a/src/livarot/PathStroke.cpp b/src/livarot/PathStroke.cpp index 50c335176..07ecc8114 100644 --- a/src/livarot/PathStroke.cpp +++ b/src/livarot/PathStroke.cpp @@ -38,9 +38,10 @@ static Geom::Point StrokeNormalize(const Geom::Point value, double length) { } } -void Path::Stroke(Shape *dest, bool doClose, double width, JoinType join, +void Path::Stroke(Shape &destr, bool doClose, double width, JoinType join, ButtType butt, double miter, bool justAdd) { + ::Shape* dest = &destr; if (dest == NULL) { return; } diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 709e9e464..37170c9e6 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -1,4 +1,5 @@ /* + * TODO: clean this up */ #ifdef HAVE_CONFIG_H @@ -382,7 +383,7 @@ static void GetDest(SPObject* child,Shape **computed) temp->LoadPathVector(curve->get_pathvector(), tr_mat, true); Shape* n_shp=new Shape; temp->Convert(0.25); - temp->Fill(n_shp,0); + temp->Fill(*n_shp,0); Shape* uncross=new Shape; SPStyle* style = u_child->style; if ( style && style->fill_rule.computed == SP_WIND_RULE_EVENODD ) { diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index c6a4b730d..26eb64c94 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -406,12 +406,12 @@ void SPOffset::set_shape() { if (this->rad >= 0) { o_width = this->rad; - orig->OutsideOutline (res, o_width, join_round, butt_straight, 20.0); + orig->OutsideOutline (*res, o_width, join_round, butt_straight, 20.0); } else { o_width = -this->rad; - orig->OutsideOutline (res, -o_width, join_round, butt_straight, 20.0); + orig->OutsideOutline (*res, -o_width, join_round, butt_straight, 20.0); } if (o_width >= 1.0) @@ -424,7 +424,7 @@ void SPOffset::set_shape() { // res->ConvertForOffset (o_width, orig, offset->rad); res->ConvertWithBackData (o_width); } - res->Fill (theShape, 0); + res->Fill (*theShape, 0); theRes->ConvertToShape (theShape, fill_positive); originaux[0] = res; @@ -489,7 +489,7 @@ void SPOffset::set_shape() { orig->ConvertWithBackData (0.5*o_width); } - orig->Fill (theShape, 0); + orig->Fill (*theShape, 0); theRes->ConvertToShape (theShape, fill_positive); Path *originaux[1]; @@ -527,7 +527,7 @@ void SPOffset::set_shape() { if ( partSurf < 0 ) { // inverse par rapport a la realite // plein holes[i]=0; - parts[i]->Fill(oneCleanPart,0); + parts[i]->Fill(*oneCleanPart, 0); onePart->ConvertToShape(oneCleanPart,fill_positive); // there aren't intersections in that one, but maybe duplicate points and null edges oneCleanPart->MakeOffset(onePart,this->rad,join_round,20.0); onePart->ConvertToShape(oneCleanPart,fill_positive); @@ -564,7 +564,7 @@ void SPOffset::set_shape() { } else { // trou holes[i]=1; - parts[i]->Fill(oneCleanPart,0,false,true,true); + parts[i]->Fill(*oneCleanPart, 0, false, true, true); onePart->ConvertToShape(oneCleanPart,fill_positive); oneCleanPart->MakeOffset(onePart,-this->rad,join_round,20.0); onePart->ConvertToShape(oneCleanPart,fill_positive); @@ -614,9 +614,9 @@ void SPOffset::set_shape() { parts[i]->ConvertWithBackData(1.0); if ( holes[i] ) { - parts[i]->Fill(theShape,i,true,true,true); + parts[i]->Fill(*theShape,i,true,true,true); } else { - parts[i]->Fill(theShape,i,true,true,false); + parts[i]->Fill(*theShape,i,true,true,false); } } } @@ -808,7 +808,7 @@ sp_offset_distance_to_original (SPOffset * offset, Geom::Point px) */ // move ((Path *) offset->originalPath)->Convert (1.0); - ((Path *) offset->originalPath)->Fill (theShape, 0); + ((Path *) offset->originalPath)->Fill (*theShape, 0); theRes->ConvertToShape (theShape, fill_oddEven); if (theRes->numberOfEdges() <= 1) @@ -987,7 +987,7 @@ sp_offset_top_point (SPOffset const * offset, Geom::Point *px) Shape *theShape = new Shape; finalPath->Convert (1.0); - finalPath->Fill (theShape, 0); + finalPath->Fill (*theShape, 0); if (theShape->hasPoints()) { @@ -1174,7 +1174,7 @@ refresh_offset_source(SPOffset* offset) Shape *theRes = new Shape; orig->ConvertWithBackData (1.0); - orig->Fill (theShape, 0); + orig->Fill (*theShape, 0); css = sp_repr_css_attr (offset->sourceRepr , "style"); val = sp_repr_css_property (css, "fill-rule", NULL); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index 8bb2a7150..c8682e6b4 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -156,13 +156,13 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat // get the polygons of each path, with the winding rule specified, and apply the operation iteratively originaux[0]->ConvertWithBackData(0.1); - originaux[0]->Fill(theShape, 0); + originaux[0]->Fill(*theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); originaux[1]->ConvertWithBackData(0.1); - originaux[1]->Fill(theShape, 1); + originaux[1]->Fill(*theShape, 1); theShapeB->ConvertToShape(theShape, origWind[1]); @@ -191,13 +191,13 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(theShape, 0); + originaux[0]->Fill(*theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); originaux[1]->ConvertWithBackData(1.0); - originaux[1]->Fill(theShape, 1,false,false,false); //do not closeIfNeeded + originaux[1]->Fill(*theShape, 1,false,false,false); //do not closeIfNeeded theShapeB->ConvertToShape(theShape, fill_justDont); // fill_justDont doesn't computes winding numbers @@ -218,11 +218,11 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(theShapeA, 0,false,false,false); // don't closeIfNeeded + originaux[0]->Fill(*theShapeA, 0,false,false,false); // don't closeIfNeeded originaux[1]->ConvertWithBackData(1.0); - originaux[1]->Fill(theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it + originaux[1]->Fill(*theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it theShape->ConvertToShape(theShapeA, fill_justDont); @@ -467,7 +467,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool // get the polygons of each path, with the winding rule specified, and apply the operation iteratively originaux[0]->ConvertWithBackData(0.1); - originaux[0]->Fill(theShape, 0); + originaux[0]->Fill(*theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); @@ -475,7 +475,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool for (GSList *l = il->next; l != NULL; l = l->next) { originaux[curOrig]->ConvertWithBackData(0.1); - originaux[curOrig]->Fill(theShape, curOrig); + originaux[curOrig]->Fill(*theShape, curOrig); theShapeB->ConvertToShape(theShape, origWind[curOrig]); @@ -549,16 +549,16 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(theShape, 0); + originaux[0]->Fill(*theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); originaux[1]->ConvertWithBackData(1.0); if ((originaux[1]->pts.size() == 2) && originaux[1]->pts[0].isMoveTo && !originaux[1]->pts[1].isMoveTo) - originaux[1]->Fill(theShape, 1,false,true,false); // see LP Bug 177956 + originaux[1]->Fill(*theShape, 1,false,true,false); // see LP Bug 177956 else - originaux[1]->Fill(theShape, 1,false,false,false); //do not closeIfNeeded + originaux[1]->Fill(*theShape, 1,false,false,false); //do not closeIfNeeded theShapeB->ConvertToShape(theShape, fill_justDont); // fill_justDont doesn't computes winding numbers @@ -579,11 +579,11 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(theShapeA, 0,false,false,false); // don't closeIfNeeded + originaux[0]->Fill(*theShapeA, 0,false,false,false); // don't closeIfNeeded originaux[1]->ConvertWithBackData(1.0); - originaux[1]->Fill(theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it + originaux[1]->Fill(*theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it theShape->ConvertToShape(theShapeA, fill_justDont); @@ -1014,9 +1014,9 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) orig->DashPolylineFromStyle(i_style, scale, 0); Shape* theShape = new Shape; - orig->Stroke(theShape, false, 0.5*o_width, o_join, o_butt, + orig->Stroke(*theShape, false, 0.5*o_width, o_join, o_butt, 0.5 * o_miter); - orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); if (!bbox_only) { Shape *theRes = new Shape; @@ -1030,7 +1030,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) } delete theShape; } else { - orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); if (!bbox_only) { orig->Coalesce(0.5 * o_width); @@ -1038,7 +1038,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) Shape *theRes = new Shape; res->ConvertWithBackData(1.0); - res->Fill(theShape, 0); + res->Fill(*theShape, 0); theRes->ConvertToShape(theShape, fill_positive); Path *originaux[1]; @@ -1060,7 +1060,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether - ret_pathv = bbox_only ? res->MakePathVector() : orig->MakePathVector(); + ret_pathv = new Geom::PathVector(bbox_only ? (res->MakePathVector()) : (orig->MakePathVector())); if (SP_IS_SHAPE(item) && SP_SHAPE(item)->hasMarkers() && !bbox_only) { SPShape *shape = SP_SHAPE(item); @@ -1283,9 +1283,9 @@ sp_selected_path_outline(SPDesktop *desktop) orig->DashPolylineFromStyle(i_style, scale, 0); Shape* theShape = new Shape; - orig->Stroke(theShape, false, 0.5*o_width, o_join, o_butt, + orig->Stroke(*theShape, false, 0.5*o_width, o_join, o_butt, 0.5 * o_miter); - orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); Shape *theRes = new Shape; @@ -1302,7 +1302,7 @@ sp_selected_path_outline(SPDesktop *desktop) } else { - orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); orig->Coalesce(0.5 * o_width); @@ -1310,7 +1310,7 @@ sp_selected_path_outline(SPDesktop *desktop) Shape *theRes = new Shape; res->ConvertWithBackData(1.0); - res->Fill(theShape, 0); + res->Fill(*theShape, 0); theRes->ConvertToShape(theShape, fill_positive); Path *originaux[1]; @@ -1644,7 +1644,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool Shape *theRes = new Shape; orig->ConvertWithBackData(1.0); - orig->Fill(theShape, 0); + orig->Fill(*theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); @@ -1843,7 +1843,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) Shape *theRes = new Shape; orig->ConvertWithBackData(0.03); - orig->Fill(theShape, 0); + orig->Fill(*theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index d74848dc6..15bc7164c 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -408,7 +408,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto Shape *path_shape = new Shape(); path->ConvertWithBackData(0.03); - path->Fill(path_shape, 0); + path->Fill(*path_shape, 0); delete path; Shape *expanded_path_shape = new Shape(); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 0e8660248..48f8c3a28 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -760,9 +760,8 @@ void PencilTool::_sketchInterpolate() { path.LoadPathVector(Geom::path_from_piecewise(this->sketch_interpolation, 0.01)); path.Simplify(0.5); - Geom::PathVector *pathv = path.MakePathVector(); - this->sketch_interpolation = (*pathv)[0].toPwSb(); - delete pathv; + Geom::PathVector pathv = path.MakePathVector(); + this->sketch_interpolation = pathv[0].toPwSb(); } else { this->sketch_interpolation = fit_pwd2; } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index 75650d3af..bc1519773 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -551,7 +551,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P Geom::Affine i2doc(item->i2doc_affine()); orig->ConvertWithBackData((0.08 - (0.07 * fidelity)) / i2doc.descrim()); // default 0.059 - orig->Fill(theShape, 0); + orig->Fill(*theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); -- cgit v1.2.3 From 67668ace6f9afe7861fe220a7a2f1c28fd7e22d0 Mon Sep 17 00:00:00 2001 From: Adib Taraben Date: Fri, 6 Jun 2014 23:56:26 +0200 Subject: merge pdf import via poppler-cairo into native importer (bzr r13409) --- src/extension/CMakeLists.txt | 2 - src/extension/init.cpp | 8 - src/extension/internal/Makefile_insert | 2 - src/extension/internal/pdf-input-cairo.cpp | 680 -------------------------- src/extension/internal/pdf-input-cairo.h | 157 ------ src/extension/internal/pdfinput/pdf-input.cpp | 233 ++++++--- src/extension/internal/pdfinput/pdf-input.h | 4 + 7 files changed, 175 insertions(+), 911 deletions(-) delete mode 100644 src/extension/internal/pdf-input-cairo.cpp delete mode 100644 src/extension/internal/pdf-input-cairo.h (limited to 'src') diff --git a/src/extension/CMakeLists.txt b/src/extension/CMakeLists.txt index 759c704f0..47292fd97 100644 --- a/src/extension/CMakeLists.txt +++ b/src/extension/CMakeLists.txt @@ -49,7 +49,6 @@ set(extension_SRC internal/metafile-print.cpp internal/odf.cpp internal/latex-text-renderer.cpp - internal/pdf-input-cairo.cpp internal/pov-out.cpp internal/javafx-out.cpp internal/svg.cpp @@ -133,7 +132,6 @@ set(extension_SRC internal/metafile-inout.h internal/metafile-print.h internal/odf.h - internal/pdf-input-cairo.h internal/pdfinput/pdf-input.h internal/pdfinput/pdf-parser.h internal/pdfinput/svg-builder.h diff --git a/src/extension/init.cpp b/src/extension/init.cpp index 0ff4b79c4..912d58a13 100644 --- a/src/extension/init.cpp +++ b/src/extension/init.cpp @@ -19,9 +19,6 @@ #ifdef HAVE_POPPLER # include "internal/pdfinput/pdf-input.h" #endif -#ifdef HAVE_POPPLER_GLIB -# include "internal/pdf-input-cairo.h" -#endif #include "path-prefix.h" @@ -173,11 +170,6 @@ init() #endif #ifdef HAVE_POPPLER Internal::PdfInput::init(); -#endif -#ifdef HAVE_POPPLER_GLIB - if (1) { - Internal::PdfInputCairo::init(); - } #endif Internal::PrintEmf::init(); Internal::Emf::init(); diff --git a/src/extension/internal/Makefile_insert b/src/extension/internal/Makefile_insert index a31843114..125776d41 100644 --- a/src/extension/internal/Makefile_insert +++ b/src/extension/internal/Makefile_insert @@ -106,8 +106,6 @@ ink_common_sources += \ extension/internal/svg.cpp \ extension/internal/svgz.h \ extension/internal/svgz.cpp \ - extension/internal/pdf-input-cairo.cpp \ - extension/internal/pdf-input-cairo.h \ extension/internal/cairo-ps-out.h \ extension/internal/cairo-ps-out.cpp \ extension/internal/cairo-render-context.h \ diff --git a/src/extension/internal/pdf-input-cairo.cpp b/src/extension/internal/pdf-input-cairo.cpp deleted file mode 100644 index 9ce73c260..000000000 --- a/src/extension/internal/pdf-input-cairo.cpp +++ /dev/null @@ -1,680 +0,0 @@ - /* - * Simple PDF import extension using libpoppler and Cairo's SVG surface. - * - * Authors: - * miklos erdelyi - * Abhishek Sharma - * - * Copyright (C) 2007 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - * - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_POPPLER_GLIB -#ifdef HAVE_POPPLER_CAIRO - -#include "pdf-input-cairo.h" -#include "extension/system.h" -#include "extension/input.h" -#include "dialogs/dialog-events.h" -#include "document.h" -#include "sp-root.h" -#include "util/units.h" - -#include <2geom/rect.h> - -#include "inkscape.h" - -#include -#include -#include -#include - -#include "ui/widget/spinbutton.h" -#include "ui/widget/frame.h" - -#include - -namespace Inkscape { -namespace Extension { -namespace Internal { - - -/** - * \brief The PDF import dialog - * FIXME: Probably this should be placed into src/ui/dialog - */ - -static const gchar * crop_setting_choices[] = { - //TRANSLATORS: The following are document crop settings for PDF import - // more info: http://www.acrobatusers.com/tech_corners/javascript_corner/tips/2006/page_bounds/ - N_("media box"), - N_("crop box"), - N_("trim box"), - N_("bleed box"), - N_("art box") -}; - -PdfImportCairoDialog::PdfImportCairoDialog(PopplerDocument *doc) -{ - if(doc == NULL) { - // if there is no document, throw exception here - throw; - } - - _poppler_doc = doc; - - cancelbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))); - okbutton = Gtk::manage(new class Gtk::Button(Gtk::StockID("gtk-ok"))); - _labelSelect = Gtk::manage(new class Gtk::Label(_("Select page:"))); - - // Page number - int num_pages = poppler_document_get_n_pages(_poppler_doc); -#if WITH_GTKMM_3_0 - Glib::RefPtr _pageNumberSpin_adj( Gtk::Adjustment::create(1, 1, num_pages, 1, 10, 0) ); - _pageNumberSpin = Gtk::manage(new class Inkscape::UI::Widget::SpinButton(_pageNumberSpin_adj, 1, 1)); -#else - Gtk::Adjustment *_pageNumberSpin_adj = Gtk::manage(new class Gtk::Adjustment(1, 1, num_pages, 1, 10, 0)); - _pageNumberSpin = Gtk::manage(new class Inkscape::UI::Widget::SpinButton(*_pageNumberSpin_adj, 1, 1)); -#endif - _labelTotalPages = Gtk::manage(new class Gtk::Label()); - hbox2 = Gtk::manage(new class Gtk::HBox(false, 0)); - // Disable the page selector when there's only one page - if ( num_pages == 1 ) { - _pageNumberSpin->set_sensitive(false); - } else { - // Display total number of pages - gchar *label_text = g_strdup_printf(_("out of %i"), num_pages); - _labelTotalPages->set_label(label_text); - g_free(label_text); - } - - // Crop settings - _cropCheck = Gtk::manage(new class Gtk::CheckButton(_("Clip to:"))); - _cropTypeCombo = Gtk::manage(new class Gtk::ComboBoxText()); - int num_crop_choices = sizeof(crop_setting_choices) / sizeof(crop_setting_choices[0]); - for ( int i = 0 ; i < num_crop_choices ; i++ ) { - _cropTypeCombo->append(_(crop_setting_choices[i])); - } - _cropTypeCombo->set_active_text(_(crop_setting_choices[0])); - _cropTypeCombo->set_sensitive(false); - - hbox3 = Gtk::manage(new class Gtk::HBox(false, 4)); - vbox2 = Gtk::manage(new class Gtk::VBox(false, 4)); - _pageSettingsFrame = Gtk::manage(new class Inkscape::UI::Widget::Frame(_("Page settings"))); - _labelPrecision = Gtk::manage(new class Gtk::Label(_("Precision of approximating gradient meshes:"))); - _labelPrecisionWarning = Gtk::manage(new class Gtk::Label(_("Note: setting the precision too high may result in a large SVG file and slow performance."))); - -#if WITH_GTKMM_3_0 - _fallbackPrecisionSlider_adj = Gtk::Adjustment::create(2, 1, 256, 1, 10, 10); - _fallbackPrecisionSlider = Gtk::manage(new Gtk::Scale(_fallbackPrecisionSlider_adj)); -#else - _fallbackPrecisionSlider_adj = Gtk::manage(new class Gtk::Adjustment(2, 1, 256, 1, 10, 10)); - _fallbackPrecisionSlider = Gtk::manage(new class Gtk::HScale(*_fallbackPrecisionSlider_adj)); -#endif - _fallbackPrecisionSlider->set_value(2.0); - _labelPrecisionComment = Gtk::manage(new class Gtk::Label(_("rough"))); - hbox6 = Gtk::manage(new class Gtk::HBox(false, 4)); - - // Text options - _labelText = Gtk::manage(new class Gtk::Label(_("Text handling:"))); - _textHandlingCombo = Gtk::manage(new class Gtk::ComboBoxText()); - _textHandlingCombo->append(_("Import text as text")); - _textHandlingCombo->set_active_text(_("Import text as text")); - _localFontsCheck = Gtk::manage(new class Gtk::CheckButton(_("Replace PDF fonts by closest-named installed fonts"))); - - hbox5 = Gtk::manage(new class Gtk::HBox(false, 4)); - _embedImagesCheck = Gtk::manage(new class Gtk::CheckButton(_("Embed images"))); - vbox3 = Gtk::manage(new class Gtk::VBox(false, 4)); - _importSettingsFrame = Gtk::manage(new class Inkscape::UI::Widget::Frame(_("Import settings"))); - vbox1 = Gtk::manage(new class Gtk::VBox(false, 4)); - _previewArea = Gtk::manage(new class Gtk::DrawingArea()); - hbox1 = Gtk::manage(new class Gtk::HBox(false, 4)); - cancelbutton->set_can_focus(); - cancelbutton->set_can_default(); - cancelbutton->set_relief(Gtk::RELIEF_NORMAL); - okbutton->set_can_focus(); - okbutton->set_can_default(); - okbutton->set_relief(Gtk::RELIEF_NORMAL); - this->get_action_area()->property_layout_style().set_value(Gtk::BUTTONBOX_END); - _labelSelect->set_alignment(0.5,0.5); - _labelSelect->set_padding(4,0); - _labelSelect->set_justify(Gtk::JUSTIFY_LEFT); - _labelSelect->set_line_wrap(false); - _labelSelect->set_use_markup(false); - _labelSelect->set_selectable(false); - _pageNumberSpin->set_can_focus(); - _pageNumberSpin->set_update_policy(Gtk::UPDATE_ALWAYS); - _pageNumberSpin->set_numeric(true); - _pageNumberSpin->set_digits(0); - _pageNumberSpin->set_wrap(false); - _labelTotalPages->set_alignment(0.5,0.5); - _labelTotalPages->set_padding(4,0); - _labelTotalPages->set_justify(Gtk::JUSTIFY_LEFT); - _labelTotalPages->set_line_wrap(false); - _labelTotalPages->set_use_markup(false); - _labelTotalPages->set_selectable(false); - hbox2->pack_start(*_labelSelect, Gtk::PACK_SHRINK, 4); - hbox2->pack_start(*_pageNumberSpin, Gtk::PACK_SHRINK, 4); - hbox2->pack_start(*_labelTotalPages, Gtk::PACK_SHRINK, 4); - _cropCheck->set_can_focus(); - _cropCheck->set_relief(Gtk::RELIEF_NORMAL); - _cropCheck->set_mode(true); - _cropCheck->set_active(false); - _cropTypeCombo->set_border_width(1); - hbox3->pack_start(*_cropCheck, Gtk::PACK_SHRINK, 4); - hbox3->pack_start(*_cropTypeCombo, Gtk::PACK_SHRINK, 0); - vbox2->pack_start(*hbox2); - vbox2->pack_start(*hbox3); - _pageSettingsFrame->add(*vbox2); - _pageSettingsFrame->set_border_width(4); - _labelPrecision->set_alignment(0,0.5); - _labelPrecision->set_padding(4,0); - _labelPrecision->set_justify(Gtk::JUSTIFY_LEFT); - _labelPrecision->set_line_wrap(true); - _labelPrecision->set_use_markup(false); - _labelPrecision->set_selectable(false); - _labelPrecisionWarning->set_alignment(0,0.5); - _labelPrecisionWarning->set_padding(4,0); - _labelPrecisionWarning->set_justify(Gtk::JUSTIFY_LEFT); - _labelPrecisionWarning->set_line_wrap(true); - _labelPrecisionWarning->set_use_markup(true); - _labelPrecisionWarning->set_selectable(false); - _fallbackPrecisionSlider->set_size_request(180,-1); - _fallbackPrecisionSlider->set_can_focus(); - _fallbackPrecisionSlider->set_inverted(false); - _fallbackPrecisionSlider->set_digits(1); - _fallbackPrecisionSlider->set_draw_value(true); - _fallbackPrecisionSlider->set_value_pos(Gtk::POS_TOP); - _labelPrecisionComment->set_size_request(90,-1); - _labelPrecisionComment->set_alignment(0.5,0.5); - _labelPrecisionComment->set_padding(4,0); - _labelPrecisionComment->set_justify(Gtk::JUSTIFY_LEFT); - _labelPrecisionComment->set_line_wrap(false); - _labelPrecisionComment->set_use_markup(false); - _labelPrecisionComment->set_selectable(false); - hbox6->pack_start(*_fallbackPrecisionSlider, Gtk::PACK_SHRINK, 4); - hbox6->pack_start(*_labelPrecisionComment, Gtk::PACK_SHRINK, 0); - _labelText->set_alignment(0.5,0.5); - _labelText->set_padding(4,0); - _labelText->set_justify(Gtk::JUSTIFY_LEFT); - _labelText->set_line_wrap(false); - _labelText->set_use_markup(false); - _labelText->set_selectable(false); - hbox5->pack_start(*_labelText, Gtk::PACK_SHRINK, 0); - hbox5->pack_start(*_textHandlingCombo, Gtk::PACK_SHRINK, 0); - _localFontsCheck->set_can_focus(); - _localFontsCheck->set_relief(Gtk::RELIEF_NORMAL); - _localFontsCheck->set_mode(true); - _localFontsCheck->set_active(true); - _embedImagesCheck->set_can_focus(); - _embedImagesCheck->set_relief(Gtk::RELIEF_NORMAL); - _embedImagesCheck->set_mode(true); - _embedImagesCheck->set_active(true); - vbox3->pack_start(*_labelPrecision, Gtk::PACK_SHRINK, 0); - vbox3->pack_start(*hbox6, Gtk::PACK_SHRINK, 0); - vbox3->pack_start(*_labelPrecisionWarning, Gtk::PACK_SHRINK, 0); - vbox3->pack_start(*hbox5, Gtk::PACK_SHRINK, 4); - vbox3->pack_start(*_localFontsCheck, Gtk::PACK_SHRINK, 0); - vbox3->pack_start(*_embedImagesCheck, Gtk::PACK_SHRINK, 0); - _importSettingsFrame->add(*vbox3); - _importSettingsFrame->set_border_width(4); - vbox1->pack_start(*_pageSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); - vbox1->pack_start(*_importSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); - hbox1->pack_start(*vbox1); - hbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 4); - -#if WITH_GTKMM_3_0 - get_content_area()->set_homogeneous(false); - get_content_area()->set_spacing(0); - get_content_area()->pack_start(*hbox1); -#else - this->get_vbox()->set_homogeneous(false); - this->get_vbox()->set_spacing(0); - this->get_vbox()->pack_start(*hbox1); -#endif - - this->set_title(_("PDF Import Settings")); - this->set_modal(true); - sp_transientize(GTK_WIDGET(this->gobj())); //Make transient - this->property_window_position().set_value(Gtk::WIN_POS_NONE); - this->set_resizable(true); - this->property_destroy_with_parent().set_value(false); - this->add_action_widget(*cancelbutton, -6); - this->add_action_widget(*okbutton, -5); - cancelbutton->show(); - okbutton->show(); - _labelSelect->show(); - _pageNumberSpin->show(); - _labelTotalPages->show(); - hbox2->show(); - _cropCheck->show(); - _cropTypeCombo->show(); - hbox3->show(); - vbox2->show(); - _pageSettingsFrame->show(); - _labelPrecision->show(); - _labelPrecisionWarning->show(); - _fallbackPrecisionSlider->show(); - _labelPrecisionComment->show(); - hbox6->show(); - _labelText->show(); - _textHandlingCombo->show(); - hbox5->show(); - _localFontsCheck->show(); - _embedImagesCheck->show(); - vbox3->show(); - _importSettingsFrame->show(); - vbox1->show(); - _previewArea->show(); - hbox1->show(); - - // Connect signals -#if WITH_GTKMM_3_0 - _previewArea->signal_draw().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onDraw)); -#else - _previewArea->signal_expose_event().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onExposePreview)); -#endif - _pageNumberSpin_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onPageNumberChanged)); - _cropCheck->signal_toggled().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onToggleCropping)); - _fallbackPrecisionSlider_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PdfImportCairoDialog::_onPrecisionChanged)); - - _render_thumb = false; - _cairo_surface = NULL; - _render_thumb = true; - - // Set default preview size - _preview_width = 200; - _preview_height = 300; - - // Init preview - _thumb_data = NULL; - _pageNumberSpin_adj->set_value(1.0); - _current_page = 1; - _setPreviewPage(_current_page); - - set_default (*okbutton); - set_focus (*okbutton); -} - -PdfImportCairoDialog::~PdfImportCairoDialog() { - if (_cairo_surface) { - cairo_surface_destroy(_cairo_surface); - } - if (_thumb_data) { - if (_render_thumb) { - delete _thumb_data; - } else { - // -->gfree(_thumb_data); - delete _thumb_data; - } - } -} - -bool PdfImportCairoDialog::showDialog() { - show(); - gint b = run(); - hide(); - if ( b == Gtk::RESPONSE_OK ) { - return TRUE; - } else { - return FALSE; - } -} - -int PdfImportCairoDialog::getSelectedPage() { - return _current_page; -} - -/** - * \brief Retrieves the current settings into a repr which SvgBuilder will use - * for determining the behaviour desired by the user - */ -void PdfImportCairoDialog::getImportSettings(Inkscape::XML::Node *prefs) { - sp_repr_set_svg_double(prefs, "selectedPage", (double)_current_page); - if (_cropCheck->get_active()) { - Glib::ustring current_choice = _cropTypeCombo->get_active_text(); - int num_crop_choices = sizeof(crop_setting_choices) / sizeof(crop_setting_choices[0]); - int i = 0; - for ( ; i < num_crop_choices ; i++ ) { - if ( current_choice == _(crop_setting_choices[i]) ) { - break; - } - } - sp_repr_set_svg_double(prefs, "cropTo", (double)i); - } else { - sp_repr_set_svg_double(prefs, "cropTo", -1.0); - } - sp_repr_set_svg_double(prefs, "approximationPrecision", - _fallbackPrecisionSlider->get_value()); - if (_localFontsCheck->get_active()) { - prefs->setAttribute("localFonts", "1"); - } else { - prefs->setAttribute("localFonts", "0"); - } - if (_embedImagesCheck->get_active()) { - prefs->setAttribute("embedImages", "1"); - } else { - prefs->setAttribute("embedImages", "0"); - } -} - -/** - * \brief Redisplay the comment on the current approximation precision setting - * Evenly divides the interval of possible values between the available labels. - */ -void PdfImportCairoDialog::_onPrecisionChanged() { - - static Glib::ustring precision_comments[] = { - Glib::ustring(C_("PDF input precision", "rough")), - Glib::ustring(C_("PDF input precision", "medium")), - Glib::ustring(C_("PDF input precision", "fine")), - Glib::ustring(C_("PDF input precision", "very fine")) - }; - - double min = _fallbackPrecisionSlider_adj->get_lower(); - double max = _fallbackPrecisionSlider_adj->get_upper(); - int num_intervals = sizeof(precision_comments) / sizeof(precision_comments[0]); - double interval_len = ( max - min ) / (double)num_intervals; - double value = _fallbackPrecisionSlider_adj->get_value(); - int comment_idx = (int)floor( ( value - min ) / interval_len ); - _labelPrecisionComment->set_label(precision_comments[comment_idx]); -} - -void PdfImportCairoDialog::_onToggleCropping() { - _cropTypeCombo->set_sensitive(_cropCheck->get_active()); -} - -void PdfImportCairoDialog::_onPageNumberChanged() { - int page = _pageNumberSpin->get_value_as_int(); - _current_page = CLAMP(page, 1, poppler_document_get_n_pages(_poppler_doc)); - _setPreviewPage(_current_page); -} - -/** - * \brief Copies image data from a Cairo surface to a pixbuf - * - * Borrowed from libpoppler, from the file poppler-page.cc - * Copyright (C) 2005, Red Hat, Inc. - * - */ -static void copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, - unsigned char *data, - GdkPixbuf *pixbuf) -{ - int cairo_width, cairo_height, cairo_rowstride; - unsigned char *pixbuf_data, *dst, *cairo_data; - int pixbuf_rowstride, pixbuf_n_channels; - unsigned int *src; - int x, y; - - cairo_width = cairo_image_surface_get_width (surface); - cairo_height = cairo_image_surface_get_height (surface); - cairo_rowstride = cairo_width * 4; - cairo_data = data; - - pixbuf_data = gdk_pixbuf_get_pixels (pixbuf); - pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); - pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf); - - if (cairo_width > gdk_pixbuf_get_width (pixbuf)) - cairo_width = gdk_pixbuf_get_width (pixbuf); - if (cairo_height > gdk_pixbuf_get_height (pixbuf)) - cairo_height = gdk_pixbuf_get_height (pixbuf); - for (y = 0; y < cairo_height; y++) - { - src = reinterpret_cast(cairo_data + y * cairo_rowstride); - dst = pixbuf_data + y * pixbuf_rowstride; - for (x = 0; x < cairo_width; x++) - { - dst[0] = (*src >> 16) & 0xff; - dst[1] = (*src >> 8) & 0xff; - dst[2] = (*src >> 0) & 0xff; - if (pixbuf_n_channels == 4) - dst[3] = (*src >> 24) & 0xff; - dst += pixbuf_n_channels; - src++; - } - } -} - -/** - * \brief Updates the preview area with the previously rendered thumbnail - */ -#if !WITH_GTKMM_3_0 -bool PdfImportCairoDialog::_onExposePreview(GdkEventExpose * /*event*/) { - Cairo::RefPtr cr = _previewArea->get_window()->create_cairo_context(); - return _onDraw(cr); -} -#endif - - -bool PdfImportCairoDialog::_onDraw(const Cairo::RefPtr& cr) { - // Check if we have a thumbnail at all - if (!_thumb_data) { - return true; - } - - // Create the pixbuf for the thumbnail - Glib::RefPtr thumb; - if (_render_thumb) { - thumb = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, - 8, _thumb_width, _thumb_height); - } else { - thumb = Gdk::Pixbuf::create_from_data(_thumb_data, Gdk::COLORSPACE_RGB, - false, 8, _thumb_width, _thumb_height, _thumb_rowstride); - } - if (!thumb) { - return true; - } - - // Set background to white - if (_render_thumb) { - thumb->fill(0xffffffff); - Gdk::Cairo::set_source_pixbuf(cr, thumb, 0, 0); - cr->paint(); - } - - // Copy the thumbnail image from the Cairo surface - if (_render_thumb) { - copy_cairo_surface_to_pixbuf(_cairo_surface, _thumb_data, thumb->gobj()); - } - Gdk::Cairo::set_source_pixbuf(cr, thumb, 0, _render_thumb ? 0 : 20); - cr->paint(); - - return true; -} - -/** - * \brief Renders the given page's thumbnail using Cairo - */ -void PdfImportCairoDialog::_setPreviewPage(int page) { - - PopplerPage *_previewed_page = poppler_document_get_page(_poppler_doc, page-1); - - // Try to get a thumbnail from the PDF if possible - if (!_render_thumb) { - if (_thumb_data) { - // --> gfree(_thumb_data); - free(_thumb_data); - _thumb_data = NULL; - } - -/* ---> if (!_previewed_page->loadThumb(&_thumb_data, - &_thumb_width, &_thumb_height, &_thumb_rowstride)) { - return; - } -*/ - // Redraw preview area - _previewArea->set_size_request(_thumb_width, _thumb_height + 20); - _previewArea->queue_draw(); - return; - } - - // Get page size by accounting for rotation - double width, height; - // --> int rotate = _previewed_page->getRotate(); - int rotate = 0; - if ( rotate == 90 || rotate == 270 ) { -// --> height = _previewed_page->getCropWidth(); -// --> width = _previewed_page->getCropHeight(); - } else { - poppler_page_get_size (_previewed_page, &width, &height); -// --> width = _previewed_page->getCropWidth(); -// --> height = _previewed_page->getCropHeight(); - } - // Calculate the needed scaling for the page - double scale_x = (double)_preview_width / width; - double scale_y = (double)_preview_height / height; - double scale_factor = ( scale_x > scale_y ) ? scale_y : scale_x; - // Create new Cairo surface - _thumb_width = (int)ceil( width * scale_factor ); - _thumb_height = (int)ceil( height * scale_factor ); - _thumb_rowstride = _thumb_width * 4; - if (_thumb_data) { - delete _thumb_data; - } - _thumb_data = new unsigned char[ _thumb_rowstride * _thumb_height ]; - if (_cairo_surface) { - cairo_surface_destroy(_cairo_surface); - } - _cairo_surface = cairo_image_surface_create_for_data(_thumb_data, - CAIRO_FORMAT_ARGB32, _thumb_width, _thumb_height, _thumb_rowstride); - cairo_t *cr = cairo_create(_cairo_surface); - cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); // Set fill color to white - cairo_paint(cr); // Clear it - cairo_scale(cr, scale_factor, scale_factor); // Use Cairo for resizing the image - // Render page - if (_poppler_doc != NULL) { - PopplerPage *poppler_page = poppler_document_get_page(_poppler_doc, page - 1); - poppler_page_render(poppler_page, cr); - g_object_unref(G_OBJECT(poppler_page)); - } - // Clean up - cairo_destroy(cr); - // Redraw preview area - _previewArea->set_size_request(_preview_width, _preview_height); - _previewArea->queue_draw(); - -} - - -static cairo_status_t _write_ustring_cb(void *closure, const unsigned char *data, unsigned int length); - -SPDocument * -PdfInputCairo::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - - g_message("Attempting to open using PdfInputCairo\n"); - - gchar* filename_uri = g_filename_to_uri(uri, NULL, NULL); - - GError *error = NULL; - /// @todo handle passwort - /// @todo check if win32 unicode needs special attention - PopplerDocument* document = poppler_document_new_from_file(filename_uri, NULL, &error); - - if(error != NULL) { - g_message("Unable to read file: %s\n", error->message); - g_error_free (error); - } - - if (document == NULL) { - return NULL; - } - - // create and show the import dialog - PdfImportCairoDialog *dlg = NULL; - if (inkscape_use_gui()) { - dlg = new PdfImportCairoDialog(document); - if (!dlg->showDialog()) { - delete dlg; - return NULL; - } - } - - // Get needed page - int page_num; - if (dlg) { - page_num = dlg->getSelectedPage(); - delete dlg; - } - else - page_num = 1; - - double width, height; - PopplerPage* page = poppler_document_get_page(document, page_num - 1); - poppler_page_get_size(page, &width, &height); - - Glib::ustring* output = new Glib::ustring(""); - cairo_surface_t* surface = cairo_svg_surface_create_for_stream(Inkscape::Extension::Internal::_write_ustring_cb, - output, width, height); - cairo_t* cr = cairo_create(surface); - - poppler_page_render_for_printing(page, cr); - cairo_show_page(cr); - - cairo_destroy(cr); - cairo_surface_destroy(surface); - - SPDocument * doc = SPDocument::createNewDocFromMem(output->c_str(), output->length(), TRUE); - - // Set viewBox if it doesn't exist - if (doc && !doc->getRoot()->viewBox_set) { - doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); - } - - delete output; - g_object_unref(page); - g_object_unref(document); - - return doc; -} - -static cairo_status_t - _write_ustring_cb(void *closure, const unsigned char *data, unsigned int length) -{ - Glib::ustring* stream = static_cast(closure); - stream->append(reinterpret_cast(data), length); - - return CAIRO_STATUS_SUCCESS; -} - - -#include "clear-n_.h" - -void -PdfInputCairo::init(void) { - Inkscape::Extension::build_from_mem( - "\n" - "" N_("PDF Input") "\n" - "org.inkscape.input.cairo-pdf\n" - "\n" - ".pdf\n" - "application/pdf\n" - "" N_("Adobe PDF via poppler-cairo (*.pdf)") "\n" - "" N_("PDF Document") "\n" - "\n" - "", new PdfInputCairo()); -} // init - -} } } /* namespace Inkscape, Extension, Implementation */ - -#endif /* HAVE_POPPLER_CAIRO */ -#endif /* HAVE_POPPLER_GLIB */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/extension/internal/pdf-input-cairo.h b/src/extension/internal/pdf-input-cairo.h deleted file mode 100644 index b65d22f48..000000000 --- a/src/extension/internal/pdf-input-cairo.h +++ /dev/null @@ -1,157 +0,0 @@ -#ifndef __EXTENSION_INTERNAL_PDFINPUTCAIRO_H__ -#define __EXTENSION_INTERNAL_PDFINPUTCAIRO_H__ - -/* - * PDF input using libpoppler and Cairo's SVG surface. - * - * Authors: - * miklos erdelyi - * - * Copyright (C) 2007 Authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_POPPLER_GLIB -#ifdef HAVE_POPPLER_CAIRO - -#include - -#include "../implementation/implementation.h" - -namespace Gtk { -#if WITH_GTKMM_3_0 - class Scale; -#else - class HScale; -#endif -} - -namespace Inkscape { - -namespace UI { -namespace Widget { - class SpinButton; - class Frame; -} -} - -namespace Extension { -namespace Internal { - -class PdfImportCairoDialog : public Gtk::Dialog -{ -public: - PdfImportCairoDialog(PopplerDocument* doc); - virtual ~PdfImportCairoDialog(); - - bool showDialog(); - int getSelectedPage(); - void getImportSettings(Inkscape::XML::Node *prefs); - -private: - void _setPreviewPage(int page); - - // Signal handlers -#if !WITH_GTKMM_3_0 - bool _onExposePreview(GdkEventExpose *event); -#endif - - bool _onDraw(const Cairo::RefPtr& cr); - void _onPageNumberChanged(); - void _onToggleCropping(); - void _onPrecisionChanged(); - - class Gtk::Button * cancelbutton; - class Gtk::Button * okbutton; - class Gtk::Label * _labelSelect; - class Inkscape::UI::Widget::SpinButton * _pageNumberSpin; - class Gtk::Label * _labelTotalPages; - class Gtk::HBox * hbox2; - class Gtk::CheckButton * _cropCheck; - class Gtk::ComboBoxText * _cropTypeCombo; - class Gtk::HBox * hbox3; - class Gtk::VBox * vbox2; - class Inkscape::UI::Widget::Frame * _pageSettingsFrame; - class Gtk::Label * _labelPrecision; - class Gtk::Label * _labelPrecisionWarning; -#if WITH_GTKMM_3_0 - class Gtk::Scale * _fallbackPrecisionSlider; - Glib::RefPtr _fallbackPrecisionSlider_adj; -#else - class Gtk::HScale * _fallbackPrecisionSlider; - class Gtk::Adjustment *_fallbackPrecisionSlider_adj; -#endif - class Gtk::Label * _labelPrecisionComment; - class Gtk::HBox * hbox6; - class Gtk::Label * _labelText; - class Gtk::ComboBoxText * _textHandlingCombo; - class Gtk::HBox * hbox5; - class Gtk::CheckButton * _localFontsCheck; - class Gtk::CheckButton * _embedImagesCheck; - class Gtk::VBox * vbox3; - class Inkscape::UI::Widget::Frame * _importSettingsFrame; - class Gtk::VBox * vbox1; - class Gtk::DrawingArea * _previewArea; - class Gtk::HBox * hbox1; - - PopplerDocument *_poppler_doc; - // PopplerPage *_previewed_page; - int _current_page; // Current selected page - unsigned char *_thumb_data; // Thumbnail image data - int _thumb_width, _thumb_height; // Thumbnail size - int _thumb_rowstride; - int _preview_width, _preview_height; // Size of the preview area - bool _render_thumb; // Whether we can/shall render thumbnails - cairo_surface_t *_cairo_surface; // this cairo surface is used for preview -}; - - -class PdfInputCairo: public Inkscape::Extension::Implementation::Implementation { - PdfInputCairo () { }; -public: - SPDocument *open( Inkscape::Extension::Input *mod, - const gchar *uri ); - static void init( void ); - -}; - -} } } /* namespace Inkscape, Extension, Implementation */ - -#endif /* HAVE_POPPLER_CAIRO */ -#endif /* HAVE_POPPLER_GLIB */ - -#endif /* __EXTENSION_INTERNAL_PDFINPUTCAIRO_H__ */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index 3155ac098..63581bd8a 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -124,6 +124,9 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/) _labelPrecision = Gtk::manage(new class Gtk::Label(_("Precision of approximating gradient meshes:"))); _labelPrecisionWarning = Gtk::manage(new class Gtk::Label(_("Note: setting the precision too high may result in a large SVG file and slow performance."))); +#ifdef HAVE_POPPLER_CAIRO + _importviaPopplerCheck = Gtk::manage(new class Gtk::CheckButton(_("import via Poppler"))); +#endif #if WITH_GTKMM_3_0 _fallbackPrecisionSlider_adj = Gtk::Adjustment::create(2, 1, 256, 1, 10, 10); _fallbackPrecisionSlider = Gtk::manage(new class Gtk::Scale(_fallbackPrecisionSlider_adj)); @@ -199,6 +202,12 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/) _labelPrecisionWarning->set_line_wrap(true); _labelPrecisionWarning->set_use_markup(true); _labelPrecisionWarning->set_selectable(false); +#ifdef HAVE_POPPLER_CAIRO + _importviaPopplerCheck->set_can_focus(); + _importviaPopplerCheck->set_relief(Gtk::RELIEF_NORMAL); + _importviaPopplerCheck->set_mode(true); + _importviaPopplerCheck->set_active(false); +#endif _fallbackPrecisionSlider->set_size_request(180,-1); _fallbackPrecisionSlider->set_can_focus(); _fallbackPrecisionSlider->set_inverted(false); @@ -230,6 +239,9 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/) _embedImagesCheck->set_relief(Gtk::RELIEF_NORMAL); _embedImagesCheck->set_mode(true); _embedImagesCheck->set_active(true); +#ifdef HAVE_POPPLER_CAIRO + vbox3->pack_start(*_importviaPopplerCheck, Gtk::PACK_SHRINK, 0); +#endif vbox3->pack_start(*_labelPrecision, Gtk::PACK_SHRINK, 0); vbox3->pack_start(*hbox6, Gtk::PACK_SHRINK, 0); vbox3->pack_start(*_labelPrecisionWarning, Gtk::PACK_SHRINK, 0); @@ -274,6 +286,9 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/) _pageSettingsFrame->show(); _labelPrecision->show(); _labelPrecisionWarning->show(); +#ifdef HAVE_POPPLER_CAIRO + _importviaPopplerCheck->show(); +#endif _fallbackPrecisionSlider->show(); _labelPrecisionComment->show(); hbox6->show(); @@ -358,6 +373,14 @@ int PdfImportDialog::getSelectedPage() { return _current_page; } +int PdfImportDialog::getImportMethod() { +#ifdef HAVE_POPPLER_CAIRO + return (_importviaPopplerCheck->get_active()) ? 1 : 0; +#else + return 0; +#endif +} + /** * \brief Retrieves the current settings into a repr which SvgBuilder will use * for determining the behaviour desired by the user @@ -389,6 +412,13 @@ void PdfImportDialog::getImportSettings(Inkscape::XML::Node *prefs) { } else { prefs->setAttribute("embedImages", "0"); } +#ifdef HAVE_POPPLER_CAIRO + if (_importviaPopplerCheck->get_active()) { + prefs->setAttribute("importviapoppler", "1"); + } else { + prefs->setAttribute("importviapoppler", "0"); + } +#endif } /** @@ -595,6 +625,18 @@ PdfInput::wasCancelled () { return _cancelled; } +#ifdef HAVE_POPPLER_CAIRO +/// helper method +static cairo_status_t + _write_ustring_cb(void *closure, const unsigned char *data, unsigned int length) +{ + Glib::ustring* stream = static_cast(closure); + stream->append(reinterpret_cast(data), length); + + return CAIRO_STATUS_SUCCESS; +} +#endif + /** * Parses the selected page of the given PDF document using PdfParser. */ @@ -672,79 +714,146 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { page_num = 1; Catalog *catalog = pdf_doc->getCatalog(); Page *page = catalog->getPage(page_num); + + int is_importvia_poppler = 0; + if(dlg) + { +#ifdef HAVE_POPPLER_CAIRO + is_importvia_poppler = dlg->getImportMethod(); +#endif + } - SPDocument *doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); - bool saved = DocumentUndo::getUndoSensitive(doc); - DocumentUndo::setUndoSensitive(doc, false); // No need to undo in this temporary document + SPDocument *doc = NULL; + bool saved = false; + if(is_importvia_poppler == 0) + { + // native importer + doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); + saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); // No need to undo in this temporary document + + // Create builder + gchar *docname = g_path_get_basename(uri); + gchar *dot = g_strrstr(docname, "."); + if (dot) { + *dot = 0; + } + SvgBuilder *builder = new SvgBuilder(doc, docname, pdf_doc->getXRef()); + + // Get preferences + Inkscape::XML::Node *prefs = builder->getPreferences(); + if (dlg) + dlg->getImportSettings(prefs); + + printf("pdf import via %s.", (is_importvia_poppler != 0) ? "poppler" : "native"); + + // Apply crop settings + PDFRectangle *clipToBox = NULL; + double crop_setting; + sp_repr_get_double(prefs, "cropTo", &crop_setting); + if ( crop_setting >= 0.0 ) { // Do page clipping + int crop_choice = (int)crop_setting; + switch (crop_choice) { + case 0: // Media box + clipToBox = page->getMediaBox(); + break; + case 1: // Crop box + clipToBox = page->getCropBox(); + break; + case 2: // Bleed box + clipToBox = page->getBleedBox(); + break; + case 3: // Trim box + clipToBox = page->getTrimBox(); + break; + case 4: // Art box + clipToBox = page->getArtBox(); + break; + default: + break; + } + } - // Create builder - gchar *docname = g_path_get_basename(uri); - gchar *dot = g_strrstr(docname, "."); - if (dot) { - *dot = 0; - } - SvgBuilder *builder = new SvgBuilder(doc, docname, pdf_doc->getXRef()); + // Create parser + PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(), + page->getResourceDict(), page->getCropBox(), clipToBox); - // Get preferences - Inkscape::XML::Node *prefs = builder->getPreferences(); - if (dlg) - dlg->getImportSettings(prefs); - - // Apply crop settings - PDFRectangle *clipToBox = NULL; - double crop_setting; - sp_repr_get_double(prefs, "cropTo", &crop_setting); - if ( crop_setting >= 0.0 ) { // Do page clipping - int crop_choice = (int)crop_setting; - switch (crop_choice) { - case 0: // Media box - clipToBox = page->getMediaBox(); - break; - case 1: // Crop box - clipToBox = page->getCropBox(); - break; - case 2: // Bleed box - clipToBox = page->getBleedBox(); - break; - case 3: // Trim box - clipToBox = page->getTrimBox(); - break; - case 4: // Art box - clipToBox = page->getArtBox(); - break; - default: - break; + // Set up approximation precision for parser + double color_delta; + sp_repr_get_double(prefs, "approximationPrecision", &color_delta); + if ( color_delta <= 0.0 ) { + color_delta = 1.0 / 2.0; + } else { + color_delta = 1.0 / color_delta; + } + for ( int i = 1 ; i <= pdfNumShadingTypes ; i++ ) { + pdf_parser->setApproximationPrecision(i, color_delta, 6); } - } - // Create parser - PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(), - page->getResourceDict(), page->getCropBox(), clipToBox); + // Parse the document structure + Object obj; + page->getContents(&obj); + if (!obj.isNull()) { + pdf_parser->parse(&obj); + } - // Set up approximation precision for parser - double color_delta; - sp_repr_get_double(prefs, "approximationPrecision", &color_delta); - if ( color_delta <= 0.0 ) { - color_delta = 1.0 / 2.0; - } else { - color_delta = 1.0 / color_delta; - } - for ( int i = 1 ; i <= pdfNumShadingTypes ; i++ ) { - pdf_parser->setApproximationPrecision(i, color_delta, 6); + // Cleanup + obj.free(); + delete pdf_parser; + delete builder; + g_free(docname); } + else + { +#ifdef HAVE_POPPLER_CAIRO + // the poppler import + gchar* filename_uri = g_filename_to_uri(uri, NULL, NULL); + GError *error = NULL; + /// @todo handle passwort + /// @todo check if win32 unicode needs special attention + PopplerDocument* document = poppler_document_new_from_file(filename_uri, NULL, &error); + + if(error != NULL) { + g_error_free (error); + } - // Parse the document structure - Object obj; - page->getContents(&obj); - if (!obj.isNull()) { - pdf_parser->parse(&obj); + if (document != NULL) + { + double width, height; + PopplerPage* page = poppler_document_get_page(document, page_num - 1); + poppler_page_get_size(page, &width, &height); + + Glib::ustring output; + cairo_surface_t* surface = cairo_svg_surface_create_for_stream(Inkscape::Extension::Internal::_write_ustring_cb, + &output, width, height); + cairo_t* cr = cairo_create(surface); + + poppler_page_render_for_printing(page, cr); + cairo_show_page(cr); + + cairo_destroy(cr); + cairo_surface_destroy(surface); + + doc = SPDocument::createNewDocFromMem(output.c_str(), output.length(), TRUE); + + // Cleanup + // delete output; + g_object_unref(G_OBJECT(page)); + g_object_unref(G_OBJECT(document)); + } + else + { + doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); // fallback create empthy document + } + saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); // No need to undo in this temporary document + + // Cleanup + g_free(filename_uri); +#endif } // Cleanup - obj.free(); - delete pdf_parser; - delete builder; - g_free(docname); delete pdf_doc; delete dlg; diff --git a/src/extension/internal/pdfinput/pdf-input.h b/src/extension/internal/pdfinput/pdf-input.h index f22a783ff..d57c3e993 100644 --- a/src/extension/internal/pdfinput/pdf-input.h +++ b/src/extension/internal/pdfinput/pdf-input.h @@ -75,6 +75,7 @@ public: bool showDialog(); int getSelectedPage(); + int getImportMethod(); void getImportSettings(Inkscape::XML::Node *prefs); private: @@ -103,6 +104,9 @@ private: class Inkscape::UI::Widget::Frame * _pageSettingsFrame; class Gtk::Label * _labelPrecision; class Gtk::Label * _labelPrecisionWarning; +#ifdef HAVE_POPPLER_CAIRO + class Gtk::CheckButton * _importviaPopplerCheck; // using poppler_cairo for importing +#endif #if WITH_GTKMM_3_0 class Gtk::Scale * _fallbackPrecisionSlider; Glib::RefPtr _fallbackPrecisionSlider_adj; -- cgit v1.2.3 From cb625f9576e23e2232aafc93e5b1582336624425 Mon Sep 17 00:00:00 2001 From: Adib Taraben Date: Sat, 7 Jun 2014 00:08:03 +0200 Subject: revise email theadib (bzr r13410) --- src/extension/internal/cairo-ps-out.cpp | 2 +- src/extension/internal/cairo-ps-out.h | 2 +- src/ui/dialog/aboutbox.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cairo-ps-out.cpp b/src/extension/internal/cairo-ps-out.cpp index 055a30add..4defc2ab9 100644 --- a/src/extension/internal/cairo-ps-out.cpp +++ b/src/extension/internal/cairo-ps-out.cpp @@ -5,7 +5,7 @@ * Authors: * Ted Gould * Ulf Erikson - * Adib Taraben + * Adib Taraben * Jon A. Cruz * Abhishek Sharma * diff --git a/src/extension/internal/cairo-ps-out.h b/src/extension/internal/cairo-ps-out.h index 7eda3c510..b438b55b4 100644 --- a/src/extension/internal/cairo-ps-out.h +++ b/src/extension/internal/cairo-ps-out.h @@ -5,7 +5,7 @@ * Authors: * Ted Gould * Ulf Erikson - * Adib Taraben + * Adib Taraben * Abhishek Sharma * * Copyright (C) 2004-2006 Authors diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 121773b6d..a66855b2a 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -442,7 +442,7 @@ void AboutBox::initStrings() { */ gchar const *allTranslators = "3ARRANO.com <3arrano@3arrano.com>, 2005.\n" -"Adib Taraben , 2004.\n" +"Adib Taraben , 2004.\n" "Alan Monfort , 2009-2010.\n" "Alastair McKinstry , 2000.\n" "Aleksandar Urošević , 2004-2006.\n" -- cgit v1.2.3 From 48ddc5ea8c9ee44c7ae388d43f9be9552acf64ae Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 6 Jun 2014 21:19:18 -0400 Subject: Undo changes in r13391 (bzr r13341.1.51) --- src/livarot/Path.h | 12 +++++------ src/livarot/PathConversion.cpp | 3 +-- src/livarot/PathCutting.cpp | 7 +++--- src/livarot/PathOutline.cpp | 9 +++----- src/livarot/PathStroke.cpp | 3 +-- src/sp-flowregion.cpp | 3 +-- src/sp-offset.cpp | 22 +++++++++---------- src/splivarot.cpp | 48 +++++++++++++++++++++--------------------- src/ui/tools/flood-tool.cpp | 2 +- src/ui/tools/pencil-tool.cpp | 5 +++-- src/ui/tools/tweak-tool.cpp | 2 +- 11 files changed, 55 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/livarot/Path.h b/src/livarot/Path.h index 5d5a24e5a..32ee71ffc 100644 --- a/src/livarot/Path.h +++ b/src/livarot/Path.h @@ -135,26 +135,26 @@ public: // closeIfNeeded=false prevent the function from closing the path (resulting in a non-eulerian graph // pathID is a identification number for the path, and is used for recomposing curves from polylines // give each different Path a different ID, and feed the appropriate orig[] to the ConvertToForme() function - void Fill(Shape &dest, int pathID = -1, bool justAdd = false, + void Fill(Shape *dest, int pathID = -1, bool justAdd = false, bool closeIfNeeded = true, bool invert = false); // - stroke the path; usual parameters: type of cap=butt, type of join=join and miter (see LivarotDefs.h) // doClose treat the path as closed (ie a loop) - void Stroke(Shape &dest, bool doClose, double width, JoinType join, + void Stroke(Shape *dest, bool doClose, double width, JoinType join, ButtType butt, double miter, bool justAdd = false); // build a Path that is the outline of the Path instance's description (the result is stored in dest) // it doesn't compute the exact offset (it's way too complicated, but an approximation made of cubic bezier patches // and segments. the algorithm was found in a plugin for Impress (by Chris Cox), but i can't find it back... - void Outline(Path &dest, double width, JoinType join, ButtType butt, + void Outline(Path *dest, double width, JoinType join, ButtType butt, double miter); // half outline with edges having the same direction as the original - void OutsideOutline(Path &dest, double width, JoinType join, ButtType butt, + void OutsideOutline(Path *dest, double width, JoinType join, ButtType butt, double miter); // half outline with edges having the opposite direction as the original - void InsideOutline (Path & dest, double width, JoinType join, ButtType butt, + void InsideOutline (Path * dest, double width, JoinType join, ButtType butt, double miter); // polyline to cubic bezier patches @@ -184,7 +184,7 @@ public: void LoadPath(Geom::Path const &path, Geom::Affine const &tr, bool doTransformation, bool append = false); void LoadPathVector(Geom::PathVector const &pv, Geom::Affine const &tr, bool doTransformation); void LoadPathVector(Geom::PathVector const &pv); - Geom::PathVector MakePathVector(); + Geom::PathVector* MakePathVector(); void Transform(const Geom::Affine &trans); diff --git a/src/livarot/PathConversion.cpp b/src/livarot/PathConversion.cpp index 0ef88841a..42df898e6 100644 --- a/src/livarot/PathConversion.cpp +++ b/src/livarot/PathConversion.cpp @@ -1269,9 +1269,8 @@ void Path::RecBezierTo(Geom::Point const &iP, Geom::Point const &iS,Geom::Point * in a path description ( you need to have prepared the back data for that, of course) */ -void Path::Fill(Shape& destr, int pathID, bool justAdd, bool closeIfNeeded, bool invert) +void Path::Fill(Shape* dest, int pathID, bool justAdd, bool closeIfNeeded, bool invert) { - Shape* dest = &destr; if ( dest == NULL ) { return; } diff --git a/src/livarot/PathCutting.cpp b/src/livarot/PathCutting.cpp index 74653ca06..49b2c5a78 100644 --- a/src/livarot/PathCutting.cpp +++ b/src/livarot/PathCutting.cpp @@ -269,11 +269,10 @@ void Path::DashSubPath(int spL, int spP, std::vector const &orig_pt } } -Geom::PathVector +Geom::PathVector * Path::MakePathVector() { - Geom::PathVector retPv; - Geom::PathVector *pv = &retPv; + Geom::PathVector *pv = new Geom::PathVector(); Geom::Path * currentpath = NULL; Geom::Point lastP,bezSt,bezEn; @@ -381,7 +380,7 @@ Path::MakePathVector() } } - return *pv; + return pv; } void Path::AddCurve(Geom::Curve const &c) diff --git a/src/livarot/PathOutline.cpp b/src/livarot/PathOutline.cpp index f1978931a..211ee31e2 100644 --- a/src/livarot/PathOutline.cpp +++ b/src/livarot/PathOutline.cpp @@ -21,9 +21,8 @@ // outline of a path. // computed by making 2 offsets, one of the "left" side of the path, one of the right side, and then glueing the two // the left side has to be reversed to make a contour -void Path::Outline(Path &destr, double width, JoinType join, ButtType butt, double miter) +void Path::Outline(Path *dest, double width, JoinType join, ButtType butt, double miter) { - ::Path * dest = &destr; if ( descr_flags & descr_adding_bezier ) { CancelBezier(); } @@ -199,10 +198,9 @@ void Path::Outline(Path &destr, double width, JoinType join, ButtType butt, doub // versions for outlining closed path: they only make one side of the offset contour void -Path::OutsideOutline (Path & destr, double width, JoinType join, ButtType butt, +Path::OutsideOutline (Path * dest, double width, JoinType join, ButtType butt, double miter) { - ::Path * dest = &destr; if (descr_flags & descr_adding_bezier) { CancelBezier(); } @@ -225,10 +223,9 @@ Path::OutsideOutline (Path & destr, double width, JoinType join, ButtType butt, } void -Path::InsideOutline (Path & destr, double width, JoinType join, ButtType butt, +Path::InsideOutline (Path * dest, double width, JoinType join, ButtType butt, double miter) { - ::Path * dest = &destr; if ( descr_flags & descr_adding_bezier ) { CancelBezier(); } diff --git a/src/livarot/PathStroke.cpp b/src/livarot/PathStroke.cpp index 07ecc8114..50c335176 100644 --- a/src/livarot/PathStroke.cpp +++ b/src/livarot/PathStroke.cpp @@ -38,10 +38,9 @@ static Geom::Point StrokeNormalize(const Geom::Point value, double length) { } } -void Path::Stroke(Shape &destr, bool doClose, double width, JoinType join, +void Path::Stroke(Shape *dest, bool doClose, double width, JoinType join, ButtType butt, double miter, bool justAdd) { - ::Shape* dest = &destr; if (dest == NULL) { return; } diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 37170c9e6..709e9e464 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -1,5 +1,4 @@ /* - * TODO: clean this up */ #ifdef HAVE_CONFIG_H @@ -383,7 +382,7 @@ static void GetDest(SPObject* child,Shape **computed) temp->LoadPathVector(curve->get_pathvector(), tr_mat, true); Shape* n_shp=new Shape; temp->Convert(0.25); - temp->Fill(*n_shp,0); + temp->Fill(n_shp,0); Shape* uncross=new Shape; SPStyle* style = u_child->style; if ( style && style->fill_rule.computed == SP_WIND_RULE_EVENODD ) { diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index 26eb64c94..c6a4b730d 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -406,12 +406,12 @@ void SPOffset::set_shape() { if (this->rad >= 0) { o_width = this->rad; - orig->OutsideOutline (*res, o_width, join_round, butt_straight, 20.0); + orig->OutsideOutline (res, o_width, join_round, butt_straight, 20.0); } else { o_width = -this->rad; - orig->OutsideOutline (*res, -o_width, join_round, butt_straight, 20.0); + orig->OutsideOutline (res, -o_width, join_round, butt_straight, 20.0); } if (o_width >= 1.0) @@ -424,7 +424,7 @@ void SPOffset::set_shape() { // res->ConvertForOffset (o_width, orig, offset->rad); res->ConvertWithBackData (o_width); } - res->Fill (*theShape, 0); + res->Fill (theShape, 0); theRes->ConvertToShape (theShape, fill_positive); originaux[0] = res; @@ -489,7 +489,7 @@ void SPOffset::set_shape() { orig->ConvertWithBackData (0.5*o_width); } - orig->Fill (*theShape, 0); + orig->Fill (theShape, 0); theRes->ConvertToShape (theShape, fill_positive); Path *originaux[1]; @@ -527,7 +527,7 @@ void SPOffset::set_shape() { if ( partSurf < 0 ) { // inverse par rapport a la realite // plein holes[i]=0; - parts[i]->Fill(*oneCleanPart, 0); + parts[i]->Fill(oneCleanPart,0); onePart->ConvertToShape(oneCleanPart,fill_positive); // there aren't intersections in that one, but maybe duplicate points and null edges oneCleanPart->MakeOffset(onePart,this->rad,join_round,20.0); onePart->ConvertToShape(oneCleanPart,fill_positive); @@ -564,7 +564,7 @@ void SPOffset::set_shape() { } else { // trou holes[i]=1; - parts[i]->Fill(*oneCleanPart, 0, false, true, true); + parts[i]->Fill(oneCleanPart,0,false,true,true); onePart->ConvertToShape(oneCleanPart,fill_positive); oneCleanPart->MakeOffset(onePart,-this->rad,join_round,20.0); onePart->ConvertToShape(oneCleanPart,fill_positive); @@ -614,9 +614,9 @@ void SPOffset::set_shape() { parts[i]->ConvertWithBackData(1.0); if ( holes[i] ) { - parts[i]->Fill(*theShape,i,true,true,true); + parts[i]->Fill(theShape,i,true,true,true); } else { - parts[i]->Fill(*theShape,i,true,true,false); + parts[i]->Fill(theShape,i,true,true,false); } } } @@ -808,7 +808,7 @@ sp_offset_distance_to_original (SPOffset * offset, Geom::Point px) */ // move ((Path *) offset->originalPath)->Convert (1.0); - ((Path *) offset->originalPath)->Fill (*theShape, 0); + ((Path *) offset->originalPath)->Fill (theShape, 0); theRes->ConvertToShape (theShape, fill_oddEven); if (theRes->numberOfEdges() <= 1) @@ -987,7 +987,7 @@ sp_offset_top_point (SPOffset const * offset, Geom::Point *px) Shape *theShape = new Shape; finalPath->Convert (1.0); - finalPath->Fill (*theShape, 0); + finalPath->Fill (theShape, 0); if (theShape->hasPoints()) { @@ -1174,7 +1174,7 @@ refresh_offset_source(SPOffset* offset) Shape *theRes = new Shape; orig->ConvertWithBackData (1.0); - orig->Fill (*theShape, 0); + orig->Fill (theShape, 0); css = sp_repr_css_attr (offset->sourceRepr , "style"); val = sp_repr_css_property (css, "fill-rule", NULL); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index c8682e6b4..8bb2a7150 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -156,13 +156,13 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat // get the polygons of each path, with the winding rule specified, and apply the operation iteratively originaux[0]->ConvertWithBackData(0.1); - originaux[0]->Fill(*theShape, 0); + originaux[0]->Fill(theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); originaux[1]->ConvertWithBackData(0.1); - originaux[1]->Fill(*theShape, 1); + originaux[1]->Fill(theShape, 1); theShapeB->ConvertToShape(theShape, origWind[1]); @@ -191,13 +191,13 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(*theShape, 0); + originaux[0]->Fill(theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); originaux[1]->ConvertWithBackData(1.0); - originaux[1]->Fill(*theShape, 1,false,false,false); //do not closeIfNeeded + originaux[1]->Fill(theShape, 1,false,false,false); //do not closeIfNeeded theShapeB->ConvertToShape(theShape, fill_justDont); // fill_justDont doesn't computes winding numbers @@ -218,11 +218,11 @@ sp_pathvector_boolop(Geom::PathVector const &pathva, Geom::PathVector const &pat } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(*theShapeA, 0,false,false,false); // don't closeIfNeeded + originaux[0]->Fill(theShapeA, 0,false,false,false); // don't closeIfNeeded originaux[1]->ConvertWithBackData(1.0); - originaux[1]->Fill(*theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it + originaux[1]->Fill(theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it theShape->ConvertToShape(theShapeA, fill_justDont); @@ -467,7 +467,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool // get the polygons of each path, with the winding rule specified, and apply the operation iteratively originaux[0]->ConvertWithBackData(0.1); - originaux[0]->Fill(*theShape, 0); + originaux[0]->Fill(theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); @@ -475,7 +475,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool for (GSList *l = il->next; l != NULL; l = l->next) { originaux[curOrig]->ConvertWithBackData(0.1); - originaux[curOrig]->Fill(*theShape, curOrig); + originaux[curOrig]->Fill(theShape, curOrig); theShapeB->ConvertToShape(theShape, origWind[curOrig]); @@ -549,16 +549,16 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(*theShape, 0); + originaux[0]->Fill(theShape, 0); theShapeA->ConvertToShape(theShape, origWind[0]); originaux[1]->ConvertWithBackData(1.0); if ((originaux[1]->pts.size() == 2) && originaux[1]->pts[0].isMoveTo && !originaux[1]->pts[1].isMoveTo) - originaux[1]->Fill(*theShape, 1,false,true,false); // see LP Bug 177956 + originaux[1]->Fill(theShape, 1,false,true,false); // see LP Bug 177956 else - originaux[1]->Fill(*theShape, 1,false,false,false); //do not closeIfNeeded + originaux[1]->Fill(theShape, 1,false,false,false); //do not closeIfNeeded theShapeB->ConvertToShape(theShape, fill_justDont); // fill_justDont doesn't computes winding numbers @@ -579,11 +579,11 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool } originaux[0]->ConvertWithBackData(1.0); - originaux[0]->Fill(*theShapeA, 0,false,false,false); // don't closeIfNeeded + originaux[0]->Fill(theShapeA, 0,false,false,false); // don't closeIfNeeded originaux[1]->ConvertWithBackData(1.0); - originaux[1]->Fill(*theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it + originaux[1]->Fill(theShapeA, 1,true,false,false);// don't closeIfNeeded and just dump in the shape, don't reset it theShape->ConvertToShape(theShapeA, fill_justDont); @@ -1014,9 +1014,9 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) orig->DashPolylineFromStyle(i_style, scale, 0); Shape* theShape = new Shape; - orig->Stroke(*theShape, false, 0.5*o_width, o_join, o_butt, + orig->Stroke(theShape, false, 0.5*o_width, o_join, o_butt, 0.5 * o_miter); - orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); if (!bbox_only) { Shape *theRes = new Shape; @@ -1030,7 +1030,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) } delete theShape; } else { - orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); if (!bbox_only) { orig->Coalesce(0.5 * o_width); @@ -1038,7 +1038,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) Shape *theRes = new Shape; res->ConvertWithBackData(1.0); - res->Fill(*theShape, 0); + res->Fill(theShape, 0); theRes->ConvertToShape(theShape, fill_positive); Path *originaux[1]; @@ -1060,7 +1060,7 @@ Geom::PathVector* item_outline(SPItem const *item, bool bbox_only) if (res->descr_cmd.size() > 1) { // if there's 0 or 1 node left, drop this path altogether - ret_pathv = new Geom::PathVector(bbox_only ? (res->MakePathVector()) : (orig->MakePathVector())); + ret_pathv = bbox_only ? res->MakePathVector() : orig->MakePathVector(); if (SP_IS_SHAPE(item) && SP_SHAPE(item)->hasMarkers() && !bbox_only) { SPShape *shape = SP_SHAPE(item); @@ -1283,9 +1283,9 @@ sp_selected_path_outline(SPDesktop *desktop) orig->DashPolylineFromStyle(i_style, scale, 0); Shape* theShape = new Shape; - orig->Stroke(*theShape, false, 0.5*o_width, o_join, o_butt, + orig->Stroke(theShape, false, 0.5*o_width, o_join, o_butt, 0.5 * o_miter); - orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); Shape *theRes = new Shape; @@ -1302,7 +1302,7 @@ sp_selected_path_outline(SPDesktop *desktop) } else { - orig->Outline(*res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); + orig->Outline(res, 0.5 * o_width, o_join, o_butt, 0.5 * o_miter); orig->Coalesce(0.5 * o_width); @@ -1310,7 +1310,7 @@ sp_selected_path_outline(SPDesktop *desktop) Shape *theRes = new Shape; res->ConvertWithBackData(1.0); - res->Fill(*theShape, 0); + res->Fill(theShape, 0); theRes->ConvertToShape(theShape, fill_positive); Path *originaux[1]; @@ -1644,7 +1644,7 @@ void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool Shape *theRes = new Shape; orig->ConvertWithBackData(1.0); - orig->Fill(*theShape, 0); + orig->Fill(theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); @@ -1843,7 +1843,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) Shape *theRes = new Shape; orig->ConvertWithBackData(0.03); - orig->Fill(*theShape, 0); + orig->Fill(theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 15bc7164c..d74848dc6 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -408,7 +408,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto Shape *path_shape = new Shape(); path->ConvertWithBackData(0.03); - path->Fill(*path_shape, 0); + path->Fill(path_shape, 0); delete path; Shape *expanded_path_shape = new Shape(); diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 48f8c3a28..0e8660248 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -760,8 +760,9 @@ void PencilTool::_sketchInterpolate() { path.LoadPathVector(Geom::path_from_piecewise(this->sketch_interpolation, 0.01)); path.Simplify(0.5); - Geom::PathVector pathv = path.MakePathVector(); - this->sketch_interpolation = pathv[0].toPwSb(); + Geom::PathVector *pathv = path.MakePathVector(); + this->sketch_interpolation = (*pathv)[0].toPwSb(); + delete pathv; } else { this->sketch_interpolation = fit_pwd2; } diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index bc1519773..75650d3af 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -551,7 +551,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P Geom::Affine i2doc(item->i2doc_affine()); orig->ConvertWithBackData((0.08 - (0.07 * fidelity)) / i2doc.descrim()); // default 0.059 - orig->Fill(*theShape, 0); + orig->Fill(theShape, 0); SPCSSAttr *css = sp_repr_css_attr(item->getRepr(), "style"); gchar const *val = sp_repr_css_property(css, "fill-rule", NULL); -- cgit v1.2.3 From 5b67a95f4477d1a69e9a0f100d71a77277d86ef2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 7 Jun 2014 13:15:07 +0200 Subject: Fix for Bug #1241902 - (bzr r13341.1.52) --- src/box3d-side.cpp | 2 + src/selection-chemistry.cpp | 4 ++ src/sp-ellipse.cpp | 2 + src/sp-item-group.cpp | 36 ++++++++--- src/sp-item-group.h | 2 +- src/sp-lpe-item.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++ src/sp-lpe-item.h | 2 + src/sp-path.cpp | 2 + src/sp-spiral.cpp | 2 + src/sp-star.cpp | 2 + 10 files changed, 192 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index dfccb63bf..a5e7eaa94 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -213,6 +213,8 @@ void Box3DSide::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 868a9d743..a350dd7a7 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3950,6 +3950,10 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = SP_OBJECT(child)->getRepr()->duplicate(xml_doc); + if(copy->attribute("inkscape:original-d")) + { + copy->setAttribute("d", copy->attribute("inkscape:original-d")); + } items_to_move = g_slist_prepend(items_to_move, copy); } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index cda59e057..428e0e3dd 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -467,6 +467,8 @@ void SPGenericEllipse::set_shape() bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 2cfe97db8..b3db0c1d7 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -778,17 +778,31 @@ void SPGroup::update_patheffect(bool write) { } } + +void +sp_gslist_update_by_clip_or_mask(GSList *item_list,SPItem * item) +{ + if(item->mask_ref->getObject()) { + SPObject * clipormask = item->mask_ref->getObject()->firstChild(); + item_list = g_slist_append(item_list,clipormask); + } + if(item->clip_ref->getObject()) { + SPObject * clipormask = item->clip_ref->getObject()->firstChild(); + item_list = g_slist_append(item_list,clipormask); + } +} + static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) { - GSList const *item_list = sp_item_group_item_list(SP_GROUP(group)); - - for ( GSList const *iter = item_list; iter; iter = iter->next ) { + GSList *item_list = sp_item_group_item_list(group); + sp_gslist_update_by_clip_or_mask(item_list,group); + for ( GSList *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast(iter->data); - if (SP_IS_GROUP(subitem)) { sp_group_perform_patheffect(SP_GROUP(subitem), topgroup, write); } else if (SP_IS_SHAPE(subitem)) { + sp_gslist_update_by_clip_or_mask(item_list,SP_ITEM(subitem)); SPCurve * c = NULL; if (SP_IS_PATH(subitem)) { @@ -799,9 +813,17 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) // only run LPEs when the shape has a curve defined if (c) { - c->transform(i2anc_affine(subitem, topgroup)); + if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { + c->transform(i2anc_affine(group, topgroup)); + } else { + c->transform(i2anc_affine(subitem, topgroup)); + } SP_LPE_ITEM(topgroup)->performPathEffect(c); - c->transform(i2anc_affine(subitem, topgroup).inverse()); + if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { + c->transform(i2anc_affine(group, topgroup).inverse()); + } else { + c->transform(i2anc_affine(subitem, topgroup).inverse()); + } SP_SHAPE(subitem)->setCurve(c, TRUE); if (write) { @@ -809,7 +831,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE -g_message("sp_group_perform_patheffect writes 'd' attribute"); + g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif g_free(str); } diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 2004a72b8..adec35571 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -88,7 +88,7 @@ public: void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true); - +void sp_gslist_update_by_clip_or_mask(GSList *item_list, SPItem * item); GSList *sp_item_group_item_list (SPGroup *group); SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 762dc3191..5818054a7 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -38,6 +38,11 @@ #include "desktop.h" #include "shape-editor.h" #include "sp-ellipse.h" +#include "display/curve.h" +#include "svg/svg.h" +#include <2geom/pathvector.h> +#include "sp-clippath.h" +#include "sp-mask.h" #include "tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/tools/tool-base.h" @@ -51,6 +56,8 @@ static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeit static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem); +static void sp_lpe_item_apply_to_clip_or_mask_group(SPGroup * group, SPItem * item); + typedef std::list HRefList; static std::string patheffectlist_write_svg(PathEffectList const & list); static std::string hreflist_write_svg(HRefList const & list); @@ -332,6 +339,16 @@ lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem) static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) + { + sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); + if(clipPath) + { + sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + } if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { @@ -352,6 +369,17 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) { + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); + if(clipPath) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + } + if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { @@ -597,6 +625,124 @@ bool SPLPEItem::hasPathEffectRecursive() const } } +void +sp_lpe_item_apply_to_clippath(SPItem * item) +{ + SPClipPath *clipPath = item->clip_ref->getObject(); + if(clipPath) { + SPObject * clip_data = clipPath->firstChild(); + SPCurve * clip_curve = NULL; + + if (SP_IS_PATH(clip_data)) { + clip_curve = SP_PATH(clip_data)->get_original_curve(); + } else if(SP_IS_SHAPE(clip_data)) { + clip_curve = SP_SHAPE(clip_data)->getCurve(); + } else if(SP_IS_GROUP(clip_data)) { + sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(clip_data), item); + return; + } + if(clip_curve) { + bool success = SP_LPE_ITEM(item)->performPathEffect(clip_curve); + Inkscape::XML::Node *reprClip = clip_data->getRepr(); + if (success) { + gchar *str = sp_svg_write_path(clip_curve->get_pathvector()); + reprClip->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = reprClip->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + SP_SHAPE(clip_data)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + clip_curve->unref(); + } + } +} + +void +sp_lpe_item_apply_to_mask(SPItem * item) +{ + SPMask *mask = item->mask_ref->getObject(); + if(mask) { + SPObject * mask_data = mask->firstChild(); + SPCurve * mask_curve = NULL; + mask_data = mask->firstChild(); + if (SP_IS_PATH(mask_data)) { + mask_curve = SP_PATH(mask_data)->get_original_curve(); + } else if(SP_IS_SHAPE(mask_data)) { + mask_curve = SP_SHAPE(mask_data)->getCurve(); + } else if(SP_IS_GROUP(mask_data)) { + sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(mask_data), item); + return; + } + if(mask_curve) { + bool success = SP_LPE_ITEM(item)->performPathEffect(mask_curve); + Inkscape::XML::Node *reprmask = mask_data->getRepr(); + if (success) { + gchar *str = sp_svg_write_path(mask_curve->get_pathvector()); + reprmask->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = reprmask->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + SP_SHAPE(mask_data)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + mask_curve->unref(); + } + } +} + +static void +sp_lpe_item_apply_to_clip_or_mask_group(SPGroup *group, SPItem *item) +{ + GSList *item_list = sp_item_group_item_list(group); + for ( GSList *iter = item_list; iter; iter = iter->next ) { + SPObject *subitem = static_cast(iter->data); + if (SP_IS_GROUP(subitem)) { + sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(subitem), item); + } else if (SP_IS_SHAPE(subitem)) { + SPCurve * c = NULL; + + if (SP_IS_PATH(subitem)) { + c = SP_PATH(subitem)->get_original_curve(); + } else { + c = SP_SHAPE(subitem)->getCurve(); + } + if (c) { + bool success = SP_LPE_ITEM(item)->performPathEffect(c); + Inkscape::XML::Node *repr = subitem->getRepr(); + if (success) { + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + SP_SHAPE(subitem)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + c->unref(); + } + } + } +} + Inkscape::LivePathEffect::Effect* SPLPEItem::getPathEffectOfType(int type) { diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 85878a95b..3e858748d 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -98,6 +98,8 @@ public: void editNextParamOncanvas(SPDesktop *dt); }; +void sp_lpe_item_apply_to_mask(SPItem * item); +void sp_lpe_item_apply_to_clippath(SPItem * item); void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); // careful, class already has method with *very* similar name! #endif /* !SP_LPE_ITEM_H_SEEN */ diff --git a/src/sp-path.cpp b/src/sp-path.cpp index d1fb850e1..9d88ec732 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -325,6 +325,8 @@ g_message("sp_path_update_patheffect"); bool success = this->performPathEffect(curve); if (success && write) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 9ef73d56d..8d4a37bf0 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -385,6 +385,8 @@ void SPSpiral::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index eac33ed7b..170a863b5 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -465,6 +465,8 @@ void SPStar::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } -- cgit v1.2.3 From 1f7ddda8ce2f2110aa3a172c6fc4222d50846eab Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 8 Jun 2014 17:23:53 +0200 Subject: Better ordering of font-face styles in UI. Rely on CSS values rather than guessing. (bzr r13413) --- src/libnrtype/FontFactory.cpp | 234 +++--------------------------------------- 1 file changed, 17 insertions(+), 217 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 4ae408397..6ab8c77b8 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -54,226 +54,11 @@ bool font_descr_equal::operator()( PangoFontDescription *const&a, PangoFontDesc /////////////////// helper functions -/** - * A wrapper for strcasestr that also provides an implementation for Win32. - */ -static bool -ink_strstr(char const *haystack, char const *pneedle) -{ - // windows has no strcasestr implementation, so here is ours... - // stolen from nmap - /* FIXME: This is broken for e.g. ink_strstr("aab", "ab"). Report to nmap. - * - * Also, suggest use of g_ascii_todown instead of buffer stuff, and g_ascii_tolower instead - * of tolower. Given that haystack is a font name (i.e. fairly short), it should be ok to - * do g_ascii_strdown on both haystack and pneedle, and do normal strstr. - * - * Rather than fixing in inkscape, consider getting rid of this routine, instead using - * strdown and plain strstr at caller. We have control over the needle values, so we can - * modify the callers rather than calling strdown there. - */ - char buf[512]; - register char const *p; - char *needle, *q, *foundto; - if (!*pneedle) return true; - if (!haystack) return false; - - needle = buf; - p = pneedle; q = needle; - while ((*q++ = tolower(*p++))) - ; - p = haystack - 1; foundto = needle; - while (*++p) { - if (tolower(*p) == *foundto) { - if (!*++foundto) { - /* Yeah, we found it */ - return true; - } - } else foundto = needle; - } - return false; -} - -/** - * Regular fonts are 'Regular', 'Roman', 'Normal', or 'Plain' - */ -// FIXME: make this UTF8, add non-English style names -static bool -is_regular(char const *s) -{ - if (ink_strstr(s, "Regular")) return true; - if (ink_strstr(s, "Roman")) return true; - if (ink_strstr(s, "Normal")) return true; - if (ink_strstr(s, "Plain")) return true; - return false; -} - -/** - * Non-bold fonts are 'Medium' or 'Book' - */ -static bool -is_nonbold(char const *s) -{ - if (ink_strstr(s, "Medium")) return true; - if (ink_strstr(s, "Book")) return true; - return false; -} - -/** - * Italic fonts are 'Italic', 'Oblique', or 'Slanted' - */ -static bool -is_italic(char const *s) -{ - if (ink_strstr(s, "Italic")) return true; - if (ink_strstr(s, "Oblique")) return true; - if (ink_strstr(s, "Slanted")) return true; - return false; -} - -/** - * Bold fonts are 'Bold' - */ -static bool -is_bold(char const *s) -{ - if (ink_strstr(s, "Bold")) return true; - return false; -} - -/** - * Caps fonts are 'Caps' - */ -static bool -is_caps(char const *s) -{ - if (ink_strstr(s, "Caps")) return true; - return false; -} - -#if 0 /* FIXME: These are all unused. Please delete them or use them (presumably in -* style_name_compare). */ -/** - * Monospaced fonts are 'Mono' - */ -static bool -is_mono(char const *s) -{ - if (ink_strstr(s, "Mono")) return true; - return false; -} - -/** - * Rounded fonts are 'Round' - */ -static bool -is_round(char const *s) -{ - if (ink_strstr(s, "Round")) return true; - return false; -} - -/** - * Outline fonts are 'Outline' - */ -static bool -is_outline(char const *s) -{ - if (ink_strstr(s, "Outline")) return true; - return false; -} - -/** - * Swash fonts are 'Swash' - */ -static bool -is_swash(char const *s) -{ - if (ink_strstr(s, "Swash")) return true; - return false; -} -#endif - -/** - * Determines if two style names match. This allows us to match - * based on the type of style rather than simply doing string matching, - * because for instance 'Plain' and 'Normal' mean the same thing. - * - * Q: Shouldn't this include the other tests such as is_outline, etc.? - * Q: Is there a problem with strcasecmp on Win32? Should it use stricmp? - */ -int -style_name_compare(char const *aa, char const *bb) -{ - char const *a = (char const *) aa; - char const *b = (char const *) bb; - - if (is_regular(a) && !is_regular(b)) return -1; - if (is_regular(b) && !is_regular(a)) return 1; - - if (is_bold(a) && !is_bold(b)) return 1; - if (is_bold(b) && !is_bold(a)) return -1; - - if (is_italic(a) && !is_italic(b)) return 1; - if (is_italic(b) && !is_italic(a)) return -1; - - if (is_nonbold(a) && !is_nonbold(b)) return 1; - if (is_nonbold(b) && !is_nonbold(a)) return -1; - - if (is_caps(a) && !is_caps(b)) return 1; - if (is_caps(b) && !is_caps(a)) return -1; - - return strcasecmp(a, b); -} - -/* - defined but not used: - -static int -style_record_compare(void const *aa, void const *bb) -{ - NRStyleRecord const *a = (NRStyleRecord const *) aa; - NRStyleRecord const *b = (NRStyleRecord const *) bb; - - return (style_name_compare(a->name, b->name)); -} - -static void font_factory_name_list_destructor(NRNameList *list) -{ - for (unsigned int i = 0; i < list->length; i++) - g_free(list->names[i]); - if ( list->names ) g_free(list->names); -} - -static void font_factory_style_list_destructor(NRStyleList *list) -{ - for (unsigned int i = 0; i < list->length; i++) { - g_free((void *) (list->records)[i].name); - g_free((void *) (list->records)[i].descr); - } - if ( list->records ) g_free(list->records); -} -*/ - -/** - * On Win32 performs a stricmp(a,b), otherwise does a strcasecmp(a,b) - */ -int -family_name_compare(char const *a, char const *b) -{ -#ifndef WIN32 - return strcasecmp((*((char const **) a)), (*((char const **) b))); -#else - return stricmp((*((char const **) a)), (*((char const **) b))); -#endif -} - static void noop(...) {} //#define PANGO_DEBUG g_print #define PANGO_DEBUG noop - ///////////////////// FontFactory #ifndef USE_PANGO_WIN32 // the substitute function to tell fontconfig to enforce outline fonts @@ -708,9 +493,24 @@ Glib::ustring font_factory::FontSpecificationBestMatch(const Glib::ustring & fon ///// -static bool StyleNameCompareInternal(Glib::ustring style1, Glib::ustring style2) +// Calculate a Style "value" based on CSS values for ordering styles. +static int StyleNameValue( const Glib::ustring &style ) +{ + + PangoFontDescription *pfd = pango_font_description_from_string ( style.c_str() ); + int value = + pango_font_description_get_weight ( pfd ) * 1000000 + + pango_font_description_get_style ( pfd ) * 10000 + + pango_font_description_get_stretch( pfd ) * 100 + + pango_font_description_get_variant( pfd ); + pango_font_description_free ( pfd ); + return value; +} + +// Determines order in which styles are presented (sorted by CSS style values) +static bool StyleNameCompareInternal(const Glib::ustring &style1, const Glib::ustring &style2) { - return (style_name_compare(style1.c_str(), style2.c_str()) < 0); + return( StyleNameValue( style1 ) < StyleNameValue( style2 ) ); } void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) -- cgit v1.2.3 From fdc7bd363b6c34bc42d246678d17faa4519323b4 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 8 Jun 2014 18:16:10 +0200 Subject: Better ordering of font-face styles in UI. Rely on CSS values rather than guessing. (bzr r13341.1.53) --- src/libnrtype/FontFactory.cpp | 234 +++--------------------------------------- 1 file changed, 17 insertions(+), 217 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 4ae408397..6ab8c77b8 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -54,226 +54,11 @@ bool font_descr_equal::operator()( PangoFontDescription *const&a, PangoFontDesc /////////////////// helper functions -/** - * A wrapper for strcasestr that also provides an implementation for Win32. - */ -static bool -ink_strstr(char const *haystack, char const *pneedle) -{ - // windows has no strcasestr implementation, so here is ours... - // stolen from nmap - /* FIXME: This is broken for e.g. ink_strstr("aab", "ab"). Report to nmap. - * - * Also, suggest use of g_ascii_todown instead of buffer stuff, and g_ascii_tolower instead - * of tolower. Given that haystack is a font name (i.e. fairly short), it should be ok to - * do g_ascii_strdown on both haystack and pneedle, and do normal strstr. - * - * Rather than fixing in inkscape, consider getting rid of this routine, instead using - * strdown and plain strstr at caller. We have control over the needle values, so we can - * modify the callers rather than calling strdown there. - */ - char buf[512]; - register char const *p; - char *needle, *q, *foundto; - if (!*pneedle) return true; - if (!haystack) return false; - - needle = buf; - p = pneedle; q = needle; - while ((*q++ = tolower(*p++))) - ; - p = haystack - 1; foundto = needle; - while (*++p) { - if (tolower(*p) == *foundto) { - if (!*++foundto) { - /* Yeah, we found it */ - return true; - } - } else foundto = needle; - } - return false; -} - -/** - * Regular fonts are 'Regular', 'Roman', 'Normal', or 'Plain' - */ -// FIXME: make this UTF8, add non-English style names -static bool -is_regular(char const *s) -{ - if (ink_strstr(s, "Regular")) return true; - if (ink_strstr(s, "Roman")) return true; - if (ink_strstr(s, "Normal")) return true; - if (ink_strstr(s, "Plain")) return true; - return false; -} - -/** - * Non-bold fonts are 'Medium' or 'Book' - */ -static bool -is_nonbold(char const *s) -{ - if (ink_strstr(s, "Medium")) return true; - if (ink_strstr(s, "Book")) return true; - return false; -} - -/** - * Italic fonts are 'Italic', 'Oblique', or 'Slanted' - */ -static bool -is_italic(char const *s) -{ - if (ink_strstr(s, "Italic")) return true; - if (ink_strstr(s, "Oblique")) return true; - if (ink_strstr(s, "Slanted")) return true; - return false; -} - -/** - * Bold fonts are 'Bold' - */ -static bool -is_bold(char const *s) -{ - if (ink_strstr(s, "Bold")) return true; - return false; -} - -/** - * Caps fonts are 'Caps' - */ -static bool -is_caps(char const *s) -{ - if (ink_strstr(s, "Caps")) return true; - return false; -} - -#if 0 /* FIXME: These are all unused. Please delete them or use them (presumably in -* style_name_compare). */ -/** - * Monospaced fonts are 'Mono' - */ -static bool -is_mono(char const *s) -{ - if (ink_strstr(s, "Mono")) return true; - return false; -} - -/** - * Rounded fonts are 'Round' - */ -static bool -is_round(char const *s) -{ - if (ink_strstr(s, "Round")) return true; - return false; -} - -/** - * Outline fonts are 'Outline' - */ -static bool -is_outline(char const *s) -{ - if (ink_strstr(s, "Outline")) return true; - return false; -} - -/** - * Swash fonts are 'Swash' - */ -static bool -is_swash(char const *s) -{ - if (ink_strstr(s, "Swash")) return true; - return false; -} -#endif - -/** - * Determines if two style names match. This allows us to match - * based on the type of style rather than simply doing string matching, - * because for instance 'Plain' and 'Normal' mean the same thing. - * - * Q: Shouldn't this include the other tests such as is_outline, etc.? - * Q: Is there a problem with strcasecmp on Win32? Should it use stricmp? - */ -int -style_name_compare(char const *aa, char const *bb) -{ - char const *a = (char const *) aa; - char const *b = (char const *) bb; - - if (is_regular(a) && !is_regular(b)) return -1; - if (is_regular(b) && !is_regular(a)) return 1; - - if (is_bold(a) && !is_bold(b)) return 1; - if (is_bold(b) && !is_bold(a)) return -1; - - if (is_italic(a) && !is_italic(b)) return 1; - if (is_italic(b) && !is_italic(a)) return -1; - - if (is_nonbold(a) && !is_nonbold(b)) return 1; - if (is_nonbold(b) && !is_nonbold(a)) return -1; - - if (is_caps(a) && !is_caps(b)) return 1; - if (is_caps(b) && !is_caps(a)) return -1; - - return strcasecmp(a, b); -} - -/* - defined but not used: - -static int -style_record_compare(void const *aa, void const *bb) -{ - NRStyleRecord const *a = (NRStyleRecord const *) aa; - NRStyleRecord const *b = (NRStyleRecord const *) bb; - - return (style_name_compare(a->name, b->name)); -} - -static void font_factory_name_list_destructor(NRNameList *list) -{ - for (unsigned int i = 0; i < list->length; i++) - g_free(list->names[i]); - if ( list->names ) g_free(list->names); -} - -static void font_factory_style_list_destructor(NRStyleList *list) -{ - for (unsigned int i = 0; i < list->length; i++) { - g_free((void *) (list->records)[i].name); - g_free((void *) (list->records)[i].descr); - } - if ( list->records ) g_free(list->records); -} -*/ - -/** - * On Win32 performs a stricmp(a,b), otherwise does a strcasecmp(a,b) - */ -int -family_name_compare(char const *a, char const *b) -{ -#ifndef WIN32 - return strcasecmp((*((char const **) a)), (*((char const **) b))); -#else - return stricmp((*((char const **) a)), (*((char const **) b))); -#endif -} - static void noop(...) {} //#define PANGO_DEBUG g_print #define PANGO_DEBUG noop - ///////////////////// FontFactory #ifndef USE_PANGO_WIN32 // the substitute function to tell fontconfig to enforce outline fonts @@ -708,9 +493,24 @@ Glib::ustring font_factory::FontSpecificationBestMatch(const Glib::ustring & fon ///// -static bool StyleNameCompareInternal(Glib::ustring style1, Glib::ustring style2) +// Calculate a Style "value" based on CSS values for ordering styles. +static int StyleNameValue( const Glib::ustring &style ) +{ + + PangoFontDescription *pfd = pango_font_description_from_string ( style.c_str() ); + int value = + pango_font_description_get_weight ( pfd ) * 1000000 + + pango_font_description_get_style ( pfd ) * 10000 + + pango_font_description_get_stretch( pfd ) * 100 + + pango_font_description_get_variant( pfd ); + pango_font_description_free ( pfd ); + return value; +} + +// Determines order in which styles are presented (sorted by CSS style values) +static bool StyleNameCompareInternal(const Glib::ustring &style1, const Glib::ustring &style2) { - return (style_name_compare(style1.c_str(), style2.c_str()) < 0); + return( StyleNameValue( style1 ) < StyleNameValue( style2 ) ); } void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) -- cgit v1.2.3 From acfb5bd375ec40f1fb59b806bfb34f66a5aa5cb1 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 9 Jun 2014 10:38:18 +0200 Subject: Display name of face from font file in Text and Font dialog (as well as CSS/Pango name). Partial fix for #165521, #167353, #1008514 (bzr r13341.1.54) --- src/libnrtype/FontFactory.cpp | 17 ++++++++------- src/libnrtype/FontFactory.h | 23 ++++++++++++++------ src/libnrtype/font-lister.cpp | 50 +++++++++++++++++++++++++++++-------------- src/libnrtype/font-lister.h | 13 +++++++---- src/widgets/font-selector.cpp | 30 +++++++++++++++++++------- 5 files changed, 91 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 6ab8c77b8..6859a4a5c 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -508,9 +508,9 @@ static int StyleNameValue( const Glib::ustring &style ) } // Determines order in which styles are presented (sorted by CSS style values) -static bool StyleNameCompareInternal(const Glib::ustring &style1, const Glib::ustring &style2) +static bool StyleNameCompareInternal(const StyleNames &style1, const StyleNames &style2) { - return( StyleNameValue( style1 ) < StyleNameValue( style2 ) ); + return( StyleNameValue( style1.CssName ) < StyleNameValue( style2.CssName ) ); } void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) @@ -536,7 +536,8 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) // If the face has a name, describe it, and then use the // description to get the UI family and face strings - if (pango_font_face_get_face_name(faces[currentFace]) == NULL) { + const gchar* displayName = pango_font_face_get_face_name(faces[currentFace]); + if (displayName == NULL) { continue; } @@ -566,26 +567,26 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) // Insert new family if (iter == map->end()) { - map->insert(std::make_pair(familyUIName, std::list())); + map->insert(std::make_pair(familyUIName, std::list())); } // Insert into the style list and save the info in the reference maps // only if the style does not yet exist bool exists = false; - std::list &styleList = (*map)[familyUIName]; + std::list &styleList = (*map)[familyUIName]; - for (std::list::iterator it=styleList.begin(); + for (std::list::iterator it=styleList.begin(); it != styleList.end(); ++it) { - if (*it == styleUIName) { + if ( (*it).CssName == styleUIName) { exists = true; break; } } if (!exists) { - styleList.push_back(styleUIName); + styleList.push_back( StyleNames(styleUIName,displayName) ); // Add the string info needed in the reference maps fontStringMap.insert( diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 7b606d200..513ee4bf7 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -51,15 +51,26 @@ struct font_descr_equal : public std::binary_function > FamilyToStylesMap; +// Class for style strings: both CSS and as suggested by font. +class StyleNames { + +public: + StyleNames() {}; + StyleNames( Glib::ustring name ) : + CssName( name ), DisplayName( name ) {}; + StyleNames( Glib::ustring cssname, Glib::ustring displayname ) : + CssName( cssname ), DisplayName( displayname ) {}; + +public: + Glib::ustring CssName; // Style as Pango/CSS would write it. + Glib::ustring DisplayName; // Style as Font designer named it. +}; + +// Map type for gathering UI family and style names +typedef std::map > FamilyToStylesMap; class font_factory { public: diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 8ce5eccfc..9ff4fad05 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -64,11 +64,13 @@ namespace Inkscape // Now go through the styles GList *styles = NULL; - std::list &styleStrings = familyStyleMap[familyName]; - for (std::list::iterator it=styleStrings.begin(); + std::list &styleStrings = familyStyleMap[familyName]; + for (std::list::iterator it=styleStrings.begin(); it != styleStrings.end(); ++it) { - styles = g_list_append(styles, g_strdup((*it).c_str())); + // Our own copy + StyleNames *copy = new StyleNames( *it ); + styles = g_list_append(styles, copy); } (*treeModelIter)[FontList.styles] = styles; @@ -81,11 +83,11 @@ namespace Inkscape current_fontspec = "sans-serif"; // Empty style -> Normal current_fontspec_system = "Sans"; - /* Create default styles for use when font-family is unknown on system. */ - default_styles = g_list_append( NULL, g_strdup("Normal") ); - default_styles = g_list_append( default_styles, g_strdup("Italic") ); - default_styles = g_list_append( default_styles, g_strdup("Bold") ); - default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); + /* Create default styles for use when font-family is unknown on system. */ + default_styles = g_list_append( NULL, new StyleNames( "Normal" ) ); + default_styles = g_list_append( default_styles, new StyleNames( "Italic" ) ); + default_styles = g_list_append( default_styles, new StyleNames( "Bold" ) ); + default_styles = g_list_append( default_styles, new StyleNames( "Bold Italic" ) ); font_list_store->thaw_notify(); @@ -96,11 +98,31 @@ namespace Inkscape style_list_store->clear(); for (GList *l=default_styles; l; l = l->next) { Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; } style_list_store->thaw_notify(); } + FontLister::~FontLister() { + + // Delete default_styles + for (GList *l=default_styles; l; l = l->next) { + delete ((StyleNames*)l->data); + } + + // Delete other styles + Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); + while( iter != font_list_store->children().end() ) { + Gtk::TreeModel::Row row = *iter; + GList *styles = row[FontList.styles]; + for (GList *l=styles; l; l = l->next) { + delete ((StyleNames*)l->data); + } + ++iter; + } + } + // Example of how to use "foreach_iter" // bool // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { @@ -113,7 +135,6 @@ namespace Inkscape // } // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); - /* Used to insert a font that was not in the document and not on the system into the font list. */ void FontLister::insert_font_family( Glib::ustring new_family ) { @@ -471,7 +492,8 @@ std::pair FontLister::new_font_family (Glib::ustri for (GList *l=styles; l; l = l->next) { Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; } style_list_store->thaw_notify(); @@ -856,7 +878,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( familyNamesAreEqual( style, row[FontStyleList.styles] ) ) { + if( familyNamesAreEqual( style, row[FontStyleList.cssStyle] ) ) { return row; } @@ -983,10 +1005,6 @@ std::pair FontLister::new_font_family (Glib::ustri return best_style; } - FontLister::~FontLister () - { - }; - const Glib::RefPtr FontLister::get_font_list () const { diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index a460388d3..c89dab550 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -100,13 +100,18 @@ namespace Inkscape : public Gtk::TreeModelColumnRecord { public: - /** Column containing the styles + /** Column containing the styles as Font designer used. */ - Gtk::TreeModelColumn styles; + Gtk::TreeModelColumn displayStyle; + + /** Column containing the styles in CSS/Pango format. + */ + Gtk::TreeModelColumn cssStyle; FontStyleListClass () { - add (styles); + add (cssStyle); + add (displayStyle); } }; @@ -276,7 +281,7 @@ namespace Inkscape private: FontLister (); - + NRNameList families; Glib::RefPtr font_list_store; diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 0e862638c..ccaf93e55 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -179,6 +179,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); Glib::RefPtr store = fontlister->get_font_list(); gtk_tree_view_set_model (GTK_TREE_VIEW(fsel->family_treeview), GTK_TREE_MODEL (Glib::unwrap (store))); + //gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(fsel->family_treeview),2); gtk_container_add(GTK_CONTAINER(sw), fsel->family_treeview); gtk_widget_show_all (sw); @@ -210,12 +211,22 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_box_pack_start(GTK_BOX (vb), sw, TRUE, TRUE, 0); fsel->style_treeview = gtk_tree_view_new (); - column = gtk_tree_view_column_new (); + + // CSS Style name cell = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - gtk_tree_view_column_set_attributes (column, cell, "text", 0, NULL); + column = gtk_tree_view_column_new_with_attributes ("CSS", cell, "text", 0, NULL ); + //gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->style_treeview), column); + + // Display Style name + cell = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Face"), cell, "text", 1, NULL ); + //gtk_tree_view_column_pack_start (column, cell, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->style_treeview), column); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->style_treeview), FALSE); + + //gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(fsel->style_treeview), 1); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->style_treeview), TRUE); gtk_container_add(GTK_CONTAINER(sw), fsel->style_treeview); gtk_widget_show_all (sw); @@ -306,13 +317,15 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, // Create our own store of styles for selected font-family and find index of best style match int path_index = 0; int index = 0; - GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); // Where is this deleted? + GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); // Where is this deleted? for ( ; list ; list = list->next ) { gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, (char*)list->data, -1); - - if( best.compare( (char*)list->data ) == 0 ) { + gtk_list_store_set (store, &iter, + 0, ((StyleNames*)list->data)->CssName.c_str(), + 1, ((StyleNames*)list->data)->DisplayName.c_str(), + -1); + if( best.compare( ((StyleNames*)list->data)->CssName ) == 0 ) { path_index = index; } ++index; @@ -320,6 +333,7 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, // Attach store to tree view. Can trigger style changed signal (but not FONT_SET): gtk_tree_view_set_model (GTK_TREE_VIEW (fsel->style_treeview), GTK_TREE_MODEL (store)); + //gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(fsel->style_treeview),1); // Get path to best style GtkTreePath *path = gtk_tree_path_new (); -- cgit v1.2.3 From 2bcf58d0c4e5d928af272c17201fbadae788ad0c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 9 Jun 2014 10:52:16 +0200 Subject: Display name of face from font file in Text and Font dialog (as well as CSS/Pango name). Partial fix for #165521, #167353, #1008514 (bzr r13414) --- src/libnrtype/FontFactory.cpp | 17 ++++++++------- src/libnrtype/FontFactory.h | 23 ++++++++++++++------ src/libnrtype/font-lister.cpp | 50 +++++++++++++++++++++++++++++-------------- src/libnrtype/font-lister.h | 13 +++++++---- src/widgets/font-selector.cpp | 30 +++++++++++++++++++------- 5 files changed, 91 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 6ab8c77b8..6859a4a5c 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -508,9 +508,9 @@ static int StyleNameValue( const Glib::ustring &style ) } // Determines order in which styles are presented (sorted by CSS style values) -static bool StyleNameCompareInternal(const Glib::ustring &style1, const Glib::ustring &style2) +static bool StyleNameCompareInternal(const StyleNames &style1, const StyleNames &style2) { - return( StyleNameValue( style1 ) < StyleNameValue( style2 ) ); + return( StyleNameValue( style1.CssName ) < StyleNameValue( style2.CssName ) ); } void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) @@ -536,7 +536,8 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) // If the face has a name, describe it, and then use the // description to get the UI family and face strings - if (pango_font_face_get_face_name(faces[currentFace]) == NULL) { + const gchar* displayName = pango_font_face_get_face_name(faces[currentFace]); + if (displayName == NULL) { continue; } @@ -566,26 +567,26 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) // Insert new family if (iter == map->end()) { - map->insert(std::make_pair(familyUIName, std::list())); + map->insert(std::make_pair(familyUIName, std::list())); } // Insert into the style list and save the info in the reference maps // only if the style does not yet exist bool exists = false; - std::list &styleList = (*map)[familyUIName]; + std::list &styleList = (*map)[familyUIName]; - for (std::list::iterator it=styleList.begin(); + for (std::list::iterator it=styleList.begin(); it != styleList.end(); ++it) { - if (*it == styleUIName) { + if ( (*it).CssName == styleUIName) { exists = true; break; } } if (!exists) { - styleList.push_back(styleUIName); + styleList.push_back( StyleNames(styleUIName,displayName) ); // Add the string info needed in the reference maps fontStringMap.insert( diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 7b606d200..513ee4bf7 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -51,15 +51,26 @@ struct font_descr_equal : public std::binary_function > FamilyToStylesMap; +// Class for style strings: both CSS and as suggested by font. +class StyleNames { + +public: + StyleNames() {}; + StyleNames( Glib::ustring name ) : + CssName( name ), DisplayName( name ) {}; + StyleNames( Glib::ustring cssname, Glib::ustring displayname ) : + CssName( cssname ), DisplayName( displayname ) {}; + +public: + Glib::ustring CssName; // Style as Pango/CSS would write it. + Glib::ustring DisplayName; // Style as Font designer named it. +}; + +// Map type for gathering UI family and style names +typedef std::map > FamilyToStylesMap; class font_factory { public: diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 8ce5eccfc..9ff4fad05 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -64,11 +64,13 @@ namespace Inkscape // Now go through the styles GList *styles = NULL; - std::list &styleStrings = familyStyleMap[familyName]; - for (std::list::iterator it=styleStrings.begin(); + std::list &styleStrings = familyStyleMap[familyName]; + for (std::list::iterator it=styleStrings.begin(); it != styleStrings.end(); ++it) { - styles = g_list_append(styles, g_strdup((*it).c_str())); + // Our own copy + StyleNames *copy = new StyleNames( *it ); + styles = g_list_append(styles, copy); } (*treeModelIter)[FontList.styles] = styles; @@ -81,11 +83,11 @@ namespace Inkscape current_fontspec = "sans-serif"; // Empty style -> Normal current_fontspec_system = "Sans"; - /* Create default styles for use when font-family is unknown on system. */ - default_styles = g_list_append( NULL, g_strdup("Normal") ); - default_styles = g_list_append( default_styles, g_strdup("Italic") ); - default_styles = g_list_append( default_styles, g_strdup("Bold") ); - default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); + /* Create default styles for use when font-family is unknown on system. */ + default_styles = g_list_append( NULL, new StyleNames( "Normal" ) ); + default_styles = g_list_append( default_styles, new StyleNames( "Italic" ) ); + default_styles = g_list_append( default_styles, new StyleNames( "Bold" ) ); + default_styles = g_list_append( default_styles, new StyleNames( "Bold Italic" ) ); font_list_store->thaw_notify(); @@ -96,11 +98,31 @@ namespace Inkscape style_list_store->clear(); for (GList *l=default_styles; l; l = l->next) { Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; } style_list_store->thaw_notify(); } + FontLister::~FontLister() { + + // Delete default_styles + for (GList *l=default_styles; l; l = l->next) { + delete ((StyleNames*)l->data); + } + + // Delete other styles + Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); + while( iter != font_list_store->children().end() ) { + Gtk::TreeModel::Row row = *iter; + GList *styles = row[FontList.styles]; + for (GList *l=styles; l; l = l->next) { + delete ((StyleNames*)l->data); + } + ++iter; + } + } + // Example of how to use "foreach_iter" // bool // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { @@ -113,7 +135,6 @@ namespace Inkscape // } // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); - /* Used to insert a font that was not in the document and not on the system into the font list. */ void FontLister::insert_font_family( Glib::ustring new_family ) { @@ -471,7 +492,8 @@ std::pair FontLister::new_font_family (Glib::ustri for (GList *l=styles; l; l = l->next) { Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; } style_list_store->thaw_notify(); @@ -856,7 +878,7 @@ std::pair FontLister::new_font_family (Glib::ustri Gtk::TreeModel::Row row = *iter; - if( familyNamesAreEqual( style, row[FontStyleList.styles] ) ) { + if( familyNamesAreEqual( style, row[FontStyleList.cssStyle] ) ) { return row; } @@ -983,10 +1005,6 @@ std::pair FontLister::new_font_family (Glib::ustri return best_style; } - FontLister::~FontLister () - { - }; - const Glib::RefPtr FontLister::get_font_list () const { diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index a460388d3..c89dab550 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -100,13 +100,18 @@ namespace Inkscape : public Gtk::TreeModelColumnRecord { public: - /** Column containing the styles + /** Column containing the styles as Font designer used. */ - Gtk::TreeModelColumn styles; + Gtk::TreeModelColumn displayStyle; + + /** Column containing the styles in CSS/Pango format. + */ + Gtk::TreeModelColumn cssStyle; FontStyleListClass () { - add (styles); + add (cssStyle); + add (displayStyle); } }; @@ -276,7 +281,7 @@ namespace Inkscape private: FontLister (); - + NRNameList families; Glib::RefPtr font_list_store; diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 0e862638c..ccaf93e55 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -179,6 +179,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); Glib::RefPtr store = fontlister->get_font_list(); gtk_tree_view_set_model (GTK_TREE_VIEW(fsel->family_treeview), GTK_TREE_MODEL (Glib::unwrap (store))); + //gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(fsel->family_treeview),2); gtk_container_add(GTK_CONTAINER(sw), fsel->family_treeview); gtk_widget_show_all (sw); @@ -210,12 +211,22 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_box_pack_start(GTK_BOX (vb), sw, TRUE, TRUE, 0); fsel->style_treeview = gtk_tree_view_new (); - column = gtk_tree_view_column_new (); + + // CSS Style name cell = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, cell, FALSE); - gtk_tree_view_column_set_attributes (column, cell, "text", 0, NULL); + column = gtk_tree_view_column_new_with_attributes ("CSS", cell, "text", 0, NULL ); + //gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->style_treeview), column); + + // Display Style name + cell = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes (_("Face"), cell, "text", 1, NULL ); + //gtk_tree_view_column_pack_start (column, cell, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->style_treeview), column); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->style_treeview), FALSE); + + //gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(fsel->style_treeview), 1); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->style_treeview), TRUE); gtk_container_add(GTK_CONTAINER(sw), fsel->style_treeview); gtk_widget_show_all (sw); @@ -306,13 +317,15 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, // Create our own store of styles for selected font-family and find index of best style match int path_index = 0; int index = 0; - GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); // Where is this deleted? + GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); // Where is this deleted? for ( ; list ; list = list->next ) { gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, (char*)list->data, -1); - - if( best.compare( (char*)list->data ) == 0 ) { + gtk_list_store_set (store, &iter, + 0, ((StyleNames*)list->data)->CssName.c_str(), + 1, ((StyleNames*)list->data)->DisplayName.c_str(), + -1); + if( best.compare( ((StyleNames*)list->data)->CssName ) == 0 ) { path_index = index; } ++index; @@ -320,6 +333,7 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, // Attach store to tree view. Can trigger style changed signal (but not FONT_SET): gtk_tree_view_set_model (GTK_TREE_VIEW (fsel->style_treeview), GTK_TREE_MODEL (store)); + //gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(fsel->style_treeview),1); // Get path to best style GtkTreePath *path = gtk_tree_path_new (); -- cgit v1.2.3 From 1fbcbe105b22951f565dd6ddecce3ceeb9e55a36 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 10 Jun 2014 00:12:02 +0200 Subject: fix a bug on spirolive close path (bzr r13341.1.55) --- src/ui/tools/pen-tool.cpp | 56 ++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 386dc43e9..f8243fb7f 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1556,12 +1556,11 @@ void PenTool::_bspline_spiro_start_anchor_off() //and we add it again with the recreation tmpCurve->append_continuous(lastSeg, 0.0625); } - if (this->sa->start) { - tmpCurve = tmpCurve->create_reverse(); - } - this->overwriteCurve = tmpCurve; } - + if (this->sa->start) { + tmpCurve = tmpCurve->create_reverse(); + } + this->overwriteCurve = tmpCurve; } void PenTool::_bspline_spiro_motion(bool shift){ @@ -1645,7 +1644,7 @@ void PenTool::_bspline_spiro_end_anchor_on() } reverse = true; } else if(this->sa){ - tmpCurve = this->overwriteCurve; + tmpCurve = this->overwriteCurve->copy(); if(!this->sa->start){ tmpCurve = tmpCurve->create_reverse(); reverse = true; @@ -1665,7 +1664,7 @@ void PenTool::_bspline_spiro_end_anchor_on() lastSeg->curveto((*cubic)[1],C,(*cubic)[3]); }else{ lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); - lastSeg->curveto(tmpCurve->last_segment()->initialPoint(),C,tmpCurve->last_segment()->finalPoint()); + lastSeg->lineto(tmpCurve->last_segment()->finalPoint()); } if( tmpCurve->get_segment_count() == 1){ tmpCurve = lastSeg; @@ -1702,7 +1701,7 @@ void PenTool::_bspline_spiro_end_anchor_off() } reverse = true; } else if(this->sa){ - tmpCurve = this->overwriteCurve; + tmpCurve = this->overwriteCurve->copy(); if(!this->sa->start){ tmpCurve = tmpCurve->create_reverse(); reverse = true; @@ -1714,25 +1713,28 @@ void PenTool::_bspline_spiro_end_anchor_off() if(cubic){ lastSeg->moveto((*cubic)[0]); lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]); - if( tmpCurve->get_segment_count() == 1){ - tmpCurve = lastSeg; - }else{ - //we eliminate the last segment - tmpCurve->backspace(); - //and we add it again with the recreation - tmpCurve->append_continuous(lastSeg, 0.0625); - } - if (reverse) { - tmpCurve = tmpCurve->create_reverse(); - } - if( this->green_anchor && this->green_anchor->active ) - { - this->green_curve->reset(); - this->green_curve = tmpCurve; - }else{ - this->overwriteCurve->reset(); - this->overwriteCurve = tmpCurve; - } + }else{ + lastSeg->moveto(tmpCurve->last_segment()->initialPoint()); + lastSeg->lineto(tmpCurve->last_segment()->finalPoint()); + } + if( tmpCurve->get_segment_count() == 1){ + tmpCurve = lastSeg; + }else{ + //we eliminate the last segment + tmpCurve->backspace(); + //and we add it again with the recreation + tmpCurve->append_continuous(lastSeg, 0.0625); + } + if (reverse) { + tmpCurve = tmpCurve->create_reverse(); + } + if( this->green_anchor && this->green_anchor->active ) + { + this->green_curve->reset(); + this->green_curve = tmpCurve; + }else{ + this->overwriteCurve->reset(); + this->overwriteCurve = tmpCurve; } } -- cgit v1.2.3 From 30add35428dda0b2ba699612148d4627994add79 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 10 Jun 2014 11:29:58 +0200 Subject: Proper quoting of CSS 'font-family' fallback lists. (bzr r13415) --- src/libnrtype/font-lister.cpp | 11 +++- src/style-internal.cpp | 29 +++++------ src/style.cpp | 114 ++++++++++++++++++++++-------------------- src/style.h | 2 + src/xml/repr-css.cpp | 32 ++++++------ 5 files changed, 102 insertions(+), 86 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 9ff4fad05..43c3045b1 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -601,8 +601,15 @@ std::pair FontLister::new_font_family (Glib::ustri Glib::ustring family = ui.first; - sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec.c_str() ); - sp_repr_css_set_property (css, "font-family", family.c_str() ); //Canonized w/ spaces + + // Font spec is single quoted... for the moment + Glib::ustring fontspec_quoted( fontspec ); + css_quote( fontspec_quoted ); + sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec_quoted.c_str() ); + + // Font families needs to be properly quoted in CSS (used unquoted in font-lister) + css_font_family_quote( family ); + sp_repr_css_set_property (css, "font-family", family.c_str() ); PangoFontDescription *desc = pango_font_description_from_string( fontspec.c_str() ); PangoWeight weight = pango_font_description_get_weight( desc ); diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 8b4f3c1cd..c686a1807 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -656,20 +656,21 @@ SPIString::read( gchar const *str ) { set = true; inherit = false; - // libcroco puts quotes around some strings... remove - Glib::ustring str_unquoted(str); - css_unquote( str_unquoted ); - - // Unquote individual family names, Pango always uses unquoted names. + Glib::ustring str_temp(str); if( name.compare( "font-family" ) == 0 ) { - css_font_family_unquote( str_unquoted ); + // Family names may be quoted in CSS, internally we use unquoted names. + css_font_family_unquote( str_temp ); + } else if( name.compare( "-inkscape-font-specification" ) == 0 ) { + css_unquote( str_temp ); } - value = g_strdup(str_unquoted.c_str()); + value = g_strdup(str_temp.c_str()); } } +// This routine is actually rarely used. Writing is done usually +// in sp_repr_css_write_string... const Glib::ustring SPIString::write( guint const flags, SPIBase const *const base) const { @@ -684,13 +685,13 @@ SPIString::write( guint const flags, SPIBase const *const base) const { } else { if( this->value ) { if( name.compare( "font-family" ) == 0 ) { - // This is for compatibilty with the C version of code. - // This is incorrect as it puts single quotes around the - // entire string rather around the individule font names. - // This should be handled by the routines that extract - // out the font family names and reassembles them into a - // font fallback list. FIXME - return (name + ":" + css2_escape_quote(this->value) + ";"); + Glib::ustring font_family( this->value ); + css_font_family_quote( font_family ); + return (name + ":" + font_family + ";"); + } else if( name.compare( "-inkscape-font-specification" ) == 0 ) { + Glib::ustring font_spec( this->value ); + css_quote( font_spec ); + return (name + ":" + font_spec + ";"); } else { return (name + ":" + this->value + ";"); } diff --git a/src/style.cpp b/src/style.cpp index 8e4c89839..c6a98e7f4 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -1826,12 +1826,67 @@ sp_css_attr_scale(SPCSSAttr *css, double ex) } +/** + * Quote and/or escape string for writing to CSS, changing strings in place. + * See: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + */ +void +css_quote(Glib::ustring &val) +{ + Glib::ustring out; + bool quote = false; + + // Can't wait for C++11! + for( Glib::ustring::iterator it = val.begin(); it != val.end(); ++it) { + if(g_ascii_isalnum(*it) || *it=='-' || *it=='_' || *it > 0xA0) { + out += *it; + } else if (*it == '\'') { + // Single quotes require escaping and quotes. + out += '\\'; + out += *it; + quote = true; + } else { + // Quote everything else including spaces. + // (CSS Fonts Level 3 recommends quoting with spaces.) + out += *it; + quote = true; + } + if( it == val.begin() && !g_ascii_isalpha(*it) ) { + // A non-ASCII/non-alpha initial value on any indentifier needs quotes. + // (Actually it's a bit more complicated but as it never hurts to quote...) + quote = true; + } + } + if( quote ) { + out.insert( out.begin(), '\'' ); + out += '\''; + } + val = out; +} + + +/** + * Quote font names in font-family lists, changing string in place. + * We use unquoted names internally but some need to be quoted in CSS. + */ +void +css_font_family_quote(Glib::ustring &val) +{ + std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", val ); + + val.erase(); + for( unsigned i=0; i < tokens.size(); ++i ) { + css_quote( tokens[i] ); + val += tokens[i] + ", "; + } + if( val.size() > 1 ) + val.erase( val.size() - 2 ); // Remove trailing ", " +} + + // Called in style-internal.cpp, xml/repr-css.cpp /** * Remove paired single and double quotes from a string, changing string in place. - * Note: in CSS (in style= and in stylesheets), unquoting and unescaping is done - * by libcroco, our CSS parser, though it adds a new pair of "" quotes for the strings - * it parsed for us. */ void css_unquote(Glib::ustring &val) @@ -1849,7 +1904,7 @@ css_unquote(Glib::ustring &val) /** * Remove paired single and double quotes from font names in font-family lists, * changing string in place. - * Pango expects unquoted font family names. We use unquoted names in interface. + * We use unquoted family names internally but CSS sometimes uses quoted names. */ void css_font_family_unquote(Glib::ustring &val) @@ -1865,57 +1920,6 @@ css_font_family_unquote(Glib::ustring &val) val.erase( val.size() - 2 ); // Remove trailing ", " } -// Called in style.cpp, xml/repr-css.cpp -/** - * Quote and/or escape string for writing to CSS (style=). Returned value must be g_free'd. - */ -Glib::ustring css2_escape_quote(gchar const *val) { - - Glib::ustring t; - bool quote = false; - bool last_was_space = false; - - for (gchar const *i = val; *i; i++) { - bool is_space = ( *i == ' ' ); - if (g_ascii_isalnum(*i) || *i=='-' || *i=='_') { - // ASCII alphanumeric, - and _ don't require quotes - t.push_back(*i); - } else if ( is_space && !last_was_space ) { - // non-consecutive spaces don't require quotes - t.push_back(*i); - } else if (*i=='\'') { - // single quotes require escaping and quotes - t.push_back('\\'); - t.push_back(*i); - quote = true; - } else { - // everything else requires quotes - t.push_back(*i); - quote = true; - } - if (i == val && !g_ascii_isalpha(*i)) { - // a non-ASCII/non-alpha initial character requires quotes - quote = true; - } - last_was_space = is_space; - } - - if (last_was_space) { - // a trailing space requires quotes - quote = true; - } - - if (quote) { - // we use single quotes so the result can be stored in an XML - // attribute without incurring un-aesthetic additional quoting - // (our XML emitter always uses double quotes) - t.insert(t.begin(), '\''); - t.push_back('\''); - } - - return t; -} - /* Local Variables: mode:c++ diff --git a/src/style.h b/src/style.h index 506b90b44..931dcc90e 100644 --- a/src/style.h +++ b/src/style.h @@ -292,7 +292,9 @@ void sp_style_unset_property_attrs(SPObject *o); void sp_style_set_property_url (SPObject *item, gchar const *property, SPObject *linked, bool recursive); +void css_quote( Glib::ustring &val ); // Add quotes around CSS values void css_unquote( Glib::ustring &val ); // Remove quotes from CSS values (style-internal.cpp, xml/repr-css.cpp) +void css_font_family_quote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp void css_font_family_unquote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp Glib::ustring css2_escape_quote(gchar const *val); diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index e462f70da..c043904a7 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -283,14 +283,7 @@ void sp_repr_css_write_string(SPCSSAttr *css, Glib::ustring &str) str.append(g_quark_to_string(iter->key)); str.push_back(':'); - if (!strcmp(g_quark_to_string(iter->key), "font-family") - || !strcmp(g_quark_to_string(iter->key), "-inkscape-font-specification")) { - // we only quote font-family/font-specification, as SPStyle does - Glib::ustring val_quoted = css2_escape_quote (iter->value); - str.append(val_quoted); - } else { - str.append(iter->value); // unquoted - } + str.append(iter->value); // Any necessary quoting to be done by calling routine. if (rest(iter)) { str.push_back(';'); @@ -346,13 +339,23 @@ void sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) /** * Merges style properties as parsed by libcroco into an existing SPCSSAttr. + * libcroco converts all single quotes to double quotes, which needs to be + * undone as we always use single quotes inside our 'style' strings since + * double quotes are used outside: e.g.: + * style="font-family:'DejaVu Sans'" */ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) { guchar *const str_value_unsigned = cr_term_to_string(decl->value); - Glib::ustring value_unquoted( reinterpret_cast(str_value_unsigned ) ); - css_unquote( value_unquoted ); // libcroco returns strings quoted in "", remove + Glib::ustring value( reinterpret_cast(str_value_unsigned ) ); + g_free(str_value_unsigned); + + Glib::ustring::size_type pos = 0; + while( (pos=value.find("\"",pos)) != Glib::ustring::npos) { + value.replace(pos,1,"'"); + ++pos; + } Glib::ustring units; @@ -363,11 +366,11 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con * * HACK for now is to strip off em and ex units and add them back at the end */ - int le = value_unquoted.length(); + int le = value.length(); if (le > 2) { - units = value_unquoted.substr(le-2, 2); + units = value.substr(le-2, 2); if ((units == "em") || (units == "ex")) { - value_unquoted = value_unquoted.substr(0, le-2); + value = value.substr(0, le-2); } else { units.clear(); @@ -378,7 +381,7 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con // CSSOStringStream is used here to write valid CSS (as in sp_style_write_string). This has // the additional benefit of respecting the numerical precission set in the SVG Output // preferences. We assume any numerical part comes first (if not, the whole string is copied). - std::stringstream ss( value_unquoted ); + std::stringstream ss( value ); double number = 0; std::string characters; std::string temp; @@ -400,7 +403,6 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con //g_message("sp_repr_css_merge_from_decl looks like em or ex units %s --> %s", str_value, os.str().c_str()); } ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); - g_free(str_value_unsigned); } /** -- cgit v1.2.3 From 3252b41582b781c90648c0ad892f45751377b57c Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 10 Jun 2014 11:40:10 +0200 Subject: Proper quoting of CSS 'font-family' fallback lists. (bzr r13341.1.56) --- src/libnrtype/font-lister.cpp | 11 +++- src/style-internal.cpp | 29 +++++------ src/style.cpp | 114 ++++++++++++++++++++++-------------------- src/style.h | 2 + src/xml/repr-css.cpp | 32 ++++++------ 5 files changed, 102 insertions(+), 86 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 9ff4fad05..43c3045b1 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -601,8 +601,15 @@ std::pair FontLister::new_font_family (Glib::ustri Glib::ustring family = ui.first; - sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec.c_str() ); - sp_repr_css_set_property (css, "font-family", family.c_str() ); //Canonized w/ spaces + + // Font spec is single quoted... for the moment + Glib::ustring fontspec_quoted( fontspec ); + css_quote( fontspec_quoted ); + sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec_quoted.c_str() ); + + // Font families needs to be properly quoted in CSS (used unquoted in font-lister) + css_font_family_quote( family ); + sp_repr_css_set_property (css, "font-family", family.c_str() ); PangoFontDescription *desc = pango_font_description_from_string( fontspec.c_str() ); PangoWeight weight = pango_font_description_get_weight( desc ); diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 8b4f3c1cd..c686a1807 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -656,20 +656,21 @@ SPIString::read( gchar const *str ) { set = true; inherit = false; - // libcroco puts quotes around some strings... remove - Glib::ustring str_unquoted(str); - css_unquote( str_unquoted ); - - // Unquote individual family names, Pango always uses unquoted names. + Glib::ustring str_temp(str); if( name.compare( "font-family" ) == 0 ) { - css_font_family_unquote( str_unquoted ); + // Family names may be quoted in CSS, internally we use unquoted names. + css_font_family_unquote( str_temp ); + } else if( name.compare( "-inkscape-font-specification" ) == 0 ) { + css_unquote( str_temp ); } - value = g_strdup(str_unquoted.c_str()); + value = g_strdup(str_temp.c_str()); } } +// This routine is actually rarely used. Writing is done usually +// in sp_repr_css_write_string... const Glib::ustring SPIString::write( guint const flags, SPIBase const *const base) const { @@ -684,13 +685,13 @@ SPIString::write( guint const flags, SPIBase const *const base) const { } else { if( this->value ) { if( name.compare( "font-family" ) == 0 ) { - // This is for compatibilty with the C version of code. - // This is incorrect as it puts single quotes around the - // entire string rather around the individule font names. - // This should be handled by the routines that extract - // out the font family names and reassembles them into a - // font fallback list. FIXME - return (name + ":" + css2_escape_quote(this->value) + ";"); + Glib::ustring font_family( this->value ); + css_font_family_quote( font_family ); + return (name + ":" + font_family + ";"); + } else if( name.compare( "-inkscape-font-specification" ) == 0 ) { + Glib::ustring font_spec( this->value ); + css_quote( font_spec ); + return (name + ":" + font_spec + ";"); } else { return (name + ":" + this->value + ";"); } diff --git a/src/style.cpp b/src/style.cpp index 8e4c89839..c6a98e7f4 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -1826,12 +1826,67 @@ sp_css_attr_scale(SPCSSAttr *css, double ex) } +/** + * Quote and/or escape string for writing to CSS, changing strings in place. + * See: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + */ +void +css_quote(Glib::ustring &val) +{ + Glib::ustring out; + bool quote = false; + + // Can't wait for C++11! + for( Glib::ustring::iterator it = val.begin(); it != val.end(); ++it) { + if(g_ascii_isalnum(*it) || *it=='-' || *it=='_' || *it > 0xA0) { + out += *it; + } else if (*it == '\'') { + // Single quotes require escaping and quotes. + out += '\\'; + out += *it; + quote = true; + } else { + // Quote everything else including spaces. + // (CSS Fonts Level 3 recommends quoting with spaces.) + out += *it; + quote = true; + } + if( it == val.begin() && !g_ascii_isalpha(*it) ) { + // A non-ASCII/non-alpha initial value on any indentifier needs quotes. + // (Actually it's a bit more complicated but as it never hurts to quote...) + quote = true; + } + } + if( quote ) { + out.insert( out.begin(), '\'' ); + out += '\''; + } + val = out; +} + + +/** + * Quote font names in font-family lists, changing string in place. + * We use unquoted names internally but some need to be quoted in CSS. + */ +void +css_font_family_quote(Glib::ustring &val) +{ + std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", val ); + + val.erase(); + for( unsigned i=0; i < tokens.size(); ++i ) { + css_quote( tokens[i] ); + val += tokens[i] + ", "; + } + if( val.size() > 1 ) + val.erase( val.size() - 2 ); // Remove trailing ", " +} + + // Called in style-internal.cpp, xml/repr-css.cpp /** * Remove paired single and double quotes from a string, changing string in place. - * Note: in CSS (in style= and in stylesheets), unquoting and unescaping is done - * by libcroco, our CSS parser, though it adds a new pair of "" quotes for the strings - * it parsed for us. */ void css_unquote(Glib::ustring &val) @@ -1849,7 +1904,7 @@ css_unquote(Glib::ustring &val) /** * Remove paired single and double quotes from font names in font-family lists, * changing string in place. - * Pango expects unquoted font family names. We use unquoted names in interface. + * We use unquoted family names internally but CSS sometimes uses quoted names. */ void css_font_family_unquote(Glib::ustring &val) @@ -1865,57 +1920,6 @@ css_font_family_unquote(Glib::ustring &val) val.erase( val.size() - 2 ); // Remove trailing ", " } -// Called in style.cpp, xml/repr-css.cpp -/** - * Quote and/or escape string for writing to CSS (style=). Returned value must be g_free'd. - */ -Glib::ustring css2_escape_quote(gchar const *val) { - - Glib::ustring t; - bool quote = false; - bool last_was_space = false; - - for (gchar const *i = val; *i; i++) { - bool is_space = ( *i == ' ' ); - if (g_ascii_isalnum(*i) || *i=='-' || *i=='_') { - // ASCII alphanumeric, - and _ don't require quotes - t.push_back(*i); - } else if ( is_space && !last_was_space ) { - // non-consecutive spaces don't require quotes - t.push_back(*i); - } else if (*i=='\'') { - // single quotes require escaping and quotes - t.push_back('\\'); - t.push_back(*i); - quote = true; - } else { - // everything else requires quotes - t.push_back(*i); - quote = true; - } - if (i == val && !g_ascii_isalpha(*i)) { - // a non-ASCII/non-alpha initial character requires quotes - quote = true; - } - last_was_space = is_space; - } - - if (last_was_space) { - // a trailing space requires quotes - quote = true; - } - - if (quote) { - // we use single quotes so the result can be stored in an XML - // attribute without incurring un-aesthetic additional quoting - // (our XML emitter always uses double quotes) - t.insert(t.begin(), '\''); - t.push_back('\''); - } - - return t; -} - /* Local Variables: mode:c++ diff --git a/src/style.h b/src/style.h index 506b90b44..931dcc90e 100644 --- a/src/style.h +++ b/src/style.h @@ -292,7 +292,9 @@ void sp_style_unset_property_attrs(SPObject *o); void sp_style_set_property_url (SPObject *item, gchar const *property, SPObject *linked, bool recursive); +void css_quote( Glib::ustring &val ); // Add quotes around CSS values void css_unquote( Glib::ustring &val ); // Remove quotes from CSS values (style-internal.cpp, xml/repr-css.cpp) +void css_font_family_quote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp void css_font_family_unquote( Glib::ustring &val ); // style-internal.cpp, text-toolbar.cpp Glib::ustring css2_escape_quote(gchar const *val); diff --git a/src/xml/repr-css.cpp b/src/xml/repr-css.cpp index e462f70da..c043904a7 100644 --- a/src/xml/repr-css.cpp +++ b/src/xml/repr-css.cpp @@ -283,14 +283,7 @@ void sp_repr_css_write_string(SPCSSAttr *css, Glib::ustring &str) str.append(g_quark_to_string(iter->key)); str.push_back(':'); - if (!strcmp(g_quark_to_string(iter->key), "font-family") - || !strcmp(g_quark_to_string(iter->key), "-inkscape-font-specification")) { - // we only quote font-family/font-specification, as SPStyle does - Glib::ustring val_quoted = css2_escape_quote (iter->value); - str.append(val_quoted); - } else { - str.append(iter->value); // unquoted - } + str.append(iter->value); // Any necessary quoting to be done by calling routine. if (rest(iter)) { str.push_back(';'); @@ -346,13 +339,23 @@ void sp_repr_css_merge(SPCSSAttr *dst, SPCSSAttr *src) /** * Merges style properties as parsed by libcroco into an existing SPCSSAttr. + * libcroco converts all single quotes to double quotes, which needs to be + * undone as we always use single quotes inside our 'style' strings since + * double quotes are used outside: e.g.: + * style="font-family:'DejaVu Sans'" */ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *const decl) { guchar *const str_value_unsigned = cr_term_to_string(decl->value); - Glib::ustring value_unquoted( reinterpret_cast(str_value_unsigned ) ); - css_unquote( value_unquoted ); // libcroco returns strings quoted in "", remove + Glib::ustring value( reinterpret_cast(str_value_unsigned ) ); + g_free(str_value_unsigned); + + Glib::ustring::size_type pos = 0; + while( (pos=value.find("\"",pos)) != Glib::ustring::npos) { + value.replace(pos,1,"'"); + ++pos; + } Glib::ustring units; @@ -363,11 +366,11 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con * * HACK for now is to strip off em and ex units and add them back at the end */ - int le = value_unquoted.length(); + int le = value.length(); if (le > 2) { - units = value_unquoted.substr(le-2, 2); + units = value.substr(le-2, 2); if ((units == "em") || (units == "ex")) { - value_unquoted = value_unquoted.substr(0, le-2); + value = value.substr(0, le-2); } else { units.clear(); @@ -378,7 +381,7 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con // CSSOStringStream is used here to write valid CSS (as in sp_style_write_string). This has // the additional benefit of respecting the numerical precission set in the SVG Output // preferences. We assume any numerical part comes first (if not, the whole string is copied). - std::stringstream ss( value_unquoted ); + std::stringstream ss( value ); double number = 0; std::string characters; std::string temp; @@ -400,7 +403,6 @@ static void sp_repr_css_merge_from_decl(SPCSSAttr *css, CRDeclaration const *con //g_message("sp_repr_css_merge_from_decl looks like em or ex units %s --> %s", str_value, os.str().c_str()); } ((Node *) css)->setAttribute(decl->property->stryng->str, os.str().c_str(), false); - g_free(str_value_unsigned); } /** -- cgit v1.2.3 From a3a5028bba5f7ec0f94bb90119d9ea884231dcdf Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 10 Jun 2014 13:49:28 +0200 Subject: Remove 'font' shorthand if we have written out font longhand properties. (bzr r13416) --- src/desktop-style.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 37f537cc5..f6347e5c0 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -211,11 +211,17 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write for (GSList const *i = desktop->selection->itemList(); i != NULL; i = i->next) { - // If not text, don't apply text attributes (can a group have text attributes?) + // If not text, don't apply text attributes (can a group have text attributes? Yes! FIXME) if ( SP_IS_TEXT(i->data) || SP_IS_FLOWTEXT(i->data) || SP_IS_TSPAN(i->data) || SP_IS_TREF(i->data) || SP_IS_TEXTPATH(i->data) || SP_IS_FLOWDIV(i->data) || SP_IS_FLOWPARA(i->data) || SP_IS_FLOWTSPAN(i->data)) { + // If any font property has changed, then we have written out the font + // properties in longhand and we need to remove the 'font' shorthand. + if( !sp_repr_css_property_is_unset(css, "font-family") ) { + sp_repr_css_unset_property(css, "font"); + } + sp_desktop_apply_css_recursive(SP_OBJECT(i->data), css, true); } else { -- cgit v1.2.3 From 1b24ee4d691f3b41195c92bbb9f2dde68487ea9d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 10 Jun 2014 13:51:22 +0200 Subject: Remove 'font' shorthand if we have written out font longhand properties. (bzr r13341.1.57) --- src/desktop-style.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 37f537cc5..f6347e5c0 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -211,11 +211,17 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write for (GSList const *i = desktop->selection->itemList(); i != NULL; i = i->next) { - // If not text, don't apply text attributes (can a group have text attributes?) + // If not text, don't apply text attributes (can a group have text attributes? Yes! FIXME) if ( SP_IS_TEXT(i->data) || SP_IS_FLOWTEXT(i->data) || SP_IS_TSPAN(i->data) || SP_IS_TREF(i->data) || SP_IS_TEXTPATH(i->data) || SP_IS_FLOWDIV(i->data) || SP_IS_FLOWPARA(i->data) || SP_IS_FLOWTSPAN(i->data)) { + // If any font property has changed, then we have written out the font + // properties in longhand and we need to remove the 'font' shorthand. + if( !sp_repr_css_property_is_unset(css, "font-family") ) { + sp_repr_css_unset_property(css, "font"); + } + sp_desktop_apply_css_recursive(SP_OBJECT(i->data), css, true); } else { -- cgit v1.2.3 From 31a25d0038886cc01a626fc4479b38fa23d260a5 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Tue, 10 Jun 2014 17:33:00 -0700 Subject: Fix for bugs 1318657 and 1298967 (bzr r13417) --- src/document.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++++------ src/id-clash.cpp | 23 +++++++++-- src/sp-gradient.cpp | 77 +++++++++++++++++++++++++----------- 3 files changed, 174 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/document.cpp b/src/document.cpp index dc7ed254c..f79a00178 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1529,7 +1529,7 @@ void SPDocument::setModifiedSinceSave(bool modified) { /** - * Paste SVG defs from the document retrieved from the clipboard into the active document. + * Paste SVG defs from the document retrieved from the clipboard or imported document into the active document. * @param clipdoc The document to paste. * @pre @c clipdoc != NULL and pasting into the active document is possible. */ @@ -1540,27 +1540,117 @@ void SPDocument::importDefs(SPDocument *source) Inkscape::XML::Node *target_defs = this->getDefs()->getRepr(); prevent_id_clashes(source, this); + + int stagger=0; + /* Note, "clipboard" throughout the comments means "the document that is either the clipboard + or an imported document", as importDefs is called in both contexts. + + The order of the records in the clipboard is unpredictable and there may be both + forward and backwards references to other records within it. There may be definitions in + the clipboard that duplicate definitions in the present document OR that duplicate other + definitions in the clipboard. (Inkscape will not have created these, but they may be read + in from other SVG sources.) + + There are 3 passes to clean this up: + + In the first find and mark definitions in the clipboard that are duplicates of those in the + present document. Change the ID to "RESERVED_FOR_INKSCAPE_DUPLICATE_DEF_XXXXXXXXX". + (Inkscape will not reuse an ID, and the XXXXXXXXX keeps it from automatically creating new ones.) + References in the clipboard to the old clipboard name are converted to the name used + in the current document. + + In the second find and mark definitions in the clipboard that are duplicates of earlier + definitions in the clipbard. Unfortunately this is O(n^2) and could be very slow for a large + SVG with thousands of definitions. As before, references are adjusted to reflect the name + going forward. + + In the final cycle copy over those records not marked with that ID. + + If an SVG file uses the special ID it will cause problems! + + If this function is called because of the paste of a true clipboard the caller will have passed in a + COPY of the clipboard items. That is good, because this routine modifies that document. If the calling + behavior ever changes, so that the same document is passed in on multiple pastes, this routine will break + as in the following example: + 1. Paste clipboard containing B same as A into document containing A. Result, B is dropped + and all references to it will point to A. + 2. Paste same clipboard into a new document. It will not contain A, so there will be unsatisfied + references in that window. + */ + + std::string DuplicateDefString = "RESERVED_FOR_INKSCAPE_DUPLICATE_DEF"; + + /* First pass: remove duplicates in clipboard of definitions in document */ for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) { - gboolean duplicate = false; + /* If this clipboard has been pasted into one document, and is now being pasted into another, + or pasted again into the same, it will already have been processed. If we detect that then + skip the rest of this pass. */ + + Glib::ustring defid = def->attribute("id"); + if( defid.find( DuplicateDefString ) != Glib::ustring::npos )break; + SPObject *src = source->getObjectByRepr(def); // Prevent duplicates of solid swatches by checking if equivalent swatch already exists if (src && SP_IS_GRADIENT(src)) { - SPGradient *gr = SP_GRADIENT(src); + SPGradient *s_gr = SP_GRADIENT(src); for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) { - if (trg && SP_IS_GRADIENT(trg) && src != trg) { - if (gr->isEquivalent(SP_GRADIENT(trg)) && - gr->isAligned(SP_GRADIENT(trg))) { - // Change object references to the existing equivalent gradient - change_def_references(src, trg); - duplicate = true; - break; + if (trg && (src != trg) && SP_IS_GRADIENT(trg)) { + SPGradient *t_gr = SP_GRADIENT(trg); + if (t_gr && s_gr->isEquivalent(t_gr)) { + // Change object references to the existing equivalent gradient + Glib::ustring newid = trg->getId(); + if(newid != defid){ // id could be the same if it is a second paste into the same document + change_def_references(src, trg); + } + gchar *longid = g_strdup_printf("%s_%9.9d", DuplicateDefString.c_str(), stagger++); + def->setAttribute("id", longid ); + g_free(longid); + // do NOT break here, there could be more than 1 duplicate! } } } } + } + + /* Second pass: remove duplicates in clipboard of earlier definitions in clipboard */ + for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) { + Glib::ustring defid = def->attribute("id"); + if( defid.find( DuplicateDefString ) != Glib::ustring::npos )continue; // this one already handled + SPObject *src = source->getObjectByRepr(def); + if (src && SP_IS_GRADIENT(src)) { + SPGradient *s_gr = SP_GRADIENT(src); + for (Inkscape::XML::Node *laterDef = def->next() ; laterDef ; laterDef = laterDef->next()) { + SPObject *trg = source->getObjectByRepr(laterDef); + if(trg && (src != trg) && SP_IS_GRADIENT(trg)) { + Glib::ustring newid = trg->getId(); + if( newid.find( DuplicateDefString ) != Glib::ustring::npos )continue; // this one already handled + SPGradient *t_gr = SP_GRADIENT(trg); + if (t_gr && s_gr->isEquivalent(t_gr)) { + // Change object references to the existing equivalent gradient + // two id's in the clipboard should never be the same, so always change references + change_def_references(trg, src); + gchar *longid = g_strdup_printf("%s_%9.9d", DuplicateDefString.c_str(), stagger++); + laterDef->setAttribute("id", longid ); + g_free(longid); + // do NOT break here, there could be more than 1 duplicate! + } + } + } + } + } + + /* Final pass: copy over those parts which are not duplicates */ + for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) { + + /* Ignore duplicate defs marked in the first pass */ + Glib::ustring defid = def->attribute("id"); + if( defid.find( DuplicateDefString ) != Glib::ustring::npos )continue; + + bool duplicate = false; + SPObject *src = source->getObjectByRepr(def); // Prevent duplication of symbols... could be more clever. // The tag "_inkscape_duplicate" is added to "id" by ClipboardManagerImpl::copySymbol(). @@ -1597,7 +1687,6 @@ void SPDocument::importDefs(SPDocument *source) Inkscape::GC::release(dup); } } - } /* diff --git a/src/id-clash.cpp b/src/id-clash.cpp index 66357b75b..94cdfef59 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -216,8 +216,7 @@ change_clashing_ids(SPDocument *imported_doc, SPDocument *current_doc, if (cd_obj && SP_IS_GRADIENT(cd_obj)) { SPGradient *cd_gr = SP_GRADIENT(cd_obj); - if ( cd_gr->isEquivalent(SP_GRADIENT(elem)) && - cd_gr->isAligned(SP_GRADIENT(elem))) { + if ( cd_gr->isEquivalent(SP_GRADIENT(elem))) { fix_clashing_ids = false; } } @@ -326,8 +325,26 @@ change_def_references(SPObject *from_obj, SPObject *to_obj) std::list::const_iterator it; const std::list::const_iterator it_end = pos->second.end(); for (it = pos->second.begin(); it != it_end; ++it) { - if (it->type == REF_STYLE) { + if (it->type == REF_HREF) { + gchar *new_uri = g_strdup_printf("#%s", to_obj->getId()); + it->elem->getRepr()->setAttribute(it->attr, new_uri); + g_free(new_uri); + } else if (it->type == REF_STYLE) { sp_style_set_property_url(it->elem, it->attr, to_obj, false); + } else if (it->type == REF_URL) { + gchar *url = g_strdup_printf("url(#%s)", to_obj->getId()); + it->elem->getRepr()->setAttribute(it->attr, url); + g_free(url); + } else if (it->type == REF_CLIPBOARD) { + SPCSSAttr *style = sp_repr_css_attr(it->elem->getRepr(), "style"); + gchar *url = g_strdup_printf("url(#%s)", to_obj->getId()); + sp_repr_css_set_property(style, it->attr, url); + g_free(url); + Glib::ustring style_string; + sp_repr_css_write_string(style, style_string); + it->elem->getRepr()->setAttribute("style", style_string.c_str()); + } else { + g_assert(0); // shouldn't happen } } } diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 115cb754a..1479acd69 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -117,12 +117,17 @@ gboolean SPGradient::isEquivalent(SPGradient *that) if (this->getStopCount() != that->getStopCount()) { break; } if (this->hasStops() != that->hasStops()) { break; } if (!this->getVector() || !that->getVector()) { break; } - if ( (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) || - (SP_IS_RADIALGRADIENT(this) && SP_IS_RADIALGRADIENT(that)) || - (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that))) { - /* OK! */ + if (this->isSwatch() != that->isSwatch()) { break; } + if ( this->isSwatch() ){ + // drop down to check stops. } - else { break; } + else if ( + (SP_IS_LINEARGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) || + (SP_IS_RADIALGRADIENT(this) && SP_IS_RADIALGRADIENT(that)) || + (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that))) { + if(!this->isAligned(that))break; + } + else { break; } // this should never happen, some unhandled type of gradient SPStop *as = this->getVector()->getFirstStop(); SPStop *bs = that->getVector()->getFirstStop(); @@ -156,6 +161,18 @@ gboolean SPGradient::isAligned(SPGradient *that) { bool status = FALSE; + /* Some gradients have coordinates/other values specified, some don't. + yes/yes check the coordinates/other values + no/no aligned (because both have all default values) + yes/no not aligned + no/yes not aligned + It is NOT safe to just compare the computed values because if that field has + not been set the computed value could be full of garbage. + + In theory the yes/no and no/yes cases could be aligned if the specified value + matches the default value. + */ + while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function if(this->gradientTransform_set != that->gradientTransform_set) { break; } if(this->gradientTransform_set && @@ -164,31 +181,45 @@ gboolean SPGradient::isAligned(SPGradient *that) SPLinearGradient *sg=SP_LINEARGRADIENT(this); SPLinearGradient *tg=SP_LINEARGRADIENT(that); - if( !sg->x1._set || !tg->x1._set || // assume that if these are set so will be all the others - (sg->x1.computed != tg->x1.computed) || - (sg->y1.computed != tg->y1.computed) || - (sg->x2.computed != tg->x2.computed) || - (sg->y2.computed != tg->y2.computed) - ) { break; } + if( sg->x1._set != tg->x1._set) { break; } + if( sg->y1._set != tg->y1._set) { break; } + if( sg->x2._set != tg->x2._set) { break; } + if( sg->y2._set != tg->y2._set) { break; } + if( sg->x1._set && sg->y1._set && sg->x2._set && sg->y2._set) { + if( (sg->x1.computed != tg->x1.computed) || + (sg->y1.computed != tg->y1.computed) || + (sg->x2.computed != tg->x2.computed) || + (sg->y2.computed != tg->y2.computed) ) { break; } + } else if( sg->x1._set || sg->y1._set || sg->x2._set || sg->y2._set) { break; } // some mix of set and not set + // none set? assume aligned and fall through } else if (SP_IS_RADIALGRADIENT(this) && SP_IS_LINEARGRADIENT(that)) { SPRadialGradient *sg=SP_RADIALGRADIENT(this); SPRadialGradient *tg=SP_RADIALGRADIENT(that); - if( !sg->cx._set || !tg->cx._set || // assume that if these are set so will be all the others - (sg->cx.computed != tg->cx.computed) || - (sg->cy.computed != tg->cy.computed) || - (sg->r.computed != tg->r.computed ) || - (sg->fx.computed != tg->fx.computed) || - (sg->fy.computed != tg->fy.computed) - ) { break; } + + if( sg->cx._set != tg->cx._set) { break; } + if( sg->cy._set != tg->cy._set) { break; } + if( sg->r._set != tg->r._set) { break; } + if( sg->fx._set != tg->fx._set) { break; } + if( sg->fy._set != tg->fy._set) { break; } + if( sg->cx._set && sg->cy._set && sg->fx._set && sg->fy._set && sg->r._set) { + if( (sg->cx.computed != tg->cx.computed) || + (sg->cy.computed != tg->cy.computed) || + (sg->r.computed != tg->r.computed ) || + (sg->fx.computed != tg->fx.computed) || + (sg->fy.computed != tg->fy.computed) ) { break; } + } else if( sg->cx._set || sg->cy._set || sg->fx._set || sg->fy._set || sg->r._set ) { break; } // some mix of set and not set + // none set? assume aligned and fall through } else if (SP_IS_MESHGRADIENT(this) && SP_IS_MESHGRADIENT(that)) { SPMeshGradient *sg=SP_MESHGRADIENT(this); SPMeshGradient *tg=SP_MESHGRADIENT(that); - if( !sg->x._set || !tg->x._set || - !sg->y._set || !tg->y._set || - (sg->x.computed != tg->x.computed) || - (sg->y.computed != tg->y.computed) - ) { break; } + if( sg->x._set != !tg->x._set) { break; } + if( sg->y._set != !tg->y._set) { break; } + if( sg->x._set && sg->y._set) { + if( (sg->x.computed != tg->x.computed) || + (sg->y.computed != tg->y.computed) ) { break; } + } else if( sg->x._set || sg->y._set) { break; } // some mix of set and not set + // none set? assume aligned and fall through } else { break; } -- cgit v1.2.3 From ce72482fe0e31786dbb2c6d3273cafe9b11f0800 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 11 Jun 2014 17:18:58 +0200 Subject: Fix for bug #1241902 (bzr r13418) --- src/box3d-side.cpp | 2 + src/selection-chemistry.cpp | 4 ++ src/sp-ellipse.cpp | 2 + src/sp-item-group.cpp | 36 ++++++++--- src/sp-item-group.h | 2 +- src/sp-lpe-item.cpp | 146 ++++++++++++++++++++++++++++++++++++++++++++ src/sp-lpe-item.h | 2 + src/sp-path.cpp | 2 + src/sp-spiral.cpp | 2 + src/sp-star.cpp | 2 + 10 files changed, 192 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index dfccb63bf..a5e7eaa94 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -213,6 +213,8 @@ void Box3DSide::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 868a9d743..a350dd7a7 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3950,6 +3950,10 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = SP_OBJECT(child)->getRepr()->duplicate(xml_doc); + if(copy->attribute("inkscape:original-d")) + { + copy->setAttribute("d", copy->attribute("inkscape:original-d")); + } items_to_move = g_slist_prepend(items_to_move, copy); } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index cda59e057..428e0e3dd 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -467,6 +467,8 @@ void SPGenericEllipse::set_shape() bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 2cfe97db8..b3db0c1d7 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -778,17 +778,31 @@ void SPGroup::update_patheffect(bool write) { } } + +void +sp_gslist_update_by_clip_or_mask(GSList *item_list,SPItem * item) +{ + if(item->mask_ref->getObject()) { + SPObject * clipormask = item->mask_ref->getObject()->firstChild(); + item_list = g_slist_append(item_list,clipormask); + } + if(item->clip_ref->getObject()) { + SPObject * clipormask = item->clip_ref->getObject()->firstChild(); + item_list = g_slist_append(item_list,clipormask); + } +} + static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) { - GSList const *item_list = sp_item_group_item_list(SP_GROUP(group)); - - for ( GSList const *iter = item_list; iter; iter = iter->next ) { + GSList *item_list = sp_item_group_item_list(group); + sp_gslist_update_by_clip_or_mask(item_list,group); + for ( GSList *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast(iter->data); - if (SP_IS_GROUP(subitem)) { sp_group_perform_patheffect(SP_GROUP(subitem), topgroup, write); } else if (SP_IS_SHAPE(subitem)) { + sp_gslist_update_by_clip_or_mask(item_list,SP_ITEM(subitem)); SPCurve * c = NULL; if (SP_IS_PATH(subitem)) { @@ -799,9 +813,17 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) // only run LPEs when the shape has a curve defined if (c) { - c->transform(i2anc_affine(subitem, topgroup)); + if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { + c->transform(i2anc_affine(group, topgroup)); + } else { + c->transform(i2anc_affine(subitem, topgroup)); + } SP_LPE_ITEM(topgroup)->performPathEffect(c); - c->transform(i2anc_affine(subitem, topgroup).inverse()); + if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { + c->transform(i2anc_affine(group, topgroup).inverse()); + } else { + c->transform(i2anc_affine(subitem, topgroup).inverse()); + } SP_SHAPE(subitem)->setCurve(c, TRUE); if (write) { @@ -809,7 +831,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE -g_message("sp_group_perform_patheffect writes 'd' attribute"); + g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif g_free(str); } diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 2004a72b8..adec35571 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -88,7 +88,7 @@ public: void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true); - +void sp_gslist_update_by_clip_or_mask(GSList *item_list, SPItem * item); GSList *sp_item_group_item_list (SPGroup *group); SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index b5dd74fc6..bfecdcf98 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -38,6 +38,11 @@ #include "desktop.h" #include "shape-editor.h" #include "sp-ellipse.h" +#include "display/curve.h" +#include "svg/svg.h" +#include <2geom/pathvector.h> +#include "sp-clippath.h" +#include "sp-mask.h" #include "tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/tools/tool-base.h" @@ -51,6 +56,8 @@ static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeit static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem); +static void sp_lpe_item_apply_to_clip_or_mask_group(SPGroup * group, SPItem * item); + typedef std::list HRefList; static std::string patheffectlist_write_svg(PathEffectList const & list); static std::string hreflist_write_svg(HRefList const & list); @@ -332,6 +339,16 @@ lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem) static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) + { + sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); + if(clipPath) + { + sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + } if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { @@ -352,6 +369,17 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) { + SPMask * mask = lpeitem->mask_ref->getObject(); + if(mask) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); + if(clipPath) + { + sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + } + if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { @@ -597,6 +625,124 @@ bool SPLPEItem::hasPathEffectRecursive() const } } +void +sp_lpe_item_apply_to_clippath(SPItem * item) +{ + SPClipPath *clipPath = item->clip_ref->getObject(); + if(clipPath) { + SPObject * clip_data = clipPath->firstChild(); + SPCurve * clip_curve = NULL; + + if (SP_IS_PATH(clip_data)) { + clip_curve = SP_PATH(clip_data)->get_original_curve(); + } else if(SP_IS_SHAPE(clip_data)) { + clip_curve = SP_SHAPE(clip_data)->getCurve(); + } else if(SP_IS_GROUP(clip_data)) { + sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(clip_data), item); + return; + } + if(clip_curve) { + bool success = SP_LPE_ITEM(item)->performPathEffect(clip_curve); + Inkscape::XML::Node *reprClip = clip_data->getRepr(); + if (success) { + gchar *str = sp_svg_write_path(clip_curve->get_pathvector()); + reprClip->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = reprClip->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + SP_SHAPE(clip_data)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + clip_curve->unref(); + } + } +} + +void +sp_lpe_item_apply_to_mask(SPItem * item) +{ + SPMask *mask = item->mask_ref->getObject(); + if(mask) { + SPObject * mask_data = mask->firstChild(); + SPCurve * mask_curve = NULL; + mask_data = mask->firstChild(); + if (SP_IS_PATH(mask_data)) { + mask_curve = SP_PATH(mask_data)->get_original_curve(); + } else if(SP_IS_SHAPE(mask_data)) { + mask_curve = SP_SHAPE(mask_data)->getCurve(); + } else if(SP_IS_GROUP(mask_data)) { + sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(mask_data), item); + return; + } + if(mask_curve) { + bool success = SP_LPE_ITEM(item)->performPathEffect(mask_curve); + Inkscape::XML::Node *reprmask = mask_data->getRepr(); + if (success) { + gchar *str = sp_svg_write_path(mask_curve->get_pathvector()); + reprmask->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = reprmask->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + SP_SHAPE(mask_data)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + mask_curve->unref(); + } + } +} + +static void +sp_lpe_item_apply_to_clip_or_mask_group(SPGroup *group, SPItem *item) +{ + GSList *item_list = sp_item_group_item_list(group); + for ( GSList *iter = item_list; iter; iter = iter->next ) { + SPObject *subitem = static_cast(iter->data); + if (SP_IS_GROUP(subitem)) { + sp_lpe_item_apply_to_clip_or_mask_group(SP_GROUP(subitem), item); + } else if (SP_IS_SHAPE(subitem)) { + SPCurve * c = NULL; + + if (SP_IS_PATH(subitem)) { + c = SP_PATH(subitem)->get_original_curve(); + } else { + c = SP_SHAPE(subitem)->getCurve(); + } + if (c) { + bool success = SP_LPE_ITEM(item)->performPathEffect(c); + Inkscape::XML::Node *repr = subitem->getRepr(); + if (success) { + gchar *str = sp_svg_write_path(c->get_pathvector()); + repr->setAttribute("d", str); + g_free(str); + } else { + // LPE was unsuccesfull. Read the old 'd'-attribute. + if (gchar const * value = repr->attribute("d")) { + Geom::PathVector pv = sp_svg_read_pathv(value); + SPCurve *oldcurve = new SPCurve(pv); + if (oldcurve) { + SP_SHAPE(subitem)->setCurve(oldcurve, TRUE); + oldcurve->unref(); + } + } + } + c->unref(); + } + } + } +} + Inkscape::LivePathEffect::Effect* SPLPEItem::getPathEffectOfType(int type) { diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index cd72ac55b..5a38fdd0b 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -97,6 +97,8 @@ public: void editNextParamOncanvas(SPDesktop *dt); }; +void sp_lpe_item_apply_to_mask(SPItem * item); +void sp_lpe_item_apply_to_clippath(SPItem * item); void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); // careful, class already has method with *very* similar name! #endif /* !SP_LPE_ITEM_H_SEEN */ diff --git a/src/sp-path.cpp b/src/sp-path.cpp index cbb61b0f6..4a68b82c7 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -310,6 +310,8 @@ g_message("sp_path_update_patheffect"); bool success = this->performPathEffect(curve); if (success && write) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 9ef73d56d..8d4a37bf0 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -385,6 +385,8 @@ void SPSpiral::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index eac33ed7b..170a863b5 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -465,6 +465,8 @@ void SPStar::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { + sp_lpe_item_apply_to_mask(this); + sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } -- cgit v1.2.3 From 0a89d049ef926a82f75e40a010193124d54dd94d Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 11 Jun 2014 18:07:06 +0200 Subject: Spray. Fix for bug #1327577 (Tablet pressure button wrongly located in Spray tool control bar). Fixed bugs: - https://launchpad.net/bugs/1327577 (bzr r13419) --- src/widgets/toolbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 3d6f73ef1..939546f78 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -314,8 +314,8 @@ static gchar const * ui_descr = " " " " " " - " " " " + " " " " " " " " -- cgit v1.2.3 From 361b0952280e8e4ec0bf4d3a5cfd6cff26084ab8 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 11 Jun 2014 20:16:02 +0200 Subject: id-clash: clean up code (bzr r13420) --- src/id-clash.cpp | 141 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/id-clash.cpp b/src/id-clash.cpp index 94cdfef59..4bd66e858 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -92,7 +92,7 @@ const char* clipboard_properties[] = { * (e.g., ID selectors in CSS stylesheets, and references in scripts). */ static void -find_references(SPObject *elem, refmap_type *refmap) +find_references(SPObject *elem, refmap_type &refmap) { if (elem->cloned) return; Inkscape::XML::Node *repr_elem = elem->getRepr(); @@ -110,7 +110,7 @@ find_references(SPObject *elem, refmap_type *refmap) gchar *uri = extract_uri(value); if (uri && uri[0] == '#') { IdReference idref = { REF_CLIPBOARD, elem, attr }; - (*refmap)[uri+1].push_back(idref); + refmap[uri+1].push_back(idref); } g_free(uri); } @@ -127,7 +127,7 @@ find_references(SPObject *elem, refmap_type *refmap) if (val && val[0] == '#') { std::string id(val+1); IdReference idref = { REF_HREF, elem, attr }; - (*refmap)[id].push_back(idref); + refmap[id].push_back(idref); } } @@ -142,7 +142,7 @@ find_references(SPObject *elem, refmap_type *refmap) if (obj) { const gchar *id = obj->getId(); IdReference idref = { REF_STYLE, elem, SPIPaint_properties[i] }; - (*refmap)[id].push_back(idref); + refmap[id].push_back(idref); } } } @@ -154,7 +154,7 @@ find_references(SPObject *elem, refmap_type *refmap) if (obj) { const gchar *id = obj->getId(); IdReference idref = { REF_STYLE, elem, "filter" }; - (*refmap)[id].push_back(idref); + refmap[id].push_back(idref); } } @@ -166,7 +166,7 @@ find_references(SPObject *elem, refmap_type *refmap) gchar *uri = extract_uri(value); if (uri && uri[0] == '#') { IdReference idref = { REF_STYLE, elem, markers[i] }; - (*refmap)[uri+1].push_back(idref); + refmap[uri+1].push_back(idref); } g_free(uri); } @@ -180,7 +180,7 @@ find_references(SPObject *elem, refmap_type *refmap) gchar *uri = extract_uri(value); if (uri && uri[0] == '#') { IdReference idref = { REF_URL, elem, attr }; - (*refmap)[uri+1].push_back(idref); + refmap[uri+1].push_back(idref); } g_free(uri); } @@ -199,7 +199,7 @@ find_references(SPObject *elem, refmap_type *refmap) */ static void change_clashing_ids(SPDocument *imported_doc, SPDocument *current_doc, - SPObject *elem, const refmap_type *refmap, + SPObject *elem, refmap_type const &refmap, id_changelist_type *id_changes) { const gchar *id = elem->getId(); @@ -233,9 +233,9 @@ change_clashing_ids(SPDocument *imported_doc, SPDocument *current_doc, } // Change to the new ID - elem->getRepr()->setAttribute("id", new_id.c_str()); + elem->getRepr()->setAttribute("id", new_id); // Make a note of this change, if we need to fix up refs to it - if (refmap->find(old_id) != refmap->end()) + if (refmap.find(old_id) != refmap.end()) id_changes->push_back(id_changeitem_type(elem, old_id)); } } @@ -252,36 +252,43 @@ change_clashing_ids(SPDocument *imported_doc, SPDocument *current_doc, * Fix up references to changed IDs. */ static void -fix_up_refs(const refmap_type *refmap, const id_changelist_type &id_changes) +fix_up_refs(refmap_type const &refmap, const id_changelist_type &id_changes) { id_changelist_type::const_iterator pp; const id_changelist_type::const_iterator pp_end = id_changes.end(); for (pp = id_changes.begin(); pp != pp_end; ++pp) { SPObject *obj = pp->first; - refmap_type::const_iterator pos = refmap->find(pp->second); + refmap_type::const_iterator pos = refmap.find(pp->second); std::list::const_iterator it; const std::list::const_iterator it_end = pos->second.end(); for (it = pos->second.begin(); it != it_end; ++it) { - if (it->type == REF_HREF) { - gchar *new_uri = g_strdup_printf("#%s", obj->getId()); - it->elem->getRepr()->setAttribute(it->attr, new_uri); - g_free(new_uri); - } else if (it->type == REF_STYLE) { - sp_style_set_property_url(it->elem, it->attr, obj, false); - } else if (it->type == REF_URL) { - gchar *url = g_strdup_printf("url(#%s)", obj->getId()); - it->elem->getRepr()->setAttribute(it->attr, url); - g_free(url); - } else if (it->type == REF_CLIPBOARD) { - SPCSSAttr *style = sp_repr_css_attr(it->elem->getRepr(), "style"); - gchar *url = g_strdup_printf("url(#%s)", obj->getId()); - sp_repr_css_set_property(style, it->attr, url); - g_free(url); - Glib::ustring style_string; - sp_repr_css_write_string(style, style_string); - it->elem->getRepr()->setAttribute("style", style_string.c_str()); - } else { - g_assert(0); // shouldn't happen + switch (it->type) { + case REF_HREF: { + gchar *new_uri = g_strdup_printf("#%s", obj->getId()); + it->elem->getRepr()->setAttribute(it->attr, new_uri); + g_free(new_uri); + break; + } + case REF_STYLE: { + sp_style_set_property_url(it->elem, it->attr, obj, false); + break; + } + case REF_URL: { + gchar *url = g_strdup_printf("url(#%s)", obj->getId()); + it->elem->getRepr()->setAttribute(it->attr, url); + g_free(url); + break; + } + case REF_CLIPBOARD: { + SPCSSAttr *style = sp_repr_css_attr(it->elem->getRepr(), "style"); + gchar *url = g_strdup_printf("url(#%s)", obj->getId()); + sp_repr_css_set_property(style, it->attr, url); + g_free(url); + Glib::ustring style_string; + sp_repr_css_write_string(style, style_string); + it->elem->getRepr()->setAttribute("style", style_string); + break; + } } } } @@ -296,7 +303,7 @@ fix_up_refs(const refmap_type *refmap, const id_changelist_type &id_changes) void prevent_id_clashes(SPDocument *imported_doc, SPDocument *current_doc) { - refmap_type *refmap = new refmap_type; + refmap_type refmap; id_changelist_type id_changes; SPObject *imported_root = imported_doc->getRoot(); @@ -304,8 +311,6 @@ prevent_id_clashes(SPDocument *imported_doc, SPDocument *current_doc) change_clashing_ids(imported_doc, current_doc, imported_root, refmap, &id_changes); fix_up_refs(refmap, id_changes); - - delete refmap; } /* @@ -314,42 +319,47 @@ prevent_id_clashes(SPDocument *imported_doc, SPDocument *current_doc) void change_def_references(SPObject *from_obj, SPObject *to_obj) { - refmap_type *refmap = new refmap_type; + refmap_type refmap; SPDocument *current_doc = from_obj->document; std::string old_id(from_obj->getId()); find_references(current_doc->getRoot(), refmap); - refmap_type::const_iterator pos = refmap->find(old_id); - if (pos != refmap->end()) { + refmap_type::const_iterator pos = refmap.find(old_id); + if (pos != refmap.end()) { std::list::const_iterator it; const std::list::const_iterator it_end = pos->second.end(); for (it = pos->second.begin(); it != it_end; ++it) { - if (it->type == REF_HREF) { - gchar *new_uri = g_strdup_printf("#%s", to_obj->getId()); - it->elem->getRepr()->setAttribute(it->attr, new_uri); - g_free(new_uri); - } else if (it->type == REF_STYLE) { - sp_style_set_property_url(it->elem, it->attr, to_obj, false); - } else if (it->type == REF_URL) { - gchar *url = g_strdup_printf("url(#%s)", to_obj->getId()); - it->elem->getRepr()->setAttribute(it->attr, url); - g_free(url); - } else if (it->type == REF_CLIPBOARD) { - SPCSSAttr *style = sp_repr_css_attr(it->elem->getRepr(), "style"); - gchar *url = g_strdup_printf("url(#%s)", to_obj->getId()); - sp_repr_css_set_property(style, it->attr, url); - g_free(url); - Glib::ustring style_string; - sp_repr_css_write_string(style, style_string); - it->elem->getRepr()->setAttribute("style", style_string.c_str()); - } else { - g_assert(0); // shouldn't happen - } + switch (it->type) { + case REF_HREF: { + gchar *new_uri = g_strdup_printf("#%s", to_obj->getId()); + it->elem->getRepr()->setAttribute(it->attr, new_uri); + g_free(new_uri); + break; + } + case REF_STYLE: { + sp_style_set_property_url(it->elem, it->attr, to_obj, false); + break; + } + case REF_URL: { + gchar *url = g_strdup_printf("url(#%s)", to_obj->getId()); + it->elem->getRepr()->setAttribute(it->attr, url); + g_free(url); + break; + } + case REF_CLIPBOARD: { + SPCSSAttr *style = sp_repr_css_attr(it->elem->getRepr(), "style"); + gchar *url = g_strdup_printf("url(#%s)", to_obj->getId()); + sp_repr_css_set_property(style, it->attr, url); + g_free(url); + Glib::ustring style_string; + sp_repr_css_write_string(style, style_string); + it->elem->getRepr()->setAttribute("style", style_string); + break; + } + } } } - - delete refmap; } /* @@ -372,8 +382,7 @@ void rename_id(SPObject *elem, Glib::ustring const &new_name) } SPDocument *current_doc = elem->document; - refmap_type *refmap = new refmap_type; - id_changelist_type id_changes; + refmap_type refmap; find_references(current_doc->getRoot(), refmap); std::string old_id(elem->getId()); @@ -391,14 +400,14 @@ void rename_id(SPObject *elem, Glib::ustring const &new_name) } // Change to the new ID - elem->getRepr()->setAttribute("id", new_name2.c_str()); + elem->getRepr()->setAttribute("id", new_name2); // Make a note of this change, if we need to fix up refs to it - if (refmap->find(old_id) != refmap->end()) { + id_changelist_type id_changes; + if (refmap.find(old_id) != refmap.end()) { id_changes.push_back(id_changeitem_type(elem, old_id)); } fix_up_refs(refmap, id_changes); - delete refmap; } /* -- cgit v1.2.3 From 4c15ea8f3e7635bd9a40ab65bccc0261f977c46e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 11 Jun 2014 20:53:35 +0200 Subject: Extensions. Fix for Bug #505920 (inkscape loads extension even if the script specified in doesn't exist). Fixed bugs: - https://launchpad.net/bugs/505920 (bzr r13421) --- src/extension/dependency.cpp | 20 ++++++++++++++------ src/extension/extension.cpp | 3 +++ 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/extension/dependency.cpp b/src/extension/dependency.cpp index 78012ccc8..e46b6fbd2 100644 --- a/src/extension/dependency.cpp +++ b/src/extension/dependency.cpp @@ -57,14 +57,22 @@ Dependency::Dependency (Inkscape::XML::Node * in_repr) Inkscape::GC::anchor(_repr); - const gchar * location = _repr->attribute("location"); - for (int i = 0; i < LOCATION_CNT && location != NULL; i++) { - if (!strcmp(location, _location_str[i])) { - _location = (location_t)i; - break; + if (const gchar * location = _repr->attribute("location")) { + for (int i = 0; i < LOCATION_CNT && location != NULL; i++) { + if (!strcmp(location, _location_str[i])) { + _location = (location_t)i; + break; + } + } + } else if (const gchar * location = _repr->attribute("reldir")) { + for (int i = 0; i < LOCATION_CNT && location != NULL; i++) { + if (!strcmp(location, _location_str[i])) { + _location = (location_t)i; + break; + } } } - + const gchar * type = _repr->attribute("type"); for (int i = 0; i < TYPE_CNT && type != NULL; i++) { if (!strcmp(type, _type_str[i])) { diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index 588efb521..06e35ff3e 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -111,6 +111,9 @@ Extension::Extension (Inkscape::XML::Node * in_repr, Implementation::Implementat if (!strcmp(chname, "dependency")) { _deps.push_back(new Dependency(child_repr)); } /* dependency */ + if (!strcmp(chname, "script")) { + _deps.push_back(new Dependency(child_repr->firstChild())); + } /* check command as a dependency (see LP #505920) */ if (!strcmp(chname, "options")) { silent = !strcmp( child_repr->attribute("silent"), "true" ); } -- cgit v1.2.3 From b2ae5212d7df04a0b973571748d402d5663312d6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 11 Jun 2014 23:53:17 +0200 Subject: pen tool: fix crash when finishing path with right-click or enter while dragging from path's startnode (otherwise closing the path) Fixed bugs: - https://launchpad.net/bugs/1326652 (bzr r13422) --- src/ui/tools/pen-tool.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 09c0a2a4f..b089065e8 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -481,6 +481,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { ret = true; } else if (bevent.button == 3 && this->npoints != 0) { // right click - finish path + this->ea = NULL; // unset end anchor if set (otherwise crashes) this->_finish(false); ret = true; } @@ -1018,6 +1019,7 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { case GDK_KEY_Return: case GDK_KEY_KP_Enter: if (this->npoints != 0) { + this->ea = NULL; // unset end anchor if set (otherwise crashes) this->_finish(false); ret = true; } -- cgit v1.2.3 From 61a6f2cc2082528d4df3147c39d3e16d41388db4 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 09:30:53 +0200 Subject: Display symbols in document order. Fix typo in FlowSymbols.svg (bzr r13424) --- src/ui/dialog/symbols.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0dfd915fe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -613,6 +613,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList *l = NULL; l = symbols_in_doc_recursive (symbolDocument->getRoot(), l ); + l = g_slist_reverse( l ); return l; } -- cgit v1.2.3 From 5e1c70580e6d156716aba9e5dcc62a15a215da06 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 09:34:58 +0200 Subject: Display symbols in document order. (bzr r13341.1.58) --- src/ui/dialog/symbols.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 8e0d085a4..0dfd915fe 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -613,6 +613,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) { GSList *l = NULL; l = symbols_in_doc_recursive (symbolDocument->getRoot(), l ); + l = g_slist_reverse( l ); return l; } -- cgit v1.2.3 From ba2d7d753aec7f4c356d3fec1f07f79db5e56eec Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 18:06:01 +0200 Subject: Allow symbol zooming independent of icon screen size. (bzr r13425) --- src/ui/dialog/symbols.cpp | 72 +++++++++++++++++++++++++++++++++++++++-------- src/ui/dialog/symbols.h | 9 +++++- 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 0dfd915fe..c58df864c 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -219,25 +219,27 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : Gtk::Label* spacer = Gtk::manage(new Gtk::Label("")); tools->pack_start(* Gtk::manage(spacer)); - in_sizes = 2; // Default 32px + // Pack size (controls display area) + pack_size = 2; // Default 32px button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); - button->set_tooltip_text(_("Make Icons bigger by zooming in.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-more")))) ); + button->set_tooltip_text(_("Display more icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore)); tools->pack_start(* button, Gtk::PACK_SHRINK); button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); - button->set_tooltip_text(_("Make Icons smaller by zooming out.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-less")))) ); + button->set_tooltip_text(_("Display fewer icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless)); tools->pack_start(* button, Gtk::PACK_SHRINK); + // Toggle scale to fit on/off fitSymbol = Gtk::manage(new Gtk::ToggleButton()); fitSymbol->add(*Gtk::manage(Glib::wrap( sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-fit")))) ); @@ -248,6 +250,28 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : fitSymbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild)); tools->pack_start(* fitSymbol, Gtk::PACK_SHRINK); + // Render size (scales symbols within display area) + scale_factor = 0; // Default 1:1 * pack_size/pack_size default + zoomOut = Gtk::manage(new Gtk::Button()); + zoomOut->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); + zoomOut->set_tooltip_text(_("Make symbols smaller by zooming out.")); + zoomOut->set_relief( Gtk::RELIEF_NONE ); + zoomOut->set_focus_on_click( false ); + zoomOut->set_sensitive( false ); + zoomOut->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + tools->pack_start(* zoomOut, Gtk::PACK_SHRINK); + + zoomIn = Gtk::manage(new Gtk::Button()); + zoomIn->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); + zoomIn->set_tooltip_text(_("Make symbols bigger by zooming in.")); + zoomIn->set_relief( Gtk::RELIEF_NONE ); + zoomIn->set_focus_on_click( false ); + zoomIn->set_sensitive( false ); + zoomIn->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + tools->pack_start(* zoomIn, Gtk::PACK_SHRINK); + ++row; /**********************************************************/ @@ -298,22 +322,44 @@ SymbolsDialog& SymbolsDialog::getInstance() return *new SymbolsDialog(); } +void SymbolsDialog::packless() { + if(pack_size < 4) { + pack_size++; + rebuild(); + } +} + +void SymbolsDialog::packmore() { + if(pack_size > 0) { + pack_size--; + rebuild(); + } +} + void SymbolsDialog::zoomin() { - if(in_sizes < 4) { - in_sizes++; + if(scale_factor < 4) { + scale_factor++; rebuild(); } } void SymbolsDialog::zoomout() { - if(in_sizes > 0) { - in_sizes--; + if(scale_factor > -8) { + scale_factor--; rebuild(); } } void SymbolsDialog::rebuild() { + if( fitSymbol->get_active() ) { + zoomIn->set_sensitive( false ); + zoomOut->set_sensitive( false ); + } else { + zoomIn->set_sensitive( true); + zoomOut->set_sensitive( true ); + } + store->clear(); Glib::ustring symbolSetString = symbolSet->get_active_text(); @@ -757,7 +803,7 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->ensureUpToDate(); SPItem *item = SP_ITEM(object_temp); - unsigned psize = SYMBOL_ICON_SIZES[in_sizes]; + unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); // We could use cache here, but it doesn't really work with the structure @@ -779,6 +825,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) if( fitSymbol->get_active() ) scale = psize / std::max(width, height); + else + scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0; pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize)); } diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index 8021fb0c1..5dc1e3cad 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -65,6 +65,8 @@ private: static SymbolColumns *getColumns(); + void packless(); + void packmore(); void zoomin(); void zoomout(); void rebuild(); @@ -95,13 +97,18 @@ private: std::map symbolSets; // Index into sizes which is selected - int in_sizes; + int pack_size; + + // Scale factor + int scale_factor; Glib::RefPtr store; Gtk::ComboBoxText* symbolSet; Gtk::IconView* iconView; Gtk::Button* addSymbol; Gtk::Button* removeSymbol; + Gtk::Button* zoomIn; + Gtk::Button* zoomOut; Gtk::ToggleButton* fitSymbol; void setTargetDesktop(SPDesktop *desktop); -- cgit v1.2.3 From 5390e245e922648d989bfa10e0613e2f588a9cc7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 13 Jun 2014 18:11:54 +0200 Subject: Allow symbol zooming independent of icon screen size. (bzr r13341.1.60) --- src/ui/dialog/symbols.cpp | 72 +++++++++++++++++++++++++++++++++++++++-------- src/ui/dialog/symbols.h | 9 +++++- 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 0dfd915fe..c58df864c 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -219,25 +219,27 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : Gtk::Label* spacer = Gtk::manage(new Gtk::Label("")); tools->pack_start(* Gtk::manage(spacer)); - in_sizes = 2; // Default 32px + // Pack size (controls display area) + pack_size = 2; // Default 32px button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); - button->set_tooltip_text(_("Make Icons bigger by zooming in.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-more")))) ); + button->set_tooltip_text(_("Display more icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packmore)); tools->pack_start(* button, Gtk::PACK_SHRINK); button = Gtk::manage(new Gtk::Button()); button->add(*Gtk::manage(Glib::wrap( - sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); - button->set_tooltip_text(_("Make Icons smaller by zooming out.")); + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("pack-less")))) ); + button->set_tooltip_text(_("Display fewer icons in row.")); button->set_relief( Gtk::RELIEF_NONE ); button->set_focus_on_click( false ); - button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + button->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::packless)); tools->pack_start(* button, Gtk::PACK_SHRINK); + // Toggle scale to fit on/off fitSymbol = Gtk::manage(new Gtk::ToggleButton()); fitSymbol->add(*Gtk::manage(Glib::wrap( sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-fit")))) ); @@ -248,6 +250,28 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : fitSymbol->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::rebuild)); tools->pack_start(* fitSymbol, Gtk::PACK_SHRINK); + // Render size (scales symbols within display area) + scale_factor = 0; // Default 1:1 * pack_size/pack_size default + zoomOut = Gtk::manage(new Gtk::Button()); + zoomOut->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-smaller")))) ); + zoomOut->set_tooltip_text(_("Make symbols smaller by zooming out.")); + zoomOut->set_relief( Gtk::RELIEF_NONE ); + zoomOut->set_focus_on_click( false ); + zoomOut->set_sensitive( false ); + zoomOut->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomout)); + tools->pack_start(* zoomOut, Gtk::PACK_SHRINK); + + zoomIn = Gtk::manage(new Gtk::Button()); + zoomIn->add(*Gtk::manage(Glib::wrap( + sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_ICON("symbol-bigger")))) ); + zoomIn->set_tooltip_text(_("Make symbols bigger by zooming in.")); + zoomIn->set_relief( Gtk::RELIEF_NONE ); + zoomIn->set_focus_on_click( false ); + zoomIn->set_sensitive( false ); + zoomIn->signal_clicked().connect(sigc::mem_fun(*this, &SymbolsDialog::zoomin)); + tools->pack_start(* zoomIn, Gtk::PACK_SHRINK); + ++row; /**********************************************************/ @@ -298,22 +322,44 @@ SymbolsDialog& SymbolsDialog::getInstance() return *new SymbolsDialog(); } +void SymbolsDialog::packless() { + if(pack_size < 4) { + pack_size++; + rebuild(); + } +} + +void SymbolsDialog::packmore() { + if(pack_size > 0) { + pack_size--; + rebuild(); + } +} + void SymbolsDialog::zoomin() { - if(in_sizes < 4) { - in_sizes++; + if(scale_factor < 4) { + scale_factor++; rebuild(); } } void SymbolsDialog::zoomout() { - if(in_sizes > 0) { - in_sizes--; + if(scale_factor > -8) { + scale_factor--; rebuild(); } } void SymbolsDialog::rebuild() { + if( fitSymbol->get_active() ) { + zoomIn->set_sensitive( false ); + zoomOut->set_sensitive( false ); + } else { + zoomIn->set_sensitive( true); + zoomOut->set_sensitive( true ); + } + store->clear(); Glib::ustring symbolSetString = symbolSet->get_active_text(); @@ -757,7 +803,7 @@ SymbolsDialog::draw_symbol(SPObject *symbol) previewDocument->ensureUpToDate(); SPItem *item = SP_ITEM(object_temp); - unsigned psize = SYMBOL_ICON_SIZES[in_sizes]; + unsigned psize = SYMBOL_ICON_SIZES[pack_size]; Glib::RefPtr pixbuf(NULL); // We could use cache here, but it doesn't really work with the structure @@ -779,6 +825,8 @@ SymbolsDialog::draw_symbol(SPObject *symbol) if( fitSymbol->get_active() ) scale = psize / std::max(width, height); + else + scale = pow( 2.0, scale_factor/2.0 ) * psize / 32.0; pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize)); } diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index 8021fb0c1..5dc1e3cad 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -65,6 +65,8 @@ private: static SymbolColumns *getColumns(); + void packless(); + void packmore(); void zoomin(); void zoomout(); void rebuild(); @@ -95,13 +97,18 @@ private: std::map symbolSets; // Index into sizes which is selected - int in_sizes; + int pack_size; + + // Scale factor + int scale_factor; Glib::RefPtr store; Gtk::ComboBoxText* symbolSet; Gtk::IconView* iconView; Gtk::Button* addSymbol; Gtk::Button* removeSymbol; + Gtk::Button* zoomIn; + Gtk::Button* zoomOut; Gtk::ToggleButton* fitSymbol; void setTargetDesktop(SPDesktop *desktop); -- cgit v1.2.3 From 013b60b9f180a1bc0ee43799c6259ff5864fbf81 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 13 Jun 2014 23:04:00 +0200 Subject: Removed original path helper paths pointed by LiamW (bzr r13341.1.61) --- src/live_effects/effect.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index eef954fe2..d0a168a14 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -514,14 +514,6 @@ Effect::getCanvasIndicators(SPLPEItem const* lpeitem) { std::vector hp_vec; - // TODO: we can probably optimize this by using a lot more references - // rather than copying PathVectors all over the place - if (SP_IS_SHAPE(lpeitem) && show_orig_path) { - // add original path to helperpaths - SPCurve* curve = SP_SHAPE(lpeitem)->getCurve (); - hp_vec.push_back(curve->get_pathvector()); - } - // add indicators provided by the effect itself addCanvasIndicators(lpeitem, hp_vec); -- cgit v1.2.3 From eb4d7e1225a2e1e5a5d1da8d0ab784632bc77291 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 14 Jun 2014 14:51:11 -0400 Subject: Add clip group option from Ponyscape (bzr r13090.1.83) --- src/interface.cpp | 11 +++++ src/interface.h | 1 + src/selection-chemistry.cpp | 112 ++++++++++++++++++++++++++++++++++++++++++++ src/selection-chemistry.h | 1 + src/ui/dialog/objects.cpp | 12 +++-- src/verbs.cpp | 5 ++ src/verbs.h | 1 + 7 files changed, 139 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/interface.cpp b/src/interface.cpp index 1cbeb44a3..e47cff598 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -1756,6 +1756,13 @@ void ContextMenu::MakeItemMenu (void) } mi->show(); append(*mi); + + /*SSet Clip Group */ + mi = Gtk::manage(new Gtk::MenuItem(_("Create Clip G_roup"),1)); + mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::CreateGroupClip)); + mi->set_sensitive(TRUE); + mi->show(); + append(*mi); /* Set Clip */ mi = Gtk::manage(new Gtk::MenuItem(_("Set Cl_ip"), 1)); @@ -1867,6 +1874,10 @@ void ContextMenu::ReleaseMask(void) sp_selection_unset_mask(_desktop, false); } +void ContextMenu::CreateGroupClip(void) +{ + sp_selection_set_clipgroup(_desktop); +} void ContextMenu::SetClip(void) { diff --git a/src/interface.h b/src/interface.h index 215a3bfc9..a4eedf9db 100644 --- a/src/interface.h +++ b/src/interface.h @@ -187,6 +187,7 @@ class ContextMenu : public Gtk::Menu void SelectSameStrokeStyle(void); void SelectSameObjectType(void); void ItemCreateLink(void); + void CreateGroupClip(void); void SetMask(void); void ReleaseMask(void); void SetClip(void); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index a350dd7a7..d2f6d692a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3661,6 +3661,118 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) g_free(filepath); } +/* Creates a mask or clipPath from selection. + * What is a clip group? + * A clip group is a tangled mess of XML that allows an object inside a group + * to clip the entire group using a few s and generally irritating me. + */ + +void sp_selection_set_clipgroup(SPDesktop *desktop) +{ + if (desktop == NULL) { + return; + } + SPDocument* doc = sp_desktop_document(desktop); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); + return; + } + + GSList const *l = const_cast(selection->reprList()); + + GSList *p = g_slist_copy(const_cast(l)); + + p = g_slist_sort(p, (GCompareFunc) sp_repr_compare_position); + + selection->clear(); + + gint topmost = (static_cast(g_slist_last(p)->data))->position(); + Inkscape::XML::Node *topmost_parent = (static_cast(g_slist_last(p)->data))->parent(); + + Inkscape::XML::Node *inner = xml_doc->createElement("svg:g"); + inner->setAttribute("inkscape:label", "Clip"); + + while (p) { + Inkscape::XML::Node *current = static_cast(p->data); + + if (current->parent() == topmost_parent) { + Inkscape::XML::Node *spnew = current->duplicate(xml_doc); + sp_repr_unparent(current); + inner->appendChild(spnew); + Inkscape::GC::release(spnew); + topmost --; // only reduce count for those items deleted from topmost_parent + } else { // move it to topmost_parent first + GSList *temp_clip = NULL; + + // At this point, current may already have no item, due to its being a clone whose original is already moved away + // So we copy it artificially calculating the transform from its repr->attr("transform") and the parent transform + gchar const *t_str = current->attribute("transform"); + Geom::Affine item_t(Geom::identity()); + if (t_str) + sp_svg_transform_read(t_str, &item_t); + item_t *= SP_ITEM(doc->getObjectByRepr(current->parent()))->i2doc_affine(); + // FIXME: when moving both clone and original from a transformed group (either by + // grouping into another parent, or by cut/paste) the transform from the original's + // parent becomes embedded into original itself, and this affects its clones. Fix + // this by remembering the transform diffs we write to each item into an array and + // then, if this is clone, looking up its original in that array and pre-multiplying + // it by the inverse of that original's transform diff. + + sp_selection_copy_one(current, item_t, &temp_clip, xml_doc); + sp_repr_unparent(current); + + // paste into topmost_parent (temporarily) + GSList *copied = sp_selection_paste_impl(doc, doc->getObjectByRepr(topmost_parent), &temp_clip); + if (temp_clip) g_slist_free(temp_clip); + if (copied) { // if success, + // take pasted object (now in topmost_parent) + Inkscape::XML::Node *in_topmost = static_cast(copied->data); + // make a copy + Inkscape::XML::Node *spnew = in_topmost->duplicate(xml_doc); + // remove pasted + sp_repr_unparent(in_topmost); + // put its copy into group + inner->appendChild(spnew); + Inkscape::GC::release(spnew); + g_slist_free(copied); + } + } + p = g_slist_remove(p, current); + } + + Inkscape::XML::Node *outer = xml_doc->createElement("svg:g"); + outer->appendChild(inner); + topmost_parent->appendChild(outer); + outer->setPosition(topmost + 1); + + Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); + clone->setAttribute("x", "0", false); + clone->setAttribute("y", "0", false); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", inner->attribute("id")), false); + + clone->setAttribute("inkscape:transform-center-x", inner->attribute("inkscape:transform-center-x"), false); + clone->setAttribute("inkscape:transform-center-y", inner->attribute("inkscape:transform-center-y"), false); + + const Geom::Affine maskTransform(Geom::Affine::identity()); + GSList *templist = NULL; + + templist = g_slist_append(templist, clone); + // add the new clone to the top of the original's parent + gchar const *mask_id = SPClipPath::create(templist, doc, &maskTransform); + + g_slist_free(templist); + + outer->setAttribute("clip-path", g_strdup_printf("url(#%s)", mask_id)); + + Inkscape::GC::release(clone); + + selection->set(outer); + DocumentUndo::done(doc, SP_VERB_OBJECT_SET_CLIPPATH, _("Create Clip Group")); +} + /** * Creates a mask or clipPath from selection. * Two different modes: diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index d76a67a9d..baa530806 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -156,6 +156,7 @@ void sp_document_get_export_hints (SPDocument * doc, Glib::ustring &filename, fl void sp_selection_create_bitmap_copy (SPDesktop *desktop); +void sp_selection_set_clipgroup(SPDesktop *desktop); void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_layer); void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path); diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 85583a0e7..2d558daae 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -106,7 +106,7 @@ enum { BUTTON_LOCK_ALL, BUTTON_UNLOCK_ALL, BUTTON_SETCLIP, -// BUTTON_CLIPGROUP, + BUTTON_CLIPGROUP, // BUTTON_SETINVCLIP, BUTTON_UNSETCLIP, BUTTON_SETMASK, @@ -269,7 +269,7 @@ Gtk::MenuItem& ObjectsPanel::_addPopupItem( SPDesktop *desktop, unsigned int cod } if ( action ) { - label = action->name; + // label = action->name; } } } @@ -1257,6 +1257,10 @@ bool ObjectsPanel::_executeAction() _fireAction( SP_VERB_LAYER_UNLOCK_ALL ); } break; + case BUTTON_CLIPGROUP: + { + _fireAction ( SP_VERB_OBJECT_CREATE_CLIP_GROUP ); + } case BUTTON_SETCLIP: { _fireAction( SP_VERB_OBJECT_SET_CLIPPATH ); @@ -1935,8 +1939,8 @@ ObjectsPanel::ObjectsPanel() : _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_CLIPPATH, 0, "Set Clip", (int)BUTTON_SETCLIP ) ); - //not implemented - //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_CREATE_CLIP_GROUP, 0, "Create Clip Group", (int)BUTTON_CLIPGROUP ) ); //will never be implemented //_watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_OBJECT_SET_INVERSE_CLIPPATH, 0, "Set Inverse Clip", (int)BUTTON_SETINVCLIP ) ); diff --git a/src/verbs.cpp b/src/verbs.cpp index 73613ab9e..f0a49a81a 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1568,6 +1568,9 @@ void ObjectVerb::perform( SPAction *action, void *data) case SP_VERB_OBJECT_SET_CLIPPATH: sp_selection_set_mask(dt, true, false); break; + case SP_VERB_OBJECT_CREATE_CLIP_GROUP: + sp_selection_set_clipgroup(dt); + break; case SP_VERB_OBJECT_EDIT_CLIPPATH: sp_selection_edit_clip_or_mask(dt, true); break; @@ -2717,6 +2720,8 @@ Verb *Verb::_base_verbs[] = { N_("Remove mask from selection"), NULL), new ObjectVerb(SP_VERB_OBJECT_SET_CLIPPATH, "ObjectSetClipPath", N_("_Set"), N_("Apply clipping path to selection (using the topmost object as clipping path)"), NULL), + new ObjectVerb(SP_VERB_OBJECT_CREATE_CLIP_GROUP, "ObjectCreateClipGroup", N_("Create Cl_ip Group"), + N_("Creates a clip group using the selected objects as a base"), NULL), new ObjectVerb(SP_VERB_OBJECT_EDIT_CLIPPATH, "ObjectEditClipPath", N_("_Edit"), N_("Edit clipping path"), INKSCAPE_ICON("path-clip-edit")), new ObjectVerb(SP_VERB_OBJECT_UNSET_CLIPPATH, "ObjectUnSetClipPath", N_("_Release"), diff --git a/src/verbs.h b/src/verbs.h index 821c9ee82..84d31fe42 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -175,6 +175,7 @@ enum { SP_VERB_OBJECT_EDIT_MASK, SP_VERB_OBJECT_UNSET_MASK, SP_VERB_OBJECT_SET_CLIPPATH, + SP_VERB_OBJECT_CREATE_CLIP_GROUP, SP_VERB_OBJECT_EDIT_CLIPPATH, SP_VERB_OBJECT_UNSET_CLIPPATH, /* Tag */ -- cgit v1.2.3 From 72c8020b8036c0f4dce9ce6c0e269a29624ed6f2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 16 Jun 2014 01:02:03 +0200 Subject: add proper refcounting to XML SignalObserver. not refcounting caused crash upon opening Filter Editor dialog for the first time with a filtered object selected. Fixed bugs: - https://launchpad.net/bugs/1328152 (bzr r13426) --- src/xml/helper-observer.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/xml/helper-observer.cpp b/src/xml/helper-observer.cpp index c54dd8e74..e56ddc6f8 100644 --- a/src/xml/helper-observer.cpp +++ b/src/xml/helper-observer.cpp @@ -5,7 +5,7 @@ namespace XML { // Very simple observer that just emits a signal if anything happens to a node SignalObserver::SignalObserver() - : _oldsel(0) + : _oldsel(NULL) {} // Add this observer to the SPObject and remove it from any previous object @@ -13,17 +13,21 @@ void SignalObserver::set(SPObject* o) { // XML Tree being used direcly in this function in the following code // while it shouldn't be + // Pointer to object is stored, so refcounting should be increased/decreased if(_oldsel) { if (_oldsel->getRepr()) { _oldsel->getRepr()->removeObserver(*this); } + sp_object_unref(_oldsel); + _oldsel = NULL; } if(o) { if (o->getRepr()) { o->getRepr()->addObserver(*this); + sp_object_ref(o); + _oldsel = o; } } - _oldsel = o; } void SignalObserver::notifyChildAdded(XML::Node&, XML::Node&, XML::Node*) -- cgit v1.2.3 From bf23e1b45a6ed8990ca3401064840159eeeb47cb Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 16 Jun 2014 20:26:07 +0200 Subject: SignalObserver: fix further refcounting issue in signal observer (bzr r13427) --- src/xml/helper-observer.cpp | 5 +++++ src/xml/helper-observer.h | 1 + 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/xml/helper-observer.cpp b/src/xml/helper-observer.cpp index e56ddc6f8..957f3df0a 100644 --- a/src/xml/helper-observer.cpp +++ b/src/xml/helper-observer.cpp @@ -8,6 +8,11 @@ SignalObserver::SignalObserver() : _oldsel(NULL) {} +SignalObserver::~SignalObserver() +{ + set(NULL); // if _oldsel!=nullptr, remove observer and decrease refcount +} + // Add this observer to the SPObject and remove it from any previous object void SignalObserver::set(SPObject* o) { diff --git a/src/xml/helper-observer.h b/src/xml/helper-observer.h index e7881cd4d..2f70ba792 100644 --- a/src/xml/helper-observer.h +++ b/src/xml/helper-observer.h @@ -17,6 +17,7 @@ namespace Inkscape { { public: SignalObserver(); + ~SignalObserver(); // Add this observer to the SPObject and remove it from any previous object void set(SPObject* o); -- cgit v1.2.3 From ba32027677dee7700542b236410411fca62ba9c7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 16 Jun 2014 23:34:16 +0200 Subject: fixes to LPEKnot, now usable again. knotholder: if knot coords are non-finite, hide knot. used for hiding the lpeknot switcher knot if there are no crossings Fixed bugs: - https://launchpad.net/bugs/781893 (bzr r13428) --- src/knot-holder-entity.cpp | 16 ++++++++++------ src/live_effects/lpe-knot.cpp | 24 +++++++++++++----------- src/live_effects/lpe-knot.h | 1 - 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp index 6471124ec..6af5c6a56 100644 --- a/src/knot-holder-entity.cpp +++ b/src/knot-holder-entity.cpp @@ -80,13 +80,17 @@ KnotHolderEntity::~KnotHolderEntity() void KnotHolderEntity::update_knot() { - Geom::Affine const i2dt(item->i2dt_affine()); + Geom::Point knot_pos(knot_get()); + if (knot_pos.isFinite()) { + Geom::Point dp(knot_pos * item->i2dt_affine()); - Geom::Point dp(knot_get() * i2dt); - - _moved_connection.block(); - knot->setPosition(dp, SP_KNOT_STATE_NORMAL); - _moved_connection.unblock(); + _moved_connection.block(); + knot->setPosition(dp, SP_KNOT_STATE_NORMAL); + _moved_connection.unblock(); + } else { + // knot coords are non-finite, hide knot + knot->hide(); + } } Geom::Point diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 581c632f5..cac3a9347 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -353,7 +353,11 @@ LPEKnot::LPEKnot(LivePathEffectObject *lpeobject) : add_other_stroke_width(_("_Crossing path stroke width"), _("Add crossed stroke width to the interruption size"), "add_other_stroke_width", &wr, this, true), switcher_size(_("S_witcher size:"), _("Orientation indicator/switcher size"), "switcher_size", &wr, this, 15), crossing_points_vector(_("Crossing Signs"), _("Crossings signs"), "crossing_points_vector", &wr, this), - gpaths(),gstroke_widths() + crossing_points(), + gpaths(), + gstroke_widths(), + selectedCrossing(0), + switcher(0.,0.) { // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter( dynamic_cast(&interruption_width) ); @@ -363,10 +367,6 @@ LPEKnot::LPEKnot(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&switcher_size) ); registerParameter( dynamic_cast(&crossing_points_vector) ); - crossing_points = LPEKnotNS::CrossingPoints(); - selectedCrossing = 0; - switcher = Geom::Point(0,0); - _provides_knotholder_entities = true; } @@ -386,9 +386,7 @@ LPEKnot::updateSwitcher(){ //std::cout<<"placing switcher at "<(); - gstroke_widths = std::vector(); + gpaths.clear(); + gstroke_widths.clear(); + collectPathsAndWidths(lpeitem, gpaths, gstroke_widths); // std::cout<<"\nPaths on input:\n"; @@ -586,7 +585,10 @@ LPEKnot::doBeforeEffect (SPLPEItem const* lpeitem) // std::cout< crossing_points_vector;//svg storage of crossing_points LPEKnotNS::CrossingPoints crossing_points;//topology representation of the knot. -- cgit v1.2.3 From b472007094a3724bef949ac45a6294d0e9cb8a01 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 16 Jun 2014 23:39:13 +0200 Subject: LPEItem enabling/disabling: rewrite mechanism to be more robust. the previous nesting behavior was not used, and code relied on non-nesting behavior. (bzr r13429) --- src/sp-lpe-item.cpp | 28 ++++------------------------ src/sp-lpe-item.h | 11 +++++++---- 2 files changed, 11 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index bfecdcf98..ad0902967 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -50,8 +50,6 @@ #include /* LPEItem base class */ -static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); - static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); @@ -115,7 +113,7 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { this->current_path_effect = NULL; // Disable the path effects while populating the LPE list - sp_lpe_item_enable_path_effects(this, false); + enablePathEffects(false); // disconnect all modified listeners: for ( std::list::iterator mod_it = this->lpe_modified_connection_list->begin(); @@ -168,7 +166,7 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { } } - sp_lpe_item_enable_path_effects(this, true); + enablePathEffects(true); } break; @@ -409,7 +407,7 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) sp_lpe_item_update_patheffect(this, false, true); // Disable the path effects while preparing the new lpe - sp_lpe_item_enable_path_effects(this, false); + enablePathEffects(false); // Add the new reference to the list of LPE references HRefList hreflist; @@ -446,7 +444,7 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) } //Enable the path effects now that everything is ready to apply the new path effect - sp_lpe_item_enable_path_effects(this, true); + enablePathEffects(true); // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); @@ -942,24 +940,6 @@ bool SPLPEItem::forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users) return forked; } -// Enable or disable the path effects of the item. -// The counter allows nested calls -static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) -{ - if (enable) { - lpeitem->path_effects_enabled++; - } - else { - lpeitem->path_effects_enabled--; - } -} - -// Are the path effects enabled on this item ? -bool SPLPEItem::pathEffectsEnabled() const -{ - return path_effects_enabled > 0; -} - /* Local Variables: mode:c++ diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 5a38fdd0b..da77ba2ca 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -39,11 +39,13 @@ namespace LivePathEffect{ typedef std::list PathEffectList; class SPLPEItem : public SPItem { +private: + mutable bool path_effects_enabled; // (mutable because preserves logical const-ness) + public: - SPLPEItem(); - virtual ~SPLPEItem(); + SPLPEItem(); + virtual ~SPLPEItem(); - int path_effects_enabled; PathEffectList* path_effect_list; std::list *lpe_modified_connection_list; // this list contains the connections for listening to lpeobject parameter changes @@ -72,7 +74,8 @@ public: bool performPathEffect(SPCurve *curve); - bool pathEffectsEnabled() const; + void enablePathEffects(bool enable) const { path_effects_enabled = enable; }; // (const because logically const) + bool pathEffectsEnabled() const { return path_effects_enabled; }; bool hasPathEffect() const; bool hasPathEffectOfType(int const type) const; bool hasPathEffectRecursive() const; -- cgit v1.2.3 From d960c55b5c993f9d43757a0a0b42a1fc8039c072 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 18 Jun 2014 08:36:04 +0200 Subject: Extensions. Fix for Bug #433860 (Live preview doesn't work after updating the values many times). Fixed bugs: - https://launchpad.net/bugs/433860 (bzr r13430) --- src/extension/prefdialog.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp index 1b657f644..d1f83701f 100644 --- a/src/extension/prefdialog.cpp +++ b/src/extension/prefdialog.cpp @@ -212,6 +212,9 @@ PrefDialog::preview_toggle (void) { void PrefDialog::param_change (void) { if (_exEnv != NULL) { + if (!_effect->loaded()) { + _effect->set_state(Extension::STATE_LOADED); + } _timersig.disconnect(); _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &PrefDialog::param_timer_expire), 250, /* ms */ -- cgit v1.2.3 From 358d04f20095b64680c378af0057d4971c6cf8cc Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Wed, 18 Jun 2014 11:32:51 -0700 Subject: packaging: Update copyrights for the release (bzr r13431) --- src/inkscape.rc | 2 +- src/inkview.rc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/inkscape.rc b/src/inkscape.rc index efa360c8d..395ef39e1 100644 --- a/src/inkscape.rc +++ b/src/inkscape.rc @@ -15,7 +15,7 @@ BEGIN VALUE "FileDescription", "Inkscape" VALUE "FileVersion", "0.48+devel" VALUE "InternalName", "Inkscape" - VALUE "LegalCopyright", " 2012 Inkscape" + VALUE "LegalCopyright", " 2014 Inkscape" VALUE "ProductName", "Inkscape" VALUE "ProductVersion", "0.48+devel" END diff --git a/src/inkview.rc b/src/inkview.rc index f1fa92247..fd7eb50a1 100644 --- a/src/inkview.rc +++ b/src/inkview.rc @@ -15,7 +15,7 @@ BEGIN VALUE "FileDescription", "Inkview" VALUE "FileVersion", "0.48+devel" VALUE "InternalName", "Inkview" - VALUE "LegalCopyright", " 2012 Inkscape" + VALUE "LegalCopyright", " 2014 Inkscape" VALUE "ProductName", "Inkview" VALUE "ProductVersion", "0.48+devel" END -- cgit v1.2.3 From d48060bf77e53bf96126151f6c47e57b3bff63b1 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 19 Jun 2014 16:12:27 -0400 Subject: Fix a crash where the canvas does not have a valid main (bzr r13341.1.64) --- src/widgets/desktop-widget.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 583dbec85..2c28dfbfa 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1246,6 +1246,9 @@ SPDesktopWidget::shutdown() */ void SPDesktopWidget::requestCanvasUpdate() { + // ^^ also this->desktop != 0 + g_return_if_fail (this->desktop != NULL); + g_return_if_fail (this->desktop->main != NULL); gtk_widget_queue_draw (GTK_WIDGET (SP_CANVAS_ITEM (this->desktop->main)->canvas)); } -- cgit v1.2.3 From 78ff8ee1445ce4b4d72e273358fbef6d0105f426 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 19 Jun 2014 16:37:29 -0400 Subject: Fix a crash where the canvas does not have a valid main element (bzr r13433) --- src/widgets/desktop-widget.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 583dbec85..1b4648286 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1246,6 +1246,9 @@ SPDesktopWidget::shutdown() */ void SPDesktopWidget::requestCanvasUpdate() { + // ^^ also this->desktop != 0 + g_return_if_fail(this->desktop != NULL); + g_return_if_fail(this->desktop->main != NULL); gtk_widget_queue_draw (GTK_WIDGET (SP_CANVAS_ITEM (this->desktop->main)->canvas)); } -- cgit v1.2.3 From 106e15e457a9b514a34bf6321d6c5cc386c2f569 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 21 Jun 2014 21:32:06 +0200 Subject: Add new named color 'rebeccapurple' (CSS4 Color). (bzr r13435) --- src/libcroco/cr-rgb.c | 1 + src/svg/svg-color.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/libcroco/cr-rgb.c b/src/libcroco/cr-rgb.c index 06e61ba41..537343579 100644 --- a/src/libcroco/cr-rgb.c +++ b/src/libcroco/cr-rgb.c @@ -150,6 +150,7 @@ static const CRRgb gv_standard_colors[] = { {(const guchar*)"plum", 221, 160, 221, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"powderblue", 176, 224, 230, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"purple", 128, 0, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"rebeccapurple", 102, 51, 153, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"red", 255, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"rosybrown", 188, 143, 143, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"royalblue", 65, 105, 225, FALSE, FALSE, FALSE, {0,0,0}}, diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index 57f542373..ca94c241f 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -173,6 +173,7 @@ static SPSVGColor const sp_svg_color_named[] = { { 0xDDA0DD, "plum" }, { 0xB0E0E6, "powderblue" }, { 0x800080, "purple" }, + { 0x663399, "rebeccapurple" }, { 0xFF0000, "red" }, { 0xBC8F8F, "rosybrown" }, { 0x4169E1, "royalblue" }, -- cgit v1.2.3 From 686e7a0457801d6b06959475a85bc107146b2055 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sat, 21 Jun 2014 21:46:31 +0200 Subject: Add new named color 'rebeccapurple' (CSS4 Color). (bzr r13341.1.65) --- src/libcroco/cr-rgb.c | 1 + src/svg/svg-color.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/libcroco/cr-rgb.c b/src/libcroco/cr-rgb.c index 06e61ba41..537343579 100644 --- a/src/libcroco/cr-rgb.c +++ b/src/libcroco/cr-rgb.c @@ -150,6 +150,7 @@ static const CRRgb gv_standard_colors[] = { {(const guchar*)"plum", 221, 160, 221, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"powderblue", 176, 224, 230, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"purple", 128, 0, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {(const guchar*)"rebeccapurple", 102, 51, 153, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"red", 255, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"rosybrown", 188, 143, 143, FALSE, FALSE, FALSE, {0,0,0}}, {(const guchar*)"royalblue", 65, 105, 225, FALSE, FALSE, FALSE, {0,0,0}}, diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index 57f542373..ca94c241f 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -173,6 +173,7 @@ static SPSVGColor const sp_svg_color_named[] = { { 0xDDA0DD, "plum" }, { 0xB0E0E6, "powderblue" }, { 0x800080, "purple" }, + { 0x663399, "rebeccapurple" }, { 0xFF0000, "red" }, { 0xBC8F8F, "rosybrown" }, { 0x4169E1, "royalblue" }, -- cgit v1.2.3 From 9494f126c9a54446dd5d049bfc5704c702dc9047 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 22 Jun 2014 18:21:48 -0400 Subject: Fix for ungrouping/non-LPEItem masks Fixed bugs: - https://launchpad.net/bugs/1333020 (bzr r13436) --- src/sp-lpe-item.cpp | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index ad0902967..e04d8f841 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -337,16 +337,24 @@ lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem) static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { + g_return_if_fail(lpeitem != NULL); SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) + + if (mask) { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { + sp_lpe_item_create_original_path_recursive(maskChild); + } } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if(clipPath) + if (clipPath) { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { + sp_lpe_item_create_original_path_recursive(clipChild); + } } + if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { @@ -367,15 +375,22 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) { + g_return_if_fail(lpeitem != NULL); SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) + + if (mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { + sp_lpe_item_cleanup_original_path_recursive(maskChild); + } } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if(clipPath) + if (clipPath) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { + sp_lpe_item_cleanup_original_path_recursive(clipChild); + } } if (SP_IS_GROUP(lpeitem)) { -- cgit v1.2.3 From 4ea46d5ce46eaaecce37c97a308762e0895adb61 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 22 Jun 2014 18:31:35 -0400 Subject: Fix for ungrouping/non-LPEItem masks Fixed bugs: - https://launchpad.net/bugs/1333020 (bzr r13341.1.66) --- src/sp-lpe-item.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 15206d446..87c9ad6fd 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -337,15 +337,22 @@ lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem) static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { + g_return_if_fail(lpeitem != NULL); SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) + + if (mask) { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { + sp_lpe_item_create_original_path_recursive(maskChild); + } } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if(clipPath) + if (clipPath) { - sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { + sp_lpe_item_create_original_path_recursive(clipChild); + } } if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); @@ -367,15 +374,22 @@ sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) { + g_return_if_fail(lpeitem != NULL); SPMask * mask = lpeitem->mask_ref->getObject(); - if(mask) + + if (mask) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(mask->firstChild())); + if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { + sp_lpe_item_cleanup_original_path_recursive(maskChild); + } } + SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if(clipPath) + if (clipPath) { - sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(clipPath->firstChild())); + if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { + sp_lpe_item_cleanup_original_path_recursive(clipChild); + } } if (SP_IS_GROUP(lpeitem)) { -- cgit v1.2.3 From 24b274159b8a31784883b5e440457ab90d6107d6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 24 Jun 2014 18:59:15 +0200 Subject: revert rev. 13429 that broke LPE Bend, Envelope, etc etc. very sorry about that. (bzr r13439) --- src/sp-lpe-item.cpp | 28 ++++++++++++++++++++++++---- src/sp-lpe-item.h | 11 ++++------- 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index e04d8f841..a5d70d573 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -50,6 +50,8 @@ #include /* LPEItem base class */ +static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); + static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); @@ -113,7 +115,7 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { this->current_path_effect = NULL; // Disable the path effects while populating the LPE list - enablePathEffects(false); + sp_lpe_item_enable_path_effects(this, false); // disconnect all modified listeners: for ( std::list::iterator mod_it = this->lpe_modified_connection_list->begin(); @@ -166,7 +168,7 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { } } - enablePathEffects(true); + sp_lpe_item_enable_path_effects(this, true); } break; @@ -422,7 +424,7 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) sp_lpe_item_update_patheffect(this, false, true); // Disable the path effects while preparing the new lpe - enablePathEffects(false); + sp_lpe_item_enable_path_effects(this, false); // Add the new reference to the list of LPE references HRefList hreflist; @@ -459,7 +461,7 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) } //Enable the path effects now that everything is ready to apply the new path effect - enablePathEffects(true); + sp_lpe_item_enable_path_effects(this, true); // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); @@ -955,6 +957,24 @@ bool SPLPEItem::forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users) return forked; } +// Enable or disable the path effects of the item. +// The counter allows nested calls +static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) +{ + if (enable) { + lpeitem->path_effects_enabled++; + } + else { + lpeitem->path_effects_enabled--; + } +} + +// Are the path effects enabled on this item ? +bool SPLPEItem::pathEffectsEnabled() const +{ + return path_effects_enabled > 0; +} + /* Local Variables: mode:c++ diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index da77ba2ca..5a38fdd0b 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -39,13 +39,11 @@ namespace LivePathEffect{ typedef std::list PathEffectList; class SPLPEItem : public SPItem { -private: - mutable bool path_effects_enabled; // (mutable because preserves logical const-ness) - public: - SPLPEItem(); - virtual ~SPLPEItem(); + SPLPEItem(); + virtual ~SPLPEItem(); + int path_effects_enabled; PathEffectList* path_effect_list; std::list *lpe_modified_connection_list; // this list contains the connections for listening to lpeobject parameter changes @@ -74,8 +72,7 @@ public: bool performPathEffect(SPCurve *curve); - void enablePathEffects(bool enable) const { path_effects_enabled = enable; }; // (const because logically const) - bool pathEffectsEnabled() const { return path_effects_enabled; }; + bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type) const; bool hasPathEffectRecursive() const; -- cgit v1.2.3 From e6530013ca6fa356b62bdcd0d2ff158617fe0a9f Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 24 Jun 2014 19:26:21 +0200 Subject: fix bug introduced in rev. 13403 (merge with trunk) (bzr r13341.1.67) --- src/sp-lpe-item.cpp | 28 ++++++++++++++++++++++++---- src/sp-lpe-item.h | 11 ++++------- 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 87c9ad6fd..9e2eff6bb 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -50,6 +50,8 @@ #include /* LPEItem base class */ +static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); + static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); @@ -113,7 +115,7 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { this->current_path_effect = NULL; // Disable the path effects while populating the LPE list - enablePathEffects(false); + sp_lpe_item_enable_path_effects(this, false); // disconnect all modified listeners: for ( std::list::iterator mod_it = this->lpe_modified_connection_list->begin(); @@ -166,7 +168,7 @@ void SPLPEItem::set(unsigned int key, gchar const* value) { } } - enablePathEffects(true); + sp_lpe_item_enable_path_effects(this, true); } break; @@ -421,7 +423,7 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) sp_lpe_item_update_patheffect(this, false, true); // Disable the path effects while preparing the new lpe - enablePathEffects(false); + sp_lpe_item_enable_path_effects(this, false); // Add the new reference to the list of LPE references HRefList hreflist; @@ -458,7 +460,7 @@ void SPLPEItem::addPathEffect(gchar *value, bool reset) } //Enable the path effects now that everything is ready to apply the new path effect - enablePathEffects(true); + sp_lpe_item_enable_path_effects(this, true); // Apply the path effect sp_lpe_item_update_patheffect(this, true, true); @@ -970,6 +972,24 @@ bool SPLPEItem::forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users) return forked; } +// Enable or disable the path effects of the item. +// The counter allows nested calls +static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) +{ + if (enable) { + lpeitem->path_effects_enabled++; + } + else { + lpeitem->path_effects_enabled--; + } +} + +// Are the path effects enabled on this item ? +bool SPLPEItem::pathEffectsEnabled() const +{ + return path_effects_enabled > 0; +} + /* Local Variables: mode:c++ diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 2bde25be8..3e858748d 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -39,13 +39,11 @@ namespace LivePathEffect{ typedef std::list PathEffectList; class SPLPEItem : public SPItem { -private: - mutable bool path_effects_enabled; // (mutable because preserves logical const-ness) - public: - SPLPEItem(); - virtual ~SPLPEItem(); + SPLPEItem(); + virtual ~SPLPEItem(); + int path_effects_enabled; PathEffectList* path_effect_list; std::list *lpe_modified_connection_list; // this list contains the connections for listening to lpeobject parameter changes @@ -74,8 +72,7 @@ public: bool performPathEffect(SPCurve *curve); - void enablePathEffects(bool enable) const { path_effects_enabled = enable; }; // (const because logically const) - bool pathEffectsEnabled() const { return path_effects_enabled; }; + bool pathEffectsEnabled() const; bool hasPathEffect() const; bool hasPathEffectOfType(int const type) const; bool hasPathEffectRecursive() const; -- cgit v1.2.3 From f1305982b84adfe04cdeb2686c3b1d7ed3a37bc7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 25 Jun 2014 23:05:33 +0200 Subject: fix windows build (gtk3) partly. broken because of windows.h poluting namespace with "interface" struct name. (bzr r13341.1.68) --- src/ui/dialog/filedialogimpl-win32.h | 3 ++- src/ui/dialog/print.cpp | 9 +++++---- src/ui/widget/preferences-widget.cpp | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index c523f041d..f77249abd 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -22,13 +22,14 @@ #endif #endif +#include "filedialogimpl-gtkmm.h" + #include "gc-core.h" // define WINVER high enough so we get the correct OPENFILENAMEW size #ifndef WINVER #define WINVER 0x0500 #endif #include -#include "filedialogimpl-gtkmm.h" namespace Inkscape diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 03ac9dc64..459e64041 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -13,10 +13,6 @@ #ifdef HAVE_CONFIG_H # include #endif -#ifdef WIN32 -#include -#include -#endif #include "print.h" #include @@ -33,6 +29,11 @@ #include +#ifdef WIN32 +#include +#include +#endif + static void draw_page( #ifdef WIN32 diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 3ba00c083..7f3e6cd47 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -14,10 +14,6 @@ # include #endif -#ifdef WIN32 -#include -#endif - #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include #endif @@ -49,6 +45,10 @@ #include #include +#ifdef WIN32 +#include +#endif + using namespace Inkscape::UI::Widget; namespace Inkscape { -- cgit v1.2.3 From f2ffaaab1e5733120394ca2bbf24403f435e47c4 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 27 Jun 2014 18:22:51 +0200 Subject: Remove the incorrect fix for the bug 1241902 (bzr r13341.1.69) --- src/box3d-side.cpp | 2 -- src/selection-chemistry.cpp | 4 ---- src/sp-ellipse.cpp | 2 -- src/sp-item-group.cpp | 36 +++++++----------------------------- src/sp-item-group.h | 2 +- src/sp-lpe-item.cpp | 36 +++--------------------------------- src/sp-path.cpp | 2 -- src/sp-spiral.cpp | 2 -- src/sp-star.cpp | 2 -- 9 files changed, 11 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index a5e7eaa94..dfccb63bf 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -213,8 +213,6 @@ void Box3DSide::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index a350dd7a7..868a9d743 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3950,10 +3950,6 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = SP_OBJECT(child)->getRepr()->duplicate(xml_doc); - if(copy->attribute("inkscape:original-d")) - { - copy->setAttribute("d", copy->attribute("inkscape:original-d")); - } items_to_move = g_slist_prepend(items_to_move, copy); } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 428e0e3dd..cda59e057 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -467,8 +467,6 @@ void SPGenericEllipse::set_shape() bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index b3db0c1d7..2cfe97db8 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -778,31 +778,17 @@ void SPGroup::update_patheffect(bool write) { } } - -void -sp_gslist_update_by_clip_or_mask(GSList *item_list,SPItem * item) -{ - if(item->mask_ref->getObject()) { - SPObject * clipormask = item->mask_ref->getObject()->firstChild(); - item_list = g_slist_append(item_list,clipormask); - } - if(item->clip_ref->getObject()) { - SPObject * clipormask = item->clip_ref->getObject()->firstChild(); - item_list = g_slist_append(item_list,clipormask); - } -} - static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) { - GSList *item_list = sp_item_group_item_list(group); - sp_gslist_update_by_clip_or_mask(item_list,group); - for ( GSList *iter = item_list; iter; iter = iter->next ) { + GSList const *item_list = sp_item_group_item_list(SP_GROUP(group)); + + for ( GSList const *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast(iter->data); + if (SP_IS_GROUP(subitem)) { sp_group_perform_patheffect(SP_GROUP(subitem), topgroup, write); } else if (SP_IS_SHAPE(subitem)) { - sp_gslist_update_by_clip_or_mask(item_list,SP_ITEM(subitem)); SPCurve * c = NULL; if (SP_IS_PATH(subitem)) { @@ -813,17 +799,9 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) // only run LPEs when the shape has a curve defined if (c) { - if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { - c->transform(i2anc_affine(group, topgroup)); - } else { - c->transform(i2anc_affine(subitem, topgroup)); - } + c->transform(i2anc_affine(subitem, topgroup)); SP_LPE_ITEM(topgroup)->performPathEffect(c); - if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { - c->transform(i2anc_affine(group, topgroup).inverse()); - } else { - c->transform(i2anc_affine(subitem, topgroup).inverse()); - } + c->transform(i2anc_affine(subitem, topgroup).inverse()); SP_SHAPE(subitem)->setCurve(c, TRUE); if (write) { @@ -831,7 +809,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); +g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif g_free(str); } diff --git a/src/sp-item-group.h b/src/sp-item-group.h index adec35571..2004a72b8 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -88,7 +88,7 @@ public: void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true); -void sp_gslist_update_by_clip_or_mask(GSList *item_list, SPItem * item); + GSList *sp_item_group_item_list (SPGroup *group); SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 9e2eff6bb..439e44508 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -340,22 +340,6 @@ static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - SPMask * mask = lpeitem->mask_ref->getObject(); - - if (mask) - { - if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { - sp_lpe_item_create_original_path_recursive(maskChild); - } - } - - SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if (clipPath) - { - if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { - sp_lpe_item_create_original_path_recursive(clipChild); - } - } if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { @@ -377,23 +361,6 @@ static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - SPMask * mask = lpeitem->mask_ref->getObject(); - - if (mask) - { - if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { - sp_lpe_item_cleanup_original_path_recursive(maskChild); - } - } - - SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if (clipPath) - { - if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { - sp_lpe_item_cleanup_original_path_recursive(clipChild); - } - } - if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); for ( GSList const *iter = item_list; iter; iter = iter->next ) { @@ -639,6 +606,9 @@ bool SPLPEItem::hasPathEffectRecursive() const } } +//The next 3 functions are because the revert of the bug 1241902 +//for the moment not used + void sp_lpe_item_apply_to_clippath(SPItem * item) { diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 9d88ec732..d1fb850e1 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -325,8 +325,6 @@ g_message("sp_path_update_patheffect"); bool success = this->performPathEffect(curve); if (success && write) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 8d4a37bf0..9ef73d56d 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -385,8 +385,6 @@ void SPSpiral::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 170a863b5..eac33ed7b 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -465,8 +465,6 @@ void SPStar::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } -- cgit v1.2.3 From 6829ce76e2ab77859c1a5fdacbb2fa71109d65b0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 27 Jun 2014 18:28:46 +0200 Subject: Remove the incorrect fix for the bug 1241902 (bzr r13441) --- src/box3d-side.cpp | 2 -- src/selection-chemistry.cpp | 4 ---- src/sp-ellipse.cpp | 2 -- src/sp-item-group.cpp | 36 +++++++----------------------------- src/sp-item-group.h | 2 +- src/sp-lpe-item.cpp | 35 +++-------------------------------- src/sp-path.cpp | 2 -- src/sp-spiral.cpp | 2 -- src/sp-star.cpp | 2 -- 9 files changed, 11 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp index a5e7eaa94..dfccb63bf 100644 --- a/src/box3d-side.cpp +++ b/src/box3d-side.cpp @@ -213,8 +213,6 @@ void Box3DSide::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index a350dd7a7..868a9d743 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3950,10 +3950,6 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = SP_OBJECT(child)->getRepr()->duplicate(xml_doc); - if(copy->attribute("inkscape:original-d")) - { - copy->setAttribute("d", copy->attribute("inkscape:original-d")); - } items_to_move = g_slist_prepend(items_to_move, copy); } diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index 428e0e3dd..cda59e057 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -467,8 +467,6 @@ void SPGenericEllipse::set_shape() bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync(c_lpe, TRUE); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index b3db0c1d7..2cfe97db8 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -778,31 +778,17 @@ void SPGroup::update_patheffect(bool write) { } } - -void -sp_gslist_update_by_clip_or_mask(GSList *item_list,SPItem * item) -{ - if(item->mask_ref->getObject()) { - SPObject * clipormask = item->mask_ref->getObject()->firstChild(); - item_list = g_slist_append(item_list,clipormask); - } - if(item->clip_ref->getObject()) { - SPObject * clipormask = item->clip_ref->getObject()->firstChild(); - item_list = g_slist_append(item_list,clipormask); - } -} - static void sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) { - GSList *item_list = sp_item_group_item_list(group); - sp_gslist_update_by_clip_or_mask(item_list,group); - for ( GSList *iter = item_list; iter; iter = iter->next ) { + GSList const *item_list = sp_item_group_item_list(SP_GROUP(group)); + + for ( GSList const *iter = item_list; iter; iter = iter->next ) { SPObject *subitem = static_cast(iter->data); + if (SP_IS_GROUP(subitem)) { sp_group_perform_patheffect(SP_GROUP(subitem), topgroup, write); } else if (SP_IS_SHAPE(subitem)) { - sp_gslist_update_by_clip_or_mask(item_list,SP_ITEM(subitem)); SPCurve * c = NULL; if (SP_IS_PATH(subitem)) { @@ -813,17 +799,9 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) // only run LPEs when the shape has a curve defined if (c) { - if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { - c->transform(i2anc_affine(group, topgroup)); - } else { - c->transform(i2anc_affine(subitem, topgroup)); - } + c->transform(i2anc_affine(subitem, topgroup)); SP_LPE_ITEM(topgroup)->performPathEffect(c); - if(SP_IS_MASK(subitem->parent) || SP_IS_CLIPPATH(subitem->parent)) { - c->transform(i2anc_affine(group, topgroup).inverse()); - } else { - c->transform(i2anc_affine(subitem, topgroup).inverse()); - } + c->transform(i2anc_affine(subitem, topgroup).inverse()); SP_SHAPE(subitem)->setCurve(c, TRUE); if (write) { @@ -831,7 +809,7 @@ sp_group_perform_patheffect(SPGroup *group, SPGroup *topgroup, bool write) gchar *str = sp_svg_write_path(c->get_pathvector()); repr->setAttribute("d", str); #ifdef GROUP_VERBOSE - g_message("sp_group_perform_patheffect writes 'd' attribute"); +g_message("sp_group_perform_patheffect writes 'd' attribute"); #endif g_free(str); } diff --git a/src/sp-item-group.h b/src/sp-item-group.h index adec35571..2004a72b8 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -88,7 +88,7 @@ public: void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true); -void sp_gslist_update_by_clip_or_mask(GSList *item_list, SPItem * item); + GSList *sp_item_group_item_list (SPGroup *group); SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name); diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index a5d70d573..321d2fc42 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -340,22 +340,6 @@ static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - SPMask * mask = lpeitem->mask_ref->getObject(); - - if (mask) - { - if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { - sp_lpe_item_create_original_path_recursive(maskChild); - } - } - - SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if (clipPath) - { - if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { - sp_lpe_item_create_original_path_recursive(clipChild); - } - } if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); @@ -378,22 +362,6 @@ static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) { g_return_if_fail(lpeitem != NULL); - SPMask * mask = lpeitem->mask_ref->getObject(); - - if (mask) - { - if (SPLPEItem* maskChild = dynamic_cast(mask->firstChild())) { - sp_lpe_item_cleanup_original_path_recursive(maskChild); - } - } - - SPClipPath * clipPath = lpeitem->clip_ref->getObject(); - if (clipPath) - { - if (SPLPEItem* clipChild = dynamic_cast(clipPath->firstChild())) { - sp_lpe_item_cleanup_original_path_recursive(clipChild); - } - } if (SP_IS_GROUP(lpeitem)) { GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); @@ -640,6 +608,9 @@ bool SPLPEItem::hasPathEffectRecursive() const } } +//The next 3 functions are because the revert of the bug 1241902 +//for the moment not used + void sp_lpe_item_apply_to_clippath(SPItem * item) { diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 4a68b82c7..cbb61b0f6 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -310,8 +310,6 @@ g_message("sp_path_update_patheffect"); bool success = this->performPathEffect(curve); if (success && write) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); // could also do this->getRepr()->updateRepr(); but only the d attribute needs updating. #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp index 8d4a37bf0..9ef73d56d 100644 --- a/src/sp-spiral.cpp +++ b/src/sp-spiral.cpp @@ -385,8 +385,6 @@ void SPSpiral::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 170a863b5..eac33ed7b 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -465,8 +465,6 @@ void SPStar::set_shape() { bool success = this->performPathEffect(c_lpe); if (success) { - sp_lpe_item_apply_to_mask(this); - sp_lpe_item_apply_to_clippath(this); this->setCurveInsync( c_lpe, TRUE); } -- cgit v1.2.3 From 96fec2043bbac0293fb30486d6c6a8650190abff Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 29 Jun 2014 09:21:44 +0200 Subject: Layers. Fix for Bug #1326131 (Can't delete layer from context menu). Fixed bugs: - https://launchpad.net/bugs/1326131 (bzr r13442) --- src/ui/dialog/layers.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index b5dac0595..65351cb68 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -926,9 +926,8 @@ LayersPanel::LayersPanel() : // ------------------------------------------------------- { - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); - _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RENAME, 0, "Rename", (int)BUTTON_RENAME ) ); _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); @@ -944,9 +943,14 @@ LayersPanel::LayersPanel() : _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); - _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), "Up", (int)BUTTON_UP ) ); - _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), "Down", (int)BUTTON_DOWN ) ); + _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("layer-raise"), "Up", (int)BUTTON_UP ) ); + _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("layer-lower"), "Down", (int)BUTTON_DOWN ) ); + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); + + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); + _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DELETE, 0, "Delete", (int)BUTTON_DELETE ) ); + _popupMenu.show_all_children(); } // ------------------------------------------------------- -- cgit v1.2.3 From 74ac381c0cfbee634a7677aba3db6b2a0fd5f13f Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 29 Jun 2014 17:10:43 +0200 Subject: Enable rendering of new filter blend modes (but don't add them to GUI). (bzr r13341.1.70) --- src/display/nr-filter-blend.cpp | 9 ++------- src/display/nr-filter-blend.h | 2 -- src/filter-enums.cpp | 8 +++++--- src/filters/blend.cpp | 8 -------- src/ui/widget/filter-effect-chooser.cpp | 13 +++++-------- 5 files changed, 12 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp index 099816bce..25aea6f13 100644 --- a/src/display/nr-filter-blend.cpp +++ b/src/display/nr-filter-blend.cpp @@ -83,8 +83,7 @@ void FilterBlend::render_cairo(FilterSlot &slot) case BLEND_LIGHTEN: cairo_set_operator(out_ct, CAIRO_OPERATOR_LIGHTEN); break; -#ifdef WITH_CSSBLEND - // NEW + // New in CSS Compositing and Blending Level 1 case BLEND_OVERLAY: cairo_set_operator(out_ct, CAIRO_OPERATOR_OVERLAY); break; @@ -118,7 +117,6 @@ void FilterBlend::render_cairo(FilterSlot &slot) case BLEND_LUMINOSITY: cairo_set_operator(out_ct, CAIRO_OPERATOR_HSL_LUMINOSITY); break; -#endif case BLEND_NORMAL: default: @@ -167,15 +165,12 @@ void FilterBlend::set_input(int input, int slot) { void FilterBlend::set_mode(FilterBlendMode mode) { if (mode == BLEND_NORMAL || mode == BLEND_MULTIPLY || mode == BLEND_SCREEN || mode == BLEND_DARKEN || - mode == BLEND_LIGHTEN -#ifdef WITH_CSSBLEND - || mode == BLEND_OVERLAY || + mode == BLEND_LIGHTEN || mode == BLEND_OVERLAY || mode == BLEND_COLORDODGE || mode == BLEND_COLORBURN || mode == BLEND_HARDLIGHT || mode == BLEND_SOFTLIGHT || mode == BLEND_DIFFERENCE || mode == BLEND_EXCLUSION || mode == BLEND_HUE || mode == BLEND_SATURATION || mode == BLEND_COLOR || mode == BLEND_LUMINOSITY -#endif ) { _blend_mode = mode; diff --git a/src/display/nr-filter-blend.h b/src/display/nr-filter-blend.h index 0a2927d87..c0504993b 100644 --- a/src/display/nr-filter-blend.h +++ b/src/display/nr-filter-blend.h @@ -28,7 +28,6 @@ enum FilterBlendMode { BLEND_SCREEN, BLEND_DARKEN, BLEND_LIGHTEN, -#ifdef WITH_CSSBLEND // New in CSS Compositing and Blending Level 1 BLEND_OVERLAY, BLEND_COLORDODGE, @@ -41,7 +40,6 @@ enum FilterBlendMode { BLEND_SATURATION, BLEND_COLOR, BLEND_LUMINOSITY, -#endif BLEND_ENDMODE, }; diff --git a/src/filter-enums.cpp b/src/filter-enums.cpp index 7ee57f7fa..09a1a7614 100644 --- a/src/filter-enums.cpp +++ b/src/filter-enums.cpp @@ -53,7 +53,6 @@ const EnumData BlendModeData[Inkscape::Filte {Inkscape::Filters::BLEND_SCREEN, _("Screen"), "screen"}, {Inkscape::Filters::BLEND_DARKEN, _("Darken"), "darken"}, {Inkscape::Filters::BLEND_LIGHTEN, _("Lighten"), "lighten"}, -#ifdef WITH_CSSBLEND // New in Compositing and Blending Level 1 {Inkscape::Filters::BLEND_OVERLAY, _("Overlay"), "overlay"}, {Inkscape::Filters::BLEND_COLORDODGE, _("Color Dodge"), "color-dodge"}, @@ -66,10 +65,13 @@ const EnumData BlendModeData[Inkscape::Filte {Inkscape::Filters::BLEND_SATURATION, _("Saturation"), "saturation"}, {Inkscape::Filters::BLEND_COLOR, _("Color"), "color"}, {Inkscape::Filters::BLEND_LUMINOSITY, _("Luminosity"), "luminosity"} -#endif }; +#ifdef WITH_CSSBLEND const EnumDataConverter BlendModeConverter(BlendModeData, Inkscape::Filters::BLEND_ENDMODE); - +#else +// Disable new blend modes in GUI until widely implemented. +const EnumDataConverter BlendModeConverter(BlendModeData, Inkscape::Filters::BLEND_OVERLAY); +#endif const EnumData ColorMatrixTypeData[Inkscape::Filters::COLORMATRIX_ENDTYPE] = { {Inkscape::Filters::COLORMATRIX_MATRIX, _("Matrix"), "matrix"}, diff --git a/src/filters/blend.cpp b/src/filters/blend.cpp index 5c78f4f9f..fd5a9871e 100644 --- a/src/filters/blend.cpp +++ b/src/filters/blend.cpp @@ -96,23 +96,18 @@ static Inkscape::Filters::FilterBlendMode sp_feBlend_readmode(gchar const *value case 's': if (strncmp(value, "screen", 6) == 0) return Inkscape::Filters::BLEND_SCREEN; -#ifdef WITH_CSSBLEND if (strncmp(value, "saturation", 6) == 0) return Inkscape::Filters::BLEND_SATURATION; -#endif break; case 'd': if (strncmp(value, "darken", 6) == 0) return Inkscape::Filters::BLEND_DARKEN; -#ifdef WITH_CSSBLEND if (strncmp(value, "difference", 10) == 0) return Inkscape::Filters::BLEND_DIFFERENCE; -#endif break; case 'l': if (strncmp(value, "lighten", 7) == 0) return Inkscape::Filters::BLEND_LIGHTEN; -#ifdef WITH_CSSBLEND if (strncmp(value, "luminosity", 10) == 0) return Inkscape::Filters::BLEND_LUMINOSITY; break; @@ -137,7 +132,6 @@ static Inkscape::Filters::FilterBlendMode sp_feBlend_readmode(gchar const *value case 'e': if (strncmp(value, "exclusion", 10) == 0) return Inkscape::Filters::BLEND_EXCLUSION; -#endif default: std::cout << "Inkscape::Filters::FilterBlendMode: Unimplemented mode: " << value << std::endl; // do nothing by default @@ -244,7 +238,6 @@ Inkscape::XML::Node* SPFeBlend::write(Inkscape::XML::Document *doc, Inkscape::XM mode = "darken"; break; case Inkscape::Filters::BLEND_LIGHTEN: mode = "lighten"; break; -#ifdef WITH_CSSBLEND // New case Inkscape::Filters::BLEND_OVERLAY: mode = "overlay"; break; @@ -268,7 +261,6 @@ Inkscape::XML::Node* SPFeBlend::write(Inkscape::XML::Document *doc, Inkscape::XM mode = "color"; break; case Inkscape::Filters::BLEND_LUMINOSITY: mode = "luminosity"; break; -#endif default: mode = 0; } diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 65706a9dc..78988a041 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -56,15 +56,12 @@ const Glib::ustring SimpleFilterModifier::get_blend_mode() if (!(_flags & BLEND)) { return "normal"; } - if (_blend.get_active_row_number() == 5) { + + const Util::EnumData *d = _blend.get_active_data(); + if (d) { + return _blend.get_active_data()->key; + } else return "normal"; - } else { - const Util::EnumData *d = _blend.get_active_data(); - if (d) { - return _blend.get_active_data()->key; - } else - return "normal"; - } } void SimpleFilterModifier::set_blend_mode(const int val) -- cgit v1.2.3 From 5382e1fb57cb06f5d4a21e3e553ccdd9395014f5 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 29 Jun 2014 17:12:27 +0200 Subject: Enable rendering of new filter blend modes (but don't add them to GUI). (bzr r13443) --- src/display/nr-filter-blend.cpp | 9 ++------- src/display/nr-filter-blend.h | 2 -- src/filter-enums.cpp | 8 +++++--- src/filters/blend.cpp | 8 -------- src/ui/widget/filter-effect-chooser.cpp | 13 +++++-------- 5 files changed, 12 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp index 099816bce..25aea6f13 100644 --- a/src/display/nr-filter-blend.cpp +++ b/src/display/nr-filter-blend.cpp @@ -83,8 +83,7 @@ void FilterBlend::render_cairo(FilterSlot &slot) case BLEND_LIGHTEN: cairo_set_operator(out_ct, CAIRO_OPERATOR_LIGHTEN); break; -#ifdef WITH_CSSBLEND - // NEW + // New in CSS Compositing and Blending Level 1 case BLEND_OVERLAY: cairo_set_operator(out_ct, CAIRO_OPERATOR_OVERLAY); break; @@ -118,7 +117,6 @@ void FilterBlend::render_cairo(FilterSlot &slot) case BLEND_LUMINOSITY: cairo_set_operator(out_ct, CAIRO_OPERATOR_HSL_LUMINOSITY); break; -#endif case BLEND_NORMAL: default: @@ -167,15 +165,12 @@ void FilterBlend::set_input(int input, int slot) { void FilterBlend::set_mode(FilterBlendMode mode) { if (mode == BLEND_NORMAL || mode == BLEND_MULTIPLY || mode == BLEND_SCREEN || mode == BLEND_DARKEN || - mode == BLEND_LIGHTEN -#ifdef WITH_CSSBLEND - || mode == BLEND_OVERLAY || + mode == BLEND_LIGHTEN || mode == BLEND_OVERLAY || mode == BLEND_COLORDODGE || mode == BLEND_COLORBURN || mode == BLEND_HARDLIGHT || mode == BLEND_SOFTLIGHT || mode == BLEND_DIFFERENCE || mode == BLEND_EXCLUSION || mode == BLEND_HUE || mode == BLEND_SATURATION || mode == BLEND_COLOR || mode == BLEND_LUMINOSITY -#endif ) { _blend_mode = mode; diff --git a/src/display/nr-filter-blend.h b/src/display/nr-filter-blend.h index 0a2927d87..c0504993b 100644 --- a/src/display/nr-filter-blend.h +++ b/src/display/nr-filter-blend.h @@ -28,7 +28,6 @@ enum FilterBlendMode { BLEND_SCREEN, BLEND_DARKEN, BLEND_LIGHTEN, -#ifdef WITH_CSSBLEND // New in CSS Compositing and Blending Level 1 BLEND_OVERLAY, BLEND_COLORDODGE, @@ -41,7 +40,6 @@ enum FilterBlendMode { BLEND_SATURATION, BLEND_COLOR, BLEND_LUMINOSITY, -#endif BLEND_ENDMODE, }; diff --git a/src/filter-enums.cpp b/src/filter-enums.cpp index 7ee57f7fa..09a1a7614 100644 --- a/src/filter-enums.cpp +++ b/src/filter-enums.cpp @@ -53,7 +53,6 @@ const EnumData BlendModeData[Inkscape::Filte {Inkscape::Filters::BLEND_SCREEN, _("Screen"), "screen"}, {Inkscape::Filters::BLEND_DARKEN, _("Darken"), "darken"}, {Inkscape::Filters::BLEND_LIGHTEN, _("Lighten"), "lighten"}, -#ifdef WITH_CSSBLEND // New in Compositing and Blending Level 1 {Inkscape::Filters::BLEND_OVERLAY, _("Overlay"), "overlay"}, {Inkscape::Filters::BLEND_COLORDODGE, _("Color Dodge"), "color-dodge"}, @@ -66,10 +65,13 @@ const EnumData BlendModeData[Inkscape::Filte {Inkscape::Filters::BLEND_SATURATION, _("Saturation"), "saturation"}, {Inkscape::Filters::BLEND_COLOR, _("Color"), "color"}, {Inkscape::Filters::BLEND_LUMINOSITY, _("Luminosity"), "luminosity"} -#endif }; +#ifdef WITH_CSSBLEND const EnumDataConverter BlendModeConverter(BlendModeData, Inkscape::Filters::BLEND_ENDMODE); - +#else +// Disable new blend modes in GUI until widely implemented. +const EnumDataConverter BlendModeConverter(BlendModeData, Inkscape::Filters::BLEND_OVERLAY); +#endif const EnumData ColorMatrixTypeData[Inkscape::Filters::COLORMATRIX_ENDTYPE] = { {Inkscape::Filters::COLORMATRIX_MATRIX, _("Matrix"), "matrix"}, diff --git a/src/filters/blend.cpp b/src/filters/blend.cpp index 5c78f4f9f..fd5a9871e 100644 --- a/src/filters/blend.cpp +++ b/src/filters/blend.cpp @@ -96,23 +96,18 @@ static Inkscape::Filters::FilterBlendMode sp_feBlend_readmode(gchar const *value case 's': if (strncmp(value, "screen", 6) == 0) return Inkscape::Filters::BLEND_SCREEN; -#ifdef WITH_CSSBLEND if (strncmp(value, "saturation", 6) == 0) return Inkscape::Filters::BLEND_SATURATION; -#endif break; case 'd': if (strncmp(value, "darken", 6) == 0) return Inkscape::Filters::BLEND_DARKEN; -#ifdef WITH_CSSBLEND if (strncmp(value, "difference", 10) == 0) return Inkscape::Filters::BLEND_DIFFERENCE; -#endif break; case 'l': if (strncmp(value, "lighten", 7) == 0) return Inkscape::Filters::BLEND_LIGHTEN; -#ifdef WITH_CSSBLEND if (strncmp(value, "luminosity", 10) == 0) return Inkscape::Filters::BLEND_LUMINOSITY; break; @@ -137,7 +132,6 @@ static Inkscape::Filters::FilterBlendMode sp_feBlend_readmode(gchar const *value case 'e': if (strncmp(value, "exclusion", 10) == 0) return Inkscape::Filters::BLEND_EXCLUSION; -#endif default: std::cout << "Inkscape::Filters::FilterBlendMode: Unimplemented mode: " << value << std::endl; // do nothing by default @@ -244,7 +238,6 @@ Inkscape::XML::Node* SPFeBlend::write(Inkscape::XML::Document *doc, Inkscape::XM mode = "darken"; break; case Inkscape::Filters::BLEND_LIGHTEN: mode = "lighten"; break; -#ifdef WITH_CSSBLEND // New case Inkscape::Filters::BLEND_OVERLAY: mode = "overlay"; break; @@ -268,7 +261,6 @@ Inkscape::XML::Node* SPFeBlend::write(Inkscape::XML::Document *doc, Inkscape::XM mode = "color"; break; case Inkscape::Filters::BLEND_LUMINOSITY: mode = "luminosity"; break; -#endif default: mode = 0; } diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 65706a9dc..78988a041 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -56,15 +56,12 @@ const Glib::ustring SimpleFilterModifier::get_blend_mode() if (!(_flags & BLEND)) { return "normal"; } - if (_blend.get_active_row_number() == 5) { + + const Util::EnumData *d = _blend.get_active_data(); + if (d) { + return _blend.get_active_data()->key; + } else return "normal"; - } else { - const Util::EnumData *d = _blend.get_active_data(); - if (d) { - return _blend.get_active_data()->key; - } else - return "normal"; - } } void SimpleFilterModifier::set_blend_mode(const int val) -- cgit v1.2.3 From fe738c88996ee6bc050b8cff8d1efc84fefe3787 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 29 Jun 2014 22:00:26 +0200 Subject: noop: fix bool type (C to C++) (bzr r13341.1.71) --- src/file.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index 51e629c7d..d8671c5d5 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -669,7 +669,7 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri, sp_ui_error_dialog(text); g_free(text); g_free(safeUri); - return FALSE; + return false; } catch (Inkscape::Extension::Output::file_read_only &e) { gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str()); gchar *text = g_strdup_printf(_("File %s is write protected. Please remove write protection and try again."), safeUri); @@ -677,7 +677,7 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri, sp_ui_error_dialog(text); g_free(text); g_free(safeUri); - return FALSE; + return false; } catch (Inkscape::Extension::Output::save_failed &e) { gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str()); gchar *text = g_strdup_printf(_("File %s could not be saved."), safeUri); @@ -685,15 +685,15 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri, sp_ui_error_dialog(text); g_free(text); g_free(safeUri); - return FALSE; + return false; } catch (Inkscape::Extension::Output::save_cancelled &e) { SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); - return FALSE; + return false; } catch (Inkscape::Extension::Output::no_overwrite &e) { return sp_file_save_dialog(parentWindow, doc, save_method); } catch (...) { SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); - return FALSE; + return false; } if (SP_ACTIVE_DESKTOP) { -- cgit v1.2.3 From 7d8304daeb171edb3fa94897f158fa5f551d8078 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Jun 2014 01:20:09 +0200 Subject: fix crash bug with connectors because of constructor "ConnRef(Router *router, const unsigned int id)", _srcVert and _dstVert can be NULL, and _active can be false. this constructor seems unfinished, but is used elsewhere in the code. hence the crash. Fixed bugs: - https://launchpad.net/bugs/977003 (bzr r13341.1.72) --- src/libavoid/connector.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/libavoid/connector.cpp b/src/libavoid/connector.cpp index 8dcb66f2d..b8c99a48c 100644 --- a/src/libavoid/connector.cpp +++ b/src/libavoid/connector.cpp @@ -442,11 +442,11 @@ void ConnRef::makeActive(void) void ConnRef::makeInactive(void) { - COLA_ASSERT(_active); - - // Remove from connRefs list. - _router->connRefs.erase(_pos); - _active = false; + if (_active) { + // Remove from connRefs list. + _router->connRefs.erase(_pos); + _active = false; + } } @@ -553,8 +553,12 @@ void ConnRef::unInitialise(void) void ConnRef::removeFromGraph(void) { - _srcVert->removeFromGraph(); - _dstVert->removeFromGraph(); + if (_srcVert) { + _srcVert->removeFromGraph(); + } + if (_dstVert) { + _dstVert->removeFromGraph(); + } } -- cgit v1.2.3 From df0fdb31cb60c71777db0f75195e9f43cd8ba6c5 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Jun 2014 01:27:37 +0200 Subject: fix crash bug with connectors because of constructor "ConnRef(Router *router, const unsigned int id)", _srcVert and _dstVert can be NULL, and _active can be false. this constructor seems unfinished, but is used elsewhere in the code. hence the crash. Fixed bugs: - https://launchpad.net/bugs/977003 (bzr r13444) --- src/libavoid/connector.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/libavoid/connector.cpp b/src/libavoid/connector.cpp index 8dcb66f2d..b8c99a48c 100644 --- a/src/libavoid/connector.cpp +++ b/src/libavoid/connector.cpp @@ -442,11 +442,11 @@ void ConnRef::makeActive(void) void ConnRef::makeInactive(void) { - COLA_ASSERT(_active); - - // Remove from connRefs list. - _router->connRefs.erase(_pos); - _active = false; + if (_active) { + // Remove from connRefs list. + _router->connRefs.erase(_pos); + _active = false; + } } @@ -553,8 +553,12 @@ void ConnRef::unInitialise(void) void ConnRef::removeFromGraph(void) { - _srcVert->removeFromGraph(); - _dstVert->removeFromGraph(); + if (_srcVert) { + _srcVert->removeFromGraph(); + } + if (_dstVert) { + _dstVert->removeFromGraph(); + } } -- cgit v1.2.3 From 6351d4ea2ea398e0096c14b3ba57ca28dfd2f8a3 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 1 Jul 2014 23:58:08 +0200 Subject: Fix pentool backspace bug. Thanks Jabier Fixed bugs: - https://launchpad.net/bugs/1336561 (bzr r13445) --- src/ui/tools/pen-tool.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index b089065e8..70cbcaf0d 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -55,15 +55,15 @@ static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical namespace { - ToolBase* createPenContext() { - return new PenTool(); - } + ToolBase* createPenContext() { + return new PenTool(); + } - bool penContextRegistered = ToolFactory::instance().registerObject("/tools/freehand/pen", createPenContext); + bool penContextRegistered = ToolFactory::instance().registerObject("/tools/freehand/pen", createPenContext); } const std::string& PenTool::getPrefsPath() { - return PenTool::prefsPath; + return PenTool::prefsPath; } const std::string PenTool::prefsPath = "/tools/freehand/pen"; @@ -277,7 +277,7 @@ bool PenTool::item_handler(SPItem* item, GdkEvent* event) { } if (!ret) { - ret = FreehandBase::item_handler(item, event); + ret = FreehandBase::item_handler(item, event); } return ret; @@ -315,7 +315,7 @@ bool PenTool::root_handler(GdkEvent* event) { } if (!ret) { - ret = FreehandBase::root_handler(event); + ret = FreehandBase::root_handler(event); } return ret; @@ -1061,8 +1061,9 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { this->red_curve->reset(); // Destroy topmost green bpath if (this->green_bpaths) { - if (this->green_bpaths->data) + if (this->green_bpaths->data) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // Get last segment @@ -1078,11 +1079,21 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { } else { this->p[1] = this->p[0]; } - Geom::Point const pt(( this->npoints < 4 - ? (Geom::Point)(crv->finalPoint()) - : this->p[3] )); + Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); this->npoints = 2; - this->green_curve->backspace(); + // delete the last segment of the green curve + if (this->green_curve->get_segment_count() == 1) { + this->npoints = 5; + if (this->green_bpaths) { + if (this->green_bpaths->data) { + sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } + this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); + } + this->green_curve->reset(); + } else { + this->green_curve->backspace(); + } sp_canvas_item_hide(this->c0); sp_canvas_item_hide(this->c1); sp_canvas_item_hide(this->cl0); -- cgit v1.2.3 From 77934815e32b73477fc5e7b19e61de702a303fd5 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 2 Jul 2014 00:13:46 +0200 Subject: pen tool: add back removal of curvature handle when backspace-deleting a node while drawing many code improvements: unnecessary casts, whitespace, { }, reduce variable scope. should all be noops. (bzr r13341.1.73) --- src/ui/tools/pen-tool.cpp | 61 +++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 0d8a2668b..aead3ebc0 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -958,40 +958,42 @@ void PenTool::_lastpointToCurve() { // avoid that if the "red_curve" contains only two points ( rect ), it doesn't stop here. if (this->npoints != 5 && !this->spiro && !this->bspline) return; - Geom::CubicBezier const * cubic; - this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); + + this->p[1] = this->red_curve->last_segment()->initialPoint() + (1./3.)*(this->red_curve->last_segment()->finalPoint() - this->red_curve->last_segment()->initialPoint()); //modificate the last segment of the green curve so it creates the type of node we need - if(this->spiro||this->bspline){ - if(!this->green_curve->is_empty()){ + if (this->spiro||this->bspline) { + if (!this->green_curve->is_empty()) { Geom::Point A(0,0); Geom::Point B(0,0); Geom::Point C(0,0); Geom::Point D(0,0); - SPCurve * previous = new SPCurve(); - cubic = dynamic_cast( this->green_curve->last_segment() ); + Geom::CubicBezier const *cubic = dynamic_cast( this->green_curve->last_segment() ); //We obtain the last segment 4 points in the previous curve if ( cubic ){ A = (*cubic)[0]; B = (*cubic)[1]; - if(this->spiro){ - C = this->p[0] + (Geom::Point)(this->p[0] - this->p[1]); - }else - C = this->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + if (this->spiro) { + C = this->p[0] + (this->p[0] - this->p[1]); + } else { + C = this->green_curve->last_segment()->finalPoint() + (1./3.)*(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + } D = (*cubic)[3]; - }else{ + } else { A = this->green_curve->last_segment()->initialPoint(); B = this->green_curve->last_segment()->initialPoint(); - if(this->spiro) - C = this->p[0] + (Geom::Point)(this->p[0] - this->p[1]); - else - C = this->green_curve->last_segment()->finalPoint() + (1./3)* (Geom::Point)(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + if (this->spiro) { + C = this->p[0] + (this->p[0] - this->p[1]); + } else { + C = this->green_curve->last_segment()->finalPoint() + (1./3.)*(this->green_curve->last_segment()->initialPoint() - this->green_curve->last_segment()->finalPoint()); + } D = this->green_curve->last_segment()->finalPoint(); } + SPCurve *previous = new SPCurve(); previous->moveto(A); previous->curveto(B, C, D); - if( this->green_curve->get_segment_count() == 1){ + if ( this->green_curve->get_segment_count() == 1) { this->green_curve = previous; - }else{ + } else { //we eliminate the last segment this->green_curve->backspace(); //and we add it again with the recreation @@ -999,7 +1001,7 @@ void PenTool::_lastpointToCurve() { } } //if the last node is an union with another curve - if(this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()){ + if (this->green_curve->is_empty() && this->sa && !this->sa->curve->is_empty()) { this->_bspline_spiro_start_anchor(false); } } @@ -1242,12 +1244,12 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { } } else { // Reset red curve - Geom::CubicBezier const * cubic = NULL; this->red_curve->reset(); // Destroy topmost green bpath if (this->green_bpaths) { - if (this->green_bpaths->data) + if (this->green_bpaths->data) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } // Get last segment @@ -1270,17 +1272,16 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); } - Geom::Point const pt((this->npoints < 4 - ? (Geom::Point)(crv->finalPoint()) - : this->p[3])); + Geom::Point const pt( (this->npoints < 4) ? crv->finalPoint() : this->p[3] ); this->npoints = 2; // delete the last segment of the green curve if( this->green_curve->get_segment_count() == 1){ this->npoints = 5; if (this->green_bpaths) { - if (this->green_bpaths->data) + if (this->green_bpaths->data) { sp_canvas_item_destroy(SP_CANVAS_ITEM(this->green_bpaths->data)); + } this->green_bpaths = g_slist_remove(this->green_bpaths, this->green_bpaths->data); } this->green_curve->reset(); @@ -1289,14 +1290,16 @@ bool PenTool::_handleKeyPress(GdkEvent *event) { } // assign the value of this->p[1] to the oposite of the green line last segment if(this->spiro){ - cubic = dynamic_cast(this->green_curve->last_segment()); + Geom::CubicBezier const *cubic = dynamic_cast(this->green_curve->last_segment()); if ( cubic ) { - this->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2]); + this->p[1] = (*cubic)[3] + (*cubic)[3] - (*cubic)[2]; SP_CTRL(this->c1)->moveto(this->p[0]); } else { this->p[1] = this->p[0]; } } + sp_canvas_item_hide(this->c0); + sp_canvas_item_hide(this->c1); sp_canvas_item_hide(this->cl0); sp_canvas_item_hide(this->cl1); this->state = PenTool::POINT; @@ -1607,7 +1610,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ if(shift) this->p[2] = this->p[3]; }else{ - this->p[1] = (*cubic)[3] + (Geom::Point)((*cubic)[3] - (*cubic)[2] ); + this->p[1] = (*cubic)[3] + ((*cubic)[3] - (*cubic)[2] ); this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); } }else{ @@ -1659,7 +1662,7 @@ void PenTool::_bspline_spiro_end_anchor_on() C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); }else{ - C = this->p[3] + (Geom::Point)(this->p[3] - this->p[2] ); + C = this->p[3] + this->p[3] - this->p[2]; } if(cubic){ lastSeg->moveto((*cubic)[0]); @@ -2164,7 +2167,7 @@ void PenTool::_finishSegment(Geom::Point const p, guint const state) { pen_last_paraxial_dir = this->nextParaxialDirection(p, this->p[0], state); } - ++this->num_clicks; + ++num_clicks; if (!this->red_curve->is_empty()) { -- cgit v1.2.3 From 371f45365a6b6ea42d17c8ea33cc0072f318967e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Jul 2014 13:14:35 +0200 Subject: Add LPE fillet-chamfer (bzr r13341.1.74) --- src/knotholder.h | 2 + src/live_effects/Makefile_insert | 2 + src/live_effects/effect.cpp | 3 + src/live_effects/lpe-fillet-chamfer.cpp | 687 +++++++++++++++++++++ src/live_effects/lpe-fillet-chamfer.h | 68 ++ src/live_effects/parameter/Makefile_insert | 2 + .../parameter/filletchamferpointarray.cpp | 653 ++++++++++++++++++++ .../parameter/filletchamferpointarray.h | 117 ++++ src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 257 ++++++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 112 ++++ src/ui/tool/multi-path-manipulator.h | 3 +- src/ui/tool/path-manipulator.cpp | 20 +- 13 files changed, 1922 insertions(+), 6 deletions(-) create mode 100644 src/live_effects/lpe-fillet-chamfer.cpp create mode 100644 src/live_effects/lpe-fillet-chamfer.h create mode 100644 src/live_effects/parameter/filletchamferpointarray.cpp create mode 100644 src/live_effects/parameter/filletchamferpointarray.h create mode 100644 src/ui/dialog/lpe-fillet-chamfer-properties.cpp create mode 100644 src/ui/dialog/lpe-fillet-chamfer-properties.h (limited to 'src') diff --git a/src/knotholder.h b/src/knotholder.h index 3632635f5..dc2300105 100644 --- a/src/knotholder.h +++ b/src/knotholder.h @@ -28,6 +28,7 @@ class Node; } namespace LivePathEffect { class PowerStrokePointArrayParamKnotHolderEntity; +class FilletPointArrayParamKnotHolderEntity; } } @@ -60,6 +61,7 @@ public: friend class ShapeEditor; friend class Inkscape::LivePathEffect::PowerStrokePointArrayParamKnotHolderEntity; + friend class Inkscape::LivePathEffect::FilletPointArrayParamKnotHolderEntity; protected: diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index c47003747..263b33b3c 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -32,6 +32,8 @@ ink_common_sources += \ live_effects/lpe-curvestitch.h \ live_effects/lpe-constructgrid.cpp \ live_effects/lpe-constructgrid.h \ + live_effects/lpe-fillet-chamfer.cpp \ + live_effects/lpe-fillet-chamfer.h \ live_effects/lpe-gears.cpp \ live_effects/lpe-gears.h \ live_effects/lpe-interpolate.cpp \ diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index d0a168a14..f70a540e8 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -263,6 +263,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case ENVELOPE_PERSPECTIVE: neweffect = static_cast ( new LPEEnvelopePerspective(lpeobj) ); break; + case FILLET_CHAMFER: + neweffect = static_cast ( new LPEFilletChamfer(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp new file mode 100644 index 000000000..c25e3bffd --- /dev/null +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -0,0 +1,687 @@ +/* + * Copyright (C) Jabiertxo Arraiza Cenoz + * Special thanks to Johan Engelen for the base of the effect -powerstroke- + * Also to ScislaC for point me to the idea + * Also su_v for his construvtive feedback and time + * Also to Mc- (IRC nick) for his important contribution to find real time + * values based on + * and finaly to Liam P. White for his big help on coding, that save me a lot of + * hours + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-fillet-chamfer.h" +#include +#include "style.h" +#include "live_effects/parameter/filletchamferpointarray.h" +//for update knot +#include <2geom/svg-elliptical-arc.h> +#include <2geom/line.h> +#include "selection.h" +#include "ui/tool/control-point-selection.h" +#include "ui/tool/selectable-control-point.h" +#include <2geom/sbasis-to-bezier.h> +#include "ui/tool/node.h" +// FIXME: The following are only needed to convert the path's SPCurve* to pwd2. +// There must be a more convenient way to achieve this. +#include "display/curve.h" +#include "helper/geom-nodetype.h" +#include "desktop.h" +#include "ui/tools/node-tool.h" +#include +#include +#include + +using namespace Geom; +namespace Inkscape { +namespace LivePathEffect { + +const double tolerance = 0.001; +const double gapHelper = 0.00001; + +LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + fillet_chamfer_values(_("Fillet point"), _("Fillet point"), + "fillet_chamfer_values", &wr, this), + hide_knots(_("Hide knots"), _("Hide knots"), "hide_knots", &wr, this, + false), + ignore_radius_0(_("Ignore 0 radius knots"), _("Ignore 0 radius knots"), + "ignore_radius_0", &wr, this, false), + only_selected(_("Change only selected nodes"), + _("Change only selected nodes"), "only_selected", &wr, this, + false), + flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), + "flexible", &wr, this, false), + unit(_("Unit"), _("Unit"), "unit", &wr, this), + radius(_("Radius (unit or %)"), _("Radius, in unit or %"), "radius", &wr, + this, 0.), + helper_size(_("Helper size with direction"), + _("Helper size with direction"), "helper_size", &wr, this, + 0) +{ + registerParameter(dynamic_cast(&fillet_chamfer_values)); + registerParameter(dynamic_cast(&unit)); + registerParameter(dynamic_cast(&radius)); + registerParameter(dynamic_cast(&helper_size)); + registerParameter(dynamic_cast(&flexible)); + registerParameter(dynamic_cast(&ignore_radius_0)); + registerParameter(dynamic_cast(&only_selected)); + registerParameter(dynamic_cast(&hide_knots)); + radius.param_set_range(0., infinity()); + radius.param_set_increments(1, 1); + radius.param_set_digits(4); + helper_size.param_set_range(0, infinity()); + helper_size.param_set_increments(5, 5); + helper_size.param_set_digits(0); +} + +LPEFilletChamfer::~LPEFilletChamfer() {} + +Gtk::Widget *LPEFilletChamfer::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "radius") { + Inkscape::UI::Widget::Scalar *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_value_changed() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::updateFillet)); + widg = dynamic_cast(widgRegistered); + if (widg) { + Gtk::HBox *scalarParameter = dynamic_cast(widg); + std::vector childList = + scalarParameter->get_children(); + Gtk::Entry *entryWidg = dynamic_cast(childList[1]); + entryWidg->set_width_chars(6); + } + } + if (param->param_key == "flexible") { + Gtk::CheckButton *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleFlexFixed)); + widg = dynamic_cast(widgRegistered); + } + if (param->param_key == "helper_size") { + Inkscape::UI::Widget::Scalar *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_value_changed() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::refreshKnots)); + widg = dynamic_cast(widgRegistered); + + } + if (param->param_key == "hide_knots") { + Gtk::CheckButton *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleHide)); + widg = dynamic_cast(widgRegistered); + } + if (param->param_key == "only_selected") { + Gtk::CheckButton *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widgRegistered); + } + if (param->param_key == "ignore_radius_0") { + Gtk::CheckButton *widgRegistered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widgRegistered); + } + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + + Gtk::HBox *filletButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *fillet = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); + fillet->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::fillet)); + filletButtonsContainer->pack_start(*fillet, true, true, 2); + Gtk::Button *inverse = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); + inverse->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverse)); + filletButtonsContainer->pack_start(*inverse, true, true, 2); + + Gtk::HBox *chamferButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *chamfer = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); + chamfer->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer)); + chamferButtonsContainer->pack_start(*chamfer, true, true, 2); + Gtk::Button *doubleChamfer = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Double chamfer")))); + doubleChamfer->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEFilletChamfer::doubleChamfer)); + chamferButtonsContainer->pack_start(*doubleChamfer, true, true, 2); + vbox->pack_start(*filletButtonsContainer, true, true, 2); + vbox->pack_start(*chamferButtonsContainer, true, true, 2); + + return dynamic_cast(vbox); +} + +void LPEFilletChamfer::toggleHide() +{ + std::vector filletChamferData = fillet_chamfer_values.data(); + std::vector result; + for (std::vector::const_iterator point_it = filletChamferData.begin(); + point_it != filletChamferData.end(); ++point_it) { + if (hide_knots) { + result.push_back(Point((*point_it)[X], abs((*point_it)[Y]) * -1)); + } else { + result.push_back(Point((*point_it)[X], abs((*point_it)[Y]))); + } + } + fillet_chamfer_values.param_set_and_write_new_value(result); + refreshKnots(); +} + +void LPEFilletChamfer::toggleFlexFixed() +{ + std::vector filletChamferData = fillet_chamfer_values.data(); + std::vector result; + unsigned int i = 0; + for (std::vector::const_iterator point_it = filletChamferData.begin(); + point_it != filletChamferData.end(); ++point_it) { + if (flexible) { + result.push_back(Point(fillet_chamfer_values.to_time(i, (*point_it)[X]), + (*point_it)[Y])); + } else { + result.push_back(Point(fillet_chamfer_values.to_len(i, (*point_it)[X]), + (*point_it)[Y])); + } + i++; + } + if (flexible) { + radius.param_set_range(0., 100); + radius.param_set_value(0); + } else { + radius.param_set_range(0., infinity()); + radius.param_set_value(0); + } + fillet_chamfer_values.param_set_and_write_new_value(result); +} + +void LPEFilletChamfer::updateFillet() +{ + double power = 0; + if (!flexible) { + power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), + "px") * -1; + } else { + power = radius; + } + Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doUpdateFillet(path_from_piecewise(pwd2, tolerance), power); +} + +void LPEFilletChamfer::fillet() +{ + Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), 1); +} + +void LPEFilletChamfer::inverse() +{ + Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), 2); +} + +void LPEFilletChamfer::chamfer() +{ + Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), 3); +} + +void LPEFilletChamfer::doubleChamfer() +{ + Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), 4); +} + +void LPEFilletChamfer::refreshKnots() +{ + Piecewise > const &pwd2 = fillet_chamfer_values.get_pwd2(); + fillet_chamfer_values.recalculate_knots(pwd2); + SPDesktop *desktop = inkscape_active_desktop(); + if (tools_isactive(desktop, TOOLS_NODES)) { + tools_switch(desktop, TOOLS_SELECT); + tools_switch(desktop, TOOLS_NODES); + } +} + +bool LPEFilletChamfer::nodeIsSelected(Geom::Point nodePoint, + std::vector point) +{ + if (point.size() > 0) { + for (std::vector::iterator i = point.begin(); i != point.end(); + ++i) { + Geom::Point p = *i; + if (Geom::are_near(p, nodePoint, 2)) { + return true; + } + } + } + return false; +} +void LPEFilletChamfer::doUpdateFillet(std::vector original_pathv, + double power) +{ + std::vector point; + SPDesktop *desktop = inkscape_active_desktop(); + if (INK_IS_NODE_TOOL(desktop->event_context)) { + Inkscape::UI::Tools::NodeTool *nodeTool = + INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::ControlPointSelection::Set &selection = + nodeTool->_selected_nodes->allPoints(); + std::vector::iterator pBegin; + for (Inkscape::UI::ControlPointSelection::Set::iterator i = + selection.begin(); + i != selection.end(); ++i) { + if ((*i)->selected()) { + Inkscape::UI::Node *n = dynamic_cast(*i); + pBegin = point.begin(); + point.insert(pBegin, desktop->doc2dt(n->position())); + } + } + } + std::vector filletChamferData = fillet_chamfer_values.data(); + std::vector result; + int counter = 0; + for (PathVector::const_iterator path_it = original_pathv.begin(); + path_it != original_pathv.end(); ++path_it) { + int pathCounter = 0; + if (path_it->empty()) + continue; + + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + if (path_it->closed() && path_it->back_closed().isDegenerate()) { + const Curve &closingline = path_it->back_closed(); + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + curve_endit = path_it->end_open(); + } + } + double powerend = 0; + while (curve_it1 != curve_endit) { + powerend = power; + if (power > 0) { + powerend = counter + (power / 100); + } + if (ignore_radius_0 && (filletChamferData[counter][X] == 0 || + filletChamferData[counter][X] == counter)) { + powerend = filletChamferData[counter][X]; + } + if (filletChamferData[counter][Y] == 0) { + powerend = filletChamferData[counter][X]; + } + if (only_selected && !nodeIsSelected(curve_it1->initialPoint(), point)) { + powerend = filletChamferData[counter][X]; + } + result.push_back(Point(powerend, filletChamferData[counter][Y])); + ++curve_it1; + ++curve_it2; + counter++; + pathCounter++; + } + } + fillet_chamfer_values.param_set_and_write_new_value(result); +} + +void LPEFilletChamfer::doChangeType(std::vector original_pathv, + int type) +{ + std::vector point; + SPDesktop *desktop = inkscape_active_desktop(); + if (INK_IS_NODE_TOOL(desktop->event_context)) { + Inkscape::UI::Tools::NodeTool *nodeTool = + INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::ControlPointSelection::Set &selection = + nodeTool->_selected_nodes->allPoints(); + std::vector::iterator pBegin; + for (Inkscape::UI::ControlPointSelection::Set::iterator i = + selection.begin(); + i != selection.end(); ++i) { + if ((*i)->selected()) { + Inkscape::UI::Node *n = dynamic_cast(*i); + pBegin = point.begin(); + point.insert(pBegin, desktop->doc2dt(n->position())); + } + } + } + std::vector filletChamferData = fillet_chamfer_values.data(); + std::vector result; + int counter = 0; + for (PathVector::const_iterator path_it = original_pathv.begin(); + path_it != original_pathv.end(); ++path_it) { + int pathCounter = 0; + if (path_it->empty()) + continue; + + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + if (path_it->closed() && path_it->back_closed().isDegenerate()) { + const Curve &closingline = path_it->back_closed(); + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + curve_endit = path_it->end_open(); + } + } + while (curve_it1 != curve_endit) { + bool toggle = true; + if (filletChamferData[counter][Y] == 0 || + (ignore_radius_0 && (filletChamferData[counter][X] == 0 || + filletChamferData[counter][X] == counter)) || + (only_selected && + !nodeIsSelected(curve_it1->initialPoint(), point))) { + toggle = false; + } + if (toggle) { + result.push_back(Point(filletChamferData[counter][X], type)); + } else { + result.push_back(filletChamferData[counter]); + } + ++curve_it1; + if (curve_it2 != curve_endit) { + ++curve_it2; + } + counter++; + pathCounter++; + } + } + fillet_chamfer_values.param_set_and_write_new_value(result); +} + +void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) +{ + if (SP_IS_SHAPE(lpeItem)) { + std::vector point; + PathVector const &original_pathv = + SP_SHAPE(lpeItem)->_curve->get_pathvector(); + Piecewise > pwd2_in = paths_to_pw(original_pathv); + for (PathVector::const_iterator path_it = original_pathv.begin(); + path_it != original_pathv.end(); ++path_it) { + if (path_it->empty()) + continue; + + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + int counter = 0; + while (curve_it1 != curve_endit) { + Geom::NodeType nodetype; + if (counter == 0) { + if (path_it->closed()) { + nodetype = get_nodetype(path_it->back_default(), *curve_it1); + } else { + nodetype = NODE_NONE; + } + } else { + nodetype = get_nodetype((*path_it)[counter - 1], *curve_it1); + } + if (nodetype == NODE_CUSP) { + point.push_back(Point(0, 1)); + } else { + point.push_back(Point(0, 0)); + } + ++curve_it1; + if (curve_it2 != curve_endit) { + ++curve_it2; + } + counter++; + } + } + fillet_chamfer_values.param_set_and_write_new_value(point); + } else { + g_warning("LPE Fillet can only be applied to shapes (not groups)."); + } +} + +void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) +{ + if (SP_IS_SHAPE(lpeItem)) { + fillet_chamfer_values.set_helper_size(helper_size); + fillet_chamfer_values.set_unit(unit.get_abbreviation()); + SPCurve *c = SP_IS_PATH(lpeItem) ? static_cast(lpeItem) + ->get_original_curve() + : SP_SHAPE(lpeItem)->getCurve(); + std::vector filletChamferData = fillet_chamfer_values.data(); + if (!filletChamferData.empty() && getKnotsNumber(c) != (int) + filletChamferData.size()) { + PathVector const original_pathv = c->get_pathvector(); + Piecewise > pwd2_in = paths_to_pw(original_pathv); + fillet_chamfer_values.recalculate_controlpoints_for_new_pwd2(pwd2_in); + } + } else { + g_warning("LPE Fillet can only be applied to shapes (not groups)."); + } +} + +int LPEFilletChamfer::getKnotsNumber(SPCurve const *c) +{ + int nKnots = c->nodes_in_path(); + PathVector const pv = c->get_pathvector(); + for (std::vector::const_iterator path_it = pv.begin(); + path_it != pv.end(); ++path_it) { + if (!(*path_it).closed()) { + nKnots--; + } + } + return nKnots; +} + +void +LPEFilletChamfer::adjustForNewPath(std::vector const &path_in) +{ + if (!path_in.empty()) { + fillet_chamfer_values.recalculate_controlpoints_for_new_pwd2(path_in[0] + .toPwSb()); + } +} + +std::vector +LPEFilletChamfer::doEffect_path(std::vector const &path_in) +{ + std::vector pathvector_out; + Piecewise > pwd2_in = paths_to_pw(path_in); + pwd2_in = remove_short_cuts(pwd2_in, .01); + Piecewise > der = derivative(pwd2_in); + Piecewise > n = rot90(unitVector(der)); + fillet_chamfer_values.set_pwd2(pwd2_in, n); + std::vector filletChamferData = fillet_chamfer_values.data(); + int counter = 0; + //from http://launchpadlibrarian.net/12692602/rcp.svg + const double K = (4. / 3) * (sqrt(2) - 1); + for (PathVector::const_iterator path_it = path_in.begin(); + path_it != path_in.end(); ++path_it) { + if (path_it->empty()) + continue; + Geom::Path path_out; + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + if (path_it->closed()) { + const Geom::Curve &closingline = path_it->back_closed(); + // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + int counterCurves = 0; + while (curve_it1 != curve_endit) { + Coord it1_length = (*curve_it1).length(tolerance); + double time_it1, time_it2, time_it1_B, intpart; + time_it1 = modf( + fillet_chamfer_values.to_time(counter, filletChamferData[counter][X]), + &intpart); + if (filletChamferData[counter][Y] == 0) { + time_it1 = 0; + } + time_it2 = modf(fillet_chamfer_values.to_time( + counter + 1, filletChamferData[counter + 1][X]), + &intpart); + if (curve_it2 == curve_endit) { + time_it2 = modf(fillet_chamfer_values.to_time( + counter - counterCurves, + filletChamferData[counter - counterCurves][X]), + &intpart); + } + double resultLenght = + it1_length + fillet_chamfer_values.to_len( + counter + 1, filletChamferData[counter + 1][X]); + time_it1_B = 1; + if (path_it->closed() && curve_it2 == curve_endit) { + resultLenght = + it1_length + fillet_chamfer_values.to_len( + counter - counterCurves, + filletChamferData[counter - counterCurves][X]); + } + if (resultLenght > 0 && time_it2 != 0) { + time_it1_B = modf(fillet_chamfer_values.to_time(counter, -resultLenght), + &intpart); + } else { + if (time_it2 == 0) { + time_it1_B = 1; + } else { + time_it1_B = gapHelper; + } + } + if (filletChamferData[counter + 1][Y] == 0) { + time_it1_B = 1; + time_it2 = 0; + } + if (time_it1_B < time_it1) { + time_it1_B = time_it1 + gapHelper; + } + Curve *knotCurve1 = curve_it1->portion(time_it1, time_it1_B); + if (counterCurves > 0) { + knotCurve1->setInitial(path_out.finalPoint()); + } else { + path_out.start((*curve_it1).pointAt(time_it1)); + } + Curve *knotCurve2 = (*path_it).front().portion(time_it2, 1); + if (curve_it2 != curve_endit) { + knotCurve2 = (*curve_it2).portion(time_it2, 1); + } + Point startArcPoint = knotCurve1->finalPoint(); + Point endArcPoint = (*path_it).front().pointAt(time_it2); + if (curve_it2 != curve_endit) { + endArcPoint = (*curve_it2).pointAt(time_it2); + } + double k1 = distance(startArcPoint, curve_it1->finalPoint()) * K; + double k2 = distance(endArcPoint, curve_it1->finalPoint()) * K; + Geom::CubicBezier const *cubic1 = + dynamic_cast(&*knotCurve1); + Ray ray1(startArcPoint, curve_it1->finalPoint()); + if (cubic1) { + ray1.setPoints((*cubic1)[2], startArcPoint); + } + Point handle1 = Point::polar(ray1.angle(),k1) + startArcPoint; + Geom::CubicBezier const *cubic2 = + dynamic_cast(&*knotCurve2); + Ray ray2(curve_it1->finalPoint(), endArcPoint); + if (cubic2) { + ray2.setPoints(endArcPoint, (*cubic2)[1]); + } + Point handle2 = endArcPoint - Point::polar(ray2.angle(),k2); + bool ccwToggle = cross(curve_it1->finalPoint() - startArcPoint, + endArcPoint - startArcPoint) < 0; + double angle = angle_between(ray1, ray2, ccwToggle); + double handleAngle = ray1.angle() - angle; + if (ccwToggle) { + handleAngle = ray1.angle() + angle; + } + Point inverseHandle1 = Point::polar(handleAngle,k1) + startArcPoint; + handleAngle = ray2.angle() + angle; + if (ccwToggle) { + handleAngle = ray2.angle() - angle; + } + Point inverseHandle2 = endArcPoint - Point::polar(handleAngle,k2); + if (time_it1_B != 1) { + if (time_it1_B != gapHelper && time_it1_B != time_it1 + gapHelper) { + path_out.append(*knotCurve1); + } + int type = abs(filletChamferData[counter + 1][Y]); + if (type == 3 || type == 4) { + if (type == 4) { + Geom::Point central = middle_point(startArcPoint, endArcPoint); + LineSegment chamferCenter(central, curve_it1->finalPoint()); + path_out.appendNew(chamferCenter.pointAt(0.5)); + } + path_out.appendNew(endArcPoint); + } else if (type == 2) { + path_out.appendNew(inverseHandle1, inverseHandle2, + endArcPoint); + } else { + path_out.appendNew(handle1, handle2, endArcPoint); + } + } else { + path_out.append(*knotCurve1); + } + if (path_it->closed() && curve_it2 == curve_endit) { + path_out.close(); + } + ++curve_it1; + if (curve_it2 != curve_endit) { + ++curve_it2; + } + counter++; + counterCurves++; + } + pathvector_out.push_back(path_out); + } + return pathvector_out; +} + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offset:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h new file mode 100644 index 000000000..f5eee0205 --- /dev/null +++ b/src/live_effects/lpe-fillet-chamfer.h @@ -0,0 +1,68 @@ +#ifndef INKSCAPE_LPE_FILLET_CHAMFER_H +#define INKSCAPE_LPE_FILLET_CHAMFER_H + +/* + * Inkscape::LPEFilletChamfer + * Copyright (C) Jabiertxo Arraiza Cenoz + * Special thanks to Johan Engelen for the base of the effect -powerstroke- + * Also to ScislaC for point me to the idea + * Also su_v for his construvtive feedback and time + * and finaly to Liam P. White for his big help on coding, that save me a lot of + * hours + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "live_effects/parameter/enum.h" +#include "live_effects/parameter/unit.h" +#include "live_effects/effect.h" +#include "live_effects/parameter/bool.h" +#include "live_effects/parameter/filletchamferpointarray.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEFilletChamfer : public Effect { + +public: + LPEFilletChamfer(LivePathEffectObject *lpeobject); + virtual ~LPEFilletChamfer(); + + std::vector doEffect_path(std::vector const &path_in); + + virtual void doOnApply(SPLPEItem const *lpeItem); + virtual void doBeforeEffect(SPLPEItem const *lpeItem); + virtual int getKnotsNumber(SPCurve const *c); + virtual void adjustForNewPath(std::vector const &path_in); + virtual void toggleHide(); + virtual void toggleFlexFixed(); + virtual void chamfer(); + virtual void fillet(); + virtual void doubleChamfer(); + virtual void inverse(); + virtual void updateFillet(); + virtual void doUpdateFillet(std::vector original_pathv, + double power); + virtual void doChangeType(std::vector original_pathv, int type); + virtual bool nodeIsSelected(Geom::Point nodePoint, + std::vector points); + virtual void refreshKnots(); + virtual Gtk::Widget *newWidget(); + FilletChamferPointArrayParam fillet_chamfer_values; + +private: + + BoolParam hide_knots; + BoolParam ignore_radius_0; + BoolParam only_selected; + BoolParam flexible; + UnitParam unit; + ScalarParam radius; + ScalarParam helper_size; + + LPEFilletChamfer(const LPEFilletChamfer &); + LPEFilletChamfer &operator=(const LPEFilletChamfer &); + +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape +#endif diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index 1026cf11c..1137ef34b 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -22,6 +22,8 @@ ink_common_sources += \ live_effects/parameter/originalpath.h \ live_effects/parameter/powerstrokepointarray.cpp \ live_effects/parameter/powerstrokepointarray.h \ + live_effects/parameter/filletchamferpointarray.cpp \ + live_effects/parameter/filletchamferpointarray.h \ live_effects/parameter/text.cpp \ live_effects/parameter/text.h \ live_effects/parameter/togglebutton.cpp \ diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp new file mode 100644 index 000000000..94a26dd8d --- /dev/null +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -0,0 +1,653 @@ +/* + * Copyright (C) Jabiertxo Arraiza Cenoz + * Special thanks to Johan Engelen for the base of the effect -powerstroke- + * Also to ScislaC for point me to the idea + * Also su_v for his construvtive feedback and time + * and finaly to Liam P. White for his big help on coding, that save me a lot of + * hours + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "ui/dialog/lpe-fillet-chamfer-properties.h" +#include "live_effects/parameter/filletchamferpointarray.h" +#include "live_effects/effect.h" +#include "svg/svg.h" +#include "svg/stringstream.h" +#include "knotholder.h" +#include "sp-lpe-item.h" +#include <2geom/piecewise.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/sbasis-geometric.h> +#include "selection.h" + +// needed for on-canvas editting: +#include "desktop.h" +#include "live_effects/lpeobject.h" +#include "helper/geom-nodetype.h" +#include "helper/geom-curves.h" +#include +#include "ui/tools/node-tool.h" +#include + +using namespace Geom; + +namespace Inkscape { + +namespace LivePathEffect { + +FilletChamferPointArrayParam::FilletChamferPointArrayParam( + const Glib::ustring &label, const Glib::ustring &tip, + const Glib::ustring &key, Inkscape::UI::Widget::Registry *wr, + Effect *effect) + : ArrayParam(label, tip, key, wr, effect, 0) +{ + knot_shape = SP_KNOT_SHAPE_DIAMOND; + knot_mode = SP_KNOT_MODE_XOR; + knot_color = 0x00ff0000; +} + +FilletChamferPointArrayParam::~FilletChamferPointArrayParam() {} + +Gtk::Widget *FilletChamferPointArrayParam::param_newWidget() +{ + return NULL; + /* + Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = + Gtk::manage( + new Inkscape::UI::Widget::RegisteredTransformedPoint( + param_label, + param_tooltip, + param_key, + *param_wr, + param_effect->getRepr(), + param_effect->getSPDoc() + ) ); + // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP) + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Affine transf = desktop->doc2dt(); + pointwdg->setTransform(transf); + pointwdg->setValue( *this ); + pointwdg->clearProgrammatically(); + pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Change point parameter")); + + Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); + static_cast(hbox)->pack_start(*pointwdg, true, true); + static_cast(hbox)->show_all_children(); + + return dynamic_cast (hbox); + */ +} + +void +FilletChamferPointArrayParam::param_transform_multiply(Affine const &postmul, + bool /*set*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + if (prefs->getBool("/options/transform/rectcorners", true) && + _vector[1][X] <= 0) { + std::vector result; + for (std::vector::const_iterator point_it = _vector.begin(); + point_it != _vector.end(); ++point_it) { + Coord A = + (*point_it)[X] * ((postmul.expansionX() + postmul.expansionY()) / 2); + result.push_back(Point(A, (*point_it)[Y])); + } + param_set_and_write_new_value(result); + } + + // param_set_and_write_new_value( (*this) * postmul ); +} + +/** call this method to recalculate the controlpoints such that they stay at the + * same location relative to the new path. Useful after adding/deleting nodes to + * the path.*/ +void FilletChamferPointArrayParam::recalculate_controlpoints_for_new_pwd2( + Piecewise > const &pwd2_in) +{ + if (!last_pwd2.empty()) { + PathVector const pathv = + path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); + PathVector last_pathv = + path_from_piecewise(remove_short_cuts(last_pwd2, 0.1), 0.001); + std::vector result; + unsigned long counter = 0; + unsigned long counterPaths = 0; + unsigned long counterCurves = 0; + long offset = 0; + long offsetPaths = 0; + Geom::NodeType nodetype; + for (PathVector::const_iterator path_it = pathv.begin(); + path_it != pathv.end(); ++path_it) { + if (path_it->empty()) { + counterPaths++; + counter++; + continue; + } + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + if (path_it->closed() && path_it->back_closed().isDegenerate()) { + const Curve &closingline = path_it->back_closed(); + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + curve_endit = path_it->end_open(); + } + } + counterCurves = 0; + while (curve_it1 != curve_endit) { + //if start a path get node type + if (counterCurves == 0) { + if (path_it->closed()) { + if (path_it->back_closed().isDegenerate()) { + nodetype = get_nodetype(path_it->back_open(), *curve_it1); + } else { + nodetype = get_nodetype(path_it->back_closed(), *curve_it1); + } + } else { + nodetype = NODE_NONE; + } + } else { + //check node type also whith straight lines because get_nodetype + //return non cusp node in a node inserted inside a straight line + //todo: if the path remove some nodes whith the result of a straight + //line but with handles, the node inserted into dont fire the knot + // because is not handle as cusp node by get_nodetype function + bool this_is_line = true; + bool next_is_line = is_straight_curve(*curve_it1); + this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); + nodetype = get_nodetype((*path_it)[counterCurves - 1], *curve_it1); + if (this_is_line || next_is_line) { + nodetype = NODE_CUSP; + } + } + if (last_pathv.size() > pathv.size() || + (last_pathv[counterPaths].size() > counter - offset && + !are_near(curve_it1->initialPoint(), + last_pathv[counterPaths][counter - offset].initialPoint(), + 0.1))) { + if (last_pathv.size() > counterPaths && curve_it2 == curve_endit) { + if (last_pathv[counterPaths].size() < pathv[counterPaths].size()) { + offset = abs(last_pathv[counterPaths].size() - + pathv[counterPaths].size()); + } else if (last_pathv[counterPaths].size() > + pathv[counterPaths].size()) { + offset = (abs(last_pathv[counterPaths].size() - + pathv[counterPaths].size())) * -1; + } else { + offset = 0; + } + offsetPaths += offset; + offset = offsetPaths; + } else if (counterCurves == 0 && last_pathv.size() <= pathv.size() && + counter - offset <= last_pathv[counterPaths].size() && + are_near(curve_it1->initialPoint(), + last_pathv[counterPaths].finalPoint(), 0.1) && + !last_pathv[counterPaths].closed()) { + long e = counter - offset + 1; + std::vector tmp = _vector; + for (unsigned long i = + last_pathv[counterPaths].size() + counter - offset; + i > counterCurves - offset + 1; i--) { + + if (tmp[i - 1][X] > 0) { + double fractpart, intpart; + fractpart = modf(tmp[i - 1][X], &intpart); + _vector[e] = Point(e + fractpart, tmp[i - 1][Y]); + } else { + _vector[e] = Point(tmp[i - 1][X], tmp[i - 1][Y]); + } + e++; + } + //delete temp vector + std::vector().swap(tmp); + if (last_pathv.size() > counterPaths) { + last_pathv[counterPaths] = last_pathv[counterPaths].reverse(); + } + } else { + if (last_pathv.size() > counterPaths) { + if (last_pathv[counterPaths].size() < + pathv[counterPaths].size()) { + offset++; + } else if (last_pathv[counterPaths].size() > + pathv[counterPaths].size()) { + offset--; + continue; + } + } else { + offset++; + } + } + double xPos = 0; + if (_vector[1][X] > 0) { + xPos = nearest_point(curve_it1->initialPoint(), pwd2_in); + } + if (nodetype == NODE_CUSP) { + result.push_back(Point(xPos, 1)); + } else { + result.push_back(Point(xPos, 0)); + } + } else { + double xPos = _vector[counter - offset][X]; + if (_vector.size() <= (unsigned)(counter - offset)) { + if (_vector[1][X] > 0) { + xPos = nearest_point(curve_it1->initialPoint(), pwd2_in); + } else { + xPos = 0; + } + } + if (nodetype == NODE_CUSP) { + double vectorY = _vector[counter - offset][Y]; + if (_vector.size() <= (unsigned)(counter - offset) || vectorY == 0) { + vectorY = 1; + } + result.push_back(Point(xPos, vectorY)); + } else { + if (_vector[1][X] < 0) { + xPos = 0; + } + result.push_back(Point(floor(xPos), 0)); + } + } + ++curve_it1; + if (curve_it2 != curve_endit) { + ++curve_it2; + } + counter++; + counterCurves++; + } + counterPaths++; + } + _vector = result; + write_to_SVG(); + } +} + +void FilletChamferPointArrayParam::recalculate_knots( + Piecewise > const &pwd2_in) +{ + bool change = false; + PathVector pathv = path_from_piecewise(pwd2_in, 0.001); + if (!pathv.empty()) { + std::vector result; + int counter = 0; + int counterCurves = 0; + Geom::NodeType nodetype; + for (PathVector::const_iterator path_it = pathv.begin(); + path_it != pathv.end(); ++path_it) { + if (path_it->empty()) { + counter++; + continue; + } + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + if (path_it->closed() && path_it->back_closed().isDegenerate()) { + const Curve &closingline = path_it->back_closed(); + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + curve_endit = path_it->end_open(); + } + } + counterCurves = 0; + while (curve_it1 != curve_endit) { + //if start a path get node type + if (counterCurves == 0) { + if (path_it->closed()) { + if (path_it->back_closed().isDegenerate()) { + nodetype = get_nodetype(path_it->back_open(), *curve_it1); + } else { + nodetype = get_nodetype(path_it->back_closed(), *curve_it1); + } + } else { + nodetype = NODE_NONE; + } + } else { + bool this_is_line = true; + bool next_is_line = is_straight_curve(*curve_it1); + this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); + nodetype = get_nodetype((*path_it)[counterCurves - 1], *curve_it1); + if (this_is_line || next_is_line) { + nodetype = NODE_CUSP; + } + } + if (nodetype == NODE_CUSP) { + double vectorY = _vector[counter][Y]; + if (vectorY == 0) { + vectorY = 1; + change = true; + } + result.push_back(Point(_vector[counter][X], vectorY)); + } else { + double xPos = floor(_vector[counter][X]); + if (_vector[1][X] < 0) { + xPos = 0; + } + double vectorY = _vector[counter][Y]; + if (vectorY != 0) { + change = true; + } + result.push_back(Point(xPos, 0)); + } + ++curve_it1; + ++curve_it2; + if (curve_it2 != curve_endit) { + counter++; + } + counterCurves++; + } + } + if (change) { + _vector = result; + write_to_SVG(); + } + } +} + +void FilletChamferPointArrayParam::set_pwd2( + Piecewise > const &pwd2_in, + Piecewise > const &pwd2_normal_in) +{ + last_pwd2 = pwd2_in; + last_pwd2_normal = pwd2_normal_in; +} + +void FilletChamferPointArrayParam::set_helper_size(int hs) +{ + helper_size = hs; +} + +void FilletChamferPointArrayParam::set_unit(const gchar *abbr) +{ + unit = abbr; +} + +void FilletChamferPointArrayParam::updateCanvasIndicators() +{ + std::vector ts = data(); + hp.clear(); + unsigned int i = 0; + Piecewise > const &n = get_pwd2_normal(); + for (std::vector::const_iterator point_it = ts.begin(); + point_it != ts.end(); ++point_it) { + double Xvalue = to_time(i, (*point_it)[X]); + double XPlusValue = to_time(i, -helper_size) - i; + if (Xvalue == i) { + i++; + continue; + } + Point canvas_point = last_pwd2.valueAt(Xvalue) + 0 * n.valueAt(Xvalue); + Point start_point = last_pwd2.valueAt(Xvalue + XPlusValue) + + helper_size * n.valueAt(Xvalue + XPlusValue); + Point end_point = last_pwd2.valueAt(Xvalue + XPlusValue) - + helper_size * n.valueAt(Xvalue + XPlusValue); + Geom::Path arrow; + arrow.start(start_point); + arrow.appendNew(canvas_point); + arrow.appendNew(end_point); + hp.push_back(arrow); + i++; + } +} + +void FilletChamferPointArrayParam::addCanvasIndicators( + SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(hp); +} + +double FilletChamferPointArrayParam::len_to_time(int index, double len) +{ + double t = 0; + if (last_pwd2.size() > (unsigned) index) { + if (len != 0) { + if (last_pwd2[index][0].degreesOfFreedom() != 2) { + Piecewise > u; + u.push_cut(0); + u.push(last_pwd2[index], 1); + std::vector t_roots = roots(arcLengthSb(u) - std::abs(len)); + if (t_roots.size() > 0) { + t = t_roots[0]; + } + } else { + double lenghtPart = 0; + if (last_pwd2.size() > (unsigned) index) { + lenghtPart = length(last_pwd2[index], EPSILON); + } + if (std::abs(len) < lenghtPart && lenghtPart != 0) { + t = std::abs(len) / lenghtPart; + } + } + } + t = double(index) + t; + } else { + t = double(last_pwd2.size() - 1); + } + + return t; +} + +double FilletChamferPointArrayParam::time_to_len(int index, double time) +{ + double intpart; + double len = 0; + time = modf(time, &intpart); + double lenghtPart = 0; + if (last_pwd2.size() <= (unsigned) index || time == 0) { + return len; + } + if (last_pwd2[index][0].degreesOfFreedom() != 2) { + Piecewise > u; + u.push_cut(0); + u.push(last_pwd2[index], 1); + u = portion(u, 0, time); + return length(u, 0.001) * -1; + } + lenghtPart = length(last_pwd2[index], EPSILON); + return (time * lenghtPart) * -1; +} + +double FilletChamferPointArrayParam::to_time(int index, double A) +{ + if (A > 0) { + return A; + } else { + return len_to_time(index, A); + } +} + +double FilletChamferPointArrayParam::to_len(int index, double A) +{ + if (A > 0) { + return time_to_len(index, A); + } else { + return A; + } +} + +void FilletChamferPointArrayParam::set_oncanvas_looks(SPKnotShapeType shape, + SPKnotModeType mode, + guint32 color) +{ + knot_shape = shape; + knot_mode = mode; + knot_color = color; +} +/* +class FilletChamferPointArrayParamKnotHolderEntity : public KnotHolderEntity { +public: + FilletChamferPointArrayParamKnotHolderEntity(FilletChamferPointArrayParam +*p, unsigned int index); + virtual ~FilletChamferPointArrayParamKnotHolderEntity() {} + + virtual void knot_set(Point const &p, Point const &origin, guint state); + virtual Point knot_get() const; + virtual void knot_click(guint state); + virtual void knot_doubleclicked(guint state); + + /Checks whether the index falls within the size of the parameter's vector/ + bool valid_index(unsigned int index) const { + return (_pparam->_vector.size() > index); + }; + +private: + FilletChamferPointArrayParam *_pparam; + unsigned int _index; +}; +/*/ + +FilletChamferPointArrayParamKnotHolderEntity:: +FilletChamferPointArrayParamKnotHolderEntity( + FilletChamferPointArrayParam *p, unsigned int index) + : _pparam(p), _index(index) {} + +void FilletChamferPointArrayParamKnotHolderEntity::knot_set(Point const &p, + Point const &origin, + guint state) +{ + using namespace Geom; + + if (!valid_index(_index)) { + return; + } + /// @todo how about item transforms??? + Piecewise > const &pwd2 = _pparam->get_pwd2(); + //todo: add snapping + //Geom::Point const s = snap_knot_position(p, state); + double t = nearest_point(p, pwd2[_index]); + if (t == 1) { + t = 0.9999; + } + t += _index; + + if (_pparam->_vector.at(_index)[X] <= 0) { + _pparam->_vector.at(_index) = + Point(_pparam->time_to_len(_index, t), _pparam->_vector.at(_index)[Y]); + } else { + _pparam->_vector.at(_index) = Point(t, _pparam->_vector.at(_index)[Y]); + } + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); +} + +Point FilletChamferPointArrayParamKnotHolderEntity::knot_get() const +{ + using namespace Geom; + + if (!valid_index(_index)) { + return Point(infinity(), infinity()); + } + + Piecewise > const &pwd2 = _pparam->get_pwd2(); + + double time_it = _pparam->to_time(_index, _pparam->_vector.at(_index)[X]); + Point canvas_point = pwd2.valueAt(time_it); + + _pparam->updateCanvasIndicators(); + return canvas_point; + +} + +void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) +{ + if (state & GDK_CONTROL_MASK) { + using namespace Geom; + double type = _pparam->_vector.at(_index)[Y] + 1; + if (type > 4) { + type = 1; + } + _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], type); + _pparam->param_set_and_write_new_value(_pparam->_vector); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + const gchar *tip; + if (type == 3) { + tip = _("Chamfer: Ctrl+click toogle type, " + "Shift+click open dialog"); + } else if (type == 2) { + tip = _("Inverse Fillet: Ctrl+click toogle type, " + "Shift+click open dialog"); + } else if (type == 1) { + tip = _("Fillet: Ctrl+click toogle type, " + "Shift+click open dialog"); + } else { + tip = _("Double Chamfer: Ctrl+click toogle type, " + "Shift+click open dialog"); + } + this->knot->tip = g_strdup(tip); + this->knot->show(); + //} + } else if ((state & GDK_MOD1_MASK) || (state & GDK_SHIFT_MASK)) { + Geom::Point offset = Geom::Point(_pparam->_vector.at(_index).x(), + _pparam->_vector.at(_index).y()); + Inkscape::UI::Dialogs::FilletChamferPropertiesDialog::showDialog( + this->desktop, offset, this, _pparam->unit); + } + +} + +void +FilletChamferPointArrayParamKnotHolderEntity::knot_doubleclicked(guint state) +{ + //todo: fill the double click dialog whith this parameters in the added file + //src/ui/dialog/lpe-fillet-chamfer-properties.cpp(.h) + //My idea for when have enought time is: + //label whith radius in percent + //label whith radius in size -maybe handle units- + //entry whith actual radius -in flexible % mode or fixed -?px- + //2 radio options to switch entry from fixed or flexible, also update the + //entry + //Checkbox or two radios to swith fillet or chamfer + +} + +void FilletChamferPointArrayParamKnotHolderEntity::knot_set_offset( + Geom::Point offset) +{ + _pparam->_vector.at(_index) = Geom::Point(offset.x(), offset.y()); + this->parent_holder->knot_ungrabbed_handler(this->knot, 0); +} + +void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, + SPDesktop *desktop, + SPItem *item) +{ + recalculate_knots(get_pwd2()); + for (unsigned int i = 0; i < _vector.size(); ++i) { + if (_vector[i][Y] <= 0) { + continue; + } + const gchar *tip; + if (_vector[i][Y] == 3) { + tip = _("Chamfer: Ctrl+click toogle type, " + "Shift+click open dialog"); + } else if (_vector[i][Y] == 2) { + tip = _("Inverse Fillet: Ctrl+click toogle type, " + "Shift+click open dialog"); + } else if (_vector[i][Y] == 1) { + tip = _("Fillet: Ctrl+click toogle type, " + "Shift+click open dialog"); + } else { + tip = _("Double Chamfer: Ctrl+click toogle type, " + "Shift+click open dialog"); + } + FilletChamferPointArrayParamKnotHolderEntity *e = + new FilletChamferPointArrayParamKnotHolderEntity(this, i); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _(tip), + knot_shape, knot_mode, knot_color); + knotholder->add(e); + } + updateCanvasIndicators(); +} + +} /* namespace LivePathEffect */ + +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/filletchamferpointarray.h b/src/live_effects/parameter/filletchamferpointarray.h new file mode 100644 index 000000000..93d6e9f4c --- /dev/null +++ b/src/live_effects/parameter/filletchamferpointarray.h @@ -0,0 +1,117 @@ +#ifndef INKSCAPE_LIVEPATHEFFECT_FILLET_CHAMFER_POINT_ARRAY_H +#define INKSCAPE_LIVEPATHEFFECT_FILLET_CHAMFER_POINT_ARRAY_H + +/* + * Inkscape::LivePathEffectParameters + * Copyright (C) Jabiertxo Arraiza Cenoz + * Special thanks to Johan Engelen for the base of the effect -powerstroke- + * Also to ScislaC for point me to the idea + * Also su_v for his construvtive feedback and time + * and finaly to Liam P. White for his big help on coding, that save me a lot of + * hours + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include <2geom/point.h> + +#include "live_effects/parameter/array.h" + +#include "knot-holder-entity.h" + +namespace Inkscape { + +namespace LivePathEffect { + +class FilletChamferPointArrayParamKnotHolderEntity; + +class FilletChamferPointArrayParam : public ArrayParam { +public: + FilletChamferPointArrayParam(const Glib::ustring &label, + const Glib::ustring &tip, + const Glib::ustring &key, + Inkscape::UI::Widget::Registry *wr, + Effect *effect); + virtual ~FilletChamferPointArrayParam(); + + virtual Gtk::Widget *param_newWidget(); + + virtual void param_transform_multiply(Geom::Affine const &postmul, + bool /*set*/); + + void set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, + guint32 color); + virtual double to_time(int index, double A); + virtual double to_len(int index, double A); + virtual double len_to_time(int index, double len); + virtual double time_to_len(int index, double time); + virtual void set_helper_size(int hs); + virtual void set_unit(const gchar *abbr); + virtual void addCanvasIndicators(SPLPEItem const *lpeitem, + std::vector &hp_vec); + virtual bool providesKnotHolderEntities() const { + return true; + } + virtual void updateCanvasIndicators(); + virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, + SPItem *item); + + void set_pwd2(Geom::Piecewise > const &pwd2_in, + Geom::Piecewise > const &pwd2_normal_in); + Geom::Piecewise > const &get_pwd2() const { + return last_pwd2; + } + Geom::Piecewise > const &get_pwd2_normal() const { + return last_pwd2_normal; + } + + void recalculate_controlpoints_for_new_pwd2( + Geom::Piecewise > const &pwd2_in); + void recalculate_knots( + Geom::Piecewise > const &pwd2_in); + friend class FilletChamferPointArrayParamKnotHolderEntity; + +private: + FilletChamferPointArrayParam(const FilletChamferPointArrayParam &); + FilletChamferPointArrayParam &operator=(const FilletChamferPointArrayParam &); + + SPKnotShapeType knot_shape; + SPKnotModeType knot_mode; + guint32 knot_color; + int helper_size; + const gchar *unit; + Geom::PathVector hp; + + Geom::Piecewise > last_pwd2; + Geom::Piecewise > last_pwd2_normal; +}; + +class FilletChamferPointArrayParamKnotHolderEntity : public KnotHolderEntity { +public: + FilletChamferPointArrayParamKnotHolderEntity(FilletChamferPointArrayParam *p, + unsigned int index); + virtual ~FilletChamferPointArrayParamKnotHolderEntity() {} + + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, + guint state); + virtual Geom::Point knot_get() const; + virtual void knot_click(guint state); + virtual void knot_doubleclicked(guint state); + virtual void knot_set_offset(Geom::Point offset); + + /*Checks whether the index falls within the size of the parameter's vector*/ + bool valid_index(unsigned int index) const { + return (_pparam->_vector.size() > index); + } + ; + +private: + FilletChamferPointArrayParam *_pparam; + unsigned int _index; +}; + +} //namespace LivePathEffect + +} //namespace Inkscape + +#endif diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index daa8aea22..1bd939707 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -114,4 +114,6 @@ ink_common_sources += \ ui/dialog/undo-history.h \ ui/dialog/xml-tree.cpp \ ui/dialog/xml-tree.h \ + ui/dialog/lpe-fillet-chamfer-properties.cpp \ + ui/dialog/lpe-fillet-chamfer-properties.h \ $(inkboard_dialogs) diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp new file mode 100644 index 000000000..a68c7ee08 --- /dev/null +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -0,0 +1,257 @@ +/** + * From the code of Liam P.White from his Power Stroke Knot dialog + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if GLIBMM_DISABLE_DEPRECATED &&HAVE_GLIBMM_THREADS_H +#include +#endif + +#include "lpe-fillet-chamfer-properties.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "layer-manager.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "sp-object.h" +#include "sp-item.h" +#include "verbs.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +#include +#include +#include "util/units.h" + +//#include "event-context.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() + : _desktop(NULL), _knotpoint(NULL), _position_visible(false) +{ + Gtk::Box *mainVBox = get_vbox(); + mainVBox->set_homogeneous(false); + _layout_table.set_spacings(4); + _layout_table.resize(2, 2); + + // Layer name widgets + _fillet_chamfer_position_entry.set_activates_default(true); + _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); + _fillet_chamfer_position_label.set_alignment(1.0, 0.5); + + _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, + Gtk::FILL); + _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, + Gtk::FILL | Gtk::EXPAND, Gtk::FILL); + _fillet_chamfer_type_fillet.set_label(_("Fillet")); + _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); + _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); + _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_double_chamfer.set_label(_("Double chamfer")); + _fillet_chamfer_type_double_chamfer.set_group(_fillet_chamfer_type_group); + + mainVBox->pack_start(_layout_table, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_double_chamfer, true, true, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_can_default(); + + _apply_button.set_use_underline(true); + _apply_button.set_can_default(); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_apply)); + + signal_delete_event().connect(sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &FilletChamferPropertiesDialog::_close)), + true)); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); + + set_focus(_fillet_chamfer_position_entry); +} + +FilletChamferPropertiesDialog::~FilletChamferPropertiesDialog() +{ + + _setDesktop(NULL); +} + +void FilletChamferPropertiesDialog::showDialog( + SPDesktop *desktop, Geom::Point knotpoint, + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt, + const gchar *unit) +{ + FilletChamferPropertiesDialog *dialog = new FilletChamferPropertiesDialog(); + + dialog->_setDesktop(desktop); + dialog->_setUnit(unit); + dialog->_setKnotPoint(knotpoint); + dialog->_setPt(pt); + + dialog->set_title(_("Modify Fillet-Chamfer")); + dialog->_apply_button.set_label(_("_Modify")); + + dialog->set_modal(true); + desktop->setWindowTransient(dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void FilletChamferPropertiesDialog::_apply() +{ + std::istringstream i_pos(_fillet_chamfer_position_entry.get_text()); + double d_pos, d_width; + if (i_pos >> d_pos) { + if (_fillet_chamfer_type_fillet.get_active() == true) { + d_width = 1; + } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { + d_width = 2; + } else if (_fillet_chamfer_type_chamfer.get_active() == true) { + d_width = 3; + } else { + d_width = 4; + } + if (_flexible) { + if (d_pos > 99.99999 || d_pos < 0) { + d_pos = 0; + } + d_pos = _index + (d_pos / 100); + } else { + d_pos = Inkscape::Util::Quantity::convert(d_pos, unit, "px"); + d_pos = d_pos * -1; + } + _knotpoint->knot_set_offset(Geom::Point(d_pos, d_width)); + } + _close(); +} + +void FilletChamferPropertiesDialog::_close() +{ + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +bool FilletChamferPropertiesDialog::_handleKeyEvent(GdkEventKey *event) +{ + return false; +} + +void FilletChamferPropertiesDialog::_handleButtonEvent(GdkEventButton *event) +{ + if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { + _apply(); + } +} + +void FilletChamferPropertiesDialog::_setKnotPoint(Geom::Point knotpoint) +{ + double position; + if (knotpoint.x() > 0) { + double intpart; + position = modf(knotpoint[Geom::X], &intpart) * 100; + _flexible = true; + _index = intpart; + _fillet_chamfer_position_label.set_label(_("Position (%):")); + } else { + _flexible = false; + std::string posConcat = + std::string(_("Position (")) + std::string(unit) + std::string(")"); + _fillet_chamfer_position_label.set_label(_(posConcat.c_str())); + position = knotpoint[Geom::X] * -1; + position = Inkscape::Util::Quantity::convert(position, "px", unit); + } + std::ostringstream s; + s.imbue(std::locale::classic()); + s << position; + _fillet_chamfer_position_entry.set_text(s.str()); + if (knotpoint.y() == 1) { + _fillet_chamfer_type_fillet.set_active(true); + } else if (knotpoint.y() == 2) { + _fillet_chamfer_type_inverse_fillet.set_active(true); + } else if (knotpoint.y() == 3) { + _fillet_chamfer_type_chamfer.set_active(true); + } else if (knotpoint.y() == 1) { + _fillet_chamfer_type_double_chamfer.set_active(true); + } +} + +void FilletChamferPropertiesDialog::_setPt( + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt) +{ + _knotpoint = const_cast< + Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity *>( + pt); +} + +void FilletChamferPropertiesDialog::_setUnit(const gchar *abbr) +{ + unit = abbr; +} + +void FilletChamferPropertiesDialog::_setDesktop(SPDesktop *desktop) +{ + if (desktop) { + Inkscape::GC::anchor(desktop); + } + if (_desktop) { + Inkscape::GC::release(_desktop); + } + _desktop = desktop; +} + +} // namespace +} // namespace +} // namespace + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: +// filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 +// : diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h new file mode 100644 index 000000000..a07b5ab66 --- /dev/null +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -0,0 +1,112 @@ +/** + * + * From the code of Liam P.White from his Power Stroke Knot dialog + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H +#define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H + +#include <2geom/point.h> +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "live_effects/parameter/filletchamferpointarray.h" + +class SPDesktop; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +class FilletChamferPropertiesDialog : public Gtk::Dialog { +public: + FilletChamferPropertiesDialog(); + virtual ~FilletChamferPropertiesDialog(); + + Glib::ustring getName() const { + return "LayerPropertiesDialog"; + } + + static void showDialog(SPDesktop *desktop, Geom::Point knotpoint, + const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt, + const gchar *unit); + +protected: + + SPDesktop *_desktop; + Inkscape::LivePathEffect::FilletChamferPointArrayParamKnotHolderEntity * + _knotpoint; + + Gtk::Label _fillet_chamfer_position_label; + Gtk::Entry _fillet_chamfer_position_entry; + Gtk::RadioButton::Group _fillet_chamfer_type_group; + Gtk::RadioButton _fillet_chamfer_type_fillet; + Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; + Gtk::RadioButton _fillet_chamfer_type_chamfer; + Gtk::RadioButton _fillet_chamfer_type_double_chamfer; + + Gtk::Table _layout_table; + bool _position_visible; + double _index; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + + sigc::connection _destroy_connection; + + static FilletChamferPropertiesDialog &_instance() { + static FilletChamferPropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setPt(const Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity *pt); + void _setUnit(const gchar *abbr); + void _apply(); + void _close(); + bool _flexible; + const gchar *unit; + void _setKnotPoint(Geom::Point knotpoint); + void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton *event); + + friend class Inkscape::LivePathEffect:: + FilletChamferPointArrayParamKnotHolderEntity; + +private: + FilletChamferPropertiesDialog( + FilletChamferPropertiesDialog const &); // no copy + FilletChamferPropertiesDialog &operator=( + FilletChamferPropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: +// filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 +// : diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index 1328372c6..569a8e154 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -53,6 +53,7 @@ public: void insertNodesAtExtrema(ExtremumType extremum); void insertNodes(); + void alertLPE(); void duplicateNodes(); void joinNodes(); void breakNodes(); @@ -104,7 +105,7 @@ private: } void _commit(CommitEvent cps); - void _done(gchar const *reason, bool alert_LPE = false); + void _done(gchar const *reason, bool alert_LPE = true); void _doneWithCleanup(gchar const *reason, bool alert_LPE = false); guint32 _getOutlineColor(ShapeRole role); diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 3beeed049..01cff5ad7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -11,6 +11,7 @@ */ #include "live_effects/lpe-powerstroke.h" +#include "live_effects/lpe-fillet-chamfer.h" #include #include #include @@ -1300,11 +1301,20 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE) _spcurve->set_pathvector(pathv); if (alert_LPE) { /// \todo note that _path can be an Inkscape::LivePathEffect::Effect* too, kind of confusing, rework member naming? - if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()) { - PathEffectList effect_list = _path->getEffectList(); - LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast( effect_list.front()->lpeobject->get_lpe() ); - if (lpe_pwr) { - lpe_pwr->adjustForNewPath(pathv); + if (SP_IS_LPE_ITEM(_path) && _path->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE); + if(thisEffect){ + LivePathEffect::LPEPowerStroke *lpe_pwr = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + if (lpe_pwr) { + lpe_pwr->adjustForNewPath(pathv); + } + } + thisEffect = SP_LPE_ITEM(_path)->getPathEffectOfType(Inkscape::LivePathEffect::FILLET_CHAMFER); + if(thisEffect){ + LivePathEffect::LPEFilletChamfer *lpe_fll = dynamic_cast(thisEffect->getLPEObj()->get_lpe()); + if (lpe_fll) { + lpe_fll->adjustForNewPath(pathv); + } } } } -- cgit v1.2.3 From 22e482dd499a412dba05b570fec09cf08bc668f2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 2 Jul 2014 13:29:03 +0200 Subject: Fixed CMakeLists.txt pointed by Liam (bzr r13341.1.75) --- src/live_effects/CMakeLists.txt | 4 ++++ src/ui/CMakeLists.txt | 2 ++ 2 files changed, 6 insertions(+) (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 5d365bb21..a4d35b339 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -14,6 +14,7 @@ set(live_effects_SRC lpe-envelope.cpp lpe-envelope-perspective.cpp lpe-extrude.cpp + lpe-fillet-chamfer.cpp lpe-gears.cpp lpe-interpolate.cpp lpe-knot.cpp @@ -48,6 +49,7 @@ set(live_effects_SRC parameter/array.cpp parameter/bool.cpp + parameter/filletchamferpointarray.cpp parameter/parameter.cpp parameter/path.cpp parameter/originalpath.cpp @@ -77,6 +79,7 @@ set(live_effects_SRC lpe-dynastroke.h lpe-envelope.h lpe-extrude.h + lpe-fillet-chamfer.h lpe-gears.h lpe-interpolate.h lpe-knot.h @@ -112,6 +115,7 @@ set(live_effects_SRC parameter/array.h parameter/bool.h + parameter/filletchamferpointarray.h parameter/enum.h parameter/parameter.h parameter/path-reference.h diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 7d80f1e36..125755c48 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -78,6 +78,7 @@ set(ui_SRC dialog/layers.cpp dialog/livepatheffect-add.cpp dialog/livepatheffect-editor.cpp + dialog/lpe-fillet-chamfer-properties.cpp dialog/memory.cpp dialog/messages.cpp dialog/new-from-template.cpp @@ -198,6 +199,7 @@ set(ui_SRC dialog/layers.h dialog/livepatheffect-add.h dialog/livepatheffect-editor.h + dialog/lpe-fillet-chamfer-properties.h dialog/memory.h dialog/messages.h dialog/new-from-template.h -- cgit v1.2.3 From 0349a5a8eee52baeed06c92aee0d4d3bc3ade043 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 2 Jul 2014 18:18:25 -0400 Subject: Fix build (bzr r13341.1.76) --- src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 4d1c1d8c1..942ef5891 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -54,6 +54,7 @@ enum EffectType { POWERSTROKE, CLONE_ORIGINAL, ENVELOPE_PERSPECTIVE, + FILLET_CHAMFER, INVALID_LPE // This must be last (I made it such that it is not needed anymore I think..., Don't trust on it being last. - johan) }; diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index f70a540e8..6e0960216 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -49,6 +49,7 @@ #include "live_effects/lpe-powerstroke.h" #include "live_effects/lpe-clone-original.h" #include "live_effects/lpe-envelope-perspective.h" +#include "live_effects/lpe-fillet-chamfer.h" #include "xml/node-event-vector.h" #include "sp-object.h" -- cgit v1.2.3 From c9db2b11320dffc291faaf044815d3c4c782211e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 3 Jul 2014 00:29:58 +0200 Subject: Put correctly doubles in a function (bzr r13341.1.77) --- src/live_effects/lpe-fillet-chamfer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index c25e3bffd..1fb68020d 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -525,7 +525,7 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) std::vector filletChamferData = fillet_chamfer_values.data(); int counter = 0; //from http://launchpadlibrarian.net/12692602/rcp.svg - const double K = (4. / 3) * (sqrt(2) - 1); + const double K = (4.0 / 3.0) * (sqrt(2.0) - 1.0); for (PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { if (path_it->empty()) -- cgit v1.2.3 From c5a3e612c363f761171123cf62f65c85808c296e Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 5 Jul 2014 15:23:33 +0200 Subject: Fix regression that prevented snapping back to original location, caused by rev. 13333 Fixed bugs: - https://launchpad.net/bugs/1337170 (bzr r13446) --- src/seltrans.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/seltrans.cpp b/src/seltrans.cpp index d6f31f073..d16e02e42 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -377,12 +377,6 @@ void Inkscape::SelTrans::transform(Geom::Affine const &rel_affine, Geom::Point c g_return_if_fail(_grabbed); g_return_if_fail(!_empty); - // E.g. scaling a perfectly vertical line in horizontal direction will not work, and will produce an identity affine - - if (rel_affine.isIdentity()) { - return; - } - Geom::Affine const affine( Geom::Translate(-norm) * rel_affine * Geom::Translate(norm) ); if (_show == SHOW_CONTENT) { @@ -1327,6 +1321,16 @@ void Inkscape::SelTrans::stretch(SPSelTransHandle const &/*handle*/, Geom::Point void Inkscape::SelTrans::scale(Geom::Point &/*pt*/, guint /*state*/) { + // E.g. scaling a perfectly vertical line in horizontal direction will not work, and will produce an identity affine + // Applying a transformation is useless, so we will not attempt to do so because this might trigger other bugs + // (see https://bugs.launchpad.net/inkscape/+bug/1256597) + // We check for this here and not in transform because identity transformations are perfectly fine for for example + // translations (e.g. a translation of (0,0), which occurs when snapping a point back to its original location) + + if (_absolute_affine.isIdentity()) { + return; + } + transform(_absolute_affine, Geom::Point(0, 0)); // we have already accounted for origin, so pass 0,0 } -- cgit v1.2.3 From 962ef8a02c2dbaf2049c1951ec8953ba885f9e19 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 5 Jul 2014 12:01:13 -0400 Subject: Fix FTBFS gtk3 & make check (bzr r13341.1.78) --- src/live_effects/parameter/filletchamferpointarray.cpp | 11 +++++++---- src/ui/dialog/lpe-fillet-chamfer-properties.h | 10 +--------- 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index 94a26dd8d..457b68dd2 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -8,6 +8,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include <2geom/piecewise.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/sbasis-geometric.h> + #include "ui/dialog/lpe-fillet-chamfer-properties.h" #include "live_effects/parameter/filletchamferpointarray.h" #include "live_effects/effect.h" @@ -15,9 +19,6 @@ #include "svg/stringstream.h" #include "knotholder.h" #include "sp-lpe-item.h" -#include <2geom/piecewise.h> -#include <2geom/sbasis-to-bezier.h> -#include <2geom/sbasis-geometric.h> #include "selection.h" // needed for on-canvas editting: @@ -25,8 +26,10 @@ #include "live_effects/lpeobject.h" #include "helper/geom-nodetype.h" #include "helper/geom-curves.h" -#include #include "ui/tools/node-tool.h" + +// TODO due to internal breakage in glibmm headers, +// this has to be included last. #include using namespace Geom; diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index a07b5ab66..d3e859bff 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -9,15 +9,7 @@ #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #include <2geom/point.h> -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include "live_effects/parameter/filletchamferpointarray.h" class SPDesktop; -- cgit v1.2.3 From f0c7df3517326ecf248ee6e768e1c835d072561c Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 6 Jul 2014 10:13:13 -0400 Subject: Fix an oddity with path effects dialog, gtk3 only (bzr r13341.1.79) --- src/live_effects/parameter/parameter.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index a5de2169e..401d89884 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -43,6 +43,14 @@ Parameter::param_write_to_repr(const char * svgd) param_effect->getRepr()->setAttribute(param_key.c_str(), svgd); } + +// In gtk2, this wasn't an issue; we could toss around +// G_MAXDOUBLE and not worry about size allocations. But +// in gtk3, it is an issue: it allocates widget size for the maxmium +// value you pass to it, leading to some insane lengths. +const double SCALARPARAM_G_MAXDOUBLE = 10000000000; + + /*########################################### * REAL PARAM */ @@ -51,8 +59,8 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, Effect* effect, gdouble default_value) : Parameter(label, tip, key, wr, effect), value(default_value), - min(-G_MAXDOUBLE), - max(G_MAXDOUBLE), + min(-SCALARPARAM_G_MAXDOUBLE), + max(SCALARPARAM_G_MAXDOUBLE), integer(false), defvalue(default_value), digits(2), -- cgit v1.2.3 From f021bb175a1d26ffe8f51df479c3cc23abfbbde4 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 6 Jul 2014 11:39:19 -0400 Subject: Extension of fix for 13420: effects often set upper limit to inf, causing problems in gtk3 (bzr r13341.1.80) --- src/live_effects/parameter/parameter.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 401d89884..7732eee76 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -48,6 +48,7 @@ Parameter::param_write_to_repr(const char * svgd) // G_MAXDOUBLE and not worry about size allocations. But // in gtk3, it is an issue: it allocates widget size for the maxmium // value you pass to it, leading to some insane lengths. +// If you need this to be more, please be conservative about it. const double SCALARPARAM_G_MAXDOUBLE = 10000000000; @@ -116,8 +117,22 @@ ScalarParam::param_set_value(gdouble val) void ScalarParam::param_set_range(gdouble min, gdouble max) { - this->min = min; - this->max = max; + // if you look at client code, you'll see that many effects + // has a tendency to set an upper range of Geom::infinity(). + // Once again, in gtk2, this is not a problem. But in gtk3, + // widgets get allocated the amount of size they ask for, + // leading to excessively long widgets. + + if (min >= -SCALARPARAM_G_MAXDOUBLE) { + this->min = min; + } else { + this->min = -SCALARPARAM_G_MAXDOUBLE; + } + if (max <= SCALARPARAM_G_MAXDOUBLE) { + this->max = max; + } else { + this->max = SCALARPARAM_G_MAXDOUBLE; + } param_set_value(value); // reset value to see whether it is in ranges } -- cgit v1.2.3 From 8ce05e18118b2fb9a1475cd833394d4b40153031 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 6 Jul 2014 13:53:10 -0400 Subject: Coding style improvements (bzr r13341.1.81) --- src/live_effects/effect.cpp | 16 +-- src/live_effects/lpe-fillet-chamfer.cpp | 202 +++++++++++++------------------- src/live_effects/lpe-fillet-chamfer.h | 69 +++++++---- src/live_effects/parameter/bool.h | 2 +- 4 files changed, 134 insertions(+), 155 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 6e0960216..f0611785b 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -108,7 +108,7 @@ const Util::EnumData LPETypeData[] = { {TEXT_LABEL, N_("Text label"), "text_label"}, #endif /* 0.46 */ - {BEND_PATH, N_("Bend"), "bend_path"}, + {BEND_PATH, N_("Bend"), "bend_path"}, {GEARS, N_("Gears"), "gears"}, {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG {CURVE_STITCH, N_("Stitch Sub-Paths"), "curvestitching"}, @@ -122,13 +122,15 @@ const Util::EnumData LPETypeData[] = { {ROUGH_HATCHES, N_("Hatches (rough)"), "rough_hatches"}, {SKETCH, N_("Sketch"), "sketch"}, {RULER, N_("Ruler"), "ruler"}, -/* 0.49 */ - {POWERSTROKE, N_("Power stroke"), "powerstroke"}, - {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, +/* 0.91 */ + {POWERSTROKE, N_("Power stroke"), "powerstroke"}, + {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, {BSPLINE, N_("BSpline"), "bspline"}, - {SIMPLIFY, N_("Simplify"), "simplify"}, - {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, - {ENVELOPE_PERSPECTIVE, N_("Envelope-Perspective"), "envelope-perspective"}, + {SIMPLIFY, N_("Simplify"), "simplify"}, + {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, + // TRANSLATORS: "Envelope Perspective" should be equivalent to "perspective transformation" + {ENVELOPE_PERSPECTIVE, N_("Envelope Perspective"), "envelope-perspective"}, + {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 1fb68020d..fc2173a67 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -1,36 +1,39 @@ /* - * Copyright (C) Jabiertxo Arraiza Cenoz + * Author(s): + * Jabiertxo Arraiza Cenoz + * + * Copyright (C) 2014 Author(s) + * * Special thanks to Johan Engelen for the base of the effect -powerstroke- * Also to ScislaC for point me to the idea * Also su_v for his construvtive feedback and time * Also to Mc- (IRC nick) for his important contribution to find real time * values based on - * and finaly to Liam P. White for his big help on coding, that save me a lot of - * hours + * and finaly to Liam P. White for his big help on coding, that save me a lot of hours + * * Released under GNU GPL, read the file 'COPYING' for more information */ - #include "live_effects/lpe-fillet-chamfer.h" -#include -#include "style.h" -#include "live_effects/parameter/filletchamferpointarray.h" -//for update knot + +#include <2geom/sbasis-to-bezier.h> #include <2geom/svg-elliptical-arc.h> #include <2geom/line.h> + +#include "desktop.h" +#include "display/curve.h" +#include "helper/geom-nodetype.h" +#include "live_effects/parameter/filletchamferpointarray.h" + +// for programmatically updating knots #include "selection.h" +#include "tools-switch.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/selectable-control-point.h" -#include <2geom/sbasis-to-bezier.h> #include "ui/tool/node.h" -// FIXME: The following are only needed to convert the path's SPCurve* to pwd2. -// There must be a more convenient way to achieve this. -#include "display/curve.h" -#include "helper/geom-nodetype.h" -#include "desktop.h" #include "ui/tools/node-tool.h" -#include -#include -#include + +// TODO due to internal breakage in glibmm headers, this must be last: +#include using namespace Geom; namespace Inkscape { @@ -39,34 +42,26 @@ namespace LivePathEffect { const double tolerance = 0.001; const double gapHelper = 0.00001; -LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) - : Effect(lpeobject), - fillet_chamfer_values(_("Fillet point"), _("Fillet point"), - "fillet_chamfer_values", &wr, this), - hide_knots(_("Hide knots"), _("Hide knots"), "hide_knots", &wr, this, - false), - ignore_radius_0(_("Ignore 0 radius knots"), _("Ignore 0 radius knots"), - "ignore_radius_0", &wr, this, false), - only_selected(_("Change only selected nodes"), - _("Change only selected nodes"), "only_selected", &wr, this, - false), - flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), - "flexible", &wr, this, false), - unit(_("Unit"), _("Unit"), "unit", &wr, this), - radius(_("Radius (unit or %)"), _("Radius, in unit or %"), "radius", &wr, - this, 0.), - helper_size(_("Helper size with direction"), - _("Helper size with direction"), "helper_size", &wr, this, - 0) +LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + fillet_chamfer_values(_("Fillet point"), _("Fillet point"), "fillet_chamfer_values", &wr, this), + hide_knots(_("Hide knots"), _("Hide knots"), "hide_knots", &wr, this, false), + ignore_radius_0(_("Ignore 0 radius knots"), _("Ignore 0 radius knots"), "ignore_radius_0", &wr, this, false), + only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false), + flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), "flexible", &wr, this, false), + unit(_("Unit"), _("Unit"), "unit", &wr, this), + radius(_("Radius (unit or %)"), _("Radius, in unit or %"), "radius", &wr, this, 0.), + helper_size(_("Helper size with direction"), _("Helper size with direction"), "helper_size", &wr, this, 0) { - registerParameter(dynamic_cast(&fillet_chamfer_values)); - registerParameter(dynamic_cast(&unit)); - registerParameter(dynamic_cast(&radius)); - registerParameter(dynamic_cast(&helper_size)); - registerParameter(dynamic_cast(&flexible)); - registerParameter(dynamic_cast(&ignore_radius_0)); - registerParameter(dynamic_cast(&only_selected)); - registerParameter(dynamic_cast(&hide_knots)); + registerParameter(&fillet_chamfer_values); + registerParameter(&unit); + registerParameter(&radius); + registerParameter(&helper_size); + registerParameter(&flexible); + registerParameter(&ignore_radius_0); + registerParameter(&only_selected); + registerParameter(&hide_knots); + radius.param_set_range(0., infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); @@ -90,53 +85,32 @@ Gtk::Widget *LPEFilletChamfer::newWidget() while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + Gtk::Widget *widg = param->param_newWidget(); if (param->param_key == "radius") { - Inkscape::UI::Widget::Scalar *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widgRegistered->signal_value_changed() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::updateFillet)); - widg = dynamic_cast(widgRegistered); + Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::updateFillet)); + widg = widgRegistered; if (widg) { Gtk::HBox *scalarParameter = dynamic_cast(widg); - std::vector childList = - scalarParameter->get_children(); + std::vector childList = scalarParameter->get_children(); Gtk::Entry *entryWidg = dynamic_cast(childList[1]); entryWidg->set_width_chars(6); } + } else if (param->param_key == "flexible") { + Gtk::CheckButton *widgRegistered = Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleFlexFixed)); + } else if (param->param_key == "helper_size") { + Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::refreshKnots)); + } else if (param->param_key == "hide_knots") { + Gtk::CheckButton *widgRegistered = Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleHide)); + } else if (param->param_key == "only_selected") { + Gtk::manage(widg); + } else if (param->param_key == "ignore_radius_0") { + Gtk::manage(widg); } - if (param->param_key == "flexible") { - Gtk::CheckButton *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widgRegistered->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleFlexFixed)); - widg = dynamic_cast(widgRegistered); - } - if (param->param_key == "helper_size") { - Inkscape::UI::Widget::Scalar *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widgRegistered->signal_value_changed() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::refreshKnots)); - widg = dynamic_cast(widgRegistered); - - } - if (param->param_key == "hide_knots") { - Gtk::CheckButton *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widgRegistered->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleHide)); - widg = dynamic_cast(widgRegistered); - } - if (param->param_key == "only_selected") { - Gtk::CheckButton *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widgRegistered); - } - if (param->param_key == "ignore_radius_0") { - Gtk::CheckButton *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widgRegistered); - } + Glib::ustring *tip = param->param_getTooltip(); if (widg) { vbox->pack_start(*widg, true, true, 2); @@ -153,32 +127,27 @@ Gtk::Widget *LPEFilletChamfer::newWidget() } Gtk::HBox *filletButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); - Gtk::Button *fillet = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); - fillet->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::fillet)); + Gtk::Button *fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); + fillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::fillet)); + filletButtonsContainer->pack_start(*fillet, true, true, 2); - Gtk::Button *inverse = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); - inverse->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverse)); + Gtk::Button *inverse = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); + inverse->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverse)); filletButtonsContainer->pack_start(*inverse, true, true, 2); Gtk::HBox *chamferButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); - Gtk::Button *chamfer = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); - chamfer->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer)); + Gtk::Button *chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); + chamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer)); + chamferButtonsContainer->pack_start(*chamfer, true, true, 2); - Gtk::Button *doubleChamfer = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Double chamfer")))); - doubleChamfer->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEFilletChamfer::doubleChamfer)); + Gtk::Button *doubleChamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Double chamfer")))); + doubleChamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::doubleChamfer)); chamferButtonsContainer->pack_start(*doubleChamfer, true, true, 2); + vbox->pack_start(*filletButtonsContainer, true, true, 2); vbox->pack_start(*chamferButtonsContainer, true, true, 2); - return dynamic_cast(vbox); + return vbox; } void LPEFilletChamfer::toggleHide() @@ -227,8 +196,7 @@ void LPEFilletChamfer::updateFillet() { double power = 0; if (!flexible) { - power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), - "px") * -1; + power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), "px") * -1; } else { power = radius; } @@ -271,8 +239,7 @@ void LPEFilletChamfer::refreshKnots() } } -bool LPEFilletChamfer::nodeIsSelected(Geom::Point nodePoint, - std::vector point) +bool LPEFilletChamfer::nodeIsSelected(Geom::Point nodePoint, std::vector point) { if (point.size() > 0) { for (std::vector::iterator i = point.begin(); i != point.end(); @@ -285,20 +252,15 @@ bool LPEFilletChamfer::nodeIsSelected(Geom::Point nodePoint, } return false; } -void LPEFilletChamfer::doUpdateFillet(std::vector original_pathv, - double power) +void LPEFilletChamfer::doUpdateFillet(std::vector const& original_pathv, double power) { std::vector point; SPDesktop *desktop = inkscape_active_desktop(); if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nodeTool = - INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = - nodeTool->_selected_nodes->allPoints(); + Inkscape::UI::Tools::NodeTool *nodeTool = INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::ControlPointSelection::Set &selection = nodeTool->_selected_nodes->allPoints(); std::vector::iterator pBegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = - selection.begin(); - i != selection.end(); ++i) { + for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i) { if ((*i)->selected()) { Inkscape::UI::Node *n = dynamic_cast(*i); pBegin = point.begin(); @@ -350,8 +312,7 @@ void LPEFilletChamfer::doUpdateFillet(std::vector original_pathv, fillet_chamfer_values.param_set_and_write_new_value(result); } -void LPEFilletChamfer::doChangeType(std::vector original_pathv, - int type) +void LPEFilletChamfer::doChangeType(std::vector const& original_pathv, int type) { std::vector point; SPDesktop *desktop = inkscape_active_desktop(); @@ -374,8 +335,7 @@ void LPEFilletChamfer::doChangeType(std::vector original_pathv, std::vector filletChamferData = fillet_chamfer_values.data(); std::vector result; int counter = 0; - for (PathVector::const_iterator path_it = original_pathv.begin(); - path_it != original_pathv.end(); ++path_it) { + for (PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { int pathCounter = 0; if (path_it->empty()) continue; @@ -418,11 +378,9 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) { if (SP_IS_SHAPE(lpeItem)) { std::vector point; - PathVector const &original_pathv = - SP_SHAPE(lpeItem)->_curve->get_pathvector(); + PathVector const &original_pathv = SP_SHAPE(lpeItem)->_curve->get_pathvector(); Piecewise > pwd2_in = paths_to_pw(original_pathv); - for (PathVector::const_iterator path_it = original_pathv.begin(); - path_it != original_pathv.end(); ++path_it) { + for (PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()) continue; diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h index f5eee0205..420425650 100644 --- a/src/live_effects/lpe-fillet-chamfer.h +++ b/src/live_effects/lpe-fillet-chamfer.h @@ -2,50 +2,57 @@ #define INKSCAPE_LPE_FILLET_CHAMFER_H /* - * Inkscape::LPEFilletChamfer - * Copyright (C) Jabiertxo Arraiza Cenoz + * Author(s): + * Jabiertxo Arraiza Cenoz + * + * Copyright (C) 2014 Author(s) + * * Special thanks to Johan Engelen for the base of the effect -powerstroke- * Also to ScislaC for point me to the idea * Also su_v for his construvtive feedback and time - * and finaly to Liam P. White for his big help on coding, that save me a lot of - * hours + * and finaly to Liam P. White for his big help on coding, that save me a lot of hours + * * Released under GNU GPL, read the file 'COPYING' for more information */ + +#include + #include "live_effects/parameter/enum.h" -#include "live_effects/parameter/unit.h" -#include "live_effects/effect.h" #include "live_effects/parameter/bool.h" +#include "live_effects/parameter/unit.h" + #include "live_effects/parameter/filletchamferpointarray.h" +#include "live_effects/effect.h" namespace Inkscape { namespace LivePathEffect { -class LPEFilletChamfer : public Effect { +class LPEFilletChamfer : public Effect { public: LPEFilletChamfer(LivePathEffectObject *lpeobject); virtual ~LPEFilletChamfer(); - std::vector doEffect_path(std::vector const &path_in); + virtual std::vector doEffect_path(std::vector const &path_in); virtual void doOnApply(SPLPEItem const *lpeItem); virtual void doBeforeEffect(SPLPEItem const *lpeItem); - virtual int getKnotsNumber(SPCurve const *c); virtual void adjustForNewPath(std::vector const &path_in); - virtual void toggleHide(); - virtual void toggleFlexFixed(); - virtual void chamfer(); - virtual void fillet(); - virtual void doubleChamfer(); - virtual void inverse(); - virtual void updateFillet(); - virtual void doUpdateFillet(std::vector original_pathv, - double power); - virtual void doChangeType(std::vector original_pathv, int type); - virtual bool nodeIsSelected(Geom::Point nodePoint, - std::vector points); - virtual void refreshKnots(); - virtual Gtk::Widget *newWidget(); + virtual Gtk::Widget* newWidget(); + + int getKnotsNumber(SPCurve const *c); + void toggleHide(); + void toggleFlexFixed(); + void chamfer(); + void fillet(); + void doubleChamfer(); + void inverse(); + void updateFillet(); + void doUpdateFillet(std::vector const& original_pathv, double power); + void doChangeType(std::vector const& original_pathv, int type); + bool nodeIsSelected(Geom::Point nodePoint, std::vector points); + void refreshKnots(); + FilletChamferPointArrayParam fillet_chamfer_values; private: @@ -63,6 +70,18 @@ private: }; -}; //namespace LivePathEffect -}; //namespace Inkscape +} //namespace LivePathEffect +} //namespace Inkscape + #endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h index fafb1beca..b45eeb0b3 100644 --- a/src/live_effects/parameter/bool.h +++ b/src/live_effects/parameter/bool.h @@ -4,7 +4,7 @@ /* * Inkscape::LivePathEffectParameters * -* Copyright (C) Johan Engelen 2007 + * Copyright (C) Johan Engelen 2007 * * Released under GNU GPL, read the file 'COPYING' for more information */ -- cgit v1.2.3 From 57e29f547e8d93040d3aa40205a8ef6b866f61a7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 7 Jul 2014 16:39:05 +0200 Subject: Changed toogle button to more clear combobox in envelope-prespective LPE (bzr r13341.1.83) --- src/live_effects/lpe-envelope-perspective.cpp | 49 ++++++++++++++++----------- src/live_effects/lpe-envelope-perspective.h | 2 +- 2 files changed, 31 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-envelope-perspective.cpp b/src/live_effects/lpe-envelope-perspective.cpp index bfd6e56d7..02cb67db3 100644 --- a/src/live_effects/lpe-envelope-perspective.cpp +++ b/src/live_effects/lpe-envelope-perspective.cpp @@ -29,17 +29,29 @@ using namespace Geom; namespace Inkscape { namespace LivePathEffect { +enum DeformationType { + DEFORMATION_ENVELOPE, + DEFORMATION_PERSPECTIVE +}; + +static const Util::EnumData DeformationTypeData[] = { + {DEFORMATION_ENVELOPE , N_("Envelope deformation"), "Envelope deformation"}, + {DEFORMATION_PERSPECTIVE , N_("Perspective"), "Perspective"} +}; + +static const Util::EnumDataConverter DeformationTypeConverter(DeformationTypeData, sizeof(DeformationTypeData)/sizeof(*DeformationTypeData)); + LPEEnvelopePerspective::LPEEnvelopePerspective(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: - perspective(_("Perspective"), _("Perspective"), "Perspective", &wr, this, false), - Up_Left_Point(_("Top Left:"), _("Top Left - Ctrl+Alt+Click to reset"), "Up_Left_Point", &wr, this), - Up_Right_Point(_("Top Right:"), _("Top Right - Ctrl+Alt+Click to reset"), "Up_Right_Point", &wr, this), - Down_Left_Point(_("Down Left:"), _("Down Left - Ctrl+Alt+Click to reset"), "Down_Left_Point", &wr, this), - Down_Right_Point(_("Down Right:"), _("Down Right - Ctrl+Alt+Click to reset"), "Down_Right_Point", &wr, this) + deform_type(_("Type"), _("Select the type of deformation"), "deform_type", DeformationTypeConverter, &wr, this, DEFORMATION_ENVELOPE), + Up_Left_Point(_("Top Left"), _("Top Left - Ctrl+Alt+Click to reset"), "Up_Left_Point", &wr, this), + Up_Right_Point(_("Top Right"), _("Top Right - Ctrl+Alt+Click to reset"), "Up_Right_Point", &wr, this), + Down_Left_Point(_("Down Left"), _("Down Left - Ctrl+Alt+Click to reset"), "Down_Left_Point", &wr, this), + Down_Right_Point(_("Down Right"), _("Down Right - Ctrl+Alt+Click to reset"), "Down_Right_Point", &wr, this) { // register all your parameters here, so Inkscape knows which parameters this effect has: - registerParameter( dynamic_cast(&perspective)); + registerParameter( dynamic_cast(&deform_type)); registerParameter( dynamic_cast(&Up_Left_Point) ); registerParameter( dynamic_cast(&Up_Right_Point) ); registerParameter( dynamic_cast(&Down_Left_Point) ); @@ -54,7 +66,7 @@ void LPEEnvelopePerspective::doEffect(SPCurve *curve) { using Geom::X; using Geom::Y; double projmatrix[3][3]; - if(perspective){ + if(deform_type == DEFORMATION_PERSPECTIVE){ std::vector handles(4); handles[0] = Down_Left_Point; handles[1] = Up_Left_Point; @@ -144,7 +156,7 @@ void LPEEnvelopePerspective::doEffect(SPCurve *curve) { curve_endit = path_it->end_open(); } } - if(perspective){ + if(deform_type == DEFORMATION_PERSPECTIVE){ nCurve->moveto(project_point(curve_it1->initialPoint(),projmatrix)); }else{ nCurve->moveto(project_point(curve_it1->initialPoint())); @@ -159,7 +171,7 @@ void LPEEnvelopePerspective::doEffect(SPCurve *curve) { pointAt2 = curve_it1->finalPoint(); } pointAt3 = curve_it1->finalPoint(); - if(perspective){ + if(deform_type == DEFORMATION_PERSPECTIVE){ pointAt1 = project_point(pointAt1,projmatrix); pointAt2 = project_point(pointAt2,projmatrix); pointAt3 = project_point(pointAt3,projmatrix); @@ -181,7 +193,7 @@ void LPEEnvelopePerspective::doEffect(SPCurve *curve) { pointAt2 = curve_it1->finalPoint(); } pointAt3 = curve_it1->finalPoint(); - if(perspective){ + if(deform_type == DEFORMATION_PERSPECTIVE){ pointAt1 = project_point(pointAt1,projmatrix); pointAt2 = project_point(pointAt2,projmatrix); pointAt3 = project_point(pointAt3,projmatrix); @@ -191,7 +203,7 @@ void LPEEnvelopePerspective::doEffect(SPCurve *curve) { pointAt3 = project_point(pointAt3); } nCurve->curveto(pointAt1, pointAt2, pointAt3); - if(perspective){ + if(deform_type == DEFORMATION_PERSPECTIVE){ nCurve->move_endpoints(project_point(path_it->begin()->initialPoint(),projmatrix), pointAt3); }else{ nCurve->move_endpoints(project_point(path_it->begin()->initialPoint()), pointAt3); @@ -251,13 +263,6 @@ LPEEnvelopePerspective::newWidget() vbox->set_border_width(5); vbox->set_homogeneous(false); vbox->set_spacing(6); - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); - - Gtk::Button* resetButton = Gtk::manage(new Gtk::Button(Gtk::Stock::CLEAR)); - resetButton->signal_clicked().connect(sigc::mem_fun (*this,&LPEEnvelopePerspective::resetGrid)); - resetButton->set_size_request(140,45); - vbox->pack_start(*hbox, true,true,2); - hbox->pack_start(*resetButton, false, false,2); std::vector::iterator it = param_vector.begin(); Gtk::HBox * hboxUpHandles = Gtk::manage(new Gtk::HBox(false,0)); Gtk::HBox * hboxDownHandles = Gtk::manage(new Gtk::HBox(false,0)); @@ -319,6 +324,12 @@ LPEEnvelopePerspective::newWidget() hboxMiddle->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); vbox->pack_start(*hboxMiddle, false, true, 2); vbox->pack_start(*hboxDownHandles, true, true, 2); + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); + Gtk::Button* resetButton = Gtk::manage(new Gtk::Button(Gtk::Stock::CLEAR)); + resetButton->signal_clicked().connect(sigc::mem_fun (*this,&LPEEnvelopePerspective::resetGrid)); + resetButton->set_size_request(140,45); + vbox->pack_start(*hbox, true,true,2); + hbox->pack_start(*resetButton, false, false,2); return dynamic_cast(vbox); } @@ -411,4 +422,4 @@ LPEEnvelopePerspective::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::v fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: file_type=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-envelope-perspective.h b/src/live_effects/lpe-envelope-perspective.h index 6aae33936..0de9a0e35 100644 --- a/src/live_effects/lpe-envelope-perspective.h +++ b/src/live_effects/lpe-envelope-perspective.h @@ -60,7 +60,7 @@ protected: void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); private: - BoolParam perspective; + EnumParam deform_type; PointReseteableParam Up_Left_Point; PointReseteableParam Up_Right_Point; PointReseteableParam Down_Left_Point; -- cgit v1.2.3 From 043a9ffa5dcd4d8492e06e8bac6679db404e1b2b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 7 Jul 2014 12:47:08 -0400 Subject: Small patch from su_v to make versioning appear on out-of-tree builds (bzr r13341.1.84) --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index bb34047a8..282797a50 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -220,7 +220,7 @@ endif # someone updates the BZR working directory. inkscape-version.cpp: $(inkscape_version_deps) VER_PREFIX="$(VERSION)";\ - VER_BZRREV=" r`bzr revno --tree`"; \ + VER_BZRREV=" r`bzr revno --tree $(top_srcdir)`"; \ if test ! -z "`bzr status -S -V $(srcdir)`"; then \ VER_CUSTOM=" custom"; \ fi; \ -- cgit v1.2.3 From 8744e466672f8dfc12ef60c9746b278d90f6dd89 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 7 Jul 2014 15:01:54 -0400 Subject: Allow basic editing capabilites if share directory is missing (bzr r13341.1.85) --- src/widgets/lpe-toolbar.cpp | 2 ++ src/widgets/node-toolbar.cpp | 1 + src/widgets/paintbucket-toolbar.cpp | 2 ++ src/widgets/rect-toolbar.cpp | 2 ++ src/widgets/select-toolbar.cpp | 2 ++ 5 files changed, 9 insertions(+) (limited to 'src') diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index e9e5af912..94d42b5eb 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -180,6 +180,7 @@ static void lpetool_unit_changed(GtkAction* /*act*/, GObject* tbl) { UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setString("/tools/lpetool/unit", unit->abbr); @@ -281,6 +282,7 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO tracker->setActiveUnit(sp_desktop_namedview(desktop)->doc_units); g_object_set_data(holder, "tracker", tracker); Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setString("/tools/lpetool/unit", unit->abbr); diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 53161857a..38e3f4fbd 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -229,6 +229,7 @@ static void sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tb return; } Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); NodeTool *nt = get_node_tool(); if (!nt || !(nt->_selected_nodes) ||nt->_selected_nodes->empty()) { diff --git a/src/widgets/paintbucket-toolbar.cpp b/src/widgets/paintbucket-toolbar.cpp index e20811de8..8ddaccf64 100644 --- a/src/widgets/paintbucket-toolbar.cpp +++ b/src/widgets/paintbucket-toolbar.cpp @@ -83,6 +83,8 @@ static void paintbucket_offset_changed(GtkAdjustment *adj, GObject *tbl) // Don't adjust the offset value because we're saving the // unit and it'll be correctly handled on load. prefs->setDouble("/tools/paintbucket/offset", (gdouble)gtk_adjustment_get_value(adj)); + + g_return_if_fail(unit != NULL); prefs->setString("/tools/paintbucket/offsetunits", unit->abbr); } diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index 6996786e3..c9a09e908 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -87,6 +87,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -180,6 +181,7 @@ static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar con UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); Unit const *unit = tracker->getActiveUnit(); Unit const *doc_unit = sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units; + g_return_if_fail(unit != NULL); gpointer item = g_object_get_data( tbl, "item" ); if (item && SP_IS_RECT(item)) { diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 284e436bf..d45fb7e4d 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -73,6 +73,7 @@ sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) if ( bbox ) { UnitTracker *tracker = reinterpret_cast(g_object_get_data(G_OBJECT(spw), "tracker")); Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); struct { char const *key; double val; } const keyval[] = { { "X", bbox->min()[X] }, @@ -178,6 +179,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) gdouble xrel = 0; gdouble yrel = 0; Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "X" ) ); GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( G_OBJECT(spw), "Y" ) ); -- cgit v1.2.3 From 88e1060e6c6ebcd0ede7cc2841b899d84072aaa0 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 7 Jul 2014 22:10:45 -0400 Subject: Bugged powerstroke point array tried accessing points on a quickly diverging path Fixed bugs: - https://launchpad.net/bugs/1333465 (bzr r13447) --- src/live_effects/parameter/powerstrokepointarray.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/parameter/powerstrokepointarray.cpp b/src/live_effects/parameter/powerstrokepointarray.cpp index fecdfeda8..647986da6 100644 --- a/src/live_effects/parameter/powerstrokepointarray.cpp +++ b/src/live_effects/parameter/powerstrokepointarray.cpp @@ -176,7 +176,10 @@ PowerStrokePointArrayParamKnotHolderEntity::knot_get() const Piecewise > const & n = _pparam->get_pwd2_normal(); Point offset_point = _pparam->_vector.at(_index); - + if (offset_point[X] > pwd2.size() || offset_point[X] < 0) { + g_warning("Broken powerstroke point at %f, I won't try to add that", offset_point[X]); + return Geom::Point(infinity(), infinity()); + } Point canvas_point = pwd2.valueAt(offset_point[X]) + offset_point[Y] * n.valueAt(offset_point[X]); return canvas_point; } -- cgit v1.2.3 From d4ca4b1bcfbfb921b3c615d1e39405ae1afc9b40 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 7 Jul 2014 22:11:55 -0400 Subject: Bugged powerstroke point array tried accessing points on a quickly diverging path Fixed bugs: - https://launchpad.net/bugs/1333465 (bzr r13341.1.86) --- src/live_effects/parameter/powerstrokepointarray.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/parameter/powerstrokepointarray.cpp b/src/live_effects/parameter/powerstrokepointarray.cpp index fecdfeda8..647986da6 100644 --- a/src/live_effects/parameter/powerstrokepointarray.cpp +++ b/src/live_effects/parameter/powerstrokepointarray.cpp @@ -176,7 +176,10 @@ PowerStrokePointArrayParamKnotHolderEntity::knot_get() const Piecewise > const & n = _pparam->get_pwd2_normal(); Point offset_point = _pparam->_vector.at(_index); - + if (offset_point[X] > pwd2.size() || offset_point[X] < 0) { + g_warning("Broken powerstroke point at %f, I won't try to add that", offset_point[X]); + return Geom::Point(infinity(), infinity()); + } Point canvas_point = pwd2.valueAt(offset_point[X]) + offset_point[Y] * n.valueAt(offset_point[X]); return canvas_point; } -- cgit v1.2.3 From 4dd0c8e37a02f75a7e301cc6ef7292bb18e86b44 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 8 Jul 2014 10:58:09 -0400 Subject: Add signals to ToggleButton; more coding style (bzr r13341.1.87) --- src/live_effects/lpe-bspline.cpp | 1242 +++++++++++++-------------- src/live_effects/lpe-bspline.h | 52 +- src/live_effects/lpe-fillet-chamfer.cpp | 4 +- src/live_effects/parameter/togglebutton.cpp | 19 +- src/live_effects/parameter/togglebutton.h | 17 +- 5 files changed, 671 insertions(+), 663 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index b19b697c0..a004b8490 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -8,10 +8,13 @@ # include #endif -#if WITH_GLIBMM_2_32 +#if WITH_GLIBMM_2_32 && HAVE_GLIBMM_THREADS_H # include #endif +#include <2geom/bezier-curve.h> +#include <2geom/point.h> + #include #include #include @@ -21,10 +24,7 @@ #include #include - #include "display/curve.h" -#include <2geom/bezier-curve.h> -#include <2geom/point.h> #include "helper/geom-curves.h" #include "live_effects/lpe-bspline.h" #include "live_effects/lpeobject.h" @@ -48,7 +48,8 @@ #include "display/sp-canvas.h" #include #include -// For handling un-continuous paths: + +// For handling non-contiguous paths: #include "message-stack.h" #include "inkscape.h" #include "desktop.h" @@ -58,320 +59,303 @@ using Inkscape::DocumentUndo; namespace Inkscape { namespace LivePathEffect { -LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) - : Effect(lpeobject), - // initialise your parameters here: - //testpointA(_("Test Point A"), _("Test A"), "ptA", &wr, this, - //Geom::Point(100,100)), - steps(_("Steps whith CTRL:"), - _("Change number of steps whith CTRL pressed"), "steps", &wr, this, - 2), - ignoreCusp(_("Ignore cusp nodes:"), _("Change ignoring cusp nodes"), - "ignoreCusp", &wr, this, true), - onlySelected(_("Change only selected nodes:"), - _("Change only selected nodes"), "onlySelected", &wr, this, - false), - weight(_("Change weight:"), _("Change weight of the effect"), "weight", - &wr, this, 0.3334) { - registerParameter(dynamic_cast(&weight)); - registerParameter(dynamic_cast(&steps)); - registerParameter(dynamic_cast(&ignoreCusp)); - registerParameter(dynamic_cast(&onlySelected)); - weight.param_set_range(0.0000, 1); - weight.param_set_increments(0.1, 0.1); - weight.param_set_digits(4); - steps.param_set_range(1, 10); - steps.param_set_increments(1, 1); - steps.param_set_digits(0); +LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2), + ignoreCusp(_("Ignore cusp nodes"), _("Change ignoring cusp nodes"), "ignoreCusp", &wr, this, true), + onlySelected(_("Change only selected nodes"), _("Change only selected nodes"), "onlySelected", &wr, this, false), + weight(_("Change weight:"), _("Change weight of the effect"), "weight", &wr, this, 0.3334) +{ + registerParameter(&weight); + registerParameter(&steps); + registerParameter(&ignoreCusp); + registerParameter(&onlySelected); + + weight.param_set_range(0.0000, 1); + weight.param_set_increments(0.1, 0.1); + weight.param_set_digits(4); + + steps.param_set_range(1, 10); + steps.param_set_increments(1, 1); + steps.param_set_digits(0); } LPEBSpline::~LPEBSpline() {} -void LPEBSpline::createAndApply(const char *name, SPDocument *doc, - SPItem *item) { - if (!SP_IS_SHAPE(item)) { - g_warning("LPE BSpline can only be applied to shapes (not groups)."); - } else { - // Path effect definition - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); - repr->setAttribute("effect", name); - - doc->getDefs()->getRepr() - ->addChild(repr, NULL); // adds to and assigns the 'id' attribute - const gchar *repr_id = repr->attribute("id"); - Inkscape::GC::release(repr); - - gchar *href = g_strdup_printf("#%s", repr_id); - SP_LPE_ITEM(item)->addPathEffect(href, true); - g_free(href); - } -} - -void LPEBSpline::doEffect(SPCurve *curve) { - if (curve->get_segment_count() < 1) - return; - // Make copy of old path as it is changed during processing - Geom::PathVector const original_pathv = curve->get_pathvector(); - curve->reset(); - - //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... - if (path_it->empty()) - continue; - //Itreadores - - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = - ++(path_it->begin()); // outgoing 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 - //dichos manejadores - SPCurve *nCurve = new SPCurve(); - Geom::Point previousNode(0, 0); - Geom::Point node(0, 0); - Geom::Point pointAt1(0, 0); - Geom::Point pointAt2(0, 0); - Geom::Point nextPointAt1(0, 0); - Geom::Point nextPointAt2(0, 0); - Geom::Point nextPointAt3(0, 0); - Geom::D2 SBasisIn; - Geom::D2 SBasisOut; - Geom::D2 SBasisHelper; - Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - const Geom::Curve &closingline = - path_it->back_closed(); // the closing line segment is always of type - // Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for - // *exact* zero length, which goes wrong for relative coordinates and - // rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } - //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 - nCurve->moveto(curve_it1->initialPoint()); - //Recorremos todos los segmentos menos el último - while (curve_it2 != curve_endit) { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path - //recto de entrada y de salida - SPCurve *in = new SPCurve(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - SBasisIn = in->first_segment()->toSBasis(); - pointAt1 = SBasisIn.valueAt( - Geom::nearest_point((*cubic)[1], *in->first_segment())); - pointAt2 = SBasisIn.valueAt( - Geom::nearest_point((*cubic)[2], *in->first_segment())); - } else { - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - } - in->reset(); - delete in; - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); - SPCurve *out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - cubic = dynamic_cast(&*curve_it2); - if (cubic) { - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt1 = SBasisOut.valueAt( - Geom::nearest_point((*cubic)[1], *out->first_segment())); - nextPointAt2 = SBasisOut.valueAt( - Geom::nearest_point((*cubic)[2], *out->first_segment())); - ; - nextPointAt3 = out->first_segment()->finalPoint(); - } else { - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - } - out->reset(); - delete out; - //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 - SPCurve *lineHelper = new SPCurve(); - lineHelper->moveto(pointAt2); - lineHelper->lineto(nextPointAt1); - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - delete lineHelper; - //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); - nCurve->curveto(pointAt1, pointAt2, node); - //aumentamos los valores para el siguiente paso en el bucle - ++curve_it1; - ++curve_it2; - } - SPCurve *out = new SPCurve(); - out->moveto(curve_it1->initialPoint()); - out->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment())); - nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2], *out->first_segment())); - nextPointAt3 = out->first_segment()->finalPoint(); +void LPEBSpline::createAndApply(const char *name, SPDocument *doc, SPItem *item) +{ + if (!SP_IS_SHAPE(item)) { + g_warning("LPE BSpline can only be applied to shapes (not groups)."); } else { - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - } - out->reset(); - delete out; - //Si está cerrada la curva, la cerramos sobre el valor guardado - //previamente - //Si no finalizamos en el punto final - Geom::Point startNode = path_it->begin()->initialPoint(); - if (path_it->closed()) { - SPCurve *start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - Geom::D2 SBasisStart = start->first_segment()->toSBasis(); - SPCurve *lineHelper = new SPCurve(); - cubic = dynamic_cast(&*path_it->begin()); - if (cubic) { - lineHelper->moveto(SBasisStart.valueAt( - Geom::nearest_point((*cubic)[1], *start->first_segment()))); - } else { - lineHelper->moveto(start->first_segment()->initialPoint()); - } - start->reset(); - delete start; - - SPCurve *end = new SPCurve(); - end->moveto(curve_it1->initialPoint()); - end->lineto(curve_it1->finalPoint()); - Geom::D2 SBasisEnd = end->first_segment()->toSBasis(); - //Geom::BezierCurve const *bezier = dynamic_cast(&*curve_endit); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - lineHelper->lineto(SBasisEnd.valueAt( - Geom::nearest_point((*cubic)[2], *end->first_segment()))); - } else { - lineHelper->lineto(end->first_segment()->finalPoint()); - } - end->reset(); - delete end; - SBasisHelper = lineHelper->first_segment()->toSBasis(); - lineHelper->reset(); - delete lineHelper; - startNode = SBasisHelper.valueAt(0.5); - nCurve->curveto(nextPointAt1, nextPointAt2, startNode); - nCurve->move_endpoints(startNode, startNode); - } else { - SPCurve *start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - startNode = start->first_segment()->initialPoint(); - start->reset(); - delete start; - nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->move_endpoints(startNode, nextPointAt3); - } - //y cerramos la curva - if (path_it->closed()) { - nCurve->closepath_current(); + // Path effect definition + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect"); + repr->setAttribute("effect", name); + + doc->getDefs()->getRepr()->addChild(repr, NULL); // adds to and assigns the 'id' attribute + const gchar *repr_id = repr->attribute("id"); + Inkscape::GC::release(repr); + + gchar *href = g_strdup_printf("#%s", repr_id); + SP_LPE_ITEM(item)->addPathEffect(href, true); + g_free(href); } - curve->append(nCurve, false); - nCurve->reset(); - delete nCurve; - } } -Gtk::Widget *LPEBSpline::newWidget() { - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - if (param->param_key == "weight"){ - Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); - Gtk::Button *defaultWeight = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); - defaultWeight->signal_clicked() - .connect(sigc::bind(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight), widg)); - buttons->pack_start(*defaultWeight, true, true, 2); - Gtk::Button *makeCusp = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); - makeCusp->signal_clicked() - .connect(sigc::bind(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp), widg)); - buttons->pack_start(*makeCusp, true, true, 2); - vbox->pack_start(*buttons, true, true, 2); - } - if (param->param_key == "weight" || param->param_key == "steps") { - Inkscape::UI::Widget::Scalar *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widgRegistered->signal_value_changed() - .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); - widg = dynamic_cast(widgRegistered); - if (widg){ - Gtk::HBox * scalarParameter = dynamic_cast(widg); - std::vector< Gtk::Widget* > childList = scalarParameter->get_children(); - Gtk::Entry* entryWidg = dynamic_cast(childList[1]); - entryWidg->set_width_chars(6); +void LPEBSpline::doEffect(SPCurve *curve) +{ + if (curve->get_segment_count() < 1) + return; + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); + curve->reset(); + + //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... + if (path_it->empty()) + continue; + //Itreadores + + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = + ++(path_it->begin()); // outgoing 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 + //dichos manejadores + SPCurve *nCurve = new SPCurve(); + Geom::Point previousNode(0, 0); + Geom::Point node(0, 0); + Geom::Point pointAt1(0, 0); + Geom::Point pointAt2(0, 0); + Geom::Point nextPointAt1(0, 0); + Geom::Point nextPointAt2(0, 0); + Geom::Point nextPointAt3(0, 0); + Geom::D2 SBasisIn; + Geom::D2 SBasisOut; + Geom::D2 SBasisHelper; + Geom::CubicBezier const *cubic = NULL; + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + //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 + nCurve->moveto(curve_it1->initialPoint()); + //Recorremos todos los segmentos menos el último + while (curve_it2 != curve_endit) { + //previousPointAt3 = pointAt3; + //Calculamos los puntos que dividirían en tres segmentos iguales el path + //recto de entrada y de salida + SPCurve *in = new SPCurve(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + SBasisIn = in->first_segment()->toSBasis(); + pointAt1 = SBasisIn.valueAt( + Geom::nearest_point((*cubic)[1], *in->first_segment())); + pointAt2 = SBasisIn.valueAt( + Geom::nearest_point((*cubic)[2], *in->first_segment())); + } else { + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } + in->reset(); + delete in; + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + SPCurve *out = new SPCurve(); + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + cubic = dynamic_cast(&*curve_it2); + if (cubic) { + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt( + Geom::nearest_point((*cubic)[1], *out->first_segment())); + nextPointAt2 = SBasisOut.valueAt( + Geom::nearest_point((*cubic)[2], *out->first_segment())); + ; + nextPointAt3 = out->first_segment()->finalPoint(); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + } + out->reset(); + delete out; + //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 + SPCurve *lineHelper = new SPCurve(); + lineHelper->moveto(pointAt2); + lineHelper->lineto(nextPointAt1); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + delete lineHelper; + //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); + nCurve->curveto(pointAt1, pointAt2, node); + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + } + SPCurve *out = new SPCurve(); + out->moveto(curve_it1->initialPoint()); + out->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment())); + nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2], *out->first_segment())); + nextPointAt3 = out->first_segment()->finalPoint(); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); } - } - if (param->param_key == "onlySelected") { - Gtk::CheckButton *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widgRegistered); - } - if (param->param_key == "ignoreCusp") { - Gtk::CheckButton *widgRegistered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widgRegistered); - } - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); + out->reset(); + delete out; + //Si está cerrada la curva, la cerramos sobre el valor guardado + //previamente + //Si no finalizamos en el punto final + Geom::Point startNode = path_it->begin()->initialPoint(); + if (path_it->closed()) { + SPCurve *start = new SPCurve(); + start->moveto(path_it->begin()->initialPoint()); + start->lineto(path_it->begin()->finalPoint()); + Geom::D2 SBasisStart = start->first_segment()->toSBasis(); + SPCurve *lineHelper = new SPCurve(); + cubic = dynamic_cast(&*path_it->begin()); + if (cubic) { + lineHelper->moveto(SBasisStart.valueAt( + Geom::nearest_point((*cubic)[1], *start->first_segment()))); + } else { + lineHelper->moveto(start->first_segment()->initialPoint()); + } + start->reset(); + delete start; + + SPCurve *end = new SPCurve(); + end->moveto(curve_it1->initialPoint()); + end->lineto(curve_it1->finalPoint()); + Geom::D2 SBasisEnd = end->first_segment()->toSBasis(); + + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + lineHelper->lineto(SBasisEnd.valueAt( + Geom::nearest_point((*cubic)[2], *end->first_segment()))); + } else { + lineHelper->lineto(end->first_segment()->finalPoint()); + } + end->reset(); + delete end; + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + delete lineHelper; + startNode = SBasisHelper.valueAt(0.5); + nCurve->curveto(nextPointAt1, nextPointAt2, startNode); + nCurve->move_endpoints(startNode, startNode); } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); + SPCurve *start = new SPCurve(); + start->moveto(path_it->begin()->initialPoint()); + start->lineto(path_it->begin()->finalPoint()); + startNode = start->first_segment()->initialPoint(); + start->reset(); + delete start; + nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + nCurve->move_endpoints(startNode, nextPointAt3); } - } + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); + } + curve->append(nCurve, false); + nCurve->reset(); + delete nCurve; } +} + +Gtk::Widget *LPEBSpline::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = Gtk::manage(param->param_newWidget()); + if (param->param_key == "weight") { + Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true, 0)); + + Gtk::Button *defaultWeight = Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); + defaultWeight->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight), widg)); + buttons->pack_start(*defaultWeight, true, true, 2); + + Gtk::Button *makeCusp = Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); + makeCusp->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp), widg)); + buttons->pack_start(*makeCusp, true, true, 2); + + vbox->pack_start(*buttons, true, true, 2); + } + if (param->param_key == "weight" || param->param_key == "steps") { + Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast(widg)); + widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); + + if (widg) { + Gtk::HBox * scalarParameter = dynamic_cast(widg); + std::vector childList = scalarParameter->get_children(); + Gtk::Entry* entryWidg = dynamic_cast(childList[1]); + entryWidg->set_width_chars(6); + } + } - ++it; - } - return dynamic_cast(vbox); + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + return vbox; } -void LPEBSpline::toDefaultWeight(Gtk::Widget *widgWeight) { +void LPEBSpline::toDefaultWeight(Gtk::Widget *widgWeight) +{ weight.param_set_value(0.3334); changeWeight(0.3334); Gtk::HBox * scalarParameter = dynamic_cast(widgWeight); @@ -380,7 +364,8 @@ void LPEBSpline::toDefaultWeight(Gtk::Widget *widgWeight) { entryWidg->set_text("0.3334"); } -void LPEBSpline::toMakeCusp(Gtk::Widget *widgWeight) { +void LPEBSpline::toMakeCusp(Gtk::Widget *widgWeight) +{ weight.param_set_value(0.0000); changeWeight(0.0000); Gtk::HBox * scalarParameter = dynamic_cast(widgWeight); @@ -389,348 +374,353 @@ void LPEBSpline::toMakeCusp(Gtk::Widget *widgWeight) { entryWidg->set_text("0.0000"); } -void LPEBSpline::toWeight() { changeWeight(weight); } - -void LPEBSpline::changeWeight(double weightValue) { - SPDesktop *desktop = inkscape_active_desktop(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList *items = (GSList *)selection->itemList(); - SPItem *item = (SPItem *)g_slist_nth(items, 0)->data; - SPPath *path = SP_PATH(item); - SPCurve *curve = path->get_curve_for_edit(); - LPEBSpline::doBSplineFromWidget(curve, weightValue); - gchar *str = sp_svg_write_path(curve->get_pathvector()); - path->getRepr()->setAttribute("inkscape:original-d", str); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); - nt->desktop->updateNow(); - } - g_free(str); - curve->unref(); - desktop->clearWaitingCursor(); - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, - _("Modified the weight of the BSpline")); +void LPEBSpline::toWeight() +{ + changeWeight(weight); } -bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint) { - using Geom::X; - using Geom::Y; - - if (points.size() > 0) { - for (std::vector::iterator i = points.begin(); - i != points.end(); ++i) { - Geom::Point p = *i; - if (Geom::are_near(p, nodePoint, 0.0001)) { - return true; - } else { - } +void LPEBSpline::changeWeight(double weightValue) +{ + SPDesktop *desktop = inkscape_active_desktop(); + Inkscape::Selection *selection = sp_desktop_selection(desktop); + GSList *items = (GSList *)selection->itemList(); + SPItem *item = (SPItem *)g_slist_nth(items, 0)->data; + SPPath *path = SP_PATH(item); + SPCurve *curve = path->get_curve_for_edit(); + LPEBSpline::doBSplineFromWidget(curve, weightValue); + gchar *str = sp_svg_write_path(curve->get_pathvector()); + path->getRepr()->setAttribute("inkscape:original-d", str); + if (INK_IS_NODE_TOOL(desktop->event_context)) { + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); + nt->desktop->updateNow(); } - } - return false; + g_free(str); + curve->unref(); + desktop->clearWaitingCursor(); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_LPE, _("Modified the weight of a BSpline")); } -void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) { - using Geom::X; - using Geom::Y; - SPDesktop *desktop = inkscape_active_desktop(); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = - nt->_selected_nodes->allPoints(); - points.clear(); - std::vector::iterator pbegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = - selection.begin(); - i != selection.end(); ++i) { - if ((*i)->selected()) { - Inkscape::UI::Node *n = dynamic_cast(*i); - pbegin = points.begin(); - points.insert(pbegin, desktop->doc2dt(n->position())); - } - } - } - //bool hasNodesSelected = LPEBspline::hasNodesSelected(); - if (curve->get_segment_count() < 1) - return; - // Make copy of old path as it is changed during processing - Geom::PathVector const original_pathv = curve->get_pathvector(); - curve->reset(); - - //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... - if (path_it->empty()) - continue; - //Itreadores - - Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve - Geom::Path::const_iterator curve_it2 = - ++(path_it->begin()); // outgoing 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 - //dichos manejadores - SPCurve *nCurve = new SPCurve(); - Geom::Point pointAt0(0, 0); - Geom::Point pointAt1(0, 0); - Geom::Point pointAt2(0, 0); - Geom::Point pointAt3(0, 0); - Geom::Point nextPointAt0(0, 0); - Geom::Point nextPointAt1(0, 0); - Geom::Point nextPointAt2(0, 0); - Geom::Point nextPointAt3(0, 0); - Geom::D2 SBasisIn; - Geom::D2 SBasisOut; - Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - const Geom::Curve &closingline = - path_it->back_closed(); // the closing line segment is always of type - // Geom::LineSegment. - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - // closingline.isDegenerate() did not work, because it only checks for - // *exact* zero length, which goes wrong for relative coordinates and - // rounding errors... - // the closing line segment has zero-length. So stop before that one! - curve_endit = path_it->end_open(); - } - } - //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 - nCurve->moveto(curve_it1->initialPoint()); - //Recorremos todos los segmentos menos el último - while (curve_it2 != curve_endit) { - //previousPointAt3 = pointAt3; - //Calculamos los puntos que dividirían en tres segmentos iguales el path - //recto de entrada y de salida - SPCurve *in = new SPCurve(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - pointAt0 = in->first_segment()->initialPoint(); - pointAt3 = in->first_segment()->finalPoint(); - SBasisIn = in->first_segment()->toSBasis(); - if (!onlySelected) { - if (cubic) { - if (!ignoreCusp || !Geom::are_near((*cubic)[1], pointAt0)) { - pointAt1 = SBasisIn.valueAt(weightValue); - if (weightValue != 0.0000) { - pointAt1 = - Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); - } - } else { - pointAt1 = in->first_segment()->initialPoint(); - } - if (!ignoreCusp || !Geom::are_near((*cubic)[2], pointAt3)) { - pointAt2 = SBasisIn.valueAt(1 - weightValue); - if (weightValue != 0.0000) { - pointAt2 = - Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); +bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint) +{ + using Geom::X; + using Geom::Y; + + if (points.size() > 0) { + for (std::vector::iterator i = points.begin(); + i != points.end(); ++i) { + Geom::Point p = *i; + if (Geom::are_near(p, nodePoint, 0.0001)) { + return true; + } else { } - } else { - pointAt2 = in->first_segment()->finalPoint(); - } - } else { - if (!ignoreCusp && weightValue != 0.0000) { - pointAt1 = SBasisIn.valueAt(weightValue); - if (weightValue != 0.0000) { - pointAt1 = - Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } + } + return false; +} + +void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue) +{ + using Geom::X; + using Geom::Y; + SPDesktop *desktop = inkscape_active_desktop(); + if (INK_IS_NODE_TOOL(desktop->event_context)) { + Inkscape::UI::Tools::NodeTool *nt = INK_NODE_TOOL(desktop->event_context); + Inkscape::UI::ControlPointSelection::Set &selection = + nt->_selected_nodes->allPoints(); + points.clear(); + std::vector::iterator pbegin; + for (Inkscape::UI::ControlPointSelection::Set::iterator i = + selection.begin(); + i != selection.end(); ++i) { + if ((*i)->selected()) { + Inkscape::UI::Node *n = dynamic_cast(*i); + pbegin = points.begin(); + points.insert(pbegin, desktop->doc2dt(n->position())); } - pointAt2 = SBasisIn.valueAt(1 - weightValue); - if (weightValue != 0.0000) { - pointAt2 = - Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } + } + //bool hasNodesSelected = LPEBspline::hasNodesSelected(); + if (curve->get_segment_count() < 1) + return; + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); + curve->reset(); + + //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... + if (path_it->empty()) + continue; + //Itreadores + + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = + ++(path_it->begin()); // outgoing 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 + //dichos manejadores + SPCurve *nCurve = new SPCurve(); + Geom::Point pointAt0(0, 0); + Geom::Point pointAt1(0, 0); + Geom::Point pointAt2(0, 0); + Geom::Point pointAt3(0, 0); + Geom::Point nextPointAt0(0, 0); + Geom::Point nextPointAt1(0, 0); + Geom::Point nextPointAt2(0, 0); + Geom::Point nextPointAt3(0, 0); + Geom::D2 SBasisIn; + Geom::D2 SBasisOut; + Geom::CubicBezier const *cubic = NULL; + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); } - } else { - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - } } - } else { - if (cubic) { - if (!ignoreCusp || !Geom::are_near((*cubic)[1], pointAt0)) { - if (nodeIsSelected(pointAt0)) { - pointAt1 = SBasisIn.valueAt(weightValue); - if (weightValue != 0.0000) { - pointAt1 = - Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); - } + //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 + nCurve->moveto(curve_it1->initialPoint()); + //Recorremos todos los segmentos menos el último + while (curve_it2 != curve_endit) { + //previousPointAt3 = pointAt3; + //Calculamos los puntos que dividirían en tres segmentos iguales el path + //recto de entrada y de salida + SPCurve *in = new SPCurve(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + cubic = dynamic_cast(&*curve_it1); + pointAt0 = in->first_segment()->initialPoint(); + pointAt3 = in->first_segment()->finalPoint(); + SBasisIn = in->first_segment()->toSBasis(); + if (!onlySelected) { + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], pointAt0)) { + pointAt1 = SBasisIn.valueAt(weightValue); + if (weightValue != 0.0000) { + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } + } else { + pointAt1 = in->first_segment()->initialPoint(); + } + if (!ignoreCusp || !Geom::are_near((*cubic)[2], pointAt3)) { + pointAt2 = SBasisIn.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } + } else { + pointAt2 = in->first_segment()->finalPoint(); + } + } else { + if (!ignoreCusp && weightValue != 0.0000) { + pointAt1 = SBasisIn.valueAt(weightValue); + if (weightValue != 0.0000) { + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } + pointAt2 = SBasisIn.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } + } else { + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } + } } else { - pointAt1 = (*cubic)[1]; + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], pointAt0)) { + if (nodeIsSelected(pointAt0)) { + pointAt1 = SBasisIn.valueAt(weightValue); + if (weightValue != 0.0000) { + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } + } else { + pointAt1 = (*cubic)[1]; + } + } else { + pointAt1 = in->first_segment()->initialPoint(); + } + if (!ignoreCusp || !Geom::are_near((*cubic)[2], pointAt3)) { + if (nodeIsSelected(pointAt3)) { + pointAt2 = SBasisIn.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } + } else { + pointAt2 = (*cubic)[2]; + } + } else { + pointAt2 = in->first_segment()->finalPoint(); + } + } else { + if (!ignoreCusp && weightValue != 0.000) { + if (nodeIsSelected(pointAt0)) { + pointAt1 = SBasisIn.valueAt(weightValue); + pointAt1 = + Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + } else { + pointAt1 = in->first_segment()->initialPoint(); + } + if (nodeIsSelected(pointAt3)) { + pointAt2 = SBasisIn.valueAt(weightValue); + pointAt2 = + Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); + } else { + pointAt2 = in->first_segment()->finalPoint(); + } + } else { + pointAt1 = in->first_segment()->initialPoint(); + pointAt2 = in->first_segment()->finalPoint(); + } + } } - } else { - pointAt1 = in->first_segment()->initialPoint(); - } - if (!ignoreCusp || !Geom::are_near((*cubic)[2], pointAt3)) { - if (nodeIsSelected(pointAt3)) { - pointAt2 = SBasisIn.valueAt(1 - weightValue); - if (weightValue != 0.0000) { - pointAt2 = - Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); - } + in->reset(); + delete in; + //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 + nCurve->curveto(pointAt1, pointAt2, pointAt3); + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + } + SPCurve *out = new SPCurve(); + out->moveto(curve_it1->initialPoint()); + out->lineto(curve_it1->finalPoint()); + SBasisOut = out->first_segment()->toSBasis(); + nextPointAt0 = out->first_segment()->initialPoint(); + nextPointAt3 = out->first_segment()->finalPoint(); + cubic = dynamic_cast(&*curve_it1); + if (!onlySelected) { + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + if (weightValue != 0.0000) { + nextPointAt1 = + Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); + } + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + } + if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) { + nextPointAt2 = SBasisOut.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + nextPointAt2 = + Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); + } + } else { + nextPointAt2 = out->first_segment()->finalPoint(); + } } else { - pointAt2 = (*cubic)[2]; + if (!ignoreCusp && weightValue != 0.0000) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = + Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); + nextPointAt2 = SBasisOut.valueAt(1 - weightValue); + nextPointAt2 = + Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + } } - } else { - pointAt2 = in->first_segment()->finalPoint(); - } } else { - if (!ignoreCusp && weightValue != 0.000) { - if (nodeIsSelected(pointAt0)) { - pointAt1 = SBasisIn.valueAt(weightValue); - pointAt1 = - Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001); + if (cubic) { + if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) { + if (nodeIsSelected(nextPointAt0)) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + if (weightValue != 0.0000) { + nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001, + nextPointAt1[Y] + 0.0001); + } + } else { + nextPointAt1 = (*cubic)[1]; + } + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + } + if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) { + if (nodeIsSelected(nextPointAt3)) { + nextPointAt2 = SBasisOut.valueAt(1 - weightValue); + if (weightValue != 0.0000) { + nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001, + nextPointAt2[Y] + 0.0001); + } + } else { + nextPointAt2 = (*cubic)[2]; + } + } else { + nextPointAt2 = out->first_segment()->finalPoint(); + } } else { - pointAt1 = in->first_segment()->initialPoint(); + if (!ignoreCusp && weightValue != 0.0000) { + if (nodeIsSelected(nextPointAt0)) { + nextPointAt1 = SBasisOut.valueAt(weightValue); + nextPointAt1 = + Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + } + if (nodeIsSelected(nextPointAt3)) { + nextPointAt2 = SBasisOut.valueAt(weightValue); + nextPointAt2 = + Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); + } else { + nextPointAt2 = out->first_segment()->finalPoint(); + } + } else { + nextPointAt1 = out->first_segment()->initialPoint(); + nextPointAt2 = out->first_segment()->finalPoint(); + } } - if (nodeIsSelected(pointAt3)) { - pointAt2 = SBasisIn.valueAt(weightValue); - pointAt2 = - Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001); - } else { - pointAt2 = in->first_segment()->finalPoint(); - } - } else { - pointAt1 = in->first_segment()->initialPoint(); - pointAt2 = in->first_segment()->finalPoint(); - } - } - } - in->reset(); - delete in; - //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 - nCurve->curveto(pointAt1, pointAt2, pointAt3); - //aumentamos los valores para el siguiente paso en el bucle - ++curve_it1; - ++curve_it2; - } - SPCurve *out = new SPCurve(); - out->moveto(curve_it1->initialPoint()); - out->lineto(curve_it1->finalPoint()); - SBasisOut = out->first_segment()->toSBasis(); - nextPointAt0 = out->first_segment()->initialPoint(); - nextPointAt3 = out->first_segment()->finalPoint(); - cubic = dynamic_cast(&*curve_it1); - if (!onlySelected) { - if (cubic) { - if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) { - nextPointAt1 = SBasisOut.valueAt(weightValue); - if (weightValue != 0.0000) { - nextPointAt1 = - Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); - } - } else { - nextPointAt1 = out->first_segment()->initialPoint(); - } - if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) { - nextPointAt2 = SBasisOut.valueAt(1 - weightValue); - if (weightValue != 0.0000) { - nextPointAt2 = - Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); - } - } else { - nextPointAt2 = out->first_segment()->finalPoint(); - } - } else { - if (!ignoreCusp && weightValue != 0.0000) { - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = - Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); - nextPointAt2 = SBasisOut.valueAt(1 - weightValue); - nextPointAt2 = - Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); - } else { - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); - } - } - } else { - if (cubic) { - if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) { - if (nodeIsSelected(nextPointAt0)) { - nextPointAt1 = SBasisOut.valueAt(weightValue); - if (weightValue != 0.0000) { - nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001, - nextPointAt1[Y] + 0.0001); - } - } else { - nextPointAt1 = (*cubic)[1]; - } - } else { - nextPointAt1 = out->first_segment()->initialPoint(); } - if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) { - if (nodeIsSelected(nextPointAt3)) { - nextPointAt2 = SBasisOut.valueAt(1 - weightValue); - if (weightValue != 0.0000) { - nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001, - nextPointAt2[Y] + 0.0001); - } - } else { - nextPointAt2 = (*cubic)[2]; - } + out->reset(); + delete out; + //Aberiguamos la ultima parte de la curva correspondiente al último + //segmento + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + if (path_it->closed()) { + nCurve->curveto(nextPointAt1, nextPointAt2, + path_it->begin()->initialPoint()); + nCurve->move_endpoints(path_it->begin()->initialPoint(), + path_it->begin()->initialPoint()); } else { - nextPointAt2 = out->first_segment()->finalPoint(); + nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + nCurve->move_endpoints(path_it->begin()->initialPoint(), nextPointAt3); } - } else { - if (!ignoreCusp && weightValue != 0.0000) { - if (nodeIsSelected(nextPointAt0)) { - nextPointAt1 = SBasisOut.valueAt(weightValue); - nextPointAt1 = - Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001); - } else { - nextPointAt1 = out->first_segment()->initialPoint(); - } - if (nodeIsSelected(nextPointAt3)) { - nextPointAt2 = SBasisOut.valueAt(weightValue); - nextPointAt2 = - Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001); - } else { - nextPointAt2 = out->first_segment()->finalPoint(); - } - } else { - nextPointAt1 = out->first_segment()->initialPoint(); - nextPointAt2 = out->first_segment()->finalPoint(); + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); } - } - } - out->reset(); - delete out; - //Aberiguamos la ultima parte de la curva correspondiente al último - //segmento - //Y hacemos lo propio con el path de salida - //nextPointAt0 = curveOut.valueAt(0); - if (path_it->closed()) { - nCurve->curveto(nextPointAt1, nextPointAt2, - path_it->begin()->initialPoint()); - nCurve->move_endpoints(path_it->begin()->initialPoint(), - path_it->begin()->initialPoint()); - } else { - nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3); - nCurve->move_endpoints(path_it->begin()->initialPoint(), nextPointAt3); - } - //y cerramos la curva - if (path_it->closed()) { - nCurve->closepath_current(); + curve->append(nCurve, false); + nCurve->reset(); + delete nCurve; } - curve->append(nCurve, false); - nCurve->reset(); - delete nCurve; - } } }; //namespace LivePathEffect diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index aff4ce812..f37741a4a 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -15,44 +15,40 @@ namespace Inkscape { namespace LivePathEffect { class LPEBSpline : public Effect { - public: - LPEBSpline(LivePathEffectObject *lpeobject); - virtual ~LPEBSpline(); - - virtual void createAndApply(const char *name, SPDocument *doc, SPItem *item); - - virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; } - - virtual void doEffect(SPCurve *curve); - - virtual void doBSplineFromWidget(SPCurve *curve, double value); - - virtual bool nodeIsSelected(Geom::Point nodePoint); - - virtual Gtk::Widget *newWidget(); + LPEBSpline(LivePathEffectObject *lpeobject); + virtual ~LPEBSpline(); - virtual void changeWeight(double weightValue); + virtual void createAndApply(const char *name, SPDocument *doc, SPItem *item); + virtual LPEPathFlashType pathFlashType() const { + return SUPPRESS_FLASH; + } + virtual void doEffect(SPCurve *curve); - virtual void toDefaultWeight(Gtk::Widget *widgWeight); + void doBSplineFromWidget(SPCurve *curve, double value); + bool nodeIsSelected(Geom::Point nodePoint); - virtual void toMakeCusp(Gtk::Widget *widgWeight); + virtual Gtk::Widget *newWidget(); - virtual void toWeight(); + void changeWeight(double weightValue); + void toDefaultWeight(Gtk::Widget *widgWeight); + void toMakeCusp(Gtk::Widget *widgWeight); + void toWeight(); - ScalarParam steps; + // TODO make this private + ScalarParam steps; private: - std::vector points; - BoolParam ignoreCusp; - BoolParam onlySelected; - ScalarParam weight; + std::vector points; + BoolParam ignoreCusp; + BoolParam onlySelected; + ScalarParam weight; - LPEBSpline(const LPEBSpline &); - LPEBSpline &operator=(const LPEBSpline &); + LPEBSpline(const LPEBSpline &); + LPEBSpline &operator=(const LPEBSpline &); }; -}; //namespace LivePathEffect -}; //namespace Inkscape +} //namespace LivePathEffect +} //namespace Inkscape #endif diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index fc2173a67..a24f5e60e 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -434,9 +434,7 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) if (SP_IS_SHAPE(lpeItem)) { fillet_chamfer_values.set_helper_size(helper_size); fillet_chamfer_values.set_unit(unit.get_abbreviation()); - SPCurve *c = SP_IS_PATH(lpeItem) ? static_cast(lpeItem) - ->get_original_curve() - : SP_SHAPE(lpeItem)->getCurve(); + SPCurve *c = SP_IS_PATH(lpeItem) ? static_cast(lpeItem)->get_original_curve() : SP_SHAPE(lpeItem)->getCurve(); std::vector filletChamferData = fillet_chamfer_values.data(); if (!filletChamferData.empty() && getKnotsNumber(c) != (int) filletChamferData.size()) { diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index 03238f935..d447afa6f 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -29,6 +29,9 @@ ToggleButtonParam::ToggleButtonParam( const Glib::ustring& label, const Glib::us ToggleButtonParam::~ToggleButtonParam() { + if (_toggled_connection.connected()) { + _toggled_connection.disconnect(); + } } void @@ -54,6 +57,10 @@ ToggleButtonParam::param_getSVGValue() const Gtk::Widget * ToggleButtonParam::param_newWidget() { + if (_toggled_connection.connected()) { + _toggled_connection.disconnect(); + } + Inkscape::UI::Widget::RegisteredToggleButton * checkwdg = Gtk::manage( new Inkscape::UI::Widget::RegisteredToggleButton( param_label, param_tooltip, @@ -65,9 +72,12 @@ ToggleButtonParam::param_newWidget() checkwdg->setActive(value); checkwdg->setProgrammatically = false; - checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change togglebutton parameter")); + // TRANSLATORS: "toggle" is a verb here + checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Toggle path effect parameter")); + + _toggled_connection = checkwdg->signal_toggled().connect(sigc::mem_fun(*this, &ToggleButtonParam::toggled)); - return dynamic_cast (checkwdg); + return checkwdg; } void @@ -76,6 +86,11 @@ ToggleButtonParam::param_setValue(bool newvalue) value = newvalue; } +void +ToggleButtonParam::toggled() { + _signal_toggled.emit(); +} + } /* namespace LivePathEffect */ } /* namespace Inkscape */ diff --git a/src/live_effects/parameter/togglebutton.h b/src/live_effects/parameter/togglebutton.h index 9b1c71185..753af6dbd 100644 --- a/src/live_effects/parameter/togglebutton.h +++ b/src/live_effects/parameter/togglebutton.h @@ -2,14 +2,14 @@ #define INKSCAPE_LIVEPATHEFFECT_PARAMETER_TOGGLEBUTTON_H /* - * Inkscape::LivePathEffectParameters - * -* Copyright (C) Johan Engelen 2007 + * Copyright (C) Jabiertxo Arraiza Cenoz 2014 * * Released under GNU GPL, read the file 'COPYING' for more information */ #include +#include +#include #include "live_effects/parameter/parameter.h" @@ -17,7 +17,10 @@ namespace Inkscape { namespace LivePathEffect { - +/** + * class ToggleButtonParam: + * represents a Gtk::ToggleButton as a Live Path Effect parameter + */ class ToggleButtonParam : public Parameter { public: ToggleButtonParam( const Glib::ustring& label, @@ -39,6 +42,9 @@ public: bool get_value() const { return value; }; inline operator bool() const { return value; }; + + sigc::signal& signal_toggled() { return _signal_toggled; } + virtual void toggled(); private: ToggleButtonParam(const ToggleButtonParam&); @@ -46,6 +52,9 @@ private: bool value; bool defvalue; + + sigc::signal _signal_toggled; + sigc::connection _toggled_connection; }; -- cgit v1.2.3 From 94b74cf00f2d605cb8268d9fe05d0bad78077f1c Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Thu, 10 Jul 2014 15:13:09 -0400 Subject: refresh SPCurve in a cloned clip (Bug 1322940) Fixed bugs: - https://launchpad.net/bugs/1322940 (bzr r13448) --- src/sp-use.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/sp-use.cpp b/src/sp-use.cpp index e8fe3687f..7d908a66a 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -37,6 +37,7 @@ #include "sp-symbol.h" #include "sp-use.h" #include "sp-use-reference.h" +#include "sp-shape.h" namespace { SPObject* createUse() { @@ -176,6 +177,8 @@ Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XM g_free(uri_string); } + if (SP_IS_SHAPE(this->child)) + SP_SHAPE(this->child)->set_shape(); // evaluate SPCurve of child return repr; } -- cgit v1.2.3 From 977a312f0979f34215f3c0ba5332d85b257d271c Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 10 Jul 2014 21:22:59 +0200 Subject: Fix crash when ungrouping a group that has a filter applied to it Fixed bugs: - https://launchpad.net/bugs/1323849 (bzr r13449) --- src/style-internal.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index c686a1807..d0e65a19a 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -1440,7 +1440,7 @@ SPIFilter::cascade( const SPIBase* const parent ) { void SPIFilter::merge( const SPIBase* const parent ) { if( const SPIFilter* p = dynamic_cast(parent) ) { - // The "correct" thing to due is to combine the filter primitives. + // The "correct" thing to do is to combine the filter primitives. // The next best thing is to keep any filter on this object. If there // is no filter on this object, then use any filter on the parent. if( (!set || inherit) && p->href && p->href->getObject() ) { // is the getObject() needed? @@ -1453,9 +1453,11 @@ SPIFilter::merge( const SPIBase* const parent ) { } } else { // If we don't have an href, create it - if( &style->document ) { // FIXME + if( style->document ) { // FIXME href = new SPFilterReference(style->document); //href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style)); + } else if (style->object) { + href = new SPFilterReference(style->object); } } if( href ) { -- cgit v1.2.3 From ac8283706beb41435d25ea5d880fe44d68679803 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Fri, 11 Jul 2014 20:28:15 +0200 Subject: Fix regression introduced by rev 13446 / 13333 Fixed bugs: - https://launchpad.net/bugs/1256597 - https://launchpad.net/bugs/1340011 (bzr r13450) --- src/seltrans.cpp | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src') diff --git a/src/seltrans.cpp b/src/seltrans.cpp index d16e02e42..4b1a3a5fa 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -1321,16 +1321,6 @@ void Inkscape::SelTrans::stretch(SPSelTransHandle const &/*handle*/, Geom::Point void Inkscape::SelTrans::scale(Geom::Point &/*pt*/, guint /*state*/) { - // E.g. scaling a perfectly vertical line in horizontal direction will not work, and will produce an identity affine - // Applying a transformation is useless, so we will not attempt to do so because this might trigger other bugs - // (see https://bugs.launchpad.net/inkscape/+bug/1256597) - // We check for this here and not in transform because identity transformations are perfectly fine for for example - // translations (e.g. a translation of (0,0), which occurs when snapping a point back to its original location) - - if (_absolute_affine.isIdentity()) { - return; - } - transform(_absolute_affine, Geom::Point(0, 0)); // we have already accounted for origin, so pass 0,0 } -- cgit v1.2.3 From 3c71759c0b922e85dbbbffe92ca31cc000d4eced Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Fri, 11 Jul 2014 18:26:18 -0400 Subject: scale tiled clones to document units (Bug 1288860) Fixed bugs: - https://launchpad.net/bugs/1288860 (bzr r13451) --- src/ui/dialog/clonetiler.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index fb131d8da..e5f18216c 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -2242,6 +2242,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) clonetiler_remove (NULL, dlg, false); + double scale_units = Inkscape::Util::Quantity::convert(1, "px", sp_desktop_document(desktop)->getDefaultUnit()); + double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); double shiftx_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_j", 0, -10000, 10000); @@ -2311,8 +2313,8 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) int jmax = prefs->getInt(prefs_path + "jmax", 2); bool fillrect = prefs->getBool(prefs_path + "fillrect"); - double fillwidth = prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); - double fillheight = prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); + double fillwidth = scale_units*prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); + double fillheight = scale_units*prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); bool dotrace = prefs->getBool(prefs_path + "dotrace"); int pick = prefs->getInt(prefs_path + "pick"); @@ -2358,11 +2360,11 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX ); Geom::OptRect r = item->documentBounds(bbox_type); if (r) { - w = r->dimensions()[Geom::X]; - h = r->dimensions()[Geom::Y]; - x0 = r->min()[Geom::X]; - y0 = r->min()[Geom::Y]; - center = desktop->dt2doc(item->getCenter()); + w = scale_units*r->dimensions()[Geom::X]; + h = scale_units*r->dimensions()[Geom::Y]; + x0 = scale_units*r->min()[Geom::X]; + y0 = scale_units*r->min()[Geom::Y]; + center = scale_units*desktop->dt2doc(item->getCenter()); sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", center[Geom::X]); sp_repr_set_svg_double(obj_repr, "inkscape:tile-cy", center[Geom::Y]); @@ -2578,7 +2580,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) Geom::Point new_center; bool center_set = false; if (obj_repr->attribute("inkscape:transform-center-x") || obj_repr->attribute("inkscape:transform-center-y")) { - new_center = desktop->dt2doc(item->getCenter()) * t; + new_center = scale_units*desktop->dt2doc(item->getCenter()) * t; center_set = true; } -- cgit v1.2.3 From f50d13ff0fa4de4abf81251ec855ca0166db9050 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 12 Jul 2014 15:32:27 +0200 Subject: Fix moving of item center: 1) at paste and 2) at changing document units Fixed bugs: - https://launchpad.net/bugs/1247799 (bzr r13452) --- src/selection-chemistry.cpp | 7 +++++-- src/sp-item-group.cpp | 3 ++- src/sp-item.cpp | 5 +++++ src/sp-item.h | 1 + 4 files changed, 13 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 868a9d743..f058189d3 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1621,10 +1621,13 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->doWriteTransform(item->getRepr(), item->transform, NULL, compensate); } - // if we're moving the actual object, not just updating the repr, we can transform the + // if we're transforming the actual object, not just updating the repr, we can transform the // center by the same matrix (only necessary for non-translations) if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { - item->setCenter(old_center * affine); + // If there's a viewbox, we might have an affine with a translation component; + // we will only apply the scaling/skewing components, not the translations + // because otherwise the center will move relative to the item + item->setCenter(old_center * affine.withoutTranslation()); item->updateRepr(); } } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 2cfe97db8..7af4e3320 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -664,7 +664,8 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p) Geom::Point old_center(0,0); if (item->isCenterSet()) { - old_center = item->getCenter(); + item->scaleCenter(sc.inverse()); // Convert the old relative center position to the new coordinates already now + old_center = item->getCenter(); // because getCenter() will use the bbox midpoint, which is also already in the new coordinates } gchar const *conn_type = NULL; diff --git a/src/sp-item.cpp b/src/sp-item.cpp index b10aae1c6..0cdff6546 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -271,6 +271,11 @@ Geom::Point SPItem::getCenter() const { } } +void +SPItem::scaleCenter(Geom::Scale const &sc) { + transform_center_x *= sc[Geom::X]; + transform_center_y *= sc[Geom::Y]; +} namespace { diff --git a/src/sp-item.h b/src/sp-item.h index d605c99b9..ce93b1d40 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -159,6 +159,7 @@ public: void unsetCenter(); bool isCenterSet() const; Geom::Point getCenter() const; + void scaleCenter(Geom::Scale const &sc); bool isVisibleAndUnlocked() const; -- cgit v1.2.3 From 6d5bd2bf07165531a10d9925e8800fe5c9cd9be3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 14 Jul 2014 00:59:33 +0200 Subject: Update togglebutton parameter to handle if you want: Active text, Active icon, Inactive text, Inactive Icon (bzr r13341.1.88) --- src/live_effects/lpe-simplify.cpp | 16 +++--- src/live_effects/parameter/togglebutton.cpp | 77 ++++++++++++++++++++++++++--- src/live_effects/parameter/togglebutton.h | 16 +++++- src/ui/widget/registered-widget.cpp | 2 +- 4 files changed, 95 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index d010e75a2..104cbde98 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -19,7 +19,7 @@ #include <2geom/d2.h> #include <2geom/generic-rect.h> #include <2geom/interval.h> - +#include "ui/icon-names.h" namespace Inkscape { namespace LivePathEffect { @@ -29,10 +29,14 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 2.), - nodes(_("Helper nodes"), _("Show helper nodes"), "nodes", &wr, this, false), - handles(_("Helper handles"), _("Show helper handles"), "handles", &wr, this, false), - simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false), - simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false) + nodes(_("Helper nodes"), _("Show helper nodes"), "nodes", &wr, this, false, + "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")), + handles(_("Helper handles"), _("Show helper handles"), "handles", &wr, this, false, + "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")), + simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false, + "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")), + simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false, + "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")) { registerParameter(dynamic_cast(&steps)); registerParameter(dynamic_cast(&threshold)); @@ -41,7 +45,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) registerParameter(dynamic_cast(&handles)); registerParameter(dynamic_cast(&simplifyindividualpaths)); registerParameter(dynamic_cast(&simplifyJustCoalesce)); - threshold.param_set_range(0., Geom::infinity()); + threshold.param_set_range(0.0001, Geom::infinity()); threshold.param_set_increments(0.0001, 0.0001); threshold.param_set_digits(6); steps.param_set_range(0, 100); diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index d447afa6f..d92b9836f 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -5,6 +5,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include +#include +#include +#include + #include "ui/widget/registered-widget.h" #include "live_effects/parameter/togglebutton.h" #include "live_effects/effect.h" @@ -14,7 +19,6 @@ #include "inkscape.h" #include "verbs.h" #include "helper-fns.h" -#include namespace Inkscape { @@ -22,9 +26,13 @@ namespace LivePathEffect { ToggleButtonParam::ToggleButtonParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, bool default_value ) - : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value) + Effect* effect, bool default_value, const Glib::ustring& inactive_label, + char const * icon_active, char const * icon_inactive, + Inkscape::IconSize icon_size) + : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value), + inactiveLabel(inactive_label), iconActive(icon_active), iconInactive(icon_inactive), iconSize(icon_size) { + checkwdg = NULL; } ToggleButtonParam::~ToggleButtonParam() @@ -61,7 +69,7 @@ ToggleButtonParam::param_newWidget() _toggled_connection.disconnect(); } - Inkscape::UI::Widget::RegisteredToggleButton * checkwdg = Gtk::manage( + checkwdg = Gtk::manage( new Inkscape::UI::Widget::RegisteredToggleButton( param_label, param_tooltip, param_key, @@ -69,21 +77,76 @@ ToggleButtonParam::param_newWidget() false, param_effect->getRepr(), param_effect->getSPDoc()) ); - + GtkWidget * boxButton = gtk_hbox_new (false, 0); + GtkWidget * labelButton = gtk_label_new (""); + if (!param_label.empty()) { + if(value || inactiveLabel.empty()){ + gtk_label_set_text(GTK_LABEL(labelButton), param_label.c_str()); + }else{ + gtk_label_set_text(GTK_LABEL(labelButton), inactiveLabel.c_str()); + } + } + gtk_widget_show(labelButton); + if ( iconActive ) { + if(!iconInactive){ + iconInactive = iconActive; + } + gtk_widget_show(boxButton); + GtkWidget *iconButton = sp_icon_new(iconSize, iconActive); + if(!value){ + iconButton = sp_icon_new(iconSize, iconInactive); + } + gtk_widget_show(iconButton); + gtk_box_pack_start (GTK_BOX(boxButton), iconButton, true, true, 2); + if (!param_label.empty()) { + gtk_box_pack_start (GTK_BOX(boxButton), labelButton, true, true, 2); + } + }else{ + gtk_box_pack_start (GTK_BOX(boxButton), labelButton, true, true, 2); + } + checkwdg->add(*Gtk::manage(Glib::wrap(boxButton))); checkwdg->setActive(value); checkwdg->setProgrammatically = false; - // TRANSLATORS: "toggle" is a verb here - checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Toggle path effect parameter")); + checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change togglebutton parameter")); _toggled_connection = checkwdg->signal_toggled().connect(sigc::mem_fun(*this, &ToggleButtonParam::toggled)); return checkwdg; } +void +ToggleButtonParam::refresh_button() +{ + if(!checkwdg){ + return; + } + Gtk::Widget * boxButton = checkwdg->get_child(); + if(!boxButton){ + return; + } + GList * childs = gtk_container_get_children(GTK_CONTAINER(boxButton->gobj())); + guint totalWidgets = g_list_length (childs); + if (!param_label.empty()) { + if(value || inactiveLabel.empty()){ + gtk_label_set_text(GTK_LABEL(g_list_nth_data(childs, totalWidgets-1)), param_label.c_str()); + }else{ + gtk_label_set_text(GTK_LABEL(g_list_nth_data(childs, totalWidgets-1)), inactiveLabel.c_str()); + } + } + if ( iconActive ) { + GdkPixbuf * iconPixbuf = sp_pixbuf_new( iconSize, iconActive ); + if(!value){ + iconPixbuf = sp_pixbuf_new( iconSize, iconInactive); + } + gtk_image_set_from_pixbuf (GTK_IMAGE(g_list_nth_data(childs, 0)), iconPixbuf); + } +} + void ToggleButtonParam::param_setValue(bool newvalue) { value = newvalue; + refresh_button(); } void diff --git a/src/live_effects/parameter/togglebutton.h b/src/live_effects/parameter/togglebutton.h index 753af6dbd..4e545bcfd 100644 --- a/src/live_effects/parameter/togglebutton.h +++ b/src/live_effects/parameter/togglebutton.h @@ -12,6 +12,8 @@ #include #include "live_effects/parameter/parameter.h" +#include "icon-size.h" +#include "ui/widget/registered-widget.h" namespace Inkscape { @@ -28,7 +30,11 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - bool default_value = false); + bool default_value = false, + const Glib::ustring& inactive_label = "", + char const * icon_active = NULL, + char const * icon_inactive = NULL, + Inkscape::IconSize icon_size = Inkscape::ICON_SIZE_SMALL_TOOLBAR); virtual ~ToggleButtonParam(); virtual Gtk::Widget * param_newWidget(); @@ -50,9 +56,15 @@ private: ToggleButtonParam(const ToggleButtonParam&); ToggleButtonParam& operator=(const ToggleButtonParam&); + void refresh_button(); bool value; bool defvalue; - + const Glib::ustring inactiveLabel; + const char * iconActive; + const char * iconInactive; + Inkscape::IconSize iconSize; + Inkscape::UI::Widget::RegisteredToggleButton * checkwdg; + sigc::signal _signal_toggled; sigc::connection _toggled_connection; }; diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 83da1a6d6..8a81b1c02 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -109,7 +109,7 @@ RegisteredToggleButton::~RegisteredToggleButton() } RegisteredToggleButton::RegisteredToggleButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str) - : RegisteredWidget(label) + : RegisteredWidget() , _active_str(active_str) , _inactive_str(inactive_str) { -- cgit v1.2.3 From 70fbc57aa2ae064f92fbc4e6c8950b5c90e4ccac Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Tue, 15 Jul 2014 16:07:09 -0700 Subject: Warnings cleaup. (bzr r13454) --- src/2geom/path.cpp | 2 +- src/display/drawing-text.cpp | 23 ++++++++++++----------- src/extension/internal/emf-print.cpp | 4 ++-- src/extension/internal/wmf-inout.cpp | 1 - src/style-internal.cpp | 10 ++++------ 5 files changed, 19 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/2geom/path.cpp b/src/2geom/path.cpp index fc4d72028..3558af3b3 100644 --- a/src/2geom/path.cpp +++ b/src/2geom/path.cpp @@ -110,7 +110,7 @@ Path &Path::operator*=(Translate const &m) { Sequence::iterator it; Point prev; for (it = get_curves().begin() ; it != last ; ++it) { - //*(const_cast(&**it)) *= m; + // *(const_cast(&**it)) *= m; const_cast(it->get())->operator*=(m); if ( it != get_curves().begin() && (*it)->initialPoint() != prev ) { THROW_CONTINUITYERROR(); diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index 05a2c3c2a..9f3b447df 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -150,25 +150,26 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext return STATE_ALL; } -DrawingItem * -DrawingGlyphs::_pickItem(Geom::Point const &p, double delta, unsigned /*flags*/) +DrawingItem *DrawingGlyphs::_pickItem(Geom::Point const &p, double /*delta*/, unsigned /*flags*/) { DrawingText *ggroup = dynamic_cast(_parent); if (!ggroup) { throw InvalidItemException(); } + DrawingItem *result = NULL; bool invisible = (ggroup->_nrstyle.fill.type == NRStyle::PAINT_NONE) && (ggroup->_nrstyle.stroke.type == NRStyle::PAINT_NONE); - if (!_font || !_bbox || (!_drawing.outline() && invisible) ) { - return NULL; - } - // With text we take a simple approach: pick if the point is in a character bbox - Geom::Rect expanded(_pick_bbox); - // FIXME, why expand by delta? When is the next line needed? - // expanded.expandBy(delta); - if (expanded.contains(p)) return this; - return NULL; + if (_font && _bbox && (_drawing.outline() || !invisible) ) { + // With text we take a simple approach: pick if the point is in a character bbox + Geom::Rect expanded(_pick_bbox); + // FIXME, why expand by delta? When is the next line needed? + // expanded.expandBy(delta); + if (expanded.contains(p)) { + result = this; + } + } + return result; } diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 9c68e40a4..0bdfd45b9 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -977,8 +977,8 @@ unsigned int PrintEmf::fill( using Geom::X; using Geom::Y; - SPItem *item = SP_ITEM(style->object); - SPClipPath *scp = (item->clip_ref ? item->clip_ref->getObject() : NULL); + //SPItem *item = SP_ITEM(style->object); + //SPClipPath *scp = (item->clip_ref ? item->clip_ref->getObject() : NULL); Geom::Affine tf = m_tr_stack.top(); diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index 85060470b..2b05c6d2c 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -63,7 +63,6 @@ namespace Extension { namespace Internal { -static U_RECT16 rc_old; static bool clipset = false; static uint32_t BLTmode=0; diff --git a/src/style-internal.cpp b/src/style-internal.cpp index d0e65a19a..6a56d75c0 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -1390,9 +1390,8 @@ SPIFilter::read( gchar const *str ) { } } -const Glib::ustring -SPIFilter::write( guint const flags, SPIBase const *const base) const { - +const Glib::ustring SPIFilter::write( guint const flags, SPIBase const *const /*base*/) const +{ // TODO: fix base //SPILength const *const my_base = dynamic_cast(base); if ( (flags & SP_STYLE_FLAG_ALWAYS) || @@ -1923,9 +1922,8 @@ SPIFont::read( gchar const *str ) { } } -const Glib::ustring -SPIFont::write( guint const flags, SPIBase const *const base) const { - +const Glib::ustring SPIFont::write( guint const /*flags*/, SPIBase const *const /*base*/) const +{ // At the moment, do nothing. We could add a preference to write out // 'font' shorthand rather than longhand properties. -- cgit v1.2.3 From 50c1511c5721029101e0e69a48401adfba104f6f Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 18 Jul 2014 21:53:39 -0400 Subject: Fix build (bzr r13341.1.89) --- src/live_effects/lpe-simplify.cpp | 6 +++--- src/live_effects/parameter/togglebutton.cpp | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 104cbde98..17b97eda9 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -1,9 +1,9 @@ -#define INKSCAPE_LPE_SIMPLIFY_C /* * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include + +#include + #include "live_effects/lpe-simplify.h" #include "display/curve.h" #include "live_effects/parameter/parameter.h" diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index d92b9836f..ceb4f98ff 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -5,9 +5,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include -#include +#include #include #include "ui/widget/registered-widget.h" -- cgit v1.2.3 From 7e68da8d1bc6a91031fa4a05cc5f8ca032bd960d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 19 Jul 2014 18:06:37 -0400 Subject: Workarounds for crash bugs 1309050, 601336; will fix properly in experimental Fixed bugs: - https://launchpad.net/bugs/601336 - https://launchpad.net/bugs/1309050 (bzr r13455) --- src/knot.cpp | 5 ++++- src/shape-editor.cpp | 2 +- src/ui/tools/tool-base.cpp | 9 +++------ 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/knot.cpp b/src/knot.cpp index 61d0dff39..a3bb85b2b 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -162,6 +162,9 @@ SPKnot::~SPKnot() { g_free(this->tip); this->tip = NULL; } + + // cannot snap to destroyed knot + sp_event_context_discard_delayed_snap_event(this->desktop->event_context); } void SPKnot::startDragging(Geom::Point const &p, gint x, gint y, guint32 etime) { @@ -282,7 +285,7 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot knot->setFlag(SP_KNOT_DRAGGING, TRUE); } - sp_event_context_snap_delay_handler(knot->desktop->event_context, NULL, (gpointer) knot, (GdkEventMotion *)event, Inkscape::UI::Tools::DelayedSnapEvent::KNOT_HANDLER); + sp_event_context_snap_delay_handler(knot->desktop->event_context, NULL, knot, (GdkEventMotion *)event, Inkscape::UI::Tools::DelayedSnapEvent::KNOT_HANDLER); sp_knot_handler_request_position(event, knot); moved = TRUE; } diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp index bf53e8bc3..acb1abfb0 100644 --- a/src/shape-editor.cpp +++ b/src/shape-editor.cpp @@ -145,7 +145,7 @@ void ShapeEditor::shapeeditor_event_attr_changed(gchar const *name) if (changed_kh) { // this can happen if an LPEItem's knotholder handle was dragged, in which case we want // to keep the knotholder; in all other cases (e.g., if the LPE itself changes) we delete it - reset_item(SH_KNOTHOLDER, !strcmp(name, "d")); + reset_item(SH_KNOTHOLDER, !strcmp(name, "d") || !strcmp(name, "style")); } } } diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 4195c9eb2..f1d90f6c6 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -1289,8 +1289,7 @@ void sp_event_context_snap_delay_handler(ToolBase *ec, // now, just in case there's no future motion event that drops under the speed limit (when // stopping abruptly) delete ec->_delayed_snap_event; - ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, - event, origin); // watchdog is reset, i.e. pushed forward in time + ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, event, origin); // watchdog is reset, i.e. pushed forward in time // If the watchdog expires before a new motion event is received, we will snap (as explained // above). This means however that when the timer is too short, we will always snap and that the // speed threshold is ineffective. In the extreme case the delay is set to zero, and snapping will @@ -1301,15 +1300,13 @@ void sp_event_context_snap_delay_handler(ToolBase *ec, // snap, and set a new watchdog again. if (ec->_delayed_snap_event == NULL) { // no watchdog has been set // it might have already expired, so we'll set a new one; the snapping frequency will be limited this way - ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, - dse_item2, event, origin); + ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, event, origin); } // else: watchdog has been set before and we'll wait for it to expire } } else { // This is the first GDK_MOTION_NOTIFY event, so postpone snapping and set the watchdog g_assert(ec->_delayed_snap_event == NULL); - ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, - event, origin); + ec->_delayed_snap_event = new DelayedSnapEvent(ec, dse_item, dse_item2, event, origin); } prev_pos = event_pos; -- cgit v1.2.3 From 94d507366a97e2d5fbfb7d2b2c32f69830844a13 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 21 Jul 2014 17:05:54 +0200 Subject: Add icons on/off to use in simplify LPE toggle buttons (bzr r13341.1.90) --- src/live_effects/lpe-simplify.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 17b97eda9..1a02375cd 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -30,13 +30,13 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 2.), nodes(_("Helper nodes"), _("Show helper nodes"), "nodes", &wr, this, false, - "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")), + "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), handles(_("Helper handles"), _("Show helper handles"), "handles", &wr, this, false, - "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")), + "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), simplifyindividualpaths(_("Paths separately"), _("Simplifying paths (separately)"), "simplifyindividualpaths", &wr, this, false, - "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")), + "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), simplifyJustCoalesce(_("Just coalesce"), _("Simplify just coalesce"), "simplifyJustCoalesce", &wr, this, false, - "", INKSCAPE_ICON("system-run"), INKSCAPE_ICON("process-stop")) + "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")) { registerParameter(dynamic_cast(&steps)); registerParameter(dynamic_cast(&threshold)); -- cgit v1.2.3 From 7fa600b68ac57b425b86cff659e740f97888d05d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 21 Jul 2014 15:00:24 -0400 Subject: Revert fix for 1309050 since it causes other regressions... (bzr r13457) --- src/knot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/knot.cpp b/src/knot.cpp index a3bb85b2b..2f8f55a2e 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -163,8 +163,8 @@ SPKnot::~SPKnot() { this->tip = NULL; } - // cannot snap to destroyed knot - sp_event_context_discard_delayed_snap_event(this->desktop->event_context); + // FIXME: cannot snap to destroyed knot (lp:1309050) + //sp_event_context_discard_delayed_snap_event(this->desktop->event_context); } void SPKnot::startDragging(Geom::Point const &p, gint x, gint y, guint32 etime) { -- cgit v1.2.3 From 9b1d9867e9cfbf56b44e8a996a4ccf2e7f288b87 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 22 Jul 2014 02:29:52 +0200 Subject: fix bug pointed by LiamW in Spirolive (bzr r13341.1.94) --- src/ui/tools/pen-tool.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index aead3ebc0..56bcbef0d 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1611,7 +1611,6 @@ void PenTool::_bspline_spiro_motion(bool shift){ this->p[2] = this->p[3]; }else{ this->p[1] = (*cubic)[3] + ((*cubic)[3] - (*cubic)[2] ); - this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); } }else{ this->p[1] = this->p[0]; -- cgit v1.2.3 From db11af074f242faa77a1763efc54d26752fa6d93 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 22 Jul 2014 18:55:10 +0200 Subject: Fixed alignaments of toggle buttons (bzr r13341.1.95) --- src/live_effects/parameter/togglebutton.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index ceb4f98ff..5658d238f 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -95,12 +95,12 @@ ToggleButtonParam::param_newWidget() iconButton = sp_icon_new(iconSize, iconInactive); } gtk_widget_show(iconButton); - gtk_box_pack_start (GTK_BOX(boxButton), iconButton, true, true, 2); + gtk_box_pack_start (GTK_BOX(boxButton), iconButton, false, false, 1); if (!param_label.empty()) { - gtk_box_pack_start (GTK_BOX(boxButton), labelButton, true, true, 2); + gtk_box_pack_start (GTK_BOX(boxButton), labelButton, false, false, 1); } }else{ - gtk_box_pack_start (GTK_BOX(boxButton), labelButton, true, true, 2); + gtk_box_pack_start (GTK_BOX(boxButton), labelButton, false, false, 1); } checkwdg->add(*Gtk::manage(Glib::wrap(boxButton))); checkwdg->setActive(value); -- cgit v1.2.3 From 38acb1deed8b48ab28cc28ba0dfc577a5e205da9 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:15:15 +0200 Subject: Fixed some unused variables warnings. (bzr r13458) --- src/box3d.cpp | 19 ------------------- src/desktop-events.cpp | 1 - src/extension/internal/emf-print.h | 2 +- src/extension/internal/wmf-print.h | 2 +- src/ui/tools/spray-tool.cpp | 2 +- 5 files changed, 3 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/box3d.cpp b/src/box3d.cpp index 13a8d0e3e..eb82524dd 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -672,15 +672,6 @@ box3d_aux_set_z_orders (int z_orders[6], int a, int b, int c, int d, int e, int z_orders[5] = f; } -static inline void -box3d_swap_z_orders (int z_orders[6]) { - int tmp; - for (int i = 0; i < 3; ++i) { - tmp = z_orders[i]; - z_orders[i] = z_orders[5-i]; - z_orders[5-i] = tmp; - } -} /* * In standard perspective we have: @@ -695,11 +686,6 @@ box3d_swap_z_orders (int z_orders[6]) { /* All VPs infinite */ static void box3d_set_new_z_orders_case0 (SPBox3D *box, int z_orders[6], Box3D::Axis central_axis) { - Persp3D *persp = box3d_get_perspective(box); - Geom::Point xdir(persp3d_get_infinite_dir(persp, Proj::X)); - Geom::Point ydir(persp3d_get_infinite_dir(persp, Proj::Y)); - Geom::Point zdir(persp3d_get_infinite_dir(persp, Proj::Z)); - bool swapped = box3d_XY_axes_are_swapped(box); switch(central_axis) { @@ -811,12 +797,7 @@ box3d_set_new_z_orders_case1 (SPBox3D *box, int z_orders[6], Box3D::Axis central /* Precisely 2 finite VPs */ static void box3d_set_new_z_orders_case2 (SPBox3D *box, int z_orders[6], Box3D::Axis central_axis, Box3D::Axis /*infinite_axis*/) { - Persp3D *persp = box3d_get_perspective(box); - Geom::Point c3(box3d_get_corner_screen(box, 3, false)); - Geom::Point xdir(persp3d_get_PL_dir_from_pt(persp, c3, Proj::X)); - Geom::Point ydir(persp3d_get_PL_dir_from_pt(persp, c3, Proj::Y)); - Geom::Point zdir(persp3d_get_PL_dir_from_pt(persp, c3, Proj::Z)); bool swapped = box3d_XY_axes_are_swapped(box); diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index 0129a382d..4023ad071 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -491,7 +491,6 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) // set move or rotate cursor Geom::Point const event_w(event->crossing.x, event->crossing.y); - Geom::Point const event_dt(desktop->w2d(event_w)); if ((event->crossing.state & GDK_SHIFT_MASK) && (drag_type != SP_DRAG_MOVE_ORIGIN)) { GdkCursor *guide_cursor; diff --git a/src/extension/internal/emf-print.h b/src/extension/internal/emf-print.h index 1e4970a46..9a1251b38 100644 --- a/src/extension/internal/emf-print.h +++ b/src/extension/internal/emf-print.h @@ -29,7 +29,7 @@ namespace Internal { class PrintEmf : public PrintMetafile { - uint32_t hbrush, hbrushOld, hpen, hpenOld; + uint32_t hbrush, hbrushOld, hpen; unsigned int print_pathv (Geom::PathVector const &pathv, const Geom::Affine &transform); bool print_simple_shape (Geom::PathVector const &pathv, const Geom::Affine &transform); diff --git a/src/extension/internal/wmf-print.h b/src/extension/internal/wmf-print.h index 1e5d4c323..e4cf19184 100644 --- a/src/extension/internal/wmf-print.h +++ b/src/extension/internal/wmf-print.h @@ -28,7 +28,7 @@ namespace Internal { class PrintWmf : public PrintMetafile { - uint32_t hbrush, hpen, hpenOld, hbrush_null, hpen_null; + uint32_t hbrush, hpen, hbrush_null, hpen_null; uint32_t hmiterlimit; // used to minimize redundant records that set this unsigned int print_pathv (Geom::PathVector const &pathv, const Geom::Affine &transform); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 08d3119a1..29f1b9a73 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -677,7 +677,7 @@ bool SprayTool::root_handler(GdkEvent* event) { desktop->setToolboxAdjustmentValue("population", this->population * 100); Geom::Point const scroll_w(event->button.x, event->button.y); Geom::Point const scroll_dt = desktop->point();; - Geom::Point motion_doc(desktop->dt2doc(scroll_dt)); + switch (event->scroll.direction) { case GDK_SCROLL_DOWN: case GDK_SCROLL_UP: { -- cgit v1.2.3 From b178124078314b78baca08fb65e12cc894242d3a Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:16:13 +0200 Subject: Replaced some abs/fabs with std::abs. (bzr r13459) --- src/desktop-events.cpp | 4 ++-- src/extension/internal/emf-inout.cpp | 4 ++-- src/extension/internal/emf-print.cpp | 2 +- src/extension/internal/wmf-inout.cpp | 4 ++-- src/extension/internal/wmf-print.cpp | 2 +- src/ui/tools/pen-tool.cpp | 2 +- src/widgets/ruler.cpp | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp index 4023ad071..8be5e001b 100644 --- a/src/desktop-events.cpp +++ b/src/desktop-events.cpp @@ -365,7 +365,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) if (event->motion.state & GDK_CONTROL_MASK) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned const snaps = abs(prefs->getInt("/options/rotationsnapsperpi/value", 12)); - bool const relative_snaps = abs(prefs->getBool("/options/relativeguiderotationsnap/value", false)); + bool const relative_snaps = prefs->getBool("/options/relativeguiderotationsnap/value", false); if (snaps) { if (relative_snaps) { Geom::Angle orig_angle(guide->normal_to_line); @@ -442,7 +442,7 @@ gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) if (event->motion.state & GDK_CONTROL_MASK) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned const snaps = abs(prefs->getInt("/options/rotationsnapsperpi/value", 12)); - bool const relative_snaps = abs(prefs->getBool("/options/relativeguiderotationsnap/value", false)); + bool const relative_snaps = prefs->getBool("/options/relativeguiderotationsnap/value", false); if (snaps) { if (relative_snaps) { Geom::Angle orig_angle(guide->normal_to_line); diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 863d1e006..257994560 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -2524,8 +2524,8 @@ std::cout << "BEFORE DRAW" double cx = pix_to_x_point( d, (rclBox.left + rclBox.right)/2.0, (rclBox.bottom + rclBox.top)/2.0 ); double cy = pix_to_y_point( d, (rclBox.left + rclBox.right)/2.0, (rclBox.bottom + rclBox.top)/2.0 ); - double rx = pix_to_abs_size( d, fabs(rclBox.right - rclBox.left )/2.0 ); - double ry = pix_to_abs_size( d, fabs(rclBox.top - rclBox.bottom)/2.0 ); + double rx = pix_to_abs_size( d, std::abs(rclBox.right - rclBox.left )/2.0 ); + double ry = pix_to_abs_size( d, std::abs(rclBox.top - rclBox.bottom)/2.0 ); SVGOStringStream tmp_ellipse; tmp_ellipse << "cx=\"" << cx << "\" "; diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 0bdfd45b9..e054829b5 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -1882,7 +1882,7 @@ unsigned int PrintEmf::text(Inkscape::Extension::Print * /*mod*/, char const *te fix90n = 1; //assume vertical rot = (double)(((int) round(rot)) - irem); rotb = rot * M_PI / 1800.0; - if (abs(rot) == 900.0) { + if (std::abs(rot) == 900.0) { fix90n = 2; } } diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index 2b05c6d2c..beb6190d3 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -2053,8 +2053,8 @@ std::cout << "BEFORE DRAW" double cx = pix_to_x_point( d, (rc.left + rc.right)/2.0, (rc.bottom + rc.top)/2.0 ); double cy = pix_to_y_point( d, (rc.left + rc.right)/2.0, (rc.bottom + rc.top)/2.0 ); - double rx = pix_to_abs_size( d, fabs(rc.right - rc.left )/2.0 ); - double ry = pix_to_abs_size( d, fabs(rc.top - rc.bottom)/2.0 ); + double rx = pix_to_abs_size( d, std::abs(rc.right - rc.left )/2.0 ); + double ry = pix_to_abs_size( d, std::abs(rc.top - rc.bottom)/2.0 ); SVGOStringStream tmp_ellipse; tmp_ellipse << "cx=\"" << cx << "\" "; diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp index 55ad5da5f..e5ff34009 100644 --- a/src/extension/internal/wmf-print.cpp +++ b/src/extension/internal/wmf-print.cpp @@ -1396,7 +1396,7 @@ unsigned int PrintWmf::text(Inkscape::Extension::Print * /*mod*/, char const *te fix90n = 1; //assume vertical rot = (double)(((int) round(rot)) - irem); rotb = rot * M_PI / 1800.0; - if (abs(rot) == 900.0) { + if (std::abs(rot) == 900.0) { fix90n = 2; } } diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 70cbcaf0d..649c64034 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1185,7 +1185,7 @@ void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint sta // we are drawing horizontal/vertical lines and hit an anchor; Geom::Point const origin = this->p[0]; // if the previous point and the anchor are not aligned either horizontally or vertically... - if ((abs(p[Geom::X] - origin[Geom::X]) > 1e-9) && (abs(p[Geom::Y] - origin[Geom::Y]) > 1e-9)) { + if ((std::abs(p[Geom::X] - origin[Geom::X]) > 1e-9) && (std::abs(p[Geom::Y] - origin[Geom::Y]) > 1e-9)) { // ...then we should draw an L-shaped path, consisting of two paraxial segments Geom::Point intermed = p; this->_setToNearestHorizVert(intermed, status, false); diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp index 5d5151343..8e818843d 100644 --- a/src/widgets/ruler.cpp +++ b/src/widgets/ruler.cpp @@ -1394,7 +1394,7 @@ sp_ruler_draw_ticks (SPRuler *ruler) (label_spacing_px > 6*digit_height || tick_index%2 == 0 || cur == 0) && (label_spacing_px > 3*digit_height || tick_index%4 == 0 || cur == 0)) { - if (fabs((int)cur) >= 2000 && (((int) cur)/1000)*1000 == ((int) cur)) + if (std::abs((int)cur) >= 2000 && (((int) cur)/1000)*1000 == ((int) cur)) sprintf (unit_str, "%dk", ((int) cur)/1000); else sprintf (unit_str, "%d", (int) cur); -- cgit v1.2.3 From d7c36cd293ee35f53a5b47f2795b061888d4f79b Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:16:52 +0200 Subject: Fixed some logic errors; clang warnings. (bzr r13460) --- src/sp-item.cpp | 2 +- src/sp-lpe-item.cpp | 4 ---- src/style-internal.cpp | 8 ++++---- src/ui/dialog/template-widget.cpp | 2 +- src/ui/widget/style-swatch.cpp | 2 +- 5 files changed, 7 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 0cdff6546..698559a9f 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -1264,7 +1264,7 @@ void SPItem::adjust_paint_recursive (Geom::Affine advertized_transform, Geom::Af // Within text, we do not fork gradients, and so must not recurse to avoid double compensation; // also we do not recurse into clones, because a clone's child is the ghost of its original - // we must not touch it - if (!(this && (SP_IS_TEXT(this) || SP_IS_USE(this)))) { + if (!(SP_IS_TEXT(this) || SP_IS_USE(this))) { for (SPObject *o = children; o != NULL; o = o->next) { if (SP_IS_ITEM(o)) { // At the level of the transformed item, t_ancestors is identity; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 321d2fc42..800b31f87 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -212,10 +212,6 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape * returns true when LPE was successful. */ bool SPLPEItem::performPathEffect(SPCurve *curve) { - if (!this) { - return false; - } - if (!curve) { return false; } diff --git a/src/style-internal.cpp b/src/style-internal.cpp index 6a56d75c0..ae70fc10d 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -270,18 +270,18 @@ SPILength::read( gchar const *str ) { } else if (!strcmp(e, "em")) { /* EM square */ unit = SP_CSS_UNIT_EM; - if( style && &style->font_size ) { + if( style ) { computed = value * style->font_size.computed; } else { - computed = value * style->font_size.font_size_default; + computed = value * SPIFontSize::font_size_default; } } else if (!strcmp(e, "ex")) { /* ex square */ unit = SP_CSS_UNIT_EX; - if( style && &style->font_size ) { + if( style ) { computed = value * style->font_size.computed * 0.5; // FIXME } else { - computed = value * style->font_size.font_size_default * 0.5; + computed = value * SPIFontSize::font_size_default * 0.5; } } else if (!strcmp(e, "%")) { /* Percentage */ diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index ef91962d4..9758b35ac 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -120,7 +120,7 @@ void TemplateWidget::_displayTemplateDetails() if (_current_template.long_description != "") message += _("Description: ") + _current_template.long_description + "\n\n"; - if (~_current_template.keywords.empty()){ + if (!_current_template.keywords.empty()){ message += _("Keywords: "); for (std::set::iterator it = _current_template.keywords.begin(); it != _current_template.keywords.end(); ++it) message += *it + " "; diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index a33c1d09f..98f4e47cd 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -261,7 +261,7 @@ void StyleSwatch::setStyle(SPCSSAttr *css) Glib::ustring css_string; sp_repr_css_write_string (_css, css_string); SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT); - if (~css_string.empty()) { + if (!css_string.empty()) { sp_style_merge_from_style_string (temp_spstyle, css_string.c_str()); } -- cgit v1.2.3 From c04d2c017d8933ea7e0d71d8387ed33a417d4167 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 22 Jul 2014 21:17:23 +0200 Subject: Fixed parentheses. (bzr r13461) --- src/extension/internal/text_reassemble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c index 810e3f8cc..b0447442c 100644 --- a/src/extension/internal/text_reassemble.c +++ b/src/extension/internal/text_reassemble.c @@ -550,7 +550,7 @@ int TR_check_set_vadvance(TR_INFO *tri, int src, int lines){ See if the line to be added is compatible. All text fields in a complex have the same advance, so just set/check the first one. vadvance must be within 1% or do not add a new line */ - if(fabs(1.0 - (tpi->chunks[trec].vadvance/newV) > 0.01)){ + if(fabs(1.0 - (tpi->chunks[trec].vadvance/newV)) > 0.01){ status = 1; } else { /* recalculate the weighted vadvance */ -- cgit v1.2.3 From fe12278d612a0c52bcbff2736f18d4e590410b71 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 22 Jul 2014 22:35:50 -0400 Subject: Duplicate LPE entries (bzr r13090.1.91) --- src/live_effects/effect.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 179759ed6..777d500e9 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -147,11 +147,6 @@ const Util::EnumData LPETypeData[] = { {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, {ENVELOPE_PERSPECTIVE, N_("Envelope-Perspective"), "envelope-perspective"}, - {SIMPLIFY, N_("Simplify"), "simplify"}, - {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, - // TRANSLATORS: "Envelope Perspective" should be equivalent to "perspective transformation" - {ENVELOPE_PERSPECTIVE, N_("Envelope Perspective"), "envelope-perspective"}, - {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); -- cgit v1.2.3 From 76244246733cc1f1f3874aa498ad75977ebc6cd7 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 22 Jul 2014 22:39:21 -0400 Subject: This file does not need executable permissions (bzr r13090.1.93) --- src/live_effects/lpe-jointype.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 src/live_effects/lpe-jointype.h (limited to 'src') diff --git a/src/live_effects/lpe-jointype.h b/src/live_effects/lpe-jointype.h old mode 100755 new mode 100644 -- cgit v1.2.3 From 3a6ed95f3fa5921c78b24f9ae73df7d442827571 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 23 Jul 2014 16:16:43 -0400 Subject: Refactoring of linejoin code (bzr r13090.1.94) --- src/live_effects/pathoutlineprovider.cpp | 551 +++++++++++++++---------------- src/live_effects/pathoutlineprovider.h | 33 +- 2 files changed, 283 insertions(+), 301 deletions(-) (limited to 'src') diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index d6e0ce7ea..482f1f5e0 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -125,8 +125,7 @@ Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in return Geom::CubicBezier( temp ); } -static boost::optional intersection_point( Geom::Point const & origin_a, Geom::Point const & vector_a, - Geom::Point const & origin_b, Geom::Point const & vector_b) +static boost::optional intersection_point(Geom::Point const & origin_a, Geom::Point const & vector_a, Geom::Point const & origin_b, Geom::Point const & vector_b) { Geom::Coord denom = cross(vector_b, vector_a); if (!Geom::are_near(denom,0.)) { @@ -135,13 +134,16 @@ static boost::optional intersection_point( Geom::Point const & orig } return boost::none; } -} + +} // namespace Geom namespace Outline { typedef Geom::D2 D2SB; typedef Geom::Piecewise PWD2; +// UTILITY + unsigned bezierOrder (const Geom::Curve* curve_in) { using namespace Geom; @@ -151,25 +153,28 @@ unsigned bezierOrder (const Geom::Curve* curve_in) return 0; } -//returns true if the angle formed by the curves and their handles -//is >180 clockwise, otherwise false. +/** + * @return true if the angle formed by the curves and their handles is greater than 180 degrees clockwise, otherwise false. + */ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) { Geom::Point start_point; Geom::Point cross_point = cbc1.finalPoint(); Geom::Point end_point; - //assert(cbc1.finalPoint() == cbc2.initialPoint()); - //short circuiting? - if (cbc1.finalPoint() != cbc2.initialPoint()) { - printf("erk! Line %d, File %s\n", __LINE__, __FILE__); + if (cross_point != cbc2.initialPoint()) { + g_warning("Non-contiguous path in Outline::outside_angle()"); return false; } - //let's try: Geom::CubicBezier cubicBezier = Geom::sbasis_to_cubicbezier(cbc1.toSBasis()); start_point = cubicBezier [2]; - //stupid thing Inkscape does: + + /* + * Because the node editor does not yet support true quadratics, paths are converted to + * cubic beziers in the node tool with degenerate handles on one side. + */ + if (are_near(start_point, cross_point, 0.0000001)) { start_point = cubicBezier [1]; } @@ -178,9 +183,11 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) if (are_near(end_point, cross_point, 0.0000001)) { end_point = cubicBezier [2]; } - //got our three points, now let's see what their clockwise angle is - //Much credit to Wikipedia for the following ( http://en.wikipedia.org/wiki/Graham_scan ) + // got our three points, now let's see what their clockwise angle is + + // Definition of a Graham scan + /******************************************************************** # Three points are a counter-clockwise turn if ccw > 0, clockwise if # ccw < 0, and collinear if ccw = 0 because ccw is a determinant that @@ -191,27 +198,90 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) double ccw = ( (cross_point.x() - start_point.x()) * (end_point.y() - start_point.y()) ) - ( (cross_point.y() - start_point.y()) * (end_point.x() - start_point.x()) ); - if (ccw > 0) return true; - return false; + return ccw > 0; } -void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, - double miter_limit, double line_width, bool outside = false) -{ - bool lineProblem = (dynamic_cast *>(cbc1)) || (dynamic_cast *>(cbc2)); - if ( outside && !lineProblem ) { - Geom::Path pth; - pth.append(*cbc1); +// LINE JOINS - Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(pth.toPwSb()[0]), 0.); +typedef Geom::BezierCurveN<1u> BezierLine; - pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); +/** + * Removes the crossings on an interior join. + * @param path_builder Contains the incoming segment; result is appended to this + * @param outgoing The outgoing segment + */ +void joinInside(Geom::Path& path_builder, Geom::Curve const& outgoing) { + Geom::Curve const& incoming = path_builder.back(); + + // Using Geom::crossings to find intersections between two curves + Geom::Crossings cross = Geom::crossings(incoming, outgoing); + if (!cross.empty()) { + // Crossings found, create the join + Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(incoming.toSBasis()); + cubic = cubic.subdivide(cross[0].ta).first; + // erase the last segment, as we're going to overwrite it now + path_builder.erase_last(); + path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); + cubic = Geom::sbasis_to_cubicbezier(outgoing.toSBasis()); + cubic = cubic.subdivide(cross[0].tb).second; + path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); + } else { + // No crossings occurred, or Geom::crossings() failed; default to bevel + if (Geom::are_near(incoming.finalPoint(), outgoing.initialPoint())) { + path_builder.appendNew(outgoing.initialPoint()); + } else { + path_builder.setFinal(outgoing.initialPoint()); + } + } +} + +/** + * Try to create a miter join. Falls back to bevel if no miter can be created. + * @param path_builder Path to append curves to; back() is the incoming curve + * @param outgoing Outgoing curve. + * @param miter_limit When mitering, don't exceed this length + * @param line_width The thickness of the line. + */ +void miter_curves(Geom::Path& path_builder, Geom::Curve const& outgoing, double miter_limit, double line_width) { + using namespace Geom; + Curve const& incoming = path_builder.back(); + Point tang1 = unitTangentAt(Geom::reverse(incoming.toSBasis()), 0.); + Point tang2 = unitTangentAt(outgoing.toSBasis(), 0); + + boost::optional p = intersection_point (incoming.finalPoint(), tang1, outgoing.initialPoint(), tang2); + if (p) { + // check size of miter + Point point_on_path = incoming.finalPoint() - rot90(tang1) * line_width; + Coord len = distance(*p, point_on_path); + if (len <= miter_limit) { + // miter OK + path_builder.appendNew(*p); + } + } + path_builder.appendNew(outgoing.initialPoint()); +} - Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(cbc1->toSBasis()), 0.); - Geom::Circle circle2 = Geom::touching_circle(cbc2->toSBasis(), 0); +/** + * Smoothly extrapolate curves along a circular route. Falls back to miter if necessary. + * @param path_builder Path to append curves to; back() is the incoming curve + * @param outgoing Outgoing curve. + * @param miter_limit When mitering, don't exceed this length + * @param line_width The thickness of the line. Used for miter fallback. + */ +void extrapolate_curves(Geom::Path& path_builder, Geom::Curve const& outgoing, double miter_limit, double line_width) { + Geom::Curve const& incoming = path_builder.back(); + Geom::Point endPt = outgoing.initialPoint(); + + // The method used when extrapolating curves fails to work when either side of the join to be extrapolated + // is a line segment. When this situation is encountered, fall back to a regular miter join. + bool lineProblem = (dynamic_cast(&incoming)) || (dynamic_cast(&outgoing)); + if (lineProblem == false) { + // Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(incoming.toSBasis()), 0.); + Geom::Point tang2 = Geom::unitTangentAt(outgoing.toSBasis(), 0); + + Geom::Circle circle1 = Geom::touching_circle(Geom::reverse(incoming.toSBasis()), 0.); + Geom::Circle circle2 = Geom::touching_circle(outgoing.toSBasis(), 0); Geom::Point points[2]; int solutions = Geom::circle_circle_intersection(circle1, circle2, points[0], points[1]); @@ -225,239 +295,161 @@ void extrapolate_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve sol = points[0]; } else { // both points are good, choose nearest - sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? - points[0] : points[1]; + sol = ( distanceSq(endPt, points[0]) < distanceSq(endPt, points[1]) ) ? points[0] : points[1]; } - Geom::EllipticalArc *arc0 = circle1.arc(cbc1->finalPoint(), 0.5*(cbc1->finalPoint()+sol), sol, true); + + Geom::EllipticalArc *arc0 = circle1.arc(incoming.finalPoint(), 0.5*(incoming.finalPoint()+sol), sol, true); Geom::EllipticalArc *arc1 = circle2.arc(sol, 0.5*(sol+endPt), endPt, true); try { if (arc0) { path_builder.append (arc0->toSBasis()); delete arc0; arc0 = NULL; + } else { + throw std::exception(); } if (arc1) { path_builder.append (arc1->toSBasis()); delete arc1; arc1 = NULL; + } else { + throw std::exception(); } - } catch (std::exception & ex) { - printf("Exception occured, probably NaN or infinite valued points: %s\n", ex.what()); + + } catch (std::exception const & ex) { + g_warning("Error extrapolating line join: %s\n", ex.what()); path_builder.appendNew(endPt); } } else { - boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) { - //check size of miter - Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; - Geom::Coord len = distance(*p, point_on_path); - if (len <= miter_limit) { - // miter OK - path_builder.appendNew (*p); - } - } - path_builder.appendNew (endPt); - } - if (cbc1->finalPoint() != cbc2->initialPoint()) { - path_builder.appendNew(cbc2->initialPoint()); - } - path_builder.append(*cbc2); - } - if ( outside && lineProblem ) { - Geom::Path pth; - pth.append(*cbc1); - Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(pth.toPwSb()[0]), 0.); - pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); - - boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) { - //check size of miter - Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; - Geom::Coord len = distance(*p, point_on_path); - if (len <= miter_limit) { - // miter OK - path_builder.appendNew (*p); - } - } - path_builder.appendNew (endPt); - if (cbc1->finalPoint() != cbc2->initialPoint()) { - path_builder.appendNew(cbc2->initialPoint()); - } - path_builder.append(*cbc2); - } - if ( !outside ) { - /*path_builder.appendNew (endPt);*/ - Geom::Crossings cross = Geom::crossings(*cbc1, *cbc2); - if (!cross.empty()) { - path_builder.erase_last(); - Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(cbc1->toSBasis()); - cubic = cubic.subdivide(cross[0].ta).first; - path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); - cubic = Geom::sbasis_to_cubicbezier(cbc2->toSBasis()); - cubic = cubic.subdivide(cross[0].tb).second; - path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); - } else { - if (Geom::distance(path_builder.finalPoint(), cbc2->initialPoint()) > 0.0000001) { - path_builder.appendNew(cbc2->initialPoint()); - } else { - path_builder.setFinal(cbc2->initialPoint()); - } - path_builder.append(*cbc2); + // 1 or no solutions found, default to miter + miter_curves(path_builder, outgoing, miter_limit, line_width); } + } else { + // Line segments exist + miter_curves(path_builder, outgoing, miter_limit, line_width); } } -void reflect_curves(Geom::Path& path_builder, Geom::Curve* cbc1, Geom::Curve* cbc2, Geom::Point endPt, - double miter_limit, double line_width, bool outside = false) +/** + * Extrapolate curves by reflecting them along the line that would be given by beveling the join. + * @param path_builder Path to append curves to; back() is the incoming curve + * @param outgoing Outgoing curve. + * @param miter_limit When mitering, don't exceed this length + * @param line_width The thickness of the line. Used for miter fallback. + */ +void reflect_curves(Geom::Path& path_builder, Geom::Curve const& outgoing, double miter_limit, double line_width) { - //the most important work for the reflected join is done here - - //determine where we are in the path. If we're on the inside, ignore - //and just lineTo. On the outside, we'll do a little reflection magic :) - Geom::Crossings cross; + using namespace Geom; + Curve const& incoming = path_builder.back(); + // On the outside, we'll take the incoming curve, the outgoing curve, and + // reflect them over the line formed by taking the unit tangent vector at times + // 0 and 1, respectively, rotated by 90 degrees. + Crossings cross; + + // reflect curves along the line that would be given by beveling the join + Point tang1 = unitTangentAt(reverse(incoming.toSBasis()), 0.); + D2SB newcurve1 = incoming.toSBasis() * reflection(-rot90(tang1), incoming.finalPoint()); + CubicBezier bzr1 = sbasis_to_cubicbezier(reverse(newcurve1)); + + Point tang2 = Geom::unitTangentAt(outgoing.toSBasis(), 0.); + D2SB newcurve2 = outgoing.toSBasis() * reflection(-rot90(tang2), outgoing.initialPoint()); + CubicBezier bzr2 = sbasis_to_cubicbezier(reverse(newcurve2)); + + cross = crossings(bzr1, bzr2); + if (cross.empty()) { + // paths don't cross, fall back to miter + miter_curves(path_builder, outgoing, miter_limit, line_width); + } else { + // reflected join + std::pair sub1 = bzr1.subdivide(cross[0].ta); + std::pair sub2 = bzr2.subdivide(cross[0].tb); + + // TODO it seems as if a bug in 2geom sometimes doesn't catch the first + // crossing of paths, but the second instead; but only sometimes. + path_builder.appendNew (sub1.first[1], sub1.first[2], sub2.second[0]); + path_builder.appendNew (sub2.second[1], sub2.second[2], outgoing.initialPoint()); + } +} - if (outside) { - Geom::Path pth; - pth.append(*cbc1); - - Geom::Point tang1 = Geom::unitTangentAt(Geom::reverse(pth.toPwSb()[0]), 0.); - - //reflect curves along the bevel - D2SB newcurve1 = pth.toPwSb()[0] * - Geom::reflection ( -Geom::rot90(tang1) , - cbc1->finalPoint() ); - - Geom::CubicBezier bzr1 = sbasis_to_cubicbezier(Geom::reverse(newcurve1)); - - pth = Geom::Path(); - pth.append( *cbc2 ); - Geom::Point tang2 = Geom::unitTangentAt(pth.toPwSb()[0], 0); - - D2SB newcurve2 = pth.toPwSb()[0] * - Geom::reflection ( -Geom::rot90(tang2) , - cbc2->initialPoint() ); - Geom::CubicBezier bzr2 = sbasis_to_cubicbezier(Geom::reverse(newcurve2)); - - cross = Geom::crossings(bzr1, bzr2); - if ( cross.empty() ) { - //curves didn't cross; default to miter - boost::optional p = intersection_point (cbc1->finalPoint(), tang1, - cbc2->initialPoint(), tang2); - if (p) { - //check size of miter - Geom::Point point_on_path = cbc1->finalPoint() - rot90(tang1) * line_width; - Geom::Coord len = distance(*p, point_on_path); - if (len <= miter_limit) { - // miter OK - path_builder.appendNew (*p); - } - } - //bevel - path_builder.appendNew( endPt ); - } else { - //join - std::pair sub1 = bzr1.subdivide(cross[0].ta); - std::pair sub2 = bzr2.subdivide(cross[0].tb); +// Ideal function pointer we want to pass +typedef void JoinFunc(Geom::Path& /*path_builder*/, Geom::Curve const& /*outgoing*/, double /*miter_limit*/, double /*line_width*/); - //@TODO joins have a strange tendency to cross themselves twice. Check this. +/** + * Helper function for repeated logic in outlineHalf. + */ +static void outlineHelper(Geom::Path& path_builder, Geom::PathVector* path_vec, bool outside, double width, double miter, JoinFunc func) { + Geom::Curve * cbc2 = path_vec->front()[0].duplicate(); - //sections commented out are for general stability - path_builder.appendNew (sub1.first[1], sub1.first[2], /*sub1.first[3]*/ sub2.second[0] ); - path_builder.appendNew (sub2.second[1], sub2.second[2], /*sub2.second[3]*/ endPt ); - } - if (cbc1->finalPoint() != cbc2->initialPoint()) { - path_builder.appendNew(cbc2->initialPoint()); - } - path_builder.append(*cbc2); + if (outside) { + func(path_builder, *cbc2, miter, width); } else { - //probably on the inside of the corner - /*path_builder.appendNew ( endPt );*/ - cross = Geom::crossings(*cbc1, *cbc2); - if (!cross.empty()) { - path_builder.erase_last(); - Geom::CubicBezier cubic = Geom::sbasis_to_cubicbezier(cbc1->toSBasis()); - cubic = cubic.subdivide(cross[0].ta).first; - path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); - cubic = Geom::sbasis_to_cubicbezier(cbc2->toSBasis()); - cubic = cubic.subdivide(cross[0].tb).second; - path_builder.append(cubic, Geom::Path::STITCH_DISCONTINUOUS); - } else { - if (Geom::distance(path_builder.finalPoint(), cbc2->initialPoint()) > 0.0000001) { - path_builder.appendNew(cbc2->initialPoint()); - } else { - path_builder.setFinal(cbc2->initialPoint()); - } - path_builder.append(*cbc2); - } + joinInside(path_builder, *cbc2); + } + + // store it + Geom::Path temp_path = path_vec->front(); + if (!outside) { + // erase the first segment since the inside join code already appended it + temp_path.erase(temp_path.begin()); + } + + if (temp_path.initialPoint() != path_builder.finalPoint()) { + temp_path.setInitial(path_builder.finalPoint()); } + + path_builder.append(temp_path); + + delete cbc2; } -/** @brief Converts a path to one half of an outline. -* path_in: The input path to use. (To create the other side use path_in.reverse() ) -* line_width: the line width to use (usually you want to divide this by 2) -* miter_limit: the miter parameter -* extrapolate: whether the join should be extrapolated instead of reflected -*/ -Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double miter_limit, bool extrapolate = false) -{ - // NOTE: it is important to notice the distinction between a Geom::Path and a livarot Path here! +/** + * Offsets exactly one half of a bezier spline (path). + * @param path_in The input path to use. (To create the other side use path_in.reverse() ) + * @param line_width the line width to use (usually you want to divide this by 2) + * @param miter_limit the miter parameter + * @param func Join function to apply at each join. + */ + +Geom::Path outlineHalf(const Geom::Path& path_in, double line_width, double miter_limit, JoinFunc func) { + // NOTE: it is important to notice the distinction between a Geom::Path and a livarot ::Path here! // if you do not see "Geom::" there is a different function set! Geom::PathVector pv = split_at_cusps(path_in); - Path to_outline; - Path outlined_result; - - Geom::Path path_builder = Geom::Path(); //the path to store the result in - Geom::PathVector * path_vec; //needed because livarot returns a goddamn pointer + ::Path to_outline; + ::Path outlined_result; - const unsigned k = pv.size(); + Geom::Path path_builder = Geom::Path(); // the path to store the result in + Geom::PathVector* path_vec; // needed because livarot returns a pointer (TODO make this not a pointer) - for (unsigned u = 0; u < k; u+=2) { + // Do two curves at a time for efficiency, since the join function needs to know the outgoing curve as well + const size_t k = pv.size(); + for (size_t u = 0; u < k; u += 2) { to_outline = Path(); outlined_result = Path(); - to_outline.LoadPath(pv[u], Geom::Affine(), false, false); + to_outline.LoadPath(pv[u], Geom::identity(), false, false); to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10); - //now a curve has been outside outlined and loaded into outlined_result + // now a curve has been outside outlined and loaded into outlined_result - //get the Geom::Path + // get the Geom::Path path_vec = outlined_result.MakePathVector(); - //thing to do on the first run through + // on the first run through, there is no join if (u == 0) { - //I could use the pv->operator[] (0) notation but that looks terrible - path_builder.start( (*path_vec)[0].initialPoint() ); - path_builder.append( (*path_vec)[0] ); + path_builder.start(path_vec->front().initialPoint()); + path_builder.append(path_vec->front()); } else { - //get the curves ready for the operation - Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate(); - - //do the reflection/extrapolation: - if (extrapolate) { - extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); - } else { - reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u - 1] [pv[u - 1].size() - 1], pv[u] [0] )); - } - //store it - Geom::Path temp_path = (*path_vec)[0]; - //erase the first segment since the join code already appended it - temp_path.erase(temp_path.begin()); - - path_builder.append( temp_path ); + outlineHelper(path_builder, path_vec, outside_angle(pv[u-1][pv[u-1].size()-1], pv[u][0]), line_width, miter_limit, func); } - //outline the next segment, but don't store it yet - if (path_vec) delete path_vec; + // outline the next segment, but don't store it yet + if (path_vec) + delete path_vec; + path_vec = NULL; + // odd number of paths if (u < k - 1) { outlined_result = Path(); to_outline = Path(); @@ -466,29 +458,11 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double to_outline.OutsideOutline(&outlined_result, line_width / 2, join_straight, butt_straight, 10); path_vec = outlined_result.MakePathVector(); + outlineHelper(path_builder, path_vec, outside_angle(pv[u][pv[u].size()-1], pv[u+1][0]), line_width, miter_limit, func); - //get the curves ready for the operation - Geom::Curve * cbc1 = path_builder[path_builder.size() - 1].duplicate(); - Geom::Curve * cbc2 = (*path_vec)[0] [0].duplicate(); - - //do the reflection/extrapolation: - if (extrapolate) { - extrapolate_curves(path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); - } else { - reflect_curves (path_builder, cbc1, cbc2, (*path_vec)[0].initialPoint(), miter_limit, line_width, - outside_angle ( pv[u] [pv[u].size()-1], pv[u+1] [0] )); - } - - //Now we can store it. - Geom::Path temp_path = (*path_vec)[0]; - temp_path.erase(temp_path.begin()); - - path_builder.append( temp_path ); - - if (cbc1) delete cbc1; - if (cbc2) delete cbc2; - if (path_vec) delete path_vec; + if (path_vec) + delete path_vec; + path_vec = NULL; } } @@ -497,7 +471,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double Geom::Curve * cbc2; if ( path_in[path_in.size()].isDegenerate() ) { - //handle case for last segment curved + // handle case for last segment curved outlined_result = Path(); to_outline = Path(); @@ -509,11 +483,12 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double path_vec = outlined_result.MakePathVector(); cbc1 = path_builder[path_builder.size() - 1].duplicate(); - cbc2 = (*path_vec)[0] [0].duplicate(); + cbc2 = path_vec->front()[0].duplicate(); delete path_vec; } else { - //handle case for last segment straight (since the path doesn't actually give us access to it) + // handle case for last segment straight + // since the path doesn't actually give us access to it, we'll do it ourselves outlined_result = Path(); to_outline = Path(); @@ -527,17 +502,10 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double cbc1 = path_builder[path_builder.size() - 1].duplicate(); cbc2 = (*path_vec)[0] [0].duplicate(); - //append the closing segment - - if (extrapolate) { - extrapolate_curves(path_builder, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( path_in[path_in.size() - 1], oneCurve [0] )); - } else { - reflect_curves (path_builder, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( path_in[path_in.size() - 1], oneCurve [0] )); - } - - delete cbc1; cbc1 = cbc2->duplicate(); + outlineHelper(path_builder, path_vec, outside_angle(path_in[path_in.size()-1], oneCurve[0]), line_width, miter_limit, func); + + delete cbc1; + cbc1 = cbc2->duplicate(); delete path_vec; oneCurve = Geom::Path(); oneCurve.append(path_in[0]); @@ -550,32 +518,35 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double delete path_vec; } - Geom::Path temporary; //just an accessory path, we won't need it for long + Geom::Path temporary; temporary.append(*cbc1); - const Geom::Curve& prev_curve = path_in[path_in.size()].isDegenerate() ? path_in[path_in.size() - 1] : - path_in[path_in.size()]; - - if (extrapolate) { - extrapolate_curves(temporary, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( prev_curve, path_in [0] )); - } else { - reflect_curves (temporary, cbc1, cbc2, cbc2->initialPoint(), miter_limit, line_width, - outside_angle ( prev_curve, path_in [0] )); - } - //extract the appended curves - //if (temporary[temporary.size()].initialPoint() != path_builder[0].initialPoint()) { - path_builder.erase(path_builder.begin()); - /*} else { - temporary.erase_last(); - }*/ - path_builder.erase_last(); - if (Geom::distance(path_builder.finalPoint(), temporary.initialPoint()) > 0.0000001) { - path_builder.appendNew(temporary.initialPoint()); + Geom::Curve const & prev_curve = path_in[path_in.size()].isDegenerate() ? path_in[path_in.size() - 1] : path_in[path_in.size()]; + Geom::Path isStraight; + isStraight.append(prev_curve); + isStraight.append(path_in[0]); + // does closing path require a join? + if (Geom::split_at_cusps(isStraight).size() > 1) { + bool outside = outside_angle(prev_curve, path_in[0]); + if (outside) { + func(temporary, *cbc2, miter_limit, line_width); + } else { + joinInside(temporary, *cbc2); + path_builder.erase(path_builder.begin()); + } + + // extract the appended curves + path_builder.erase_last(); + if (Geom::are_near(path_builder.finalPoint(), temporary.initialPoint())) { + path_builder.setFinal(temporary.initialPoint()); + } else { + path_builder.appendNew(temporary.initialPoint()); + } + path_builder.append(temporary); } else { - path_builder.setFinal(temporary.initialPoint()); + // closing path does not require a join + path_builder.setFinal(path_builder.initialPoint()); } - path_builder.append(temporary); path_builder.close(); if (cbc1) delete cbc1; @@ -585,8 +556,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double return path_builder; } -Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, - ButtTypeMod butt, double miter_lim, bool extrapolate, double start_lean, double end_lean) +Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, ButtTypeMod butt, double miter_lim, bool extrapolate, double start_lean, double end_lean) { Geom::PathVector path_out; @@ -594,16 +564,14 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, for (unsigned i = 0; i < pv_size; i++) { if (path_in[i].size() > 1) { - //since you've made it this far, hopefully all this is obvious :P Geom::Path with_direction; Geom::Path against_direction; - - with_direction = Outline::doAdvHalfOutline( path_in[i], -line_width, miter_lim, extrapolate ); - against_direction = Outline::doAdvHalfOutline( path_in[i].reverse(), -line_width, miter_lim, extrapolate ); + + with_direction = Outline::outlineHalf(path_in[i], -line_width, miter_lim, extrapolate ? extrapolate_curves : reflect_curves); + against_direction = Outline::outlineHalf(path_in[i].reverse(), -line_width, miter_lim, extrapolate ? extrapolate_curves : reflect_curves); Geom::PathBuilder pb; - //add in the...do I really need to say this? pb.moveTo(with_direction.initialPoint()); pb.append(with_direction); @@ -724,8 +692,7 @@ Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, return path_out; } -Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtTypeMod linecap_type, - LineJoinType linejoin_type, double miter_limit, double start_lean, double end_lean) +Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line_width, ButtTypeMod linecap_type, LineJoinType linejoin_type, double miter_limit, double start_lean, double end_lean) { std::vector path_out = std::vector(); if (path_in.empty()) { @@ -761,21 +728,21 @@ Geom::PathVector PathVectorOutline(Geom::PathVector const & path_in, double line break; } } - if (linejoin_type <= 2) { + if (linejoin_type <= LINEJOIN_POINTY) { p.Outline(&outlinepath, line_width / 2, static_cast(linejoin_type), original_butt, miter_lim); - //fix memory leak + // fix memory leak std::vector *pv_p = outlinepath.MakePathVector(); path_out = *pv_p; delete pv_p; - } else if (linejoin_type == 3) { - //reflected arc join + } else if (linejoin_type == LINEJOIN_REFLECTED) { + // reflected arc join path_out = outlinePath(path_in, line_width, static_cast(linejoin_type), linecap_type , miter_lim, false, start_lean, end_lean); - } else if (linejoin_type == 4) { - //extrapolated arc join + } else if (linejoin_type == LINEJOIN_EXTRAPOLATED) { + // extrapolated arc join path_out = outlinePath(path_in, line_width, LINEJOIN_STRAIGHT, linecap_type, miter_lim, true, start_lean, end_lean); } @@ -800,16 +767,14 @@ Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, Lin path_outline.OutsideOutline(&path_tangent, line_width / 2, static_cast(linejoin_type), butt_straight, miter_lim); pathvec = path_tangent.MakePathVector(); - path_out = pathvec[0]/* deref pointer */[0]/*actual object ref*/; + path_out = pathvec->front(); delete pathvec; return path_out; } else if (linejoin_type == LINEJOIN_REFLECTED) { - //reflected half outline - path_out = doAdvHalfOutline(path_in, line_width, miter_lim, false); + path_out = outlineHalf(path_in, line_width, miter_lim, reflect_curves); return path_out; } else if (linejoin_type == LINEJOIN_EXTRAPOLATED) { - //what the hell do you think this is? :P - path_out = doAdvHalfOutline(path_in, line_width, miter_lim, true); + path_out = outlineHalf(path_in, line_width, miter_lim, extrapolate_curves); return path_out; } #undef miter_lim @@ -827,4 +792,4 @@ Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, Lin fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8 : diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h index 272c93a49..c17584be2 100644 --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -1,5 +1,13 @@ -#ifndef _SEEN_PATH_OUTLINE_H -#define _SEEN_PATH_OUTLINE_H +#ifndef SEEN_PATH_OUTLINE_H +#define SEEN_PATH_OUTLINE_H + +/* Author: + * Liam P. White + * + * Copyright (C) 2014 Author + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ #include #include @@ -18,10 +26,11 @@ enum ButtTypeMod { BUTT_POINTY, BUTT_LEANED }; + namespace Geom { - Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in); - std::vector split_at_cusps(const Geom::Path& in); + Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in); + std::vector split_at_cusps(const Geom::Path& in); } namespace Outline @@ -29,10 +38,18 @@ namespace Outline unsigned bezierOrder (const Geom::Curve* curve_in); std::vector PathVectorOutline(std::vector const & path_in, double line_width, ButtTypeMod linecap_type, LineJoinType linejoin_type, double miter_limit, double start_lean = 0, double end_lean = 0); - - /*Geom::PathVector outlinePath(const Geom::PathVector& path_in, double line_width, LineJoinType join, - ButtTypeMod butt, double miter_lim, bool extrapolate = false);*/ Geom::Path PathOutsideOutline(Geom::Path const & path_in, double line_width, LineJoinType linejoin_type, double miter_limit); } -#endif // _SEEN_PATH_OUTLINE_H +#endif // SEEN_PATH_OUTLINE_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : -- cgit v1.2.3 From d9e1d33c2eb1793056aab9c4d567e7981042a294 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Wed, 23 Jul 2014 22:29:55 +0200 Subject: Partly reverted r13460. (bzr r13464) --- src/sp-item.cpp | 2 +- src/sp-lpe-item.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 698559a9f..0cdff6546 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -1264,7 +1264,7 @@ void SPItem::adjust_paint_recursive (Geom::Affine advertized_transform, Geom::Af // Within text, we do not fork gradients, and so must not recurse to avoid double compensation; // also we do not recurse into clones, because a clone's child is the ghost of its original - // we must not touch it - if (!(SP_IS_TEXT(this) || SP_IS_USE(this))) { + if (!(this && (SP_IS_TEXT(this) || SP_IS_USE(this)))) { for (SPObject *o = children; o != NULL; o = o->next) { if (SP_IS_ITEM(o)) { // At the level of the transformed item, t_ancestors is identity; diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 800b31f87..321d2fc42 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -212,6 +212,10 @@ Inkscape::XML::Node* SPLPEItem::write(Inkscape::XML::Document *xml_doc, Inkscape * returns true when LPE was successful. */ bool SPLPEItem::performPathEffect(SPCurve *curve) { + if (!this) { + return false; + } + if (!curve) { return false; } -- cgit v1.2.3 From bc1648c615a36a3b1e302f8ee5bca1c35b223db7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 24 Jul 2014 00:58:41 +0200 Subject: Fix crash bug with cloned item with gradient. The fix does not solve the root cause, it only fixes the symptom. Fixed bugs: - https://launchpad.net/bugs/453067 (bzr r13465) --- src/gradient-chemistry.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 89b7968fc..27f4d7a98 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -1296,6 +1296,10 @@ Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, guint point_ break; case POINT_LG_MID: { + if (lg->vector.stops.size() < point_i) { + g_message("POINT_LG_MID bug trigger, see LP bug #453067"); + break; + } gdouble offset = lg->vector.stops.at(point_i).offset; p = (1-offset) * Geom::Point(lg->x1.computed, lg->y1.computed) + offset * Geom::Point(lg->x2.computed, lg->y2.computed); } @@ -1321,12 +1325,20 @@ Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, guint point_ break; case POINT_RG_MID1: { + if (rg->vector.stops.size() < point_i) { + g_message("POINT_RG_MID1 bug trigger, see LP bug #453067"); + break; + } gdouble offset = rg->vector.stops.at(point_i).offset; p = (1-offset) * Geom::Point (rg->cx.computed, rg->cy.computed) + offset * Geom::Point(rg->cx.computed + rg->r.computed, rg->cy.computed); } break; case POINT_RG_MID2: { + if (rg->vector.stops.size() < point_i) { + g_message("POINT_RG_MID2 bug trigger, see LP bug #453067"); + break; + } gdouble offset = rg->vector.stops.at(point_i).offset; p = (1-offset) * Geom::Point (rg->cx.computed, rg->cy.computed) + offset * Geom::Point(rg->cx.computed, rg->cy.computed - rg->r.computed); } -- cgit v1.2.3 From 693e6eb237a6c4fbc9a9d47a30fad10b74e2157b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 24 Jul 2014 01:20:18 +0200 Subject: Fix bug on closed nodes in fillet-chamfer LPE (bzr r13341.1.96) --- src/live_effects/lpe-fillet-chamfer.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index a24f5e60e..1c3dc645c 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -512,24 +512,27 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) if (filletChamferData[counter][Y] == 0) { time_it1 = 0; } - time_it2 = modf(fillet_chamfer_values.to_time( - counter + 1, filletChamferData[counter + 1][X]), - &intpart); - if (curve_it2 == curve_endit) { + if (path_it->closed() && curve_it2 == curve_endit) { time_it2 = modf(fillet_chamfer_values.to_time( counter - counterCurves, filletChamferData[counter - counterCurves][X]), &intpart); + } else { + time_it2 = modf(fillet_chamfer_values.to_time( + counter + 1, filletChamferData[counter + 1][X]), + &intpart); } - double resultLenght = - it1_length + fillet_chamfer_values.to_len( - counter + 1, filletChamferData[counter + 1][X]); + double resultLenght = 0; time_it1_B = 1; if (path_it->closed() && curve_it2 == curve_endit) { resultLenght = it1_length + fillet_chamfer_values.to_len( counter - counterCurves, filletChamferData[counter - counterCurves][X]); + } else { + resultLenght = + it1_length + fillet_chamfer_values.to_len( + counter + 1, filletChamferData[counter + 1][X]); } if (resultLenght > 0 && time_it2 != 0) { time_it1_B = modf(fillet_chamfer_values.to_time(counter, -resultLenght), @@ -541,7 +544,12 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) time_it1_B = gapHelper; } } - if (filletChamferData[counter + 1][Y] == 0) { + if (path_it->closed() && curve_it2 == curve_endit && + filletChamferData[counter - counterCurves][Y] == 0) { + time_it1_B = 1; + time_it2 = 0; + } else if (path_it->size() > counterCurves + 1 && + filletChamferData[counter + 1][Y] == 0) { time_it1_B = 1; time_it2 = 0; } -- cgit v1.2.3 From 590e801edf05b0063e54dbe36d785c88b65a264a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 24 Jul 2014 02:31:02 +0200 Subject: Fix a bug on type of 'fillet' on the closing node (bzr r13341.1.97) --- src/live_effects/lpe-fillet-chamfer.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 1c3dc645c..eae37ad36 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -479,7 +479,7 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) Piecewise > n = rot90(unitVector(der)); fillet_chamfer_values.set_pwd2(pwd2_in, n); std::vector filletChamferData = fillet_chamfer_values.data(); - int counter = 0; + unsigned int counter = 0; //from http://launchpadlibrarian.net/12692602/rcp.svg const double K = (4.0 / 3.0) * (sqrt(2.0) - 1.0); for (PathVector::const_iterator path_it = path_in.begin(); @@ -502,7 +502,7 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) curve_endit = path_it->end_open(); } } - int counterCurves = 0; + unsigned int counterCurves = 0; while (curve_it1 != curve_endit) { Coord it1_length = (*curve_it1).length(tolerance); double time_it1, time_it2, time_it1_B, intpart; @@ -604,7 +604,12 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) if (time_it1_B != gapHelper && time_it1_B != time_it1 + gapHelper) { path_out.append(*knotCurve1); } - int type = abs(filletChamferData[counter + 1][Y]); + int type = 0; + if(path_it->closed() && curve_it2 == curve_endit){ + type = abs(filletChamferData[counter - counterCurves][Y]); + } else { + type = abs(filletChamferData[counter + 1][Y]); + } if (type == 3 || type == 4) { if (type == 4) { Geom::Point central = middle_point(startArcPoint, endArcPoint); -- cgit v1.2.3 From b784997fa7a911f53b1ad9386f8ac631d85143b2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Jul 2014 11:43:00 +0200 Subject: Basic support for element (rendring only as a paint server). (bzr r13341.1.98) --- src/CMakeLists.txt | 2 ++ src/Makefile_insert | 1 + src/attributes.cpp | 2 ++ src/attributes.h | 2 ++ src/sp-solid-color.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/sp-solid-color.h | 46 ++++++++++++++++++++++++ src/style.cpp | 23 ++++++++++++ src/style.h | 5 +++ 8 files changed, 178 insertions(+) create mode 100644 src/sp-solid-color.cpp create mode 100644 src/sp-solid-color.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d40aad802..4a792af6b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,6 +63,7 @@ set(sp_SRC sp-root.cpp sp-script.cpp sp-shape.cpp + sp-solid-color.cpp sp-spiral.cpp sp-star.cpp sp-stop.cpp @@ -147,6 +148,7 @@ set(sp_SRC sp-root.h sp-script.h sp-shape.h + sp-solid-color.h sp-spiral.h sp-star.h sp-stop.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 6d0d6b08c..f191839a1 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -192,6 +192,7 @@ ink_common_sources += \ sp-root.cpp sp-root.h \ sp-script.cpp sp-script.h \ sp-shape.cpp sp-shape.h \ + sp-solid-color.cpp sp-solid-color.h \ sp-spiral.cpp sp-spiral.h \ sp-star.cpp sp-star.h \ sp-stop.cpp sp-stop.h \ diff --git a/src/attributes.cpp b/src/attributes.cpp index ee2a80fd3..da7b25f03 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -475,6 +475,8 @@ static SPStyleProp const props[] = { {SP_PROP_MARKER_START, "marker-start"}, {SP_PROP_PAINT_ORDER, "paint-order" }, {SP_PROP_SHAPE_RENDERING, "shape-rendering"}, + {SP_PROP_SOLID_COLOR, "solid-color"}, + {SP_PROP_SOLID_OPACITY, "solid-opacity"}, {SP_PROP_STROKE, "stroke"}, {SP_PROP_STROKE_DASHARRAY, "stroke-dasharray"}, {SP_PROP_STROKE_DASHOFFSET, "stroke-dashoffset"}, diff --git a/src/attributes.h b/src/attributes.h index b8843fcb7..82e7ca8a6 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -476,6 +476,8 @@ enum SPAttributeEnum { SP_PROP_MARKER_START, SP_PROP_PAINT_ORDER, /* SVG2 */ SP_PROP_SHAPE_RENDERING, + SP_PROP_SOLID_COLOR, + SP_PROP_SOLID_OPACITY, SP_PROP_STROKE, SP_PROP_STROKE_DASHARRAY, SP_PROP_STROKE_DASHOFFSET, diff --git a/src/sp-solid-color.cpp b/src/sp-solid-color.cpp new file mode 100644 index 000000000..1f606d176 --- /dev/null +++ b/src/sp-solid-color.cpp @@ -0,0 +1,97 @@ +/** @file + * @solid color class. + */ +/* Authors: + * Tavmjong Bah + * + * Copyright (C) 2014 Tavmjong Bah + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "sp-solid-color.h" + +#include "attributes.h" +#include "style.h" +#include "xml/repr.h" + +#include "sp-factory.h" +#include "sp-item.h" +#include "style-internal.h" + +namespace { + SPObject* createSolidColor() { + return new SPSolidColor(); + } + + bool solidColorRegistered = SPFactory::instance().registerObject("svg:solidColor", createSolidColor); +} + + +/* + * Solid Color + */ +SPSolidColor::SPSolidColor() : SPPaintServer() { +} + +SPSolidColor::~SPSolidColor() { +} + +void SPSolidColor::build(SPDocument* doc, Inkscape::XML::Node* repr) { + SPPaintServer::build(doc, repr); + + this->readAttr( "style" ); + this->readAttr( "solid-color" ); + this->readAttr( "solid-opacity" ); +} + +/** + * Virtual build: set solidcolor attributes from its associated XML node. + */ + +void SPSolidColor::set(unsigned int key, const gchar* value) { + + if (SP_ATTRIBUTE_IS_CSS(key)) { + sp_style_read_from_object(this->style, this); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } else { + SPPaintServer::set(key, value); + } +} + +/** + * Virtual set: set attribute to value. + */ + +Inkscape::XML::Node* SPSolidColor::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("svg:solidColor"); + } + + SPObject::write(xml_doc, repr, flags); + + return repr; +} + +cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const &bbox, double opacity) { + + SPIColor *c = &(this->style->solid_color); + cairo_pattern_t *cp = cairo_pattern_create_rgba ( c->value.color.v.c[0], c->value.color.v.c[1], c->value.color.v.c[2], SP_SCALE24_TO_FLOAT(this->style->solid_opacity.value) * opacity ); + + return cp; +} + + +/** + * Virtual write: write object attributes to repr. + */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-solid-color.h b/src/sp-solid-color.h new file mode 100644 index 000000000..0ff09762e --- /dev/null +++ b/src/sp-solid-color.h @@ -0,0 +1,46 @@ +#ifndef SEEN_SP_SOLIDCOLOR_H +#define SEEN_SP_SOLIDCOLOR_H + +/** \file + * SPSolidColor: SVG implementation. + */ +/* + * Authors: Tavmjong Bah + * Copyright (C) 2012 Tavmjong Bah + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "color.h" +#include "sp-paint-server.h" + +#define SP_SOLIDCOLOR(obj) (dynamic_cast((SPObject*)obj)) +#define SP_IS_SOLIDCOLOR(obj) (dynamic_cast((SPObject*)obj) != NULL) + +/** Gradient SolidColor. */ +class SPSolidColor : public SPPaintServer { +public: + SPSolidColor(); + virtual ~SPSolidColor(); + + virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); + +protected: + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void set(unsigned int key, const gchar* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); +}; + +#endif /* !SEEN_SP_SOLIDCOLOR_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/style.cpp b/src/style.cpp index c6a98e7f4..3691a3e48 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -153,6 +153,10 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : color_interpolation( "color-interpolation", enum_color_interpolation, SP_CSS_COLOR_INTERPOLATION_SRGB), color_interpolation_filters("color-interpolation-filters", enum_color_interpolation, SP_CSS_COLOR_INTERPOLATION_LINEARRGB), + // Solid color properties + solid_color( "solid-color" ), // SPIColor + solid_opacity( "solid-opacity", SP_SCALE24_MAX ), + // Fill properties fill( "fill" ), // SPIPaint fill_opacity( "fill-opacity", SP_SCALE24_MAX ), @@ -311,6 +315,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &color_interpolation ); _properties.push_back( &color_interpolation_filters ); + _properties.push_back( &solid_color ); + _properties.push_back( &solid_opacity ); + _properties.push_back( &fill ); _properties.push_back( &fill_opacity ); _properties.push_back( &fill_rule ); @@ -390,10 +397,14 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( color_interpolation.name, reinterpret_cast(&SPStyle::color_interpolation ) ) ); // _propmap.insert( std::make_pair( color_interpolation_filters.name, reinterpret_cast(&SPStyle::color_interpolation_filters ) ) ); + // _propmap.insert( std::make_pair( solid_color.name, reinterpret_cast(&SPStyle::solid_color ) ) ); + // _propmap.insert( std::make_pair( solid_opacity.name, reinterpret_cast(&SPStyle::solid_opacity ) ) ); + // _propmap.insert( std::make_pair( fill.name, reinterpret_cast(&SPStyle::fill ) ) ); // _propmap.insert( std::make_pair( fill_opacity.name, reinterpret_cast(&SPStyle::fill_opacity ) ) ); // _propmap.insert( std::make_pair( fill_rule.name, reinterpret_cast(&SPStyle::fill_rule ) ) ); + // _propmap.insert( std::make_pair( stroke.name, reinterpret_cast(&SPStyle::stroke ) ) ); // _propmap.insert( std::make_pair( stroke_width.name, reinterpret_cast(&SPStyle::stroke_width ) ) ); // _propmap.insert( std::make_pair( stroke_linecap.name, reinterpret_cast(&SPStyle::stroke_linecap ) ) ); @@ -790,6 +801,12 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_COLOR_RENDERING: color_rendering.readIfUnset( val ); break; + case SP_PROP_SOLID_COLOR: + solid_color.readIfUnset( val ); + break; + case SP_PROP_SOLID_OPACITY: + solid_opacity.readIfUnset( val ); + break; case SP_PROP_FILL: fill.readIfUnset( val ); break; @@ -1557,6 +1574,12 @@ sp_style_unset_property_attrs(SPObject *o) if (style->color_interpolation_filters.set) { repr->setAttribute("color-interpolation-filters", NULL); } + if (style->solid_color.set) { + repr->setAttribute("solid-color", NULL); + } + if (style->solid_opacity.set) { + repr->setAttribute("solid-opacity", NULL); + } if (style->fill.set) { repr->setAttribute("fill", NULL); } diff --git a/src/style.h b/src/style.h index 931dcc90e..eb8a3ed91 100644 --- a/src/style.h +++ b/src/style.h @@ -180,6 +180,11 @@ public: /** color-interpolation-filters */ SPIEnum color_interpolation_filters; + /** solid-color */ + SPIColor solid_color; + /** solid-opacity */ + SPIScale24 solid_opacity; + /** fill */ SPIPaint fill; /** fill-opacity */ -- cgit v1.2.3 From 21300686829d99d1624df916d09f8d7b1bce2e79 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Jul 2014 13:42:04 +0200 Subject: Read HSL color (CSS Color Module Level 3). (bzr r13341.1.99) --- src/svg/svg-color.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src') diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index ca94c241f..5108b7702 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -310,6 +310,59 @@ static guint32 internal_sp_svg_read_color(gchar const *str, gchar const **end_pt *end_ptr = s; } return val; + } else if (strneq(str, "hsl(", 4)) { + + gchar *ptr = (gchar *) str + 4; + + gchar *e; // ptr after read + + double h = g_ascii_strtod(ptr, &e); // Read h (0-360) + if (ptr == e) return def; // Read failed + ptr = e; + + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != ',') return def; // Need comma + ptr += 1; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + + double s = g_ascii_strtod(ptr, &e); // Read s (percent) + if (ptr == e) return def; // Read failed + ptr = e; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != '%') return def; // Need % + ptr += 1; + + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != ',') return def; // Need comma + ptr += 1; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + + double l = g_ascii_strtod(ptr, &e); // Read l (percent) + if (ptr == e) return def; // Read failed + ptr = e; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != '%') return def; // Need % + ptr += 1; + + if (end_ptr) { + *end_ptr = ptr; + } + + + // Normalize to 0..1 + h /= 360.0; + s /= 100.0; + l /= 100.0; + + gfloat rgb[3]; + + sp_color_hsl_to_rgb_floatv( rgb, h, s, l ); + + val = static_cast(floor(CLAMP(rgb[0], 0.0, 1.0) * 255.9999)) << 24; + val |= (static_cast(floor(CLAMP(rgb[1], 0.0, 1.0) * 255.9999)) << 16); + val |= (static_cast(floor(CLAMP(rgb[2], 0.0, 1.0) * 255.9999)) << 8); + return val; + } else { gint i; if (colors.empty()) { -- cgit v1.2.3 From bd69a4d9fc5e4ad2586b35cd84c7f9368cc640bc Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 24 Jul 2014 13:58:33 +0200 Subject: Read HSL colors (CSS Color Module Level 3). (bzr r13466) --- src/svg/svg-color.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'src') diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index ca94c241f..5108b7702 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -310,6 +310,59 @@ static guint32 internal_sp_svg_read_color(gchar const *str, gchar const **end_pt *end_ptr = s; } return val; + } else if (strneq(str, "hsl(", 4)) { + + gchar *ptr = (gchar *) str + 4; + + gchar *e; // ptr after read + + double h = g_ascii_strtod(ptr, &e); // Read h (0-360) + if (ptr == e) return def; // Read failed + ptr = e; + + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != ',') return def; // Need comma + ptr += 1; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + + double s = g_ascii_strtod(ptr, &e); // Read s (percent) + if (ptr == e) return def; // Read failed + ptr = e; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != '%') return def; // Need % + ptr += 1; + + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != ',') return def; // Need comma + ptr += 1; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + + double l = g_ascii_strtod(ptr, &e); // Read l (percent) + if (ptr == e) return def; // Read failed + ptr = e; + while (*ptr && g_ascii_isspace(*ptr)) ptr += 1; // Remove any white space + if (*ptr != '%') return def; // Need % + ptr += 1; + + if (end_ptr) { + *end_ptr = ptr; + } + + + // Normalize to 0..1 + h /= 360.0; + s /= 100.0; + l /= 100.0; + + gfloat rgb[3]; + + sp_color_hsl_to_rgb_floatv( rgb, h, s, l ); + + val = static_cast(floor(CLAMP(rgb[0], 0.0, 1.0) * 255.9999)) << 24; + val |= (static_cast(floor(CLAMP(rgb[1], 0.0, 1.0) * 255.9999)) << 16); + val |= (static_cast(floor(CLAMP(rgb[2], 0.0, 1.0) * 255.9999)) << 8); + return val; + } else { gint i; if (colors.empty()) { -- cgit v1.2.3 From 836c1d6fa8bc1430f4f677a636f74e586f1a85e2 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Thu, 24 Jul 2014 14:31:00 -0700 Subject: Fix for bug 1336753 (bzr r13467) --- src/extension/internal/text_reassemble.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c index b0447442c..9b1cff46e 100644 --- a/src/extension/internal/text_reassemble.c +++ b/src/extension/internal/text_reassemble.c @@ -1820,6 +1820,8 @@ printf("Face idx:%d bbox: xMax/Min:%ld,%ld yMax/Min:%ld,%ld UpEM:%d asc/des:%d,% fasc = ((double) (fsp->face->ascender) )/64.0; fdsc = ((double) (fsp->face->descender))/64.0; + /* originally the denominator was just 32.0, but it broke when units_per_EM wasn't 2048 */ + double fixscale = tsp->fs/(((double) fsp->face->units_per_EM)/64.0); if(tri->load_flags & FT_LOAD_NO_SCALE) xe *= tsp->fs/32.0; /* now place the rectangle using ALN information */ @@ -1837,11 +1839,11 @@ printf("Face idx:%d bbox: xMax/Min:%ld,%ld yMax/Min:%ld,%ld UpEM:%d asc/des:%d,% } tpi->chunks[current].ldir = tsp->ldir; - if(tri->load_flags & FT_LOAD_NO_SCALE){ - asc *= tsp->fs/32.0; - dsc *= tsp->fs/32.0; - fasc *= tsp->fs/32.0; - fdsc *= tsp->fs/32.0; + if(tri->load_flags & FT_LOAD_NO_SCALE){ + asc *= fixscale; + dsc *= fixscale; + fasc *= fixscale; + fdsc *= fixscale; } -- cgit v1.2.3 From 6fe910b77009aa33629d055c847592a8006d05d2 Mon Sep 17 00:00:00 2001 From: mathog <> Date: Thu, 24 Jul 2014 16:09:10 -0700 Subject: Fix for bug 1340683 (bzr r13468) --- src/extension/internal/emf-inout.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 257994560..084fbcd58 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -1641,11 +1641,19 @@ int Emf::myEnhMetaFileProc(char *contents, unsigned int length, PEMF_CALLBACK_DA // next record is valid type and forces pending text to be drawn immediately if ((d->dc[d->level].dirty & DIRTY_TEXT) || ((emr_mask != U_EMR_INVALID) && (emr_mask & U_DRAW_TEXT) && d->tri->dirty)){ TR_layout_analyze(d->tri); + if (d->dc[d->level].clip_id){ + SVGOStringStream tmp_clip; + tmp_clip << "\ndc[d->level].clip_id << ")\"\n>"; + d->outsvg += tmp_clip.str().c_str(); + } TR_layout_2_svg(d->tri); SVGOStringStream ts; ts << d->tri->out; d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); + if (d->dc[d->level].clip_id){ + d->outsvg += "\n\n"; + } } if(d->dc[d->level].dirty){ //Apply the delayed background changes, clear the flag d->dc[d->level].bkMode = tbkMode; @@ -3141,11 +3149,19 @@ std::cout << "BEFORE DRAW" int status = trinfo_load_textrec(d->tri, &tsp, tsp.ori,TR_EMFBOT); // ori is actually escapement if(status==-1){ // change of escapement, emit what we have and reset TR_layout_analyze(d->tri); + if (d->dc[d->level].clip_id){ + SVGOStringStream tmp_clip; + tmp_clip << "\ndc[d->level].clip_id << ")\"\n>"; + d->outsvg += tmp_clip.str().c_str(); + } TR_layout_2_svg(d->tri); ts << d->tri->out; d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); (void) trinfo_load_textrec(d->tri, &tsp, tsp.ori,TR_EMFBOT); // ignore return status, it must work + if (d->dc[d->level].clip_id){ + d->outsvg += "\n\n"; + } } g_free(escaped_text); @@ -3479,7 +3495,7 @@ Emf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) if (d.pDesc){ free( d.pDesc ); } -// std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl; +// std::cout << "SVG Output: " << std::endl << d.outsvg << std::endl; SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg.c_str(), strlen(d.outsvg.c_str()), TRUE); -- cgit v1.2.3 From 3b21971e6bf1c012eed2aa9f054bb1cee6ac8a4b Mon Sep 17 00:00:00 2001 From: mathog <> Date: Thu, 24 Jul 2014 17:37:03 -0700 Subject: sync with libTere version of text_reassemble.c (bzr r13469) --- src/extension/internal/text_reassemble.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c index 9b1cff46e..4dfc49420 100644 --- a/src/extension/internal/text_reassemble.c +++ b/src/extension/internal/text_reassemble.c @@ -67,8 +67,8 @@ Optional compiler switches for development: File: text_reassemble.c -Version: 0.0.14 -Date: 25-MAR-2014 +Version: 0.0.15 +Date: 24-JUL-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) @@ -1822,7 +1822,7 @@ printf("Face idx:%d bbox: xMax/Min:%ld,%ld yMax/Min:%ld,%ld UpEM:%d asc/des:%d,% /* originally the denominator was just 32.0, but it broke when units_per_EM wasn't 2048 */ double fixscale = tsp->fs/(((double) fsp->face->units_per_EM)/64.0); - if(tri->load_flags & FT_LOAD_NO_SCALE) xe *= tsp->fs/32.0; + if(tri->load_flags & FT_LOAD_NO_SCALE) xe *= fixscale; /* now place the rectangle using ALN information */ if( taln & ALIHORI & ALILEFT ){ -- cgit v1.2.3 From 962b4e5a31b1128cdb9dfcccac87e7449a3351f1 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Fri, 25 Jul 2014 17:23:13 -0400 Subject: refresh text objects when clipping (Bug 1339305) Fixed bugs: - https://launchpad.net/bugs/1339305 (bzr r13470) --- src/sp-flowregion.cpp | 4 ++++ src/sp-flowtext.cpp | 2 ++ src/sp-text.cpp | 1 + src/sp-use.cpp | 12 +++++++++++- 4 files changed, 18 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 709e9e464..e8e5c3d95 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -185,6 +185,8 @@ Inkscape::XML::Node *SPFlowregion::write(Inkscape::XML::Document *xml_doc, Inksc SPItem::write(xml_doc, repr, flags); + this->UpdateComputed(); // copied from update(), see LP Bug 1339305 + return repr; } @@ -372,6 +374,8 @@ static void GetDest(SPObject* child,Shape **computed) tr_mat = SP_ITEM(u_child)->transform; } if ( SP_IS_SHAPE (u_child) ) { + if (!(SP_SHAPE(u_child)->_curve)) + SP_SHAPE (u_child)->set_shape (); curve = SP_SHAPE (u_child)->getCurve (); } else if ( SP_IS_TEXT (u_child) ) { curve = SP_TEXT (u_child)->getNormalizedBpath (); diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index b4fd54ee4..59832a2b4 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -255,6 +255,8 @@ Inkscape::XML::Node* SPFlowtext::write(Inkscape::XML::Document* doc, Inkscape::X } } + this->rebuildLayout(); // copied from update(), see LP Bug 1339305 + SPItem::write(doc, repr, flags); return repr; diff --git a/src/sp-text.cpp b/src/sp-text.cpp index bbc7ec43d..9a7f0b7a0 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -278,6 +278,7 @@ Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::X } this->attributes.writeTo(repr); + this->rebuildLayout(); // copied from update(), see LP Bug 1339305 // deprecated attribute, but keep it around for backwards compatibility if (this->style->line_height.set && !this->style->line_height.inherit && !this->style->line_height.normal && this->style->line_height.unit == SP_CSS_UNIT_PERCENT) { diff --git a/src/sp-use.cpp b/src/sp-use.cpp index 7d908a66a..e3fcd252a 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -38,6 +38,8 @@ #include "sp-use.h" #include "sp-use-reference.h" #include "sp-shape.h" +#include "sp-text.h" +#include "sp-flowtext.h" namespace { SPObject* createUse() { @@ -177,8 +179,16 @@ Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XM g_free(uri_string); } - if (SP_IS_SHAPE(this->child)) + if (SP_IS_SHAPE(this->child)) { SP_SHAPE(this->child)->set_shape(); // evaluate SPCurve of child + } else if (SP_IS_TEXT(this->child)) { + SP_TEXT(this->child)->rebuildLayout(); // refresh Layout, LP Bug 1339305 + } else if (SP_IS_FLOWTEXT(this->child)) { + if (SP_IS_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild())) + SP_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild())->UpdateComputed(); + SP_FLOWTEXT(this->child)->rebuildLayout(); + } + return repr; } -- cgit v1.2.3 From 964d747265af3f80ed83a54b444ed5ae200a441d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 26 Jul 2014 11:50:39 -0400 Subject: Fix for crash regression 1348927 -- dialogs that are shown but have not been presented are buggy Fixed bugs: - https://launchpad.net/bugs/1348927 (bzr r13471) --- src/ui/dialog/dialog-manager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index d427e3590..7e69e439a 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -251,7 +251,7 @@ void DialogManager::showDialog(gchar const *name, bool grabfocus) { /** * Shows the named dialog, creating it if necessary. */ -void DialogManager::showDialog(GQuark name, bool grabfocus) { +void DialogManager::showDialog(GQuark name, bool /*grabfocus*/) { bool wantTiming = Inkscape::Preferences::get()->getBool("/dialogs/debug/trackAppear", false); GTimer *timer = (wantTiming) ? g_timer_new() : 0; // if needed, must be created/started before getDialog() Dialog *dialog = getDialog(name); @@ -262,8 +262,8 @@ void DialogManager::showDialog(GQuark name, bool grabfocus) { tracker->setAutodelete(true); timer = 0; } - if (grabfocus) - dialog->present(); + // should check for grabfocus, but lp:1348927 prevents it + dialog->present(); } if ( timer ) { -- cgit v1.2.3 From cc73219a498e87298578996011b80680214f7a96 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 26 Jul 2014 13:11:51 -0400 Subject: Clean up some ShapeHolder related things (bzr r13341.1.100) --- src/shape-editor.cpp | 202 +++++++++++++------------------------------ src/shape-editor.h | 54 +++--------- src/ui/tools/arc-tool.cpp | 6 +- src/ui/tools/box3d-tool.cpp | 6 +- src/ui/tools/flood-tool.cpp | 6 +- src/ui/tools/lpe-tool.cpp | 7 +- src/ui/tools/node-tool.cpp | 2 +- src/ui/tools/rect-tool.cpp | 6 +- src/ui/tools/spiral-tool.cpp | 6 +- src/ui/tools/star-tool.cpp | 6 +- src/ui/tools/text-tool.cpp | 6 +- 11 files changed, 98 insertions(+), 209 deletions(-) (limited to 'src') diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp index bf53e8bc3..7915fe533 100644 --- a/src/shape-editor.cpp +++ b/src/shape-editor.cpp @@ -14,24 +14,15 @@ #include #include -#include "sp-object.h" -#include "sp-item.h" -#include "sp-lpe-item.h" -#include "live_effects/lpeobject.h" -#include "selection.h" -#include "desktop.h" -#include "document.h" #include "desktop-handles.h" +#include "document.h" +#include "gc-anchored.h" #include "knotholder.h" -#include "live_effects/parameter/point.h" -#include "xml/node-event-vector.h" -#include "preferences.h" #include "object-edit.h" -#include "style.h" -#include "display/curve.h" -#include <2geom/pathvector.h> - +#include "sp-item.h" +#include "sp-object.h" #include "shape-editor.h" +#include "xml/node-event-vector.h" using Inkscape::createKnotHolder; @@ -44,133 +35,80 @@ ShapeEditor::ShapeEditor(SPDesktop *dt) { } ShapeEditor::~ShapeEditor() { - unset_item(SH_KNOTHOLDER); + unset_item(); } -void ShapeEditor::unset_item(SubType type, bool keep_knotholder) { - switch (type) { - case SH_NODEPATH: - // defunct - break; - case SH_KNOTHOLDER: - if (this->knotholder) { - Inkscape::XML::Node *old_repr = this->knotholder->repr; - if (old_repr && old_repr == knotholder_listener_attached_for) { - sp_repr_remove_listener_by_data(old_repr, this); - Inkscape::GC::release(old_repr); - knotholder_listener_attached_for = NULL; - } - - if (!keep_knotholder) { - delete this->knotholder; - this->knotholder = NULL; - } - } - break; - } -} +void ShapeEditor::unset_item(bool keep_knotholder) { + if (this->knotholder) { + Inkscape::XML::Node *old_repr = this->knotholder->repr; + if (old_repr && old_repr == knotholder_listener_attached_for) { + sp_repr_remove_listener_by_data(old_repr, this); + Inkscape::GC::release(old_repr); + knotholder_listener_attached_for = NULL; + } -bool ShapeEditor::has_nodepath () { - return false; + if (!keep_knotholder) { + delete this->knotholder; + this->knotholder = NULL; + } + } } -bool ShapeEditor::has_knotholder () { - return (this->knotholder != NULL); +bool ShapeEditor::has_knotholder() { + return this->knotholder != NULL; } -void ShapeEditor::update_knotholder () { +void ShapeEditor::update_knotholder() { if (this->knotholder) this->knotholder->update_knots(); } -bool ShapeEditor::has_local_change (SubType type) { - switch (type) { - case SH_NODEPATH: - // defunct - return false; - case SH_KNOTHOLDER: - return (this->knotholder && this->knotholder->local_change != 0); - default: - g_assert_not_reached(); - } +bool ShapeEditor::has_local_change() { + return (this->knotholder && this->knotholder->local_change != 0); } -void ShapeEditor::decrement_local_change (SubType type) { - switch (type) { - case SH_NODEPATH: - // defunct - break; - case SH_KNOTHOLDER: - if (this->knotholder) { - this->knotholder->local_change = FALSE; - } - break; - default: - g_assert_not_reached(); +void ShapeEditor::decrement_local_change() { + if (this->knotholder) { + this->knotholder->local_change = FALSE; } } -const SPItem *ShapeEditor::get_item (SubType type) { +const SPItem *ShapeEditor::get_item() { const SPItem *item = NULL; - switch (type) { - case SH_NODEPATH: - // defunct - break; - case SH_KNOTHOLDER: - if (this->has_knotholder()) { - item = this->knotholder->getItem(); - } - break; + if (this->has_knotholder()) { + item = this->knotholder->getItem(); } return item; } -GList *ShapeEditor::save_nodepath_selection () { - // defunct stub - return NULL; -} - -void ShapeEditor::restore_nodepath_selection (GList */*saved*/) { - // defunct stub -} - -void ShapeEditor::shapeeditor_event_attr_changed(gchar const *name) +void ShapeEditor::event_attr_changed(Inkscape::XML::Node *, gchar const *name, gchar const *, gchar const *, bool, void *data) { - gboolean changed_kh = FALSE; + g_assert(data); + ShapeEditor *sh = static_cast(data); + bool changed_kh = false; - if (has_knotholder()) + if (sh->has_knotholder()) { - changed_kh = !has_local_change(SH_KNOTHOLDER); - decrement_local_change(SH_KNOTHOLDER); + changed_kh = !sh->has_local_change(); + sh->decrement_local_change(); if (changed_kh) { // this can happen if an LPEItem's knotholder handle was dragged, in which case we want // to keep the knotholder; in all other cases (e.g., if the LPE itself changes) we delete it - reset_item(SH_KNOTHOLDER, !strcmp(name, "d")); + sh->reset_item(!strcmp(name, "d")); } } } - -static void shapeeditor_event_attr_changed(Inkscape::XML::Node */*repr*/, gchar const *name, - gchar const */*old_value*/, gchar const */*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - g_assert(data); - ShapeEditor *sh = static_cast(data); - - sh->shapeeditor_event_attr_changed(name); -} - static Inkscape::XML::NodeEventVector shapeeditor_repr_events = { NULL, /* child_added */ NULL, /* child_removed */ - shapeeditor_event_attr_changed, + ShapeEditor::event_attr_changed, NULL, /* content_changed */ NULL /* order_changed */ }; -void ShapeEditor::set_item(SPItem *item, SubType type, bool keep_knotholder) { +void ShapeEditor::set_item(SPItem *item, bool keep_knotholder) { if (_blockSetItem) { return; } @@ -178,60 +116,38 @@ void ShapeEditor::set_item(SPItem *item, SubType type, bool keep_knotholder) { // this happens (and should only happen) when for an LPEItem having both knotholder and // nodepath the knotholder is adapted; in this case we don't want to delete the knotholder // since this freezes the handles - unset_item(type, keep_knotholder); + unset_item(keep_knotholder); if (item) { Inkscape::XML::Node *repr; - switch(type) { - case SH_NODEPATH: - // defunct - break; - - case SH_KNOTHOLDER: - if (!this->knotholder) { - // only recreate knotholder if none is present - this->knotholder = createKnotHolder(item, desktop); - } - if (this->knotholder) { - this->knotholder->update_knots(); - // setting new listener - repr = this->knotholder->repr; - if (repr != knotholder_listener_attached_for) { - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &shapeeditor_repr_events, this); - knotholder_listener_attached_for = repr; - } - } - break; + if (!this->knotholder) { + // only recreate knotholder if none is present + this->knotholder = createKnotHolder(item, desktop); + } + if (this->knotholder) { + this->knotholder->update_knots(); + // setting new listener + repr = this->knotholder->repr; + if (repr != knotholder_listener_attached_for) { + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &shapeeditor_repr_events, this); + knotholder_listener_attached_for = repr; + } } } } /** FIXME: This thing is only called when the item needs to be updated in response to repr change. - Why not make a reload function in NodePath and in KnotHolder? */ -void ShapeEditor::reset_item (SubType type, bool keep_knotholder) + Why not make a reload function in KnotHolder? */ +void ShapeEditor::reset_item(bool keep_knotholder) { - switch (type) { - case SH_NODEPATH: - // defunct - break; - case SH_KNOTHOLDER: - if ( knotholder ) { - SPObject *obj = sp_desktop_document(desktop)->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. - set_item(SP_ITEM(obj), SH_KNOTHOLDER, keep_knotholder); - } - break; + if (knotholder) { + SPObject *obj = sp_desktop_document(desktop)->getObjectByRepr(knotholder_listener_attached_for); /// note that it is not certain that this is an SPItem; it could be a LivePathEffectObject. + set_item(SP_ITEM(obj), keep_knotholder); } } -void ShapeEditor::nodepath_destroyed () { -} - -bool ShapeEditor::has_selection() { - return false; // so far, knotholder cannot have selection -} - /** * Returns true if this ShapeEditor has a knot above which the mouse currently hovers. */ diff --git a/src/shape-editor.h b/src/shape-editor.h index ec4b50fa3..df0dbfa3a 100644 --- a/src/shape-editor.h +++ b/src/shape-editor.h @@ -4,8 +4,8 @@ /* * Inkscape::ShapeEditor * - * This is a container class which contains either knotholder (for shapes) or nodepath (for - * paths). It is attached to a single item so only one of these is active at a time. + * This is a container class which contains a knotholder for shapes. + * It is attached to a single item. * * Authors: * bulia byak @@ -14,27 +14,12 @@ #include -#include <2geom/forward.h> - - -namespace Inkscape { namespace NodePath { class Path; } } namespace Inkscape { namespace XML { class Node; } } class KnotHolder; class LivePathEffectObject; class SPDesktop; class SPItem; -class SPNodeContext; -class ShapeEditorsCollective; - -#include <2geom/point.h> -#include -#include - -enum SubType{ - SH_NODEPATH, - SH_KNOTHOLDER -}; class ShapeEditor { public: @@ -42,36 +27,25 @@ public: ShapeEditor(SPDesktop *desktop); ~ShapeEditor(); - void set_item (SPItem *item, SubType type, bool keep_knotholder = false); - void unset_item (SubType type, bool keep_knotholder = false); - - bool has_nodepath (); //((deprecated)) - void update_knotholder (); //((deprecated)) + void set_item(SPItem *item, bool keep_knotholder = false); + void unset_item(bool keep_knotholder = false); - bool has_local_change (SubType type); - void decrement_local_change (SubType type); + void update_knotholder(); //((deprecated)) - GList *save_nodepath_selection (); - void restore_nodepath_selection (GList *saved); - - void nodepath_destroyed (); - - bool has_selection (); - - Inkscape::NodePath::Path *get_nodepath() {return NULL;} //((deprecated)) - ShapeEditorsCollective *get_container() {return NULL;} - - // this one is only public because it's called from non-C++ repr changed callback - void shapeeditor_event_attr_changed(gchar const *name); + bool has_local_change(); + void decrement_local_change(); bool knot_mouseover() const; - static void blockSetItem(bool b) {_blockSetItem = b;} + static void blockSetItem(bool b) { _blockSetItem = b; } // kludge? + static void event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar const *name, gchar const * /*old_value*/, + gchar const * /*new_value*/, bool /*is_interactive*/, void *data); private: - bool has_knotholder (); - void reset_item (SubType type, bool keep_knotholder = true); - const SPItem *get_item (SubType type); + bool has_knotholder(); + void reset_item (bool keep_knotholder = true); + const SPItem *get_item(); + static bool _blockSetItem; SPDesktop *desktop; diff --git a/src/ui/tools/arc-tool.cpp b/src/ui/tools/arc-tool.cpp index 43f8eb9e1..9fd68f1b9 100644 --- a/src/ui/tools/arc-tool.cpp +++ b/src/ui/tools/arc-tool.cpp @@ -102,8 +102,8 @@ ArcTool::~ArcTool() { * destroys old and creates new knotholder. */ void ArcTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void ArcTool::setup() { @@ -115,7 +115,7 @@ void ArcTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp index e00894d55..b998267c2 100644 --- a/src/ui/tools/box3d-tool.cpp +++ b/src/ui/tools/box3d-tool.cpp @@ -112,8 +112,8 @@ Box3dTool::~Box3dTool() { * destroys old and creates new knotholder. */ void Box3dTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); if (selection->perspList().size() == 1) { // selecting a single box changes the current perspective @@ -147,7 +147,7 @@ void Box3dTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index d74848dc6..3fb56b2ad 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -119,8 +119,8 @@ FloodTool::~FloodTool() { * destroys old and creates new knotholder. */ void FloodTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void FloodTool::setup() { @@ -130,7 +130,7 @@ void FloodTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp index 9ab6d7814..e9b9421f1 100644 --- a/src/ui/tools/lpe-tool.cpp +++ b/src/ui/tools/lpe-tool.cpp @@ -129,8 +129,7 @@ void LpeTool::setup() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (item) { - this->shape_editor->set_item(item, SH_NODEPATH); - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } if (prefs->getBool("/tools/lpetool/selcue")) { @@ -146,9 +145,9 @@ void sp_lpetool_context_selection_changed(Inkscape::Selection *selection, gpoint { LpeTool *lc = SP_LPETOOL_CONTEXT(data); - lc->shape_editor->unset_item(SH_KNOTHOLDER); + lc->shape_editor->unset_item(); SPItem *item = selection->singleItem(); - lc->shape_editor->set_item(item, SH_KNOTHOLDER); + lc->shape_editor->set_item(item); } void LpeTool::set(const Inkscape::Preferences::Entry& val) { diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index ce487831d..36f33e478 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -438,7 +438,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { this->_shape_editors.find(r.item) == this->_shape_editors.end()) { ShapeEditor *si = new ShapeEditor(this->desktop); - si->set_item(r.item, SH_KNOTHOLDER); + si->set_item(r.item); this->_shape_editors.insert(const_cast(r.item), si); } } diff --git a/src/ui/tools/rect-tool.cpp b/src/ui/tools/rect-tool.cpp index 39f422c1a..819671dd6 100644 --- a/src/ui/tools/rect-tool.cpp +++ b/src/ui/tools/rect-tool.cpp @@ -102,8 +102,8 @@ RectTool::~RectTool() { * destroys old and creates new knotholder. */ void RectTool::selection_changed(Inkscape::Selection* selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void RectTool::setup() { @@ -113,7 +113,7 @@ void RectTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection.disconnect(); diff --git a/src/ui/tools/spiral-tool.cpp b/src/ui/tools/spiral-tool.cpp index 5ae229df8..83712457a 100644 --- a/src/ui/tools/spiral-tool.cpp +++ b/src/ui/tools/spiral-tool.cpp @@ -104,8 +104,8 @@ SpiralTool::~SpiralTool() { * destroys old and creates new knotholder. */ void SpiralTool::selection_changed(Inkscape::Selection *selection) { - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void SpiralTool::setup() { @@ -119,7 +119,7 @@ void SpiralTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } Inkscape::Selection *selection = sp_desktop_selection(this->desktop); diff --git a/src/ui/tools/star-tool.cpp b/src/ui/tools/star-tool.cpp index 68f998920..ed28c0a8d 100644 --- a/src/ui/tools/star-tool.cpp +++ b/src/ui/tools/star-tool.cpp @@ -112,8 +112,8 @@ StarTool::~StarTool() { void StarTool::selection_changed(Inkscape::Selection* selection) { g_assert (selection != NULL); - this->shape_editor->unset_item(SH_KNOTHOLDER); - this->shape_editor->set_item(selection->singleItem(), SH_KNOTHOLDER); + this->shape_editor->unset_item(); + this->shape_editor->set_item(selection->singleItem()); } void StarTool::setup() { @@ -129,7 +129,7 @@ void StarTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } Inkscape::Selection *selection = sp_desktop_selection(this->desktop); diff --git a/src/ui/tools/text-tool.cpp b/src/ui/tools/text-tool.cpp index ac830fe6b..b60a39e5d 100644 --- a/src/ui/tools/text-tool.cpp +++ b/src/ui/tools/text-tool.cpp @@ -177,7 +177,7 @@ void TextTool::setup() { SPItem *item = sp_desktop_selection(this->desktop)->singleItem(); if (item && SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { - this->shape_editor->set_item(item, SH_KNOTHOLDER); + this->shape_editor->set_item(item); } this->sel_changed_connection = sp_desktop_selection(desktop)->connectChangedFirst( @@ -1411,10 +1411,10 @@ void TextTool::_selectionChanged(Inkscape::Selection *selection) ToolBase *ec = SP_EVENT_CONTEXT(this); - ec->shape_editor->unset_item(SH_KNOTHOLDER); + ec->shape_editor->unset_item(); SPItem *item = selection->singleItem(); if (item && SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { - ec->shape_editor->set_item(item, SH_KNOTHOLDER); + ec->shape_editor->set_item(item); } if (this->text && (item != this->text)) { -- cgit v1.2.3 From 6694df39c1a9850cac05888db6b3531e17debef5 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 26 Jul 2014 20:19:01 -0400 Subject: Properly fix 1309050, revert incorrect fix for 601336 Fixed bugs: - https://launchpad.net/bugs/1309050 (bzr r13472) --- src/gradient-drag.cpp | 9 ++++++--- src/shape-editor.cpp | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index ee4c1bc8c..a14220cfa 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -21,7 +21,6 @@ #include #include #include -//#include <2geom/bezier-curve.h> #include "desktop-handles.h" #include "selection.h" @@ -38,6 +37,7 @@ #include "svg/css-ostringstream.h" #include "svg/svg.h" #include "preferences.h" +#include "inkscape.h" #include "sp-item.h" #include "style.h" #include "knot.h" @@ -55,6 +55,7 @@ #include "verbs.h" #include "display/sp-canvas.h" #include "ui/control-manager.h" +#include "ui/tools/tool-base.h" using Inkscape::ControlManager; using Inkscape::CtrlLineType; @@ -783,6 +784,9 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui dragger->parent->draggers = g_list_remove (dragger->parent->draggers, dragger); delete dragger; + // throw out delayed snap context + Inkscape::UI::Tools::sp_event_context_discard_delayed_snap_event(SP_ACTIVE_DESKTOP->event_context); + // update the new merged dragger d_new->fireDraggables(true, false, true); d_new->parent->updateLines(); @@ -790,8 +794,7 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui d_new->updateKnotShape (); d_new->updateTip (); d_new->updateDependencies(true); - DocumentUndo::done(sp_desktop_document (d_new->parent->desktop), SP_VERB_CONTEXT_GRADIENT, - _("Merge gradient handles")); + DocumentUndo::done(sp_desktop_document (d_new->parent->desktop), SP_VERB_CONTEXT_GRADIENT, _("Merge gradient handles")); return; } } diff --git a/src/shape-editor.cpp b/src/shape-editor.cpp index acb1abfb0..bf53e8bc3 100644 --- a/src/shape-editor.cpp +++ b/src/shape-editor.cpp @@ -145,7 +145,7 @@ void ShapeEditor::shapeeditor_event_attr_changed(gchar const *name) if (changed_kh) { // this can happen if an LPEItem's knotholder handle was dragged, in which case we want // to keep the knotholder; in all other cases (e.g., if the LPE itself changes) we delete it - reset_item(SH_KNOTHOLDER, !strcmp(name, "d") || !strcmp(name, "style")); + reset_item(SH_KNOTHOLDER, !strcmp(name, "d")); } } } -- cgit v1.2.3 From 579cbdca891707a3aa4da7f0593221cc80c493ac Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 26 Jul 2014 20:24:51 -0400 Subject: Fix for 1309050 Fixed bugs: - https://launchpad.net/bugs/1309050 (bzr r13341.1.101) --- src/gradient-drag.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index ee4c1bc8c..42b8ad8fe 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -38,6 +38,7 @@ #include "svg/css-ostringstream.h" #include "svg/svg.h" #include "preferences.h" +#include "inkscape.h" #include "sp-item.h" #include "style.h" #include "knot.h" @@ -55,6 +56,7 @@ #include "verbs.h" #include "display/sp-canvas.h" #include "ui/control-manager.h" +#include "ui/tools/tool-base.h" using Inkscape::ControlManager; using Inkscape::CtrlLineType; @@ -783,6 +785,9 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui dragger->parent->draggers = g_list_remove (dragger->parent->draggers, dragger); delete dragger; + // throw out delayed snap context + Inkscape::UI::Tools::sp_event_context_discard_delayed_snap_event(SP_ACTIVE_DESKTOP->event_context); + // update the new merged dragger d_new->fireDraggables(true, false, true); d_new->parent->updateLines(); -- cgit v1.2.3 From cea97264b15dcb4b25a52673c9405fa5733d9f6e Mon Sep 17 00:00:00 2001 From: mathog <> Date: Mon, 28 Jul 2014 09:49:26 -0700 Subject: Fix for bug 1340683 for WMF input (bzr r13473) --- src/extension/internal/wmf-inout.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index beb6190d3..5ccad678a 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -670,7 +670,7 @@ void Wmf::add_clips(PWMF_CALLBACK_DATA d, const char *clippath, unsigned int log SVGOStringStream tmp_clippath; tmp_clippath << "\ndc[d->level].clip_id << "\""; + tmp_clippath << "\n\tid=\"clipWmfPath" << d->dc[d->level].clip_id << "\""; tmp_clippath << " >"; tmp_clippath << "\n\tdc[d->level].clip_id) - tmp_style << "\n\tclip-path=\"url(#clipEmfPath" << d->dc[d->level].clip_id << ")\" "; + tmp_style << "\n\tclip-path=\"url(#clipWmfPath" << d->dc[d->level].clip_id << ")\" "; d->outsvg += tmp_style.str().c_str(); } @@ -1688,11 +1688,19 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK // next record is valid type and forces pending text to be drawn immediately if ((d->dc[d->level].dirty & DIRTY_TEXT) || ((wmr_mask != U_WMR_INVALID) && (wmr_mask & U_DRAW_TEXT) && d->tri->dirty)){ TR_layout_analyze(d->tri); + if (d->dc[d->level].clip_id){ + SVGOStringStream tmp_clip; + tmp_clip << "\ndc[d->level].clip_id << ")\"\n>"; + d->outsvg += tmp_clip.str().c_str(); + } TR_layout_2_svg(d->tri); SVGOStringStream ts; ts << d->tri->out; d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); + if (d->dc[d->level].clip_id){ + d->outsvg += "\n\n"; + } } if(d->dc[d->level].dirty){ //Apply the delayed background changes, clear the flag d->dc[d->level].bkMode = tbkMode; @@ -2590,11 +2598,19 @@ std::cout << "BEFORE DRAW" status = trinfo_load_textrec(d->tri, &tsp, tsp.ori,TR_EMFBOT); // ori is actually escapement if(status==-1){ // change of escapement, emit what we have and reset TR_layout_analyze(d->tri); + if (d->dc[d->level].clip_id){ + SVGOStringStream tmp_clip; + tmp_clip << "\ndc[d->level].clip_id << ")\"\n>"; + d->outsvg += tmp_clip.str().c_str(); + } TR_layout_2_svg(d->tri); ts << d->tri->out; d->outsvg += ts.str().c_str(); d->tri = trinfo_clear(d->tri); (void) trinfo_load_textrec(d->tri, &tsp, tsp.ori,TR_EMFBOT); // ignore return status, it must work + if (d->dc[d->level].clip_id){ + d->outsvg += "\n\n"; + } } g_free(escaped_text); @@ -3071,7 +3087,7 @@ Wmf::open( Inkscape::Extension::Input * /*mod*/, const gchar *uri ) (void) myMetaFileProc(contents,length, &d); free(contents); -// std::cout << "SVG Output: " << std::endl << *(d.outsvg) << std::endl; +// std::cout << "SVG Output: " << std::endl << d.outsvg << std::endl; SPDocument *doc = SPDocument::createNewDocFromMem(d.outsvg.c_str(), strlen(d.outsvg.c_str()), TRUE); -- cgit v1.2.3 From f29837e4e28f859bd83c8002453e4dd8b82ef08f Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 28 Jul 2014 15:08:20 -0400 Subject: Fix placement news and calls to destructor. Fixes crash regressions #1348891, #1344217, #1333445, and stubborn Windows bug #956225 (possibly more). Fixed bugs: - https://launchpad.net/bugs/1348891 - https://launchpad.net/bugs/1344217 - https://launchpad.net/bugs/1333445 - https://launchpad.net/bugs/956225 (bzr r13474) --- src/sp-offset.cpp | 5 ----- src/style.cpp | 11 ----------- 2 files changed, 16 deletions(-) (limited to 'src') diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp index c6a4b730d..3aa1e4eb6 100644 --- a/src/sp-offset.cpp +++ b/src/sp-offset.cpp @@ -107,11 +107,6 @@ SPOffset::SPOffset() : SPShape() { this->sourceRepr = NULL; this->sourceObject = NULL; - new (&this->_modified_connection) sigc::connection(); - new (&this->_delete_connection) sigc::connection(); - new (&this->_changed_connection) sigc::connection(); - new (&this->_transformed_connection) sigc::connection(); - // set up the uri reference this->sourceRef = new SPUseReference(this); this->_changed_connection = this->sourceRef->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_offset_href_changed), this)); diff --git a/src/style.cpp b/src/style.cpp index c6a98e7f4..222155a0c 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -227,11 +227,6 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : document = document_in; } - new (&release_connection) sigc::connection(); - new (&filter_modified_connection) sigc::connection(); - new (&fill_ps_modified_connection) sigc::connection(); - new (&stroke_ps_modified_connection) sigc::connection(); - // 'font' shorthand requires access to included properties. font.setStylePointer( this ); @@ -431,7 +426,6 @@ SPStyle::~SPStyle() { // Remove connections release_connection.disconnect(); - release_connection.~connection(); // The following shoud be moved into SPIPaint and SPIFilter if (fill.value.href) { @@ -446,12 +440,7 @@ SPStyle::~SPStyle() { filter_modified_connection.disconnect(); } - filter_modified_connection.~connection(); - fill_ps_modified_connection.~connection(); - stroke_ps_modified_connection.~connection(); - _properties.clear(); - //_propmap.clear(); // std::cout << "SPStyle::~SPstyle(): Exit\n" << std::endl; } -- cgit v1.2.3 From 653be18705548ae8ab5a0358ecf77feca1b22e54 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Jul 2014 21:34:56 +0200 Subject: noop: remove commented-out code that is dangerous and should not come back (bzr r13475) --- src/sp-flowregion.cpp | 3 --- src/sp-gradient.cpp | 2 -- src/sp-item-group.cpp | 2 -- src/sp-item.cpp | 4 ---- src/sp-string.cpp | 1 - src/sp-text.cpp | 5 ----- src/sp-tref.cpp | 7 ------- src/sp-tspan.cpp | 2 -- 8 files changed, 26 deletions(-) (limited to 'src') diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index e8e5c3d95..32d3b0f60 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -42,15 +42,12 @@ static void GetDest(SPObject* child,Shape **computed); SPFlowregion::SPFlowregion() : SPItem() { - //new (&this->computed) std::vector; } SPFlowregion::~SPFlowregion() { for (std::vector::iterator it = this->computed.begin() ; it != this->computed.end() ; ++it) { delete *it; } - - //this->computed.~vector(); } void SPFlowregion::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) { diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 1479acd69..70c54451a 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -262,8 +262,6 @@ SPGradient::SPGradient() : SPPaintServer(), units(), this->vector.built = false; this->vector.stops.clear(); - - //new (&this->modified_connection) sigc::connection(); } SPGradient::~SPGradient() { diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 7af4e3320..657aca692 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -70,11 +70,9 @@ namespace { SPGroup::SPGroup() : SPLPEItem() { this->_layer_mode = SPGroup::GROUP; - //new (&this->_display_modes) std::map(); } SPGroup::~SPGroup() { - //this->_display_modes.~map(); } void SPGroup::build(SPDocument *document, Inkscape::XML::Node *repr) { diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 0cdff6546..a3f1a5d64 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -118,10 +118,6 @@ SPItem::SPItem() : SPObject() { mask_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(mask_ref_changed), this)); avoidRef = new SPAvoidRef(this); - - //new (&constraints) std::vector(); - - //new (&_transformed_signal) sigc::signal(); } SPItem::~SPItem() { diff --git a/src/sp-string.cpp b/src/sp-string.cpp index 08755a5fc..e9dfc168b 100644 --- a/src/sp-string.cpp +++ b/src/sp-string.cpp @@ -47,7 +47,6 @@ namespace { #####################################################*/ SPString::SPString() : SPObject() { - //new (&this->string) Glib::ustring(); } SPString::~SPString() { diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 9a7f0b7a0..ccc5adf59 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -70,8 +70,6 @@ namespace { # SPTEXT #####################################################*/ SPText::SPText() : SPItem() { - //new (&this->layout) Inkscape::Text::Layout; - //new (&this->attributes) TextTagAttributes; } SPText::~SPText() { @@ -90,9 +88,6 @@ void SPText::build(SPDocument *doc, Inkscape::XML::Node *repr) { } void SPText::release() { - //this->attributes.~TextTagAttributes(); - //this->layout.~Layout(); - SPItem::release(); } diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index edbb9faa7..0f6eb106f 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -64,12 +64,8 @@ static void sp_tref_delete_self(SPObject *deleted, SPTRef *self); SPTRef::SPTRef() : SPItem() { this->stringChild = NULL; - //new (&this->attributes) TextTagAttributes; - this->href = NULL; this->uriOriginalRef = new SPTRefReference(this); - //new (&this->_delete_connection) sigc::connection(); - //new (&this->_changed_connection) sigc::connection(); this->_changed_connection = this->uriOriginalRef->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_tref_href_changed), this)); @@ -77,9 +73,6 @@ SPTRef::SPTRef() : SPItem() { SPTRef::~SPTRef() { delete this->uriOriginalRef; - - //this->_delete_connection.~connection(); - //this->_changed_connection.~connection(); } void SPTRef::build(SPDocument *document, Inkscape::XML::Node *repr) { diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 8c4105777..58a4da75c 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -227,8 +227,6 @@ const char* SPTSpan::displayName() const { void refresh_textpath_source(SPTextPath* offset); SPTextPath::SPTextPath() : SPItem() { - //new (&this->attributes) TextTagAttributes; - this->startOffset._set = false; this->originalPath = NULL; this->isUpdating=false; -- cgit v1.2.3 From 5a7378908bff31485572833da4db1185eac5ae55 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Jul 2014 21:36:45 +0200 Subject: noop: remove commented-out code that is dangerous and should not come back (bzr r13476) --- src/sp-flowtext.cpp | 2 -- src/sp-tspan.cpp | 3 --- 2 files changed, 5 deletions(-) (limited to 'src') diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index 59832a2b4..7de65ccc3 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -46,11 +46,9 @@ namespace { SPFlowtext::SPFlowtext() : SPItem() { this->par_indent = 0; - //new (&this->layout) Inkscape::Text::Layout(); } SPFlowtext::~SPFlowtext() { - //this->layout.~Layout(); } void SPFlowtext::child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref) { diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 58a4da75c..c3f7689e7 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -63,7 +63,6 @@ namespace { #####################################################*/ SPTSpan::SPTSpan() : SPItem() { this->role = SP_TSPAN_ROLE_UNSPECIFIED; - //new (&this->attributes) TextTagAttributes; } SPTSpan::~SPTSpan() { @@ -81,8 +80,6 @@ void SPTSpan::build(SPDocument *doc, Inkscape::XML::Node *repr) { } void SPTSpan::release() { - //this->attributes.~TextTagAttributes(); - SPItem::release(); } -- cgit v1.2.3 From 9fb31e5a547d84fd087fc74ffeae6950e9441326 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Jul 2014 21:42:08 +0200 Subject: related to lp:inkscape r13474, remove unnecessary/broken placement news (bzr r13477) --- src/sp-shape.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index 61d35e6ff..de9103dee 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -57,8 +57,6 @@ static void sp_shape_update_marker_view (SPShape *shape, Inkscape::DrawingItem * SPShape::SPShape() : SPLPEItem() { for ( int i = 0 ; i < SP_MARKER_LOC_QTY ; i++ ) { - new (&this->_release_connect[i]) sigc::connection(); - new (&this->_modified_connect[i]) sigc::connection(); this->_marker[i] = NULL; } -- cgit v1.2.3 From c263637743407a181ac2f12226727553bda6cb37 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 28 Jul 2014 17:25:41 -0400 Subject: Fix for copy&paste clone original with clip-path/mask Fixed bugs: - https://launchpad.net/bugs/1293979 (bzr r13478) --- src/ui/clipboard.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 8e2502545..1209b19cd 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -601,6 +601,12 @@ Glib::ustring ClipboardManagerImpl::getPathParameter(SPDesktop* desktop) */ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) { + // https://bugs.launchpad.net/inkscape/+bug/1293979 + // basically, when we do a depth-first search, we're stopping + // at the first object to be or . + // but that could then return the id of the object's + // clip path or mask, not the original path! + SPDocument *tempdoc = _retrieveClipboard(); // any target will do here if ( tempdoc == NULL ) { _userWarn(desktop, _("Nothing on the clipboard.")); @@ -608,6 +614,9 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) } Inkscape::XML::Node *root = tempdoc->getReprRoot(); + // 1293979: strip out the defs of the document + root->removeChild(tempdoc->getDefs()->getRepr()); + Inkscape::XML::Node *repr = sp_repr_lookup_name(root, "svg:path", -1); // unlimited search depth if ( repr == NULL ) { repr = sp_repr_lookup_name(root, "svg:text", -1); -- cgit v1.2.3 From ae3b6608ecb46d6a71f6de95768aa0ed72e2dc08 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 28 Jul 2014 17:30:16 -0400 Subject: Don't update path effects on document load (#1299948) Fixed bugs: - https://launchpad.net/bugs/1299948 (bzr r13479) --- src/live_effects/parameter/path.cpp | 5 +++++ src/sp-path.cpp | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index cdbbef1db..44d414942 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -118,6 +118,11 @@ PathParam::param_readSVGValue(const gchar * strvalue) // Now do the attaching, which emits the changed signal. try { ref.attach(Inkscape::URI(href)); + //lp:1299948 + SPItem* i = ref.getObject(); + if (i) { + linked_modified_callback(i, SP_OBJECT_MODIFIED_FLAG); + } // else: document still processing new events. Repr of the linked object not created yet. } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); ref.detach(); diff --git a/src/sp-path.cpp b/src/sp-path.cpp index cbb61b0f6..5bb7bf548 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -140,7 +140,21 @@ void SPPath::build(SPDocument *document, Inkscape::XML::Node *repr) { SPShape::build(document, repr); - this->readAttr( "inkscape:original-d" ); + // this->readAttr( "inkscape:original-d" ); // lp1299948 + if ((gchar const* s = this->getRepr()->attribute("inkscape:original-d"))) + { + // write it to XML, and to my curve, but don't update patheffects + Geom::PathVector pv = sp_svg_read_pathv(s); + SPCurve *curve = new SPCurve(pv); + + if (_curve_before_lpe) { + _curve_before_lpe = _curve_before_lpe->unref(); + } + + if (curve) { + _curve_before_lpe = curve->ref(); + } + } this->readAttr( "d" ); /* d is a required attribute */ @@ -314,7 +328,6 @@ g_message("sp_path_update_patheffect"); #ifdef PATH_VERBOSE g_message("sp_path_update_patheffect writes 'd' attribute"); #endif - if (_curve) { gchar *str = sp_svg_write_path(this->_curve->get_pathvector()); repr->setAttribute("d", str); -- cgit v1.2.3 From 03e8e4c2d075e2d6bfdf44c461b810b0e8b68456 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Jul 2014 23:44:54 +0200 Subject: fix build. gcc 4.6.1 does not like double parens here :/ (bzr r13480) --- src/sp-path.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 5bb7bf548..5c076b7cb 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -141,7 +141,7 @@ void SPPath::build(SPDocument *document, Inkscape::XML::Node *repr) { SPShape::build(document, repr); // this->readAttr( "inkscape:original-d" ); // lp1299948 - if ((gchar const* s = this->getRepr()->attribute("inkscape:original-d"))) + if (gchar const* s = this->getRepr()->attribute("inkscape:original-d")) { // write it to XML, and to my curve, but don't update patheffects Geom::PathVector pv = sp_svg_read_pathv(s); -- cgit v1.2.3 From 553293740817862cb756c770f6bee01dd00089bf Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 28 Jul 2014 23:48:41 +0200 Subject: fix crash bug (reported by su_v on IRC) related to removing color profiles (bzr r13481) --- src/ui/dialog/document-properties.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 2674efc1e..9141b2268 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -596,6 +596,7 @@ void DocumentProperties::removeSelectedProfile(){ //XML Tree being used directly here while it shouldn't be. sp_repr_unparent(obj->getRepr()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_COLOR_PROFILE, _("Remove linked color profile")); + break; // removing the color profile likely invalidates part of the traversed list, stop traversing here. } current = g_slist_next(current); } -- cgit v1.2.3 From 6934b8ce1b39c6d3533fa3da86aa32cac5282056 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 28 Jul 2014 21:47:11 -0400 Subject: Fix for 1346972 (freehand shape mode should pick stroke width from tool's active style) Fixed bugs: - https://launchpad.net/bugs/1346972 (bzr r13482) --- src/ui/tools/freehand-base.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 288a200f4..a90a23a3e 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -225,6 +225,31 @@ static void spdc_apply_powerstroke_shape(const std::vector & points Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); static_cast(lpe)->offset_points.param_set_and_write_new_value(points); + // find out stroke width (TODO: is there an easier way??) + SPDesktop *desktop = dc->desktop; + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); + Inkscape::GC::release(repr); + + char const* tool = SP_IS_PEN_CONTEXT(dc) ? "/tools/freehand/pen" : "/tools/freehand/pencil"; + + // apply the tool's current style + sp_desktop_apply_style_tool(desktop, repr, tool, false); + + double stroke_width = 1.0; + char const *style_str = NULL; + style_str = repr->attribute("style"); + if (style_str) { + SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT); + sp_style_merge_from_style_string(style, style_str); + stroke_width = style->stroke_width.computed; + style->stroke_width.computed = 0; + sp_style_unref(style); + } + + char * width_str = new char[50]; + sprintf(width_str, "0,%f", stroke_width / 2.); + // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); lpe->getRepr()->setAttribute("end_linecap_type", "zerowidth"); @@ -232,6 +257,9 @@ static void spdc_apply_powerstroke_shape(const std::vector & points lpe->getRepr()->setAttribute("sort_points", "true"); lpe->getRepr()->setAttribute("interpolator_type", "CubicBezierJohan"); lpe->getRepr()->setAttribute("interpolator_beta", "0.2"); + lpe->getRepr()->setAttribute("offset_points", width_str); + + delete [] width_str; } static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, SPCurve *curve) -- cgit v1.2.3 From 61efb08544085d06a84067707c9ce0e79760965b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 29 Jul 2014 16:54:43 -0400 Subject: Refactor some disgusting code (bzr r13341.1.105) --- src/connection-pool.h | 128 ++++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/connection-pool.h b/src/connection-pool.h index b1ac6f07a..4637a3cc1 100644 --- a/src/connection-pool.h +++ b/src/connection-pool.h @@ -1,84 +1,100 @@ +/* + * Author: + * mderezynski + * + * Copyright (C) 2006 Author + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + #ifndef CONNECTION_POOL_H #define CONNECTION_POOL_H -#include #include -#include -#include #include -namespace Inkscape -{ -class ConnectionPool -{ - public: +#include +#include +#include +#include + +namespace Inkscape { + +/** + * @class ConnectionPool + * an auxilliary class to manage sigc::connections as if the referred object + * were a GObject; in that way, the class that holds a ConnectionPool does not + * need to also hold several sigc::connection objects + */ +class ConnectionPool { +public: + typedef std::map ConnectionMap; - enum Exception - { - NAME_EXISTS, - NAME_DOES_NOT_EXIST + struct NameExistsException : public std::exception { + virtual const char* what() const throw() { return "Inkscape::ConnectionPool: name exists"; } + }; + struct NameDoesNotExistException : public std::exception { + virtual const char* what() const throw() { return "Inkscape::ConnectionPool: name doesn't exist"; } }; - typedef std::map ConnectionMap; - - virtual ~ConnectionPool () - { - for (ConnectionMap::iterator iter = map.begin (), end = map.end (); iter != end; ++iter) { - sigc::connection* connection = (*iter).second; - connection->disconnect (); - delete connection; + void add_connection(std::string name, sigc::connection* connection) { + if (_map.find(name) != _map.end()) { + throw NameExistsException(); } + _map.insert(std::make_pair(name, connection)); } - void - add_connection (std::string name, sigc::connection* connection) - { - if (map.find (name) != map.end ()) throw NAME_EXISTS; - map.insert (std::make_pair (name, connection)); - } - - void - del_connection (std::string name) - { - ConnectionMap::iterator iter = map.find (name); - if (iter == map.end ()) throw NAME_DOES_NOT_EXIST; - sigc::connection* connection = (*iter).second; - connection->disconnect (); - delete connection; + void del_connection(std::string name) { + ConnectionMap::iterator iter = _map.find(name); + if (iter == _map.end()) { + throw NameDoesNotExistException(); + } + sigc::connection* connection = (*iter).second; + connection->disconnect(); + delete connection; } - static Inkscape::ConnectionPool* - new_connection_pool (std::string name) - { - return new ConnectionPool (name); + static Inkscape::ConnectionPool* new_connection_pool(std::string name) { + return new ConnectionPool(name); } - static void - del_connection_pool (Inkscape::ConnectionPool* pool) - { - delete pool; + static void del_connection_pool(ConnectionPool* pool) { + delete pool; } - static void - connect_destroy (GObject *obj, Inkscape::ConnectionPool *pool) - { - g_object_connect (obj, "swapped-signal::destroy", G_CALLBACK (del_connection_pool), pool, NULL); + static void connect_destroy(GObject *obj, ConnectionPool *pool) { + g_object_connect (obj, "swapped-signal::destroy", G_CALLBACK(del_connection_pool), pool, NULL); } - operator std::string () - { - return name; + operator std::string() { + return _name; } - private: - - ConnectionPool (std::string name) : name (name) - {} +private: + ConnectionPool(std::string name) : _name(name) {} + virtual ~ConnectionPool() { + for (ConnectionMap::iterator iter = _map.begin(), end = _map.end(); iter != end; ++iter) { + sigc::connection* connection = (*iter).second; + connection->disconnect(); + delete connection; + } + } - ConnectionMap map; - std::string name; + ConnectionMap _map; + std::string _name; }; } #endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : -- cgit v1.2.3 From bb7b71e3af74c4270b4f67210660e33c39386f07 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 30 Jul 2014 02:13:11 +0200 Subject: Added roughen LPE (bzr r13341.1.106) --- src/live_effects/CMakeLists.txt | 2 + src/live_effects/Makefile_insert | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 5 + src/live_effects/lpe-roughen.cpp | 389 +++++++++++++++++++++++++++++++++++++++ src/live_effects/lpe-roughen.h | 57 ++++++ 6 files changed, 456 insertions(+) create mode 100644 src/live_effects/lpe-roughen.cpp create mode 100644 src/live_effects/lpe-roughen.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index a4d35b339..3c64e5c8e 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -35,6 +35,7 @@ set(live_effects_SRC # lpe-skeleton.cpp lpe-sketch.cpp lpe-spiro.cpp + lpe-roughen.cpp lpe-tangent_to_curve.cpp lpe-test-doEffect-stack.cpp lpe-bspline.cpp @@ -101,6 +102,7 @@ set(live_effects_SRC lpe-skeleton.h lpe-sketch.h lpe-spiro.h + lpe-roughen.h lpe-tangent_to_curve.h lpe-test-doEffect-stack.h lpe-bspline.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 263b33b3c..91651a7c8 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -46,6 +46,8 @@ ink_common_sources += \ live_effects/lpe-lattice.h \ live_effects/lpe-lattice2.cpp \ live_effects/lpe-lattice2.h \ + live_effects/lpe-roughen.cpp \ + live_effects/lpe-roughen.h \ live_effects/lpe-simplify.cpp \ live_effects/lpe-simplify.h \ live_effects/lpe-envelope.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 942ef5891..dac44981c 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -29,6 +29,7 @@ enum EffectType { SPIRO, LATTICE, LATTICE2, + ROUGHEN, SIMPLIFY, ENVELOPE, CONSTRUCT_GRID, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index f0611785b..387dd7b8d 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -27,6 +27,7 @@ #include "live_effects/lpe-spiro.h" #include "live_effects/lpe-lattice.h" #include "live_effects/lpe-lattice2.h" +#include "live_effects/lpe-roughen.h" #include "live_effects/lpe-simplify.h" #include "live_effects/lpe-envelope.h" #include "live_effects/lpe-constructgrid.h" @@ -125,6 +126,7 @@ const Util::EnumData LPETypeData[] = { /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, + {ROUGHEN, N_("Roughen"), "roughen"}, {BSPLINE, N_("BSpline"), "bspline"}, {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, @@ -269,6 +271,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case FILLET_CHAMFER: neweffect = static_cast ( new LPEFilletChamfer(lpeobj) ); break; + case ROUGHEN: + neweffect = static_cast ( new LPERoughen(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp new file mode 100644 index 000000000..803ab5844 --- /dev/null +++ b/src/live_effects/lpe-roughen.cpp @@ -0,0 +1,389 @@ +#define INKSCAPE_LPE_ROUGHEN_C +/* + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-roughen.h" +#include "display/curve.h" +#include "live_effects/parameter/parameter.h" +#include "helper/geom.h" +#include +#include +#include + +namespace Inkscape { +namespace LivePathEffect { + +static const Util::EnumData DivisionMethodData[DM_END] = { + { DM_SEGMENTS, N_("By number of segments"), "segments" }, + { DM_SIZE, N_("By max. segment size"), "size" } +}; +static const Util::EnumDataConverter + DMConverter(DivisionMethodData, DM_END); + +LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + // initialise your parameters here: + unit(_("Unit:"), _("Unit"), "unit", &wr, this), + method(_("Method:"), _("Division method"), "method", DMConverter, &wr, + this, DM_SEGMENTS), + maxSegmentSize(_("Max. segment size:"), _("Max. segment size"), + "maxSegmentSize", &wr, this, 10.), + segments(_("Number of segments:"), _("Number of segments"), "segments", + &wr, this, 2), + displaceX(_("Max. displacement in X:"), _("Max. displacement in X"), + "displaceX", &wr, this, 10.), + displaceY(_("Max. displacement in Y:"), _("Max. displacement in Y"), + "displaceY", &wr, this, 10.), + shiftNodes(_("Shift nodes"), _("Shift nodes"), "shiftNodes", &wr, this, + true), + shiftNodeHandles(_("Shift node handles"), _("Shift node handles"), + "shiftNodeHandles", &wr, this, true) { + registerParameter(dynamic_cast(&unit)); + registerParameter(dynamic_cast(&method)); + registerParameter(dynamic_cast(&maxSegmentSize)); + registerParameter(dynamic_cast(&segments)); + registerParameter(dynamic_cast(&displaceX)); + registerParameter(dynamic_cast(&displaceY)); + registerParameter(dynamic_cast(&shiftNodes)); + registerParameter(dynamic_cast(&shiftNodeHandles)); + displaceX.param_set_range(0., Geom::infinity()); + displaceY.param_set_range(0., Geom::infinity()); + maxSegmentSize.param_set_range(0., Geom::infinity()); + maxSegmentSize.param_set_increments(1, 1); + maxSegmentSize.param_set_digits(1); + segments.param_set_range(1, Geom::infinity()); + segments.param_set_increments(1, 1); + segments.param_set_digits(0); +} + +LPERoughen::~LPERoughen() {} + +void LPERoughen::doBeforeEffect(SPLPEItem const */*lpeitem*/) { + displaceX.resetRandomizer(); + displaceY.resetRandomizer(); + srand(1); +} + +Gtk::Widget *LPERoughen::newWidget() { + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + vbox->set_border_width(5); + vbox->set_homogeneous(false); + vbox->set_spacing(2); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "unit") { + Gtk::Label *unitLabel = Gtk::manage(new Gtk::Label( + Glib::ustring(_("Roughen unit")), Gtk::ALIGN_START)); + unitLabel->set_use_markup(true); + vbox->pack_start(*unitLabel, false, false, 2); + vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), + Gtk::PACK_EXPAND_WIDGET); + } + if (param->param_key == "method") { + Gtk::Label *methodLabel = Gtk::manage(new Gtk::Label( + Glib::ustring(_("Add nodes Subdivide each segment")), + Gtk::ALIGN_START)); + methodLabel->set_use_markup(true); + vbox->pack_start(*methodLabel, false, false, 2); + vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), + Gtk::PACK_EXPAND_WIDGET); + } + if (param->param_key == "displaceX") { + Gtk::Label *displaceXLabel = Gtk::manage(new Gtk::Label( + Glib::ustring(_("Jitter nodes Move nodes/handles")), + Gtk::ALIGN_START)); + displaceXLabel->set_use_markup(true); + vbox->pack_start(*displaceXLabel, false, false, 2); + vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), + Gtk::PACK_EXPAND_WIDGET); + } + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + +double LPERoughen::sign(double randNumber) { + if (rand() % 100 < 49) { + randNumber *= -1.; + } + return randNumber; +} + +Geom::Point LPERoughen::randomize() { + double displaceXParsed = Inkscape::Util::Quantity::convert( + displaceX, unit.get_abbreviation(), "px"); + double displaceYParsed = Inkscape::Util::Quantity::convert( + displaceY, unit.get_abbreviation(), "px"); + //maybe is better divide this point by 2... + Geom::Point output = + Geom::Point(sign(displaceXParsed), sign(displaceYParsed)); + return output; +} + +void LPERoughen::doEffect(SPCurve *curve) { + Geom::PathVector const original_pathv = + pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); + curve->reset(); + + //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... + if (path_it->empty()) + continue; + //Itreadores + + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = + ++(path_it->begin()); // outgoing 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 + //dichos manejadores + SPCurve *nCurve = new SPCurve(); + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = + path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + //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 + Geom::Point initialMove(0, 0); + if (shiftNodes) { + initialMove = randomize(); + } + Geom::Point initialPoint = curve_it1->initialPoint() + initialMove; + nCurve->moveto(initialPoint); + Geom::Point A0(0, 0); + Geom::Point A1(0, 0); + Geom::Point A2(0, 0); + Geom::Point A3(0, 0); + while (curve_it2 != curve_endit) { + //aumentamos los valores para el siguiente paso en el bucle + //Recorremos todos los segmentos menos el último + Geom::CubicBezier const *cubic = NULL; + A0 = curve_it1->initialPoint(); + A1 = curve_it1->initialPoint(); + A2 = curve_it1->finalPoint(); + A3 = curve_it1->finalPoint(); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + A1 = (*cubic)[1]; + if (shiftNodes) { + A1 = (*cubic)[1] + initialMove; + } + A2 = (*cubic)[2]; + nCurve->curveto(A1, A2, A3); + } else { + nCurve->lineto(A3); + } + double length = Inkscape::Util::Quantity::convert( + curve_it1->length(0.001), "px", unit.get_abbreviation()); + unsigned int splits = 0; + if (method == DM_SEGMENTS) { + splits = segments; + } else { + splits = ceil(length / maxSegmentSize); + } + for (unsigned int t = splits; t >= 1; t--) { + if (t == 1 && splits != 1) { + continue; + } + const SPCurve *tmp; + if (splits == 1) { + tmp = jitter(nCurve->last_segment()); + } else { + tmp = addNodesAndJitter(nCurve->last_segment(), 1. / t); + } + if (nCurve->get_segment_count() > 1) { + nCurve->backspace(); + nCurve->append_continuous(tmp, 0.001); + } else { + nCurve = tmp->copy(); + } + delete tmp; + } + ++curve_it1; + ++curve_it2; + } + Geom::CubicBezier const *cubic = NULL; + A0 = curve_it1->initialPoint(); + A1 = curve_it1->initialPoint(); + A2 = curve_it1->finalPoint(); + A3 = curve_it1->finalPoint(); + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + A1 = (*cubic)[1]; + A2 = (*cubic)[2]; + if (path_it->closed()) { + A2 = A2 + initialMove; + A3 = initialPoint; + } + nCurve->curveto(A1, A2, A3); + } else { + if (path_it->closed()) { + A3 = initialPoint; + } + nCurve->lineto(A3); + } + double length = Inkscape::Util::Quantity::convert( + curve_it1->length(0.001), "px", unit.get_abbreviation()); + unsigned int splits = 0; + if (method == DM_SEGMENTS) { + splits = segments; + } else { + splits = ceil(length / maxSegmentSize); + } + for (unsigned int t = splits; t >= 1; t--) { + if (t == 1 && splits != 1) { + continue; + } + const SPCurve *tmp; + if (splits == 1) { + tmp = jitter(nCurve->last_segment()); + } else { + tmp = addNodesAndJitter(nCurve->last_segment(), 1. / t); + } + if (nCurve->get_segment_count() > 1) { + nCurve->backspace(); + nCurve->append_continuous(tmp, 0.001); + } else { + nCurve = tmp->copy(); + } + delete tmp; + } + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); + } + curve->append(nCurve, false); + nCurve->reset(); + delete nCurve; + } +} + +SPCurve *LPERoughen::addNodesAndJitter(const Geom::Curve *A, double t) { + SPCurve *out = new SPCurve(); + Geom::CubicBezier const *cubic = dynamic_cast(&*A); + Geom::Point A1(0, 0); + Geom::Point A2(0, 0); + Geom::Point A3(0, 0); + Geom::Point B1(0, 0); + Geom::Point B2(0, 0); + Geom::Point B3(0, 0); + if (shiftNodes) { + A3 = randomize(); + B3 = randomize(); + } + if (shiftNodeHandles) { + A1 = randomize(); + A2 = randomize(); + B1 = randomize(); + B2 = randomize(); + } else { + A2 = A3; + B1 = A3; + B2 = B3; + } + if (cubic) { + std::pair div = cubic->subdivide(t); + std::vector seg1 = div.first.points(), + seg2 = div.second.points(); + out->moveto(seg1[0]); + out->curveto(seg1[1] + A1, seg1[2] + A2, seg1[3] + A3); + out->curveto(seg2[1] + B1, seg2[2], seg2[3]); + } else if (shiftNodeHandles) { + out->moveto(A->initialPoint()); + out->curveto(A->pointAt(t / 3) + A1, A->pointAt((t / 3) * 2) + A2, + A->pointAt(t) + A3); + out->curveto(A->pointAt(t + (t / 3)) + B1, A->pointAt(t + ((t / 3) * 2)), + A->finalPoint()); + } else { + out->moveto(A->initialPoint()); + out->lineto(A->pointAt(t) + A3); + out->lineto(A->finalPoint()); + } + return out; +} + +SPCurve *LPERoughen::jitter(const Geom::Curve *A) { + SPCurve *out = new SPCurve(); + Geom::CubicBezier const *cubic = dynamic_cast(&*A); + Geom::Point A1(0, 0); + Geom::Point A2(0, 0); + Geom::Point A3(0, 0); + if (shiftNodes) { + A3 = randomize(); + } + if (shiftNodeHandles) { + A1 = randomize(); + A2 = randomize(); + } else { + A2 = A3; + } + if (cubic) { + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1] + A1, (*cubic)[2] + A2, (*cubic)[3] + A3); + } else if (shiftNodeHandles) { + out->moveto(A->initialPoint()); + out->curveto(A->pointAt(0.3333) + A1, A->pointAt(0.6666) + A2, + A->finalPoint() + A3); + } else { + out->moveto(A->initialPoint()); + out->lineto(A->finalPoint() + A3); + } + return out; +} + +Geom::Point LPERoughen::tpoint(Geom::Point A, Geom::Point B, double t) { + using Geom::X; + using Geom::Y; + return Geom::Point(A[X] + t * (B[X] - A[X]), A[Y] + t * (B[Y] - A[Y])); +} + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h new file mode 100644 index 000000000..cc7784dc0 --- /dev/null +++ b/src/live_effects/lpe-roughen.h @@ -0,0 +1,57 @@ +#ifndef INKSCAPE_LPE_ROUGHEN_H +#define INKSCAPE_LPE_ROUGHEN_H + +/* + * Inkscape::LPERoughen + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "live_effects/parameter/enum.h" +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/path.h" +#include "live_effects/parameter/bool.h" +#include "live_effects/parameter/unit.h" +#include "live_effects/parameter/random.h" + +namespace Inkscape { +namespace LivePathEffect { + +enum DivisionMethod { + DM_SEGMENTS, + DM_SIZE, + DM_END +}; + +class LPERoughen : public Effect { + +public: + LPERoughen(LivePathEffectObject *lpeobject); + virtual ~LPERoughen(); + + virtual void doEffect(SPCurve *curve); + virtual double sign(double randNumber); + virtual Geom::Point randomize(); + virtual void doBeforeEffect(SPLPEItem const */*lpeitem*/); + virtual SPCurve *addNodesAndJitter(const Geom::Curve *A, double t); + virtual SPCurve *jitter(const Geom::Curve *A); + virtual Geom::Point tpoint(Geom::Point A, Geom::Point B, double t = 0.5); + virtual Gtk::Widget *newWidget(); + +private: + UnitParam unit; + EnumParam method; + ScalarParam maxSegmentSize; + ScalarParam segments; + RandomParam displaceX; + RandomParam displaceY; + BoolParam shiftNodes; + BoolParam shiftNodeHandles; + LPERoughen(const LPERoughen &); + LPERoughen &operator=(const LPERoughen &); + +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape +#endif -- cgit v1.2.3 From 6303e158736b41c75bf93afc0f07a27c4a41ae8e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 30 Jul 2014 02:22:33 +0200 Subject: Fix a bug pointed by LiamW (bzr r13341.1.107) --- src/live_effects/lpe-roughen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 803ab5844..9af849530 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -1,14 +1,14 @@ -#define INKSCAPE_LPE_ROUGHEN_C /* * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "live_effects/lpe-roughen.h" #include "display/curve.h" #include "live_effects/parameter/parameter.h" #include "helper/geom.h" #include -#include #include namespace Inkscape { -- cgit v1.2.3 From 702d7523e258cb18802dfedeef642589e99e89f0 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 30 Jul 2014 02:26:30 +0200 Subject: add last applied branch - mode to strokes on pen/pencil (bzr r13341.1.108) --- src/ui/tools/freehand-base.cpp | 45 ++++++++++++++++++++++++++++++++++++------ src/widgets/pencil-toolbar.cpp | 1 + 2 files changed, 40 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 1c5b7b8e3..86b78c953 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -44,6 +44,8 @@ #include "live_effects/lpe-powerstroke.h" #include "style.h" #include "ui/control-manager.h" +// clipboard support +#include "ui/clipboard.h" #include "ui/tools/freehand-base.h" #include @@ -261,7 +263,13 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } - int shape = prefs->getInt(tool_name(dc) + "/shape", 0); + //Store the clipboard path to apply in the future without the use of clipboard + static Geom::PathVector previous_shape_pathv; + enum shapeType { NONE, TRIANGLE_IN, TRIANGLE_OUT, ELLIPSE, CLIPBOARD, LAST_APPLIED }; + static shapeType previous_shape_type = NONE; + + + shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0); bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); @@ -269,11 +277,18 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 + if(shape == LAST_APPLIED){ + shape = previous_shape_type; + if(shape == CLIPBOARD){ + shape = LAST_APPLIED; + } + } + switch (shape) { - case 0: + case NONE: // don't apply any shape break; - case 1: + case TRIANGLE_IN: { // "triangle in" std::vector points(1); @@ -283,7 +298,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shape_applied = true; break; } - case 2: + case TRIANGLE_OUT: { // "triangle out" guint curve_length = curve->get_segment_count(); @@ -294,7 +309,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shape_applied = true; break; } - case 3: + case ELLIPSE: { // "ellipse" SPCurve *c = new SPCurve(); @@ -307,22 +322,40 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, c->closepath(); spdc_paste_curve_as_freehand_shape(c, dc, item); c->unref(); + shape_applied = true; break; } - case 4: + case CLIPBOARD: { // take shape from clipboard; TODO: catch the case where clipboard is empty Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); static_cast(lpe)->pattern.on_paste_button_click(); + Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); + Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); + previous_shape_pathv = sp_svg_read_pathv(svgd.data()); shape_applied = true; break; } + case LAST_APPLIED: + { + if(previous_shape_pathv.size() != 0){ + SPCurve * c = new SPCurve(); + c->set_pathvector(previous_shape_pathv); + spdc_paste_curve_as_freehand_shape(c, dc, item); + c->unref(); + + shape_applied = true; + } + break; + } default: break; } + previous_shape_type = shape; + if (shape_applied) { // apply original stroke color as fill and unset stroke; then return SPCSSAttr *css = sp_repr_css_attr_new(); diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 772107101..cf09a4d34 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -162,6 +162,7 @@ static GList * freehand_shape_dropdown_items_list() { glist = g_list_append (glist, _("Triangle out")); glist = g_list_append (glist, _("Ellipse")); glist = g_list_append (glist, _("From clipboard")); + glist = g_list_append (glist, _("Last applied")); return glist; } -- cgit v1.2.3 From ebdfe1ab7d7a3b73346885c635e98b2021921010 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 30 Jul 2014 02:36:53 +0200 Subject: Fix a bug pointed by su_v on fillet-chamfer open paths (bzr r13341.1.109) --- src/live_effects/lpe-fillet-chamfer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index eae37ad36..1dffba1bf 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -517,6 +517,8 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) counter - counterCurves, filletChamferData[counter - counterCurves][X]), &intpart); + } else if (!path_it->closed() && curve_it2 == curve_endit){ + time_it2 = 0; } else { time_it2 = modf(fillet_chamfer_values.to_time( counter + 1, filletChamferData[counter + 1][X]), @@ -529,6 +531,8 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) it1_length + fillet_chamfer_values.to_len( counter - counterCurves, filletChamferData[counter - counterCurves][X]); + } else if (!path_it->closed() && curve_it2 == curve_endit){ + resultLenght = 0; } else { resultLenght = it1_length + fillet_chamfer_values.to_len( @@ -607,6 +611,8 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) int type = 0; if(path_it->closed() && curve_it2 == curve_endit){ type = abs(filletChamferData[counter - counterCurves][Y]); + } else if (!path_it->closed() && curve_it2 == curve_endit){ + //0 } else { type = abs(filletChamferData[counter + 1][Y]); } -- cgit v1.2.3 From b7ebc313abd7f6aa501370d58ba54e6169e4218e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 30 Jul 2014 10:31:31 +0200 Subject: Read CSS Text 3 'white-space' property, SVG 2 'width', 'height' attributes. (bzr r13341.1.110) --- src/attributes.cpp | 10 +++-- src/attributes.h | 31 ++++++++++---- src/sp-string.cpp | 119 ++++++++++++++++++++++++++++++++++++++++++----------- src/sp-text.cpp | 30 ++++++++++++++ src/sp-text.h | 6 ++- src/style-enums.h | 17 ++++++++ src/style.cpp | 10 +++++ src/style.h | 40 ++++++++++++------ 8 files changed, 212 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index da7b25f03..3cca90105 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -413,10 +413,6 @@ static SPStyleProp const props[] = { /* Text */ {SP_PROP_TEXT_INDENT, "text-indent"}, {SP_PROP_TEXT_ALIGN, "text-align"}, - {SP_PROP_TEXT_DECORATION, "text-decoration"}, - {SP_PROP_TEXT_DECORATION_LINE, "text-decoration-line"}, - {SP_PROP_TEXT_DECORATION_STYLE,"text-decoration-style"}, - {SP_PROP_TEXT_DECORATION_COLOR,"text-decoration-color"}, {SP_PROP_LINE_HEIGHT, "line-height"}, {SP_PROP_LETTER_SPACING, "letter-spacing"}, {SP_PROP_WORD_SPACING, "word-spacing"}, @@ -433,6 +429,12 @@ static SPStyleProp const props[] = { {SP_PROP_GLYPH_ORIENTATION_VERTICAL, "glyph-orientation-vertical"}, {SP_PROP_KERNING, "kerning"}, {SP_PROP_TEXT_ANCHOR, "text-anchor"}, + {SP_PROP_WHITE_SPACE, "white-space"}, + /* Text Decoration */ + {SP_PROP_TEXT_DECORATION, "text-decoration"}, + {SP_PROP_TEXT_DECORATION_LINE, "text-decoration-line"}, + {SP_PROP_TEXT_DECORATION_STYLE,"text-decoration-style"}, + {SP_PROP_TEXT_DECORATION_COLOR,"text-decoration-color"}, /* Misc */ {SP_PROP_CLIP, "clip"}, {SP_PROP_COLOR, "color"}, diff --git a/src/attributes.h b/src/attributes.h index 82e7ca8a6..47199ac51 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -399,9 +399,11 @@ enum SPAttributeEnum { SP_ATTR_TEXT_EXCLUDE, SP_ATTR_LAYOUT_OPTIONS, - /* CSS2 */ - /* Custom full font name because Font stuff below is inadequate */ + /* CSS & SVG Properties */ + + /* Custom full font name because Font stuff below is inadequate REMOVE ME */ SP_PROP_INKSCAPE_FONT_SPEC, + /* Font */ SP_PROP_FONT, SP_PROP_FONT_FAMILY, @@ -411,18 +413,16 @@ enum SPAttributeEnum { SP_PROP_FONT_STYLE, SP_PROP_FONT_VARIANT, SP_PROP_FONT_WEIGHT, - /* Text */ + + /* Text Layout */ SP_PROP_TEXT_INDENT, SP_PROP_TEXT_ALIGN, - SP_PROP_TEXT_DECORATION, /* SVG 1 underline etc.( no color or style) OR SVG2 with _LINE, _STYLE, _COLOR values */ - SP_PROP_TEXT_DECORATION_LINE, /* SVG 2 underline etc. */ - SP_PROP_TEXT_DECORATION_STYLE, /* SVG 2 proposed solid [SVG 1], dotted, etc.)*/ - SP_PROP_TEXT_DECORATION_COLOR, /* SVG 2 proposed same as text [SVG 1], specified*/ + SP_PROP_LINE_HEIGHT, SP_PROP_LETTER_SPACING, SP_PROP_WORD_SPACING, SP_PROP_TEXT_TRANSFORM, - /* text (css3) */ + SP_PROP_DIRECTION, SP_PROP_BLOCK_PROGRESSION, SP_PROP_WRITING_MODE, @@ -434,6 +434,14 @@ enum SPAttributeEnum { SP_PROP_GLYPH_ORIENTATION_VERTICAL, SP_PROP_KERNING, SP_PROP_TEXT_ANCHOR, + SP_PROP_WHITE_SPACE, + + /* Text Decoration */ + SP_PROP_TEXT_DECORATION, /* SVG 1 underline etc.( no color or style) OR SVG2 with _LINE, _STYLE, _COLOR values */ + SP_PROP_TEXT_DECORATION_LINE, /* SVG 2 underline etc. */ + SP_PROP_TEXT_DECORATION_STYLE, /* SVG 2 proposed solid [SVG 1], dotted, etc.)*/ + SP_PROP_TEXT_DECORATION_COLOR, /* SVG 2 proposed same as text [SVG 1], specified*/ + /* Misc */ SP_PROP_CLIP, SP_PROP_COLOR, @@ -443,24 +451,29 @@ enum SPAttributeEnum { SP_PROP_VISIBILITY, SP_PROP_BLEND_MODE, SP_PROP_ISOLATION, + /* SVG */ /* Clip/Mask */ SP_PROP_CLIP_PATH, SP_PROP_CLIP_RULE, SP_PROP_MASK, SP_PROP_OPACITY, + /* Filter */ SP_PROP_ENABLE_BACKGROUND, SP_PROP_FILTER, SP_PROP_FLOOD_COLOR, SP_PROP_FLOOD_OPACITY, SP_PROP_LIGHTING_COLOR, + /* Gradient */ SP_PROP_STOP_COLOR, SP_PROP_STOP_OPACITY, SP_PROP_STOP_PATH, + /* Interactivity */ SP_PROP_POINTER_EVENTS, + /* Paint */ SP_PROP_COLOR_INTERPOLATION, SP_PROP_COLOR_INTERPOLATION_FILTERS, @@ -487,10 +500,12 @@ enum SPAttributeEnum { SP_PROP_STROKE_OPACITY, SP_PROP_STROKE_WIDTH, SP_PROP_TEXT_RENDERING, + /* Conditional */ SP_PROP_SYSTEM_LANGUAGE, SP_PROP_REQUIRED_FEATURES, SP_PROP_REQUIRED_EXTENSIONS, + /* LivePathEffect */ SP_PROP_PATH_EFFECT, }; diff --git a/src/sp-string.cpp b/src/sp-string.cpp index e9dfc168b..b561187d0 100644 --- a/src/sp-string.cpp +++ b/src/sp-string.cpp @@ -30,10 +30,14 @@ #include "sp-string.h" +#include "style.h" + #include "xml/repr.h" #include "sp-factory.h" +#include + namespace { SPObject* createString() { return new SPString(); @@ -65,45 +69,110 @@ void SPString::release() { void SPString::read_content() { - SPString* object = this; + SPString* object = this; SPString *string = SP_STRING(object); string->string.clear(); //XML Tree being used directly here while it shouldn't be. gchar const *xml_string = string->getRepr()->content(); - // see algorithms described in svg 1.1 section 10.15 - if (object->xml_space.value == SP_XML_SPACE_PRESERVE) { - for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) { - gunichar c = g_utf8_get_char(xml_string); - if ((c == 0xa) || (c == 0xd) || (c == '\t')) { - c = ' '; - } - string->string += c; + + // std::cout << ">" << (xml_string?xml_string:"Null") << "<" << std::endl; + + // SVG2/CSS Text Level 3 'white-space' has five values. + // See: http://dev.w3.org/csswg/css-text/#white-space + // | New Lines | Spaces/Tabs | Text Wrapping + // ---------|------------|--------------|-------------- + // normal | Collapes | Collapse | Wrap + // pre | Preserve | Preserve | No Wrap + // nowrap | Collapse | Collapse | No Wrap + // pre-wrap | Preserve | Preserve | Wrap + // pre-line | Preserve | Collapse | Wrap + + // 'xml:space' has two values: + // 'default' which corresponds to 'normal' (without wrapping). + // 'preserve' which corresponds to 'pre' except new lines are converted to spaces. + // See algorithms described in svg 1.1 section 10.15 + + bool collapse_space = true; + bool collapse_line = true; + bool is_css = false; + + // Strings don't have style, check parent for style + if( object->parent && object->parent->style ) { + if( object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRE || + object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PREWRAP || + object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRELINE ) { + collapse_line = false; + } + if( object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PRE || + object->parent->style->white_space.computed == SP_CSS_WHITE_SPACE_PREWRAP ) { + collapse_space = false; + } + if( object->parent->style->white_space.computed != SP_CSS_WHITE_SPACE_NORMAL ) { + is_css = true; // If white-space not normal, we assume white-space is set. } } - else { - bool whitespace = false; - for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) { - gunichar c = g_utf8_get_char(xml_string); - if ((c == 0xa) || (c == 0xd)) { + if( !is_css ) { + // SVG 2: Use 'xml:space' only if 'white-space' not 'normal'. + if (object->xml_space.value == SP_XML_SPACE_PRESERVE) { + collapse_space = false; + } + } + + bool white_space = false; + for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) { + + gunichar c = g_utf8_get_char(xml_string); + switch (c) { + case 0xd: // Carriage return + // XML Parsers convert 0xa, 0xd, 0xD 0xA to 0xA. CSS also follows this rule so we + // should never see 0xd. + std::cerr << "SPString: Carriage Return found! Argh!" << std::endl; continue; - } - if ((c == ' ') || (c == '\t')) { - whitespace = true; - } else { - if (whitespace && (!string->string.empty() || (object->getPrev() != NULL))) { + break; + case 0xa: // Line feed + if( collapse_line ) { + if( !is_css && collapse_space ) continue; // xml:space == 'default' strips LFs. + white_space = true; // Convert to space and collapse + } else { + string->string += c; // Preserve line feed + continue; + } + break; + case '\t': // Tab + if( collapse_space ) { + white_space = true; // Convert to space and collapse + } else { + string->string += c; // Preserve tab + continue; + } + break; + case ' ': // Space + if( collapse_space ) { + white_space = true; // Collapse white space + } else { + string->string += c; // Preserve space + continue; + } + break; + default: + if( white_space && (!string->string.empty() || (object->getPrev() != NULL))) { string->string += ' '; } string->string += c; - whitespace = false; - } - } - if (whitespace && object->getRepr()->next() != NULL) { // can't use SPObject::getNext() when the SPObject tree is still being built - string->string += ' '; - } + white_space = false; + + } // End switch + } // End loop + + // Insert white space at end if more text follows + if (white_space && object->getRepr()->next() != NULL) { // can't use SPObject::getNext() when the SPObject tree is still being built + string->string += ' '; } + + // std::cout << ">" << string->string << "<" << std::endl; object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } diff --git a/src/sp-text.cpp b/src/sp-text.cpp index ccc5adf59..3bb1e16d0 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -82,6 +82,10 @@ void SPText::build(SPDocument *doc, Inkscape::XML::Node *repr) { this->readAttr( "dy" ); this->readAttr( "rotate" ); + // SVG 2 Auto wrapped text + this->readAttr( "width" ); + this->readAttr( "height" ); + SPItem::build(doc, repr); this->readAttr( "sodipodi:linespacing" ); // has to happen after the styles are read @@ -92,6 +96,8 @@ void SPText::release() { } void SPText::set(unsigned int key, const gchar* value) { + //std::cout << "SPText::set: " << sp_attribute_name( key ) << ": " << (value?value:"Null") << std::endl; + if (this->attributes.readSingleAttribute(key, value)) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } else { @@ -109,6 +115,22 @@ void SPText::set(unsigned int key, const gchar* value) { this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); break; + case SP_ATTR_WIDTH: + if (!this->width.read(value) || this->width.value < 0.0) { + this->width.unset(); + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_HEIGHT: + if (!this->height.read(value) || this->height.value < 0.0) { + this->height.unset(); + } + + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: SPItem::set(key, value); break; @@ -284,6 +306,14 @@ Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::X this->getRepr()->setAttribute("sodipodi:linespacing", NULL); } + // SVG 2 Auto-wrapped text + if( this->width.computed > 0.0 ) { + sp_repr_set_svg_double(repr, "width", this->width.computed); + } + if( this->height.computed > 0.0 ) { + sp_repr_set_svg_double(repr, "height", this->height.computed); + } + SPItem::write(xml_doc, repr, flags); return repr; diff --git a/src/sp-text.h b/src/sp-text.h index 5f0485083..b9ae745c9 100644 --- a/src/sp-text.h +++ b/src/sp-text.h @@ -45,7 +45,11 @@ public: //semiprivate: (need to be accessed by the C-style functions still) TextTagAttributes attributes; Inkscape::Text::Layout layout; - + + // SVG 2 Auto-wrapped text + SVGLength width; + SVGLength height; + /** when the object is transformed it's nicer to change the font size and coordinates when we can, rather than just applying a matrix transform. is_root is used to indicate to the function that it should diff --git a/src/style-enums.h b/src/style-enums.h index 356029a40..024943458 100644 --- a/src/style-enums.h +++ b/src/style-enums.h @@ -113,6 +113,14 @@ enum SPTextAnchor { SP_CSS_TEXT_ANCHOR_END }; +enum SPWhiteSpace { + SP_CSS_WHITE_SPACE_NORMAL, + SP_CSS_WHITE_SPACE_PRE, + SP_CSS_WHITE_SPACE_NOWRAP, + SP_CSS_WHITE_SPACE_PREWRAP, + SP_CSS_WHITE_SPACE_PRELINE +}; + enum SPCSSBaselineShift { SP_CSS_BASELINE_SHIFT_BASELINE, SP_CSS_BASELINE_SHIFT_SUB, @@ -326,6 +334,15 @@ static SPStyleEnum const enum_text_anchor[] = { {NULL, -1} }; +static SPStyleEnum const enum_white_space[] = { + {"normal", SP_CSS_WHITE_SPACE_NORMAL }, + {"pre", SP_CSS_WHITE_SPACE_PRE }, + {"nowrap", SP_CSS_WHITE_SPACE_NOWRAP }, + {"pre-wrap", SP_CSS_WHITE_SPACE_PREWRAP}, + {"pre-line", SP_CSS_WHITE_SPACE_PRELINE}, + {NULL, -1} +}; + static SPStyleEnum const enum_direction[] = { {"ltr", SP_CSS_DIRECTION_LTR}, {"rtl", SP_CSS_DIRECTION_RTL}, diff --git a/src/style.cpp b/src/style.cpp index f0710e404..97aae016a 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -135,6 +135,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : writing_mode( "writing-mode", enum_writing_mode, SP_CSS_WRITING_MODE_LR_TB ), baseline_shift(), text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), + white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), // General visual properties clip_rule( "clip-rule", enum_clip_rule, SP_WIND_RULE_NONZERO ), @@ -297,6 +298,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &writing_mode ); _properties.push_back( &baseline_shift ); _properties.push_back( &text_anchor ); + _properties.push_back( &white_space ); _properties.push_back( &clip_rule ); _properties.push_back( &display ); @@ -379,6 +381,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( writing_mode.name, reinterpret_cast(&SPStyle::writing_mode ) ) ); // _propmap.insert( std::make_pair( baseline_shift.name, reinterpret_cast(&SPStyle::baseline_shift ) ) ); // _propmap.insert( std::make_pair( text_anchor.name, reinterpret_cast(&SPStyle::text_anchor ) ) ); + // _propmap.insert( std::make_pair( white_space.name, reinterpret_cast(&SPStyle::white_space ) ) ); // _propmap.insert( std::make_pair( clip_rule.name, reinterpret_cast(&SPStyle::clip_rule ) ) ); // _propmap.insert( std::make_pair( display.name, reinterpret_cast(&SPStyle::display ) ) ); @@ -670,6 +673,9 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_TEXT_ANCHOR: text_anchor.readIfUnset( val ); break; + case SP_PROP_WHITE_SPACE: + white_space.readIfUnset( val ); + break; case SP_PROP_BASELINE_SHIFT: baseline_shift.readIfUnset( val ); break; @@ -1623,6 +1629,9 @@ sp_style_unset_property_attrs(SPObject *o) if (style->text_anchor.set) { repr->setAttribute("text-anchor", NULL); } + if (style->white_space.set) { + repr->setAttribute("white_space", NULL); + } if (style->writing_mode.set) { repr->setAttribute("writing_mode", NULL); } @@ -1712,6 +1721,7 @@ sp_css_attr_unset_text(SPCSSAttr *css) sp_repr_css_set_property(css, "block-progression", NULL); sp_repr_css_set_property(css, "writing-mode", NULL); sp_repr_css_set_property(css, "text-anchor", NULL); + sp_repr_css_set_property(css, "white_space", NULL); sp_repr_css_set_property(css, "kerning", NULL); // not implemented yet sp_repr_css_set_property(css, "dominant-baseline", NULL); // not implemented yet sp_repr_css_set_property(css, "alignment-baseline", NULL); // not implemented yet diff --git a/src/style.h b/src/style.h index eb8a3ed91..8d0befe0e 100644 --- a/src/style.h +++ b/src/style.h @@ -92,8 +92,10 @@ private: public: /* ----------------------- THE PROPERTIES ------------------------- */ + /* Match order in style.cpp. */ + + /* Font ---------------------------- */ - /* Font */ /** Font style */ SPIEnum font_style; /** Which substyle of the font */ @@ -113,23 +115,13 @@ public: /** Full font name, as font_factory::ConstructFontSpecification would give, for internal use. */ SPIString font_specification; + /* Text ----------------------------- */ + /** First line indent of paragraphs (css2 16.1) */ SPILength text_indent; /** text alignment (css2 16.2) (not to be confused with text-anchor) */ SPIEnum text_align; - /** text decoration (css2 16.3.1) */ - SPITextDecoration text_decoration; - /** CSS 3 2.1, 2.2, 2.3 */ - /** Not done yet, test_decoration3 = css3 2.4*/ - SPITextDecorationLine text_decoration_line; - SPITextDecorationStyle text_decoration_style; // SPIEnum? Only one can be set at time. - SPIColor text_decoration_color; - // used to implement text_decoration, not saved to or read from SVG file - SPITextDecorationData text_decoration_data; - - // 16.3.2 is text-shadow. That's complicated. - /** letter spacing (css2 16.4) */ SPILengthOrNormal letter_spacing; /** word spacing (also css2 16.4) */ @@ -151,6 +143,25 @@ public: /** Anchor of the text (svg1.1 10.9.1) */ SPIEnum text_anchor; + /** white space (svg2) */ + SPIEnum white_space; + + /* Text Decoration ----------------------- */ + + /** text decoration (css2 16.3.1) */ + SPITextDecoration text_decoration; + /** CSS 3 2.1, 2.2, 2.3 */ + /** Not done yet, test_decoration3 = css3 2.4*/ + SPITextDecorationLine text_decoration_line; + SPITextDecorationStyle text_decoration_style; // SPIEnum? Only one can be set at time. + SPIColor text_decoration_color; + // used to implement text_decoration, not saved to or read from SVG file + SPITextDecorationData text_decoration_data; + + // 16.3.2 is text-shadow. That's complicated. + + /* General visual properties ------------- */ + /** clip-rule: 0 nonzero, 1 evenodd */ SPIEnum clip_rule; @@ -216,6 +227,8 @@ public: SPIString marker_end; SPIString* marker_ptrs[SP_MARKER_LOC_QTY]; + /* Filter effects ------------------------ */ + /** Filter effect */ SPIFilter filter; /** Filter blend mode */ @@ -226,6 +239,7 @@ public: /** enable-background, used for defining where filter effects get their background image */ SPIEnum enable_background; + /* Rendering hints ----------------------- */ /** hints on how to render: e.g. speed vs. accuracy. * As of April, 2013, only image_rendering used. */ -- cgit v1.2.3 From 64fb7253a1d2771c4f844d1c2266a90f328895b5 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Wed, 30 Jul 2014 22:47:29 +0200 Subject: Limit the number of paths to be used as snap targets, to keep Inkscape responsive in very complex drawings Fixed bugs: - https://launchpad.net/bugs/1348959 (bzr r13483) --- src/object-snapper.cpp | 4 ++++ src/seltrans.cpp | 1 + 2 files changed, 5 insertions(+) (limited to 'src') diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index 3b8956bc8..0f7aa6368 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -147,6 +147,10 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, // For debugging: print the id of the candidate to the console // SPObject *obj = (SPObject*)item; // std::cout << "Snap candidate added: " << obj->getId() << std::endl; + if (_candidates->size() > 200) { // This makes Inkscape crawl already + std::cout << "Warning: limit of 200 snap target paths reached, some will be ignored" << std::endl; + break; + } } } } diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 4b1a3a5fa..6b8cd19bb 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -304,6 +304,7 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s /* Snapping a huge number of nodes will take way too long, so limit the number of snappable nodes A typical user would rarely ever try to snap such a large number of nodes anyway, because (s)he would hardly be able to discern which node would be snapping */ + std::cout << "Warning: limit of 200 snap sources reached, some will be ignored" << std::endl; _snap_points.resize(200); // Unfortunately, by now we will have lost the font-baseline snappoints :-( } -- cgit v1.2.3 From 291925ef62d1068af1c4b7f3614c96d46f3c20f2 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 31 Jul 2014 16:31:01 +0200 Subject: Basic support for element (rendering only as a paint server). (bzr r13484) --- src/CMakeLists.txt | 2 ++ src/Makefile_insert | 1 + src/attributes.cpp | 2 ++ src/attributes.h | 2 ++ src/sp-solid-color.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/sp-solid-color.h | 46 ++++++++++++++++++++++++ src/style.cpp | 23 ++++++++++++ src/style.h | 5 +++ 8 files changed, 178 insertions(+) create mode 100644 src/sp-solid-color.cpp create mode 100644 src/sp-solid-color.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d40aad802..4a792af6b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,6 +63,7 @@ set(sp_SRC sp-root.cpp sp-script.cpp sp-shape.cpp + sp-solid-color.cpp sp-spiral.cpp sp-star.cpp sp-stop.cpp @@ -147,6 +148,7 @@ set(sp_SRC sp-root.h sp-script.h sp-shape.h + sp-solid-color.h sp-spiral.h sp-star.h sp-stop.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 6d0d6b08c..f191839a1 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -192,6 +192,7 @@ ink_common_sources += \ sp-root.cpp sp-root.h \ sp-script.cpp sp-script.h \ sp-shape.cpp sp-shape.h \ + sp-solid-color.cpp sp-solid-color.h \ sp-spiral.cpp sp-spiral.h \ sp-star.cpp sp-star.h \ sp-stop.cpp sp-stop.h \ diff --git a/src/attributes.cpp b/src/attributes.cpp index ee2a80fd3..da7b25f03 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -475,6 +475,8 @@ static SPStyleProp const props[] = { {SP_PROP_MARKER_START, "marker-start"}, {SP_PROP_PAINT_ORDER, "paint-order" }, {SP_PROP_SHAPE_RENDERING, "shape-rendering"}, + {SP_PROP_SOLID_COLOR, "solid-color"}, + {SP_PROP_SOLID_OPACITY, "solid-opacity"}, {SP_PROP_STROKE, "stroke"}, {SP_PROP_STROKE_DASHARRAY, "stroke-dasharray"}, {SP_PROP_STROKE_DASHOFFSET, "stroke-dashoffset"}, diff --git a/src/attributes.h b/src/attributes.h index b8843fcb7..82e7ca8a6 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -476,6 +476,8 @@ enum SPAttributeEnum { SP_PROP_MARKER_START, SP_PROP_PAINT_ORDER, /* SVG2 */ SP_PROP_SHAPE_RENDERING, + SP_PROP_SOLID_COLOR, + SP_PROP_SOLID_OPACITY, SP_PROP_STROKE, SP_PROP_STROKE_DASHARRAY, SP_PROP_STROKE_DASHOFFSET, diff --git a/src/sp-solid-color.cpp b/src/sp-solid-color.cpp new file mode 100644 index 000000000..1f606d176 --- /dev/null +++ b/src/sp-solid-color.cpp @@ -0,0 +1,97 @@ +/** @file + * @solid color class. + */ +/* Authors: + * Tavmjong Bah + * + * Copyright (C) 2014 Tavmjong Bah + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "sp-solid-color.h" + +#include "attributes.h" +#include "style.h" +#include "xml/repr.h" + +#include "sp-factory.h" +#include "sp-item.h" +#include "style-internal.h" + +namespace { + SPObject* createSolidColor() { + return new SPSolidColor(); + } + + bool solidColorRegistered = SPFactory::instance().registerObject("svg:solidColor", createSolidColor); +} + + +/* + * Solid Color + */ +SPSolidColor::SPSolidColor() : SPPaintServer() { +} + +SPSolidColor::~SPSolidColor() { +} + +void SPSolidColor::build(SPDocument* doc, Inkscape::XML::Node* repr) { + SPPaintServer::build(doc, repr); + + this->readAttr( "style" ); + this->readAttr( "solid-color" ); + this->readAttr( "solid-opacity" ); +} + +/** + * Virtual build: set solidcolor attributes from its associated XML node. + */ + +void SPSolidColor::set(unsigned int key, const gchar* value) { + + if (SP_ATTRIBUTE_IS_CSS(key)) { + sp_style_read_from_object(this->style, this); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } else { + SPPaintServer::set(key, value); + } +} + +/** + * Virtual set: set attribute to value. + */ + +Inkscape::XML::Node* SPSolidColor::write(Inkscape::XML::Document* xml_doc, Inkscape::XML::Node* repr, guint flags) { + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("svg:solidColor"); + } + + SPObject::write(xml_doc, repr, flags); + + return repr; +} + +cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const &bbox, double opacity) { + + SPIColor *c = &(this->style->solid_color); + cairo_pattern_t *cp = cairo_pattern_create_rgba ( c->value.color.v.c[0], c->value.color.v.c[1], c->value.color.v.c[2], SP_SCALE24_TO_FLOAT(this->style->solid_opacity.value) * opacity ); + + return cp; +} + + +/** + * Virtual write: write object attributes to repr. + */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/sp-solid-color.h b/src/sp-solid-color.h new file mode 100644 index 000000000..0ff09762e --- /dev/null +++ b/src/sp-solid-color.h @@ -0,0 +1,46 @@ +#ifndef SEEN_SP_SOLIDCOLOR_H +#define SEEN_SP_SOLIDCOLOR_H + +/** \file + * SPSolidColor: SVG implementation. + */ +/* + * Authors: Tavmjong Bah + * Copyright (C) 2012 Tavmjong Bah + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "color.h" +#include "sp-paint-server.h" + +#define SP_SOLIDCOLOR(obj) (dynamic_cast((SPObject*)obj)) +#define SP_IS_SOLIDCOLOR(obj) (dynamic_cast((SPObject*)obj) != NULL) + +/** Gradient SolidColor. */ +class SPSolidColor : public SPPaintServer { +public: + SPSolidColor(); + virtual ~SPSolidColor(); + + virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); + +protected: + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void set(unsigned int key, const gchar* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); +}; + +#endif /* !SEEN_SP_SOLIDCOLOR_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/style.cpp b/src/style.cpp index 222155a0c..f0710e404 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -153,6 +153,10 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : color_interpolation( "color-interpolation", enum_color_interpolation, SP_CSS_COLOR_INTERPOLATION_SRGB), color_interpolation_filters("color-interpolation-filters", enum_color_interpolation, SP_CSS_COLOR_INTERPOLATION_LINEARRGB), + // Solid color properties + solid_color( "solid-color" ), // SPIColor + solid_opacity( "solid-opacity", SP_SCALE24_MAX ), + // Fill properties fill( "fill" ), // SPIPaint fill_opacity( "fill-opacity", SP_SCALE24_MAX ), @@ -306,6 +310,9 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &color_interpolation ); _properties.push_back( &color_interpolation_filters ); + _properties.push_back( &solid_color ); + _properties.push_back( &solid_opacity ); + _properties.push_back( &fill ); _properties.push_back( &fill_opacity ); _properties.push_back( &fill_rule ); @@ -385,10 +392,14 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( color_interpolation.name, reinterpret_cast(&SPStyle::color_interpolation ) ) ); // _propmap.insert( std::make_pair( color_interpolation_filters.name, reinterpret_cast(&SPStyle::color_interpolation_filters ) ) ); + // _propmap.insert( std::make_pair( solid_color.name, reinterpret_cast(&SPStyle::solid_color ) ) ); + // _propmap.insert( std::make_pair( solid_opacity.name, reinterpret_cast(&SPStyle::solid_opacity ) ) ); + // _propmap.insert( std::make_pair( fill.name, reinterpret_cast(&SPStyle::fill ) ) ); // _propmap.insert( std::make_pair( fill_opacity.name, reinterpret_cast(&SPStyle::fill_opacity ) ) ); // _propmap.insert( std::make_pair( fill_rule.name, reinterpret_cast(&SPStyle::fill_rule ) ) ); + // _propmap.insert( std::make_pair( stroke.name, reinterpret_cast(&SPStyle::stroke ) ) ); // _propmap.insert( std::make_pair( stroke_width.name, reinterpret_cast(&SPStyle::stroke_width ) ) ); // _propmap.insert( std::make_pair( stroke_linecap.name, reinterpret_cast(&SPStyle::stroke_linecap ) ) ); @@ -779,6 +790,12 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_COLOR_RENDERING: color_rendering.readIfUnset( val ); break; + case SP_PROP_SOLID_COLOR: + solid_color.readIfUnset( val ); + break; + case SP_PROP_SOLID_OPACITY: + solid_opacity.readIfUnset( val ); + break; case SP_PROP_FILL: fill.readIfUnset( val ); break; @@ -1546,6 +1563,12 @@ sp_style_unset_property_attrs(SPObject *o) if (style->color_interpolation_filters.set) { repr->setAttribute("color-interpolation-filters", NULL); } + if (style->solid_color.set) { + repr->setAttribute("solid-color", NULL); + } + if (style->solid_opacity.set) { + repr->setAttribute("solid-opacity", NULL); + } if (style->fill.set) { repr->setAttribute("fill", NULL); } diff --git a/src/style.h b/src/style.h index 931dcc90e..eb8a3ed91 100644 --- a/src/style.h +++ b/src/style.h @@ -180,6 +180,11 @@ public: /** color-interpolation-filters */ SPIEnum color_interpolation_filters; + /** solid-color */ + SPIColor solid_color; + /** solid-opacity */ + SPIScale24 solid_opacity; + /** fill */ SPIPaint fill; /** fill-opacity */ -- cgit v1.2.3 From b9a8b72cd7bb5c6dbfe5118f15fa870cff8eb4c5 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 31 Jul 2014 14:53:10 -0400 Subject: I'm an idiot (bzr r13090.1.97) --- src/knotholder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/knotholder.cpp b/src/knotholder.cpp index aea983cbb..9890647e1 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -213,7 +213,7 @@ KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/, guint) if (dynamic_cast (object)) { // This writes all parameters to SVG. Is this sufficiently efficient or should we only // write the ones that were changed? - SPLPEItem * lpeitem = SP_LPE_ITEM(this->item); + SPLPEItem * lpeitem = SP_LPE_ITEM(object); if (lpeitem) { Inkscape::LivePathEffect::Effect *lpe = lpeitem->getCurrentLPE(); if (lpe) { -- cgit v1.2.3 From 8b31d0e28a6cf0f916f5267c54fed76c712c48a3 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 1 Aug 2014 10:13:43 +0200 Subject: Rename 'blend-mode' property to 'mix-blend-mode' per CSS spec. (bzr r13341.1.113) --- src/attributes.cpp | 2 +- src/attributes.h | 2 +- src/display/drawing-item.cpp | 14 +++++++------- src/display/drawing-item.h | 2 +- src/sp-item.cpp | 4 ++-- src/style.cpp | 10 +++++----- src/style.h | 3 +-- 7 files changed, 18 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index 3cca90105..2474e4abe 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -442,7 +442,7 @@ static SPStyleProp const props[] = { {SP_PROP_DISPLAY, "display"}, {SP_PROP_OVERFLOW, "overflow"}, {SP_PROP_VISIBILITY, "visibility"}, - {SP_PROP_BLEND_MODE, "mix-blend-mode"}, // CSS Blending and Compositing + {SP_PROP_MIX_BLEND_MODE, "mix-blend-mode"}, // CSS Blending and Compositing {SP_PROP_ISOLATION, "isolation"}, /* SVG */ /* Clip/Mask */ diff --git a/src/attributes.h b/src/attributes.h index 47199ac51..7f18cb5ea 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -449,7 +449,7 @@ enum SPAttributeEnum { SP_PROP_DISPLAY, SP_PROP_OVERFLOW, SP_PROP_VISIBILITY, - SP_PROP_BLEND_MODE, + SP_PROP_MIX_BLEND_MODE, SP_PROP_ISOLATION, /* SVG */ diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 0bfb00b62..80eb69546 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -127,7 +127,7 @@ DrawingItem::DrawingItem(Drawing &drawing) , _pick_children(0) , _antialias(1) , _isolation(SP_CSS_ISOLATION_AUTO) - , _blend_mode(SP_CSS_BLEND_NORMAL) + , _mix_blend_mode(SP_CSS_BLEND_NORMAL) {} DrawingItem::~DrawingItem() @@ -291,10 +291,10 @@ DrawingItem::setIsolation(unsigned isolation) } void -DrawingItem::setBlendMode(unsigned blend_mode) +DrawingItem::setBlendMode(unsigned mix_blend_mode) { - _blend_mode = blend_mode; - //if( blend_mode != 0 ) std::cout << "setBlendMode: " << blend_mode << std::endl; + _mix_blend_mode = mix_blend_mode; + //if( mix_blend_mode != 0 ) std::cout << "setBlendMode: " << mix_blend_mode << std::endl; _markForRendering(); } @@ -592,7 +592,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag if (_cached) { if (_cache) { _cache->prepare(); - set_cairo_blend_operator( dc, _blend_mode ); + set_cairo_blend_operator( dc, _mix_blend_mode ); _cache->paintFromCache(dc, carea); if (!carea) return RENDER_OK; @@ -622,7 +622,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag nir |= (_filter != NULL && render_filters); // 3. it has a filter nir |= needs_opacity; // 4. it is non-opaque nir |= (_cache != NULL); // 5. it is cached - nir |= (_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal + nir |= (_mix_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal nir |= (_isolation == SP_CSS_ISOLATION_ISOLATE); // 7. Explicit isolatiom /* How the rendering is done. @@ -735,7 +735,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag } dc.rectangle(*carea); dc.setSource(&intermediate); - set_cairo_blend_operator( dc, _blend_mode ); + set_cairo_blend_operator( dc, _mix_blend_mode ); dc.fill(); dc.setSource(0,0,0,0); // the call above is to clear a ref on the intermediate surface held by dc diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index d89299eeb..925bcbddb 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -209,7 +209,7 @@ protected: unsigned _antialias : 1; ///< Whether to use antialiasing unsigned _isolation : 1; - unsigned _blend_mode : 4; + unsigned _mix_blend_mode : 4; friend class Drawing; }; diff --git a/src/sp-item.cpp b/src/sp-item.cpp index a3f1a5d64..6c2ada9d7 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -602,7 +602,7 @@ void SPItem::update(SPCtx* /*ctx*/, guint flags) { v->arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(object->style->opacity.value)); v->arenaitem->setAntialiasing(object->style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); v->arenaitem->setIsolation( object->style->isolation.value ); - v->arenaitem->setBlendMode( object->style->blend_mode.value ); + v->arenaitem->setBlendMode( object->style->mix_blend_mode.value ); v->arenaitem->setVisible(!item->isHidden()); } } @@ -1028,7 +1028,7 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned ai->setTransform(transform); ai->setOpacity(SP_SCALE24_TO_FLOAT(style->opacity.value)); ai->setIsolation( style->isolation.value ); - ai->setBlendMode( style->blend_mode.value ); + ai->setBlendMode( style->mix_blend_mode.value ); //ai->setCompositeOperator( style->composite_op.value ); ai->setVisible(!isHidden()); ai->setSensitive(sensitive); diff --git a/src/style.cpp b/src/style.cpp index 97aae016a..5f8a8d82e 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -145,7 +145,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : opacity( "opacity", SP_SCALE24_MAX, false ), isolation( "isolation", enum_isolation, SP_CSS_ISOLATION_AUTO ), - blend_mode( "blend_mode", enum_blend_mode, SP_CSS_BLEND_NORMAL ), + mix_blend_mode( "mix_blend_mode", enum_blend_mode, SP_CSS_BLEND_NORMAL ), paint_order(), // SPIPaintOrder @@ -307,7 +307,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &opacity ); _properties.push_back( &isolation ); - _properties.push_back( &blend_mode ); + _properties.push_back( &mix_blend_mode ); _properties.push_back( &color_interpolation ); _properties.push_back( &color_interpolation_filters ); @@ -390,7 +390,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( opacity.name, reinterpret_cast(&SPStyle::opacity ) ) ); // _propmap.insert( std::make_pair( isolation.name, reinterpret_cast(&SPStyle::isolation ) ) ); - // _propmap.insert( std::make_pair( blend_mode.name, reinterpret_cast(&SPStyle::blend_mode ) ) ); + // _propmap.insert( std::make_pair( mix_blend_mode.name, reinterpret_cast(&SPStyle::mix_blend_mode ) ) ); // _propmap.insert( std::make_pair( color_interpolation.name, reinterpret_cast(&SPStyle::color_interpolation ) ) ); // _propmap.insert( std::make_pair( color_interpolation_filters.name, reinterpret_cast(&SPStyle::color_interpolation_filters ) ) ); @@ -719,8 +719,8 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_ISOLATION: isolation.readIfUnset( val ); break; - case SP_PROP_BLEND_MODE: - blend_mode.readIfUnset( val ); + case SP_PROP_MIX_BLEND_MODE: + mix_blend_mode.readIfUnset( val ); break; /* SVG */ diff --git a/src/style.h b/src/style.h index 8d0befe0e..01a9d4b84 100644 --- a/src/style.h +++ b/src/style.h @@ -179,8 +179,7 @@ public: /** mix-blend-mode: CSS Compositing and Blending Level 1 */ SPIEnum isolation; - // Could be shared with Filter blending mode - SPIEnum blend_mode; + SPIEnum mix_blend_mode; SPIPaintOrder paint_order; -- cgit v1.2.3 From 6dde092cd67702688e9c5e243c5b1fcf8a46d8f9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 1 Aug 2014 11:02:54 +0200 Subject: Fix type in 'mix-blend-mode'. (bzr r13341.1.114) --- src/style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/style.cpp b/src/style.cpp index 5f8a8d82e..a91611d89 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -145,7 +145,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : opacity( "opacity", SP_SCALE24_MAX, false ), isolation( "isolation", enum_isolation, SP_CSS_ISOLATION_AUTO ), - mix_blend_mode( "mix_blend_mode", enum_blend_mode, SP_CSS_BLEND_NORMAL ), + mix_blend_mode( "mix-blend-mode", enum_blend_mode, SP_CSS_BLEND_NORMAL ), paint_order(), // SPIPaintOrder -- cgit v1.2.3 From 97a4ef4fd8b0c841a90f3bb29dee13fd96edecb7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 1 Aug 2014 11:04:51 +0200 Subject: Rename 'blend-mode' property to 'mix-blend-mode' per CSS spec. (bzr r13485) --- src/attributes.cpp | 2 +- src/attributes.h | 2 +- src/display/drawing-item.cpp | 14 +++++++------- src/display/drawing-item.h | 2 +- src/sp-item.cpp | 4 ++-- src/style.cpp | 10 +++++----- src/style.h | 3 +-- 7 files changed, 18 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index da7b25f03..fec5d3af4 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -440,7 +440,7 @@ static SPStyleProp const props[] = { {SP_PROP_DISPLAY, "display"}, {SP_PROP_OVERFLOW, "overflow"}, {SP_PROP_VISIBILITY, "visibility"}, - {SP_PROP_BLEND_MODE, "mix-blend-mode"}, // CSS Blending and Compositing + {SP_PROP_MIX_BLEND_MODE, "mix-blend-mode"}, // CSS Blending and Compositing {SP_PROP_ISOLATION, "isolation"}, /* SVG */ /* Clip/Mask */ diff --git a/src/attributes.h b/src/attributes.h index 82e7ca8a6..3397e4034 100644 --- a/src/attributes.h +++ b/src/attributes.h @@ -441,7 +441,7 @@ enum SPAttributeEnum { SP_PROP_DISPLAY, SP_PROP_OVERFLOW, SP_PROP_VISIBILITY, - SP_PROP_BLEND_MODE, + SP_PROP_MIX_BLEND_MODE, SP_PROP_ISOLATION, /* SVG */ /* Clip/Mask */ diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 0bfb00b62..80eb69546 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -127,7 +127,7 @@ DrawingItem::DrawingItem(Drawing &drawing) , _pick_children(0) , _antialias(1) , _isolation(SP_CSS_ISOLATION_AUTO) - , _blend_mode(SP_CSS_BLEND_NORMAL) + , _mix_blend_mode(SP_CSS_BLEND_NORMAL) {} DrawingItem::~DrawingItem() @@ -291,10 +291,10 @@ DrawingItem::setIsolation(unsigned isolation) } void -DrawingItem::setBlendMode(unsigned blend_mode) +DrawingItem::setBlendMode(unsigned mix_blend_mode) { - _blend_mode = blend_mode; - //if( blend_mode != 0 ) std::cout << "setBlendMode: " << blend_mode << std::endl; + _mix_blend_mode = mix_blend_mode; + //if( mix_blend_mode != 0 ) std::cout << "setBlendMode: " << mix_blend_mode << std::endl; _markForRendering(); } @@ -592,7 +592,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag if (_cached) { if (_cache) { _cache->prepare(); - set_cairo_blend_operator( dc, _blend_mode ); + set_cairo_blend_operator( dc, _mix_blend_mode ); _cache->paintFromCache(dc, carea); if (!carea) return RENDER_OK; @@ -622,7 +622,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag nir |= (_filter != NULL && render_filters); // 3. it has a filter nir |= needs_opacity; // 4. it is non-opaque nir |= (_cache != NULL); // 5. it is cached - nir |= (_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal + nir |= (_mix_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal nir |= (_isolation == SP_CSS_ISOLATION_ISOLATE); // 7. Explicit isolatiom /* How the rendering is done. @@ -735,7 +735,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag } dc.rectangle(*carea); dc.setSource(&intermediate); - set_cairo_blend_operator( dc, _blend_mode ); + set_cairo_blend_operator( dc, _mix_blend_mode ); dc.fill(); dc.setSource(0,0,0,0); // the call above is to clear a ref on the intermediate surface held by dc diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index d89299eeb..925bcbddb 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -209,7 +209,7 @@ protected: unsigned _antialias : 1; ///< Whether to use antialiasing unsigned _isolation : 1; - unsigned _blend_mode : 4; + unsigned _mix_blend_mode : 4; friend class Drawing; }; diff --git a/src/sp-item.cpp b/src/sp-item.cpp index a3f1a5d64..6c2ada9d7 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -602,7 +602,7 @@ void SPItem::update(SPCtx* /*ctx*/, guint flags) { v->arenaitem->setOpacity(SP_SCALE24_TO_FLOAT(object->style->opacity.value)); v->arenaitem->setAntialiasing(object->style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); v->arenaitem->setIsolation( object->style->isolation.value ); - v->arenaitem->setBlendMode( object->style->blend_mode.value ); + v->arenaitem->setBlendMode( object->style->mix_blend_mode.value ); v->arenaitem->setVisible(!item->isHidden()); } } @@ -1028,7 +1028,7 @@ Inkscape::DrawingItem *SPItem::invoke_show(Inkscape::Drawing &drawing, unsigned ai->setTransform(transform); ai->setOpacity(SP_SCALE24_TO_FLOAT(style->opacity.value)); ai->setIsolation( style->isolation.value ); - ai->setBlendMode( style->blend_mode.value ); + ai->setBlendMode( style->mix_blend_mode.value ); //ai->setCompositeOperator( style->composite_op.value ); ai->setVisible(!isHidden()); ai->setSensitive(sensitive); diff --git a/src/style.cpp b/src/style.cpp index f0710e404..abc928d76 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -144,7 +144,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : opacity( "opacity", SP_SCALE24_MAX, false ), isolation( "isolation", enum_isolation, SP_CSS_ISOLATION_AUTO ), - blend_mode( "blend_mode", enum_blend_mode, SP_CSS_BLEND_NORMAL ), + mix_blend_mode( "mix-blend-mode", enum_blend_mode, SP_CSS_BLEND_NORMAL ), paint_order(), // SPIPaintOrder @@ -305,7 +305,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : _properties.push_back( &opacity ); _properties.push_back( &isolation ); - _properties.push_back( &blend_mode ); + _properties.push_back( &mix_blend_mode ); _properties.push_back( &color_interpolation ); _properties.push_back( &color_interpolation_filters ); @@ -387,7 +387,7 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // _propmap.insert( std::make_pair( opacity.name, reinterpret_cast(&SPStyle::opacity ) ) ); // _propmap.insert( std::make_pair( isolation.name, reinterpret_cast(&SPStyle::isolation ) ) ); - // _propmap.insert( std::make_pair( blend_mode.name, reinterpret_cast(&SPStyle::blend_mode ) ) ); + // _propmap.insert( std::make_pair( mix_blend_mode.name, reinterpret_cast(&SPStyle::mix_blend_mode ) ) ); // _propmap.insert( std::make_pair( color_interpolation.name, reinterpret_cast(&SPStyle::color_interpolation ) ) ); // _propmap.insert( std::make_pair( color_interpolation_filters.name, reinterpret_cast(&SPStyle::color_interpolation_filters ) ) ); @@ -713,8 +713,8 @@ SPStyle::readIfUnset( gint id, gchar const *val ) { case SP_PROP_ISOLATION: isolation.readIfUnset( val ); break; - case SP_PROP_BLEND_MODE: - blend_mode.readIfUnset( val ); + case SP_PROP_MIX_BLEND_MODE: + mix_blend_mode.readIfUnset( val ); break; /* SVG */ diff --git a/src/style.h b/src/style.h index eb8a3ed91..3627b4ec2 100644 --- a/src/style.h +++ b/src/style.h @@ -168,8 +168,7 @@ public: /** mix-blend-mode: CSS Compositing and Blending Level 1 */ SPIEnum isolation; - // Could be shared with Filter blending mode - SPIEnum blend_mode; + SPIEnum mix_blend_mode; SPIPaintOrder paint_order; -- cgit v1.2.3 From d95b9fa8bd9aeacf16ab7075305edd19300bfe76 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 1 Aug 2014 10:20:42 -0400 Subject: Fix for #1348385 (filtered shape losing filter on conversion) Fixed bugs: - https://launchpad.net/bugs/1348385 (bzr r13486) --- src/style-internal.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/style-internal.cpp b/src/style-internal.cpp index ae70fc10d..2212f8fff 100644 --- a/src/style-internal.cpp +++ b/src/style-internal.cpp @@ -1395,7 +1395,8 @@ const Glib::ustring SPIFilter::write( guint const flags, SPIBase const *const /* // TODO: fix base //SPILength const *const my_base = dynamic_cast(base); if ( (flags & SP_STYLE_FLAG_ALWAYS) || - ((flags & SP_STYLE_FLAG_IFSET) && this->set)) + ((flags & SP_STYLE_FLAG_IFSET) && this->set) || + ((flags & SP_STYLE_FLAG_IFDIFF) && this->set)) { if (this->inherit) { return (name + ":inherit;"); -- cgit v1.2.3 From a0acffb60236ee6d8c6f8ccc2f29d36b5aa02dda Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 1 Aug 2014 10:28:31 -0400 Subject: Fix for #906794, #1246550 (live effects not showing helper paths) Fixed bugs: - https://launchpad.net/bugs/1246550 - https://launchpad.net/bugs/906794 (bzr r13487) --- src/ui/tools/node-tool.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- src/ui/tools/node-tool.h | 2 ++ 2 files changed, 47 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index b1e11bd66..0778e3f3f 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -19,6 +19,7 @@ #include "display/curve.h" #include "display/sp-canvas.h" #include "document.h" +#include "live_effects/effect.h" #include "live_effects/lpeobject.h" #include "message-context.h" #include "selection.h" @@ -166,6 +167,9 @@ NodeTool::~NodeTool() { if (this->flash_tempitem) { this->desktop->remove_temporary_canvasitem(this->flash_tempitem); } + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + } this->_selection_changed_connection.disconnect(); //this->_selection_modified_connection.disconnect(); @@ -246,6 +250,7 @@ void NodeTool::setup() { ))) ); + this->helperpath_tmpitem = NULL; this->cursor_drag = false; this->show_transform_handles = true; this->single_node_transform_handles = false; @@ -278,6 +283,44 @@ void NodeTool::setup() { } this->desktop->emitToolSubselectionChanged(NULL); // sets the coord entry fields to inactive + this->update_helperpath(); +} + +// show helper paths of the applied LPE, if any +void NodeTool::update_helperpath () { + Inkscape::Selection *selection = sp_desktop_selection (this->desktop); + + if (this->helperpath_tmpitem) { + this->desktop->remove_temporary_canvasitem(this->helperpath_tmpitem); + this->helperpath_tmpitem = NULL; + } + + if (SP_IS_LPE_ITEM(selection->singleItem())) { + Inkscape::LivePathEffect::Effect *lpe = SP_LPE_ITEM(selection->singleItem())->getCurrentLPE(); + if (lpe && lpe->isVisible()/* && lpe->showOrigPath()*/) { + if (lpe) { + SPCurve *c = new SPCurve(); + SPCurve *cc = new SPCurve(); + std::vector cs = lpe->getCanvasIndicators(SP_LPE_ITEM(selection->singleItem())); + for (std::vector::iterator p = cs.begin(); p != cs.end(); ++p) { + cc->set_pathvector(*p); + c->append(cc, false); + cc->reset(); + } + if (!c->is_empty()) { + c->transform(selection->singleItem()->i2dt_affine()); + SPCanvasItem *helperpath = sp_canvas_bpath_new(sp_desktop_tempgroup(this->desktop), c); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(helperpath), + 0x0000ff9A, 1.0, + SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(helperpath), 0, SP_WIND_RULE_NONZERO); + this->helperpath_tmpitem = this->desktop->add_temporary_canvasitem(helperpath,0); + } + c->unref(); + cc->unref(); + } + } + } } void NodeTool::set(const Inkscape::Preferences::Entry& value) { @@ -392,7 +435,7 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { for (std::set::iterator i = shapes.begin(); i != shapes.end(); ++i) { ShapeRecord const &r = *i; - if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item)) && + if ((SP_IS_SHAPE(r.item) || SP_IS_TEXT(r.item) || SP_IS_GROUP(r.item) || SP_IS_OBJECTGROUP(r.item)) && this->_shape_editors.find(r.item) == this->_shape_editors.end()) { ShapeEditor *si = new ShapeEditor(this->desktop); @@ -432,6 +475,7 @@ bool NodeTool::root_handler(GdkEvent* event) { switch (event->type) { case GDK_MOTION_NOTIFY: { + this->update_helperpath(); combine_motion_events(desktop->canvas, event->motion, 0); SPItem *over_item = sp_event_context_find_item (desktop, event_point(event->button), FALSE, TRUE); diff --git a/src/ui/tools/node-tool.h b/src/ui/tools/node-tool.h index 4d15ab70e..459ecd0a7 100644 --- a/src/ui/tools/node-tool.h +++ b/src/ui/tools/node-tool.h @@ -51,6 +51,7 @@ public: static const std::string prefsPath; virtual void setup(); + virtual void update_helperpath(); virtual void set(const Inkscape::Preferences::Entry& val); virtual bool root_handler(GdkEvent* event); @@ -62,6 +63,7 @@ private: sigc::connection _sizeUpdatedConn; SPItem *flashed_item; + Inkscape::Display::TemporaryItem *helperpath_tmpitem; Inkscape::Display::TemporaryItem *flash_tempitem; Inkscape::UI::Selector* _selector; Inkscape::UI::PathSharedData* _path_data; -- cgit v1.2.3 From b2842360758b2333a651ef9932c1e438e90628e3 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 4 Aug 2014 11:21:54 +0200 Subject: Fixed some redraw problems moving nodes in bspline mode (bzr r13341.1.115) --- src/ui/tool/path-manipulator.cpp | 6 ++++-- src/ui/tools/pen-tool.cpp | 16 ++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 01cff5ad7..9839be437 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -1219,6 +1219,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ h = h2; } double pos = 0.0000; + const double handleCubicGap = 0.01; Node *n = h->parent(); Node * nextNode = NULL; nextNode = n->nodeToward(h); @@ -1226,7 +1227,7 @@ double PathManipulator::BSplineHandlePosition(Handle *h, Handle *h2){ SPCurve *lineInsideNodes = new SPCurve(); lineInsideNodes->moveto(n->position()); lineInsideNodes->lineto(nextNode->position()); - pos = Geom::nearest_point(h->position(),*lineInsideNodes->first_segment()); + pos = Geom::nearest_point(Geom::Point(h->position()[X] - handleCubicGap,h->position()[Y] - handleCubicGap),*lineInsideNodes->first_segment()); } if (pos == 0.0000 && !h2){ return BSplineHandlePosition(h, h->other()); @@ -1244,6 +1245,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h, Handle *h2){ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ using Geom::X; using Geom::Y; + const double handleCubicGap = 0.01; Geom::Point ret = h->position(); Node *n = h->parent(); Geom::D2< Geom::SBasis > SBasisInsideNodes; @@ -1255,7 +1257,7 @@ Geom::Point PathManipulator::BSplineHandleReposition(Handle *h,double pos){ lineInsideNodes->lineto(nextNode->position()); SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis(); ret = SBasisInsideNodes.valueAt(pos); - ret = Geom::Point(ret[X] + 0.005,ret[Y] + 0.005); + ret = Geom::Point(ret[X] + handleCubicGap,ret[Y] + handleCubicGap); }else{ if(pos == 0.0000){ ret = n->position(); diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index d826eaf48..9a73d497f 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -84,7 +84,7 @@ namespace Tools { static Geom::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical - +const double handleCubicGap = 0.01; namespace { ToolBase* createPenContext() { return new PenTool(); @@ -1454,7 +1454,7 @@ void PenTool::_bspline_spiro_on() this->p[0] = this->red_curve->first_segment()->initialPoint(); this->p[3] = this->red_curve->first_segment()->finalPoint(); this->p[2] = this->p[3] + (1./3)*(this->p[0] - this->p[3]); - this->p[2] = Geom::Point(this->p[2][X] + 0.005,this->p[2][Y] + 0.005); + this->p[2] = Geom::Point(this->p[2][X] + handleCubicGap,this->p[2][Y] + handleCubicGap); } } @@ -1522,7 +1522,7 @@ void PenTool::_bspline_spiro_start_anchor_on() Geom::Point A = tmpCurve->last_segment()->initialPoint(); Geom::Point D = tmpCurve->last_segment()->finalPoint(); Geom::Point C = D + (1./3)*(A - D); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); + C = Geom::Point(C[X] + handleCubicGap,C[Y] + handleCubicGap); if(cubic){ lastSeg->moveto(A); lastSeg->curveto((*cubic)[1],C,D); @@ -1580,10 +1580,10 @@ void PenTool::_bspline_spiro_motion(bool shift){ this->npoints = 5; SPCurve *tmpCurve = new SPCurve(); this->p[2] = this->p[3] + (1./3)*(this->p[0] - this->p[3]); - this->p[2] = Geom::Point(this->p[2][X] + 0.005,this->p[2][Y] + 0.005); + this->p[2] = Geom::Point(this->p[2][X] + handleCubicGap,this->p[2][Y] + handleCubicGap); if(this->green_curve->is_empty() && !this->sa){ this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]); - this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); + this->p[1] = Geom::Point(this->p[1][X] + handleCubicGap,this->p[1][Y] + handleCubicGap); }else if(!this->green_curve->is_empty()){ tmpCurve = this->green_curve->copy(); }else{ @@ -1608,7 +1608,7 @@ void PenTool::_bspline_spiro_motion(bool shift){ WPower->reset(); this->p[1] = SBasisWPower.valueAt(WP); if(!Geom::are_near(this->p[1],this->p[0])) - this->p[1] = Geom::Point(this->p[1][X] + 0.005,this->p[1][Y] + 0.005); + this->p[1] = Geom::Point(this->p[1][X] + handleCubicGap,this->p[1][Y] + handleCubicGap); if(shift) this->p[2] = this->p[3]; }else{ @@ -1638,7 +1638,7 @@ void PenTool::_bspline_spiro_end_anchor_on() using Geom::X; using Geom::Y; this->p[2] = this->p[3] + (1./3)*(this->p[0] - this->p[3]); - this->p[2] = Geom::Point(this->p[2][X] + 0.005,this->p[2][Y] + 0.005); + this->p[2] = Geom::Point(this->p[2][X] + handleCubicGap,this->p[2][Y] + handleCubicGap); SPCurve *tmpCurve = new SPCurve(); SPCurve *lastSeg = new SPCurve(); Geom::Point C(0,0); @@ -1661,7 +1661,7 @@ void PenTool::_bspline_spiro_end_anchor_on() Geom::CubicBezier const * cubic = dynamic_cast(&*tmpCurve->last_segment()); if(this->bspline){ C = tmpCurve->last_segment()->finalPoint() + (1./3)*(tmpCurve->last_segment()->initialPoint() - tmpCurve->last_segment()->finalPoint()); - C = Geom::Point(C[X] + 0.005,C[Y] + 0.005); + C = Geom::Point(C[X] + handleCubicGap,C[Y] + handleCubicGap); }else{ C = this->p[3] + this->p[3] - this->p[2]; } -- cgit v1.2.3 From acd8f135f2a901c5f046e51ad7783e442c43997a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 4 Aug 2014 12:10:37 -0400 Subject: Allow editing of fill and stroke patterns simultaneously. Fixes #601336, #604025, #486192 Fixed bugs: - https://launchpad.net/bugs/601336 - https://launchpad.net/bugs/604025 - https://launchpad.net/bugs/486192 (bzr r13489) --- src/knot-holder-entity.cpp | 18 +++++++++--------- src/knot-holder-entity.h | 10 ++++++++++ src/knotholder.cpp | 32 ++++++++++++++++++++++++++------ src/object-edit.cpp | 4 ++-- src/sp-item.cpp | 8 +++++--- src/sp-item.h | 9 ++++++++- 6 files changed, 60 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp index 6af5c6a56..b66156b09 100644 --- a/src/knot-holder-entity.cpp +++ b/src/knot-holder-entity.cpp @@ -158,7 +158,7 @@ static Geom::Point sp_pattern_extract_trans(SPPattern const *pat) void PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) { - SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); // FIXME: this snapping should be done together with knowing whether control was pressed. If GDK_CONTROL_MASK, then constrained snapping should be used. Geom::Point p_snapped = snap_knot_position(p, state); @@ -173,7 +173,7 @@ PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &ori if (state) { Geom::Point const q = p_snapped - sp_pattern_extract_trans(pat); - item->adjust_pattern(Geom::Affine(Geom::Translate(q))); + item->adjust_pattern(Geom::Translate(q), false, _fill ? TRANSFORM_FILL : TRANSFORM_STROKE); } item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -182,14 +182,14 @@ PatternKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &ori Geom::Point PatternKnotHolderEntityXY::knot_get() const { - SPPattern const *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); return sp_pattern_extract_trans(pat); } Geom::Point PatternKnotHolderEntityAngle::knot_get() const { - SPPattern const *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); gdouble x = pattern_width(pat); gdouble y = 0; @@ -207,7 +207,7 @@ PatternKnotHolderEntityAngle::knot_set(Geom::Point const &p, Geom::Point const & Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); - SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); // get the angle from pattern 0,0 to the cursor pos Geom::Point delta = p - sp_pattern_extract_trans(pat); @@ -223,14 +223,14 @@ PatternKnotHolderEntityAngle::knot_set(Geom::Point const &p, Geom::Point const & Geom::Point const t = sp_pattern_extract_trans(pat); rot[4] = t[Geom::X]; rot[5] = t[Geom::Y]; - item->adjust_pattern(rot, true); + item->adjust_pattern(rot, true, _fill ? TRANSFORM_FILL : TRANSFORM_STROKE); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } void PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) { - SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); // FIXME: this snapping should be done together with knowing whether control was pressed. If GDK_CONTROL_MASK, then constrained snapping should be used. Geom::Point p_snapped = snap_knot_position(p, state); @@ -257,7 +257,7 @@ PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const & Geom::Point const t = sp_pattern_extract_trans(pat); rot[4] = t[Geom::X]; rot[5] = t[Geom::Y]; - item->adjust_pattern(rot, true); + item->adjust_pattern(rot, true, _fill ? TRANSFORM_FILL : TRANSFORM_STROKE); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } @@ -265,7 +265,7 @@ PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const & Geom::Point PatternKnotHolderEntityScale::knot_get() const { - SPPattern const *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); gdouble x = pattern_width(pat); gdouble y = pattern_height(pat); diff --git a/src/knot-holder-entity.h b/src/knot-holder-entity.h index a9268d396..dde60f515 100644 --- a/src/knot-holder-entity.h +++ b/src/knot-holder-entity.h @@ -101,20 +101,30 @@ protected: class PatternKnotHolderEntityXY : public KnotHolderEntity { public: + PatternKnotHolderEntityXY(bool fill) : KnotHolderEntity(), _fill(fill) {} virtual Geom::Point knot_get() const; virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); +private: + // true if the entity tracks fill, false for stroke + bool _fill; }; class PatternKnotHolderEntityAngle : public KnotHolderEntity { public: + PatternKnotHolderEntityAngle(bool fill) : KnotHolderEntity(), _fill(fill) {} virtual Geom::Point knot_get() const; virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); +private: + bool _fill; }; class PatternKnotHolderEntityScale : public KnotHolderEntity { public: + PatternKnotHolderEntityScale(bool fill) : KnotHolderEntity(), _fill(fill) {} virtual Geom::Point knot_get() const; virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); +private: + bool _fill; }; #endif /* !SEEN_KNOT_HOLDER_ENTITY_H */ diff --git a/src/knotholder.cpp b/src/knotholder.cpp index cf87423d4..f0e69716b 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -247,12 +247,32 @@ void KnotHolder::add(KnotHolderEntity *e) void KnotHolder::add_pattern_knotholder() { - if ((item->style->fill.isPaintserver()) - && SP_IS_PATTERN(item->style->getFillPaintServer())) - { - PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY(); - PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle(); - PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale(); + if ((item->style->fill.isPaintserver()) && SP_IS_PATTERN(item->style->getFillPaintServer())) { + PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY(true); + PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle(true); + PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale(true); + entity_xy->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT, + // TRANSLATORS: This refers to the pattern that's inside the object + _("Move the pattern fill inside the object"), + SP_KNOT_SHAPE_CROSS); + + entity_scale->create(desktop, item, this, Inkscape::CTRL_TYPE_SIZER, + _("Scale the pattern fill; uniformly if with Ctrl"), + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR); + + entity_angle->create(desktop, item, this, Inkscape::CTRL_TYPE_ROTATE, + _("Rotate the pattern fill; with Ctrl to snap angle"), + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR); + + entity.push_back(entity_xy); + entity.push_back(entity_angle); + entity.push_back(entity_scale); + } + + if ((item->style->stroke.isPaintserver()) && SP_IS_PATTERN(item->style->getStrokePaintServer())) { + PatternKnotHolderEntityXY *entity_xy = new PatternKnotHolderEntityXY(false); + PatternKnotHolderEntityAngle *entity_angle = new PatternKnotHolderEntityAngle(false); + PatternKnotHolderEntityScale *entity_scale = new PatternKnotHolderEntityScale(false); entity_xy->create(desktop, item, this, Inkscape::CTRL_TYPE_POINT, // TRANSLATORS: This refers to the pattern that's inside the object _("Move the pattern fill inside the object"), diff --git a/src/object-edit.cpp b/src/object-edit.cpp index e9b183eca..fe22f6c1c 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -79,8 +79,8 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) knotholder = new OffsetKnotHolder(desktop, item, NULL); } else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { knotholder = new FlowtextKnotHolder(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL); - } else if ((item->style->fill.isPaintserver()) - && SP_IS_PATTERN(item->style->getFillPaintServer())) { + } else if ((item->style->fill.isPaintserver() && SP_IS_PATTERN(item->style->getFillPaintServer())) || + (item->style->stroke.isPaintserver() && SP_IS_PATTERN(item->style->getStrokePaintServer()))) { knotholder = new KnotHolder(desktop, item, NULL); knotholder->add_pattern_knotholder(); } diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 6c2ada9d7..780845deb 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -1109,9 +1109,10 @@ void SPItem::invoke_hide(unsigned key) // Adjusters -void SPItem::adjust_pattern (Geom::Affine const &postmul, bool set) +void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransform pt) { - if (style && (style->fill.isPaintserver())) { + bool fill = (pt == TRANSFORM_FILL || pt == TRANSFORM_BOTH); + if (fill && style && (style->fill.isPaintserver())) { SPObject *server = style->getFillPaintServer(); if ( SP_IS_PATTERN(server) ) { SPPattern *pattern = sp_pattern_clone_if_necessary(this, SP_PATTERN(server), "fill"); @@ -1119,7 +1120,8 @@ void SPItem::adjust_pattern (Geom::Affine const &postmul, bool set) } } - if (style && (style->stroke.isPaintserver())) { + bool stroke = (pt == TRANSFORM_STROKE || pt == TRANSFORM_BOTH); + if (stroke && style && (style->stroke.isPaintserver())) { SPObject *server = style->getStrokePaintServer(); if ( SP_IS_PATTERN(server) ) { SPPattern *pattern = sp_pattern_clone_if_necessary(this, SP_PATTERN(server), "stroke"); diff --git a/src/sp-item.h b/src/sp-item.h index ce93b1d40..2880f4a8e 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -51,6 +51,13 @@ enum { SP_EVENT_MOUSEOUT }; +// TODO fix this +enum PatternTransform { + TRANSFORM_BOTH, + TRANSFORM_FILL, + TRANSFORM_STROKE +}; + /** * Event structure. * @@ -199,7 +206,7 @@ public: Inkscape::DrawingItem *invoke_show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); void invoke_hide(unsigned int key); void getSnappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs=0) const; - void adjust_pattern(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false); + void adjust_pattern(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false, PatternTransform = TRANSFORM_BOTH); void adjust_gradient(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false); void adjust_stroke(gdouble ex); void adjust_stroke_width_recursive(gdouble ex); -- cgit v1.2.3 From 45ec749062c3d4fce289013150cb7b59e3f8c8d5 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 4 Aug 2014 12:51:39 -0400 Subject: Add context to TODO comment (bzr r13490) --- src/sp-item.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-item.h b/src/sp-item.h index 2880f4a8e..15784d041 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -51,7 +51,8 @@ enum { SP_EVENT_MOUSEOUT }; -// TODO fix this +// TODO make a completely new function that transforms either the fill or +// stroke of any SPItem without adding an extra parameter to adjust_pattern. enum PatternTransform { TRANSFORM_BOTH, TRANSFORM_FILL, -- cgit v1.2.3 From db7a8fdb0e8141c84886129ff2344c1959a26c49 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 4 Aug 2014 13:07:28 -0400 Subject: Warnings cleanup. (bzr r13341.1.117) --- src/style-internal.h | 2 +- src/style.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/style-internal.h b/src/style-internal.h index e76f9faaf..b549bb8ef 100644 --- a/src/style-internal.h +++ b/src/style-internal.h @@ -340,7 +340,7 @@ class SPIEnum : public SPIBase { public: SPIEnum() : SPIBase( "anonymous_enum" ), enums( NULL ), value(0), computed(0) {}; - SPIEnum( Glib::ustring name, SPStyleEnum const *enums, unsigned value = 0, bool inherits = true ) : + SPIEnum( Glib::ustring const name, SPStyleEnum const *enums, unsigned value = 0, bool inherits = true ) : SPIBase( name, inherits ), enums( enums ), value(value), computed(value), value_default(value), computed_default(value) {}; // Following is needed for font-weight diff --git a/src/style.cpp b/src/style.cpp index a91611d89..66672e949 100644 --- a/src/style.cpp +++ b/src/style.cpp @@ -121,10 +121,6 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : // Text related properties text_indent( "text-indent", 0.0 ), // SPILength text_align( "text-align", enum_text_align, SP_CSS_TEXT_ALIGN_START ), - text_decoration(), - text_decoration_line(), - text_decoration_style(), - text_decoration_color( "text-decoration-color" ), // SPIColor letter_spacing( "letter-spacing", 0.0 ), // SPILengthOrNormal word_spacing( "word-spacing", 0.0 ), // SPILengthOrNormal @@ -137,6 +133,11 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : text_anchor( "text-anchor", enum_text_anchor, SP_CSS_TEXT_ANCHOR_START ), white_space( "white-space", enum_white_space, SP_CSS_WHITE_SPACE_NORMAL ), + text_decoration(), + text_decoration_line(), + text_decoration_style(), + text_decoration_color( "text-decoration-color" ), // SPIColor + // General visual properties clip_rule( "clip-rule", enum_clip_rule, SP_WIND_RULE_NONZERO ), display( "display", enum_display, SP_CSS_DISPLAY_INLINE, false ), @@ -190,7 +191,6 @@ SPStyle::SPStyle(SPDocument *document_in, SPObject *object_in) : image_rendering( "image-rendering", enum_image_rendering, SP_CSS_IMAGE_RENDERING_AUTO), shape_rendering( "shape-rendering", enum_shape_rendering, SP_CSS_SHAPE_RENDERING_AUTO), text_rendering( "text-rendering", enum_text_rendering, SP_CSS_TEXT_RENDERING_AUTO ) - { // std::cout << "SPStyle::SPStyle( SPDocument ): Entrance: (" << _count << ")" << std::endl; // std::cout << " Document: " << (document_in?"present":"null") << std::endl; -- cgit v1.2.3 From 6c4eb87454986e1e4c680b7b7f8fe8a166b25cda Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Mon, 4 Aug 2014 13:23:56 -0400 Subject: refresh bbox of clipped clone (Bug 1349018) Fixed bugs: - https://launchpad.net/bugs/1349018 (bzr r13491) --- src/sp-item.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 780845deb..0cacc86b1 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -778,6 +778,7 @@ Geom::OptRect SPItem::visualBounds(Geom::Affine const &transform) const bbox = const_cast(this)->bbox(transform, SPItem::VISUAL_BBOX); } if (clip_ref->getObject()) { + SP_ITEM(clip_ref->getOwner())->bbox_valid = FALSE; // LP Bug 1349018 bbox.intersectWith(SP_CLIPPATH(clip_ref->getObject())->geometricBounds(transform)); } -- cgit v1.2.3 From e10cfb995e21d325b6d70e54b6a58d604af4e1a5 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 5 Aug 2014 10:03:55 -0400 Subject: Fix for parsing of incorrect SVG arcs (bug #1330295) Fixed bugs: - https://launchpad.net/bugs/1330295 (bzr r13492) --- src/2geom/svg-path-parser.cpp | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp index ccc383920..811a04c3c 100644 --- a/src/2geom/svg-path-parser.cpp +++ b/src/2geom/svg-path-parser.cpp @@ -1,5 +1,3 @@ - -#line 1 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" /** * \file * \brief parse SVG path specifications @@ -130,6 +128,9 @@ private: void _arcTo(double rx, double ry, double angle, bool large_arc, bool sweep, Point p) { + if (_current == p) { + return; + } _quad_tangent = _cubic_tangent = _current = p; _sink.arcTo(rx, ry, angle, large_arc, sweep, p); } @@ -141,7 +142,6 @@ private: }; -#line 145 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" static const char _svg_path_actions[] = { 0, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 15, 1, @@ -1147,9 +1147,6 @@ static const int svg_path_first_final = 270; //static const int svg_path_en_main = 1; -#line 144 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" - - void Parser::parse(char const *str) throw(SVGPathParseError) { @@ -1159,13 +1156,11 @@ throw(SVGPathParseError) _reset(); - -#line 1164 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" { cs = svg_path_start; } -#line 1169 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" + { int _klen; unsigned int _trans; @@ -1238,13 +1233,12 @@ _match: switch ( *_acts++ ) { case 0: -#line 156 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { start = p; } break; case 1: -#line 160 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { char const *end=p; std::string buf(start, end); @@ -1253,55 +1247,49 @@ _match: } break; case 2: -#line 167 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { _push(1.0); } break; case 3: -#line 171 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { _push(0.0); } break; case 4: -#line 175 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" + { _absolute = true; } break; case 5: -#line 179 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _absolute = false; } break; case 6: -#line 183 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _moveTo(_pop_point()); } break; case 7: -#line 187 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _lineTo(_pop_point()); } break; case 8: -#line 191 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _hlineTo(Point(_pop_coord(X), _current[Y])); } break; case 9: -#line 195 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _vlineTo(Point(_current[X], _pop_coord(Y))); } break; case 10: -#line 199 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1310,7 +1298,6 @@ _match: } break; case 11: -#line 206 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c1 = _pop_point(); @@ -1318,7 +1305,6 @@ _match: } break; case 12: -#line 212 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); Point c = _pop_point(); @@ -1326,14 +1312,12 @@ _match: } break; case 13: -#line 218 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point p = _pop_point(); _quadTo(_quad_tangent, p); } break; case 14: -#line 223 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { Point point = _pop_point(); bool sweep = _pop_flag(); @@ -1346,16 +1330,13 @@ _match: } break; case 15: -#line 234 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" { _closePath(); } break; case 16: -#line 370 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" {{p++; goto _out; }} break; -#line 1359 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.cpp" } } @@ -1367,8 +1348,6 @@ _again: _out: {} } -#line 380 "/home/tweenk/src/lib2geom/src/2geom/svg-path-parser.rl" - if ( cs < svg_path_first_final ) { throw SVGPathParseError(); -- cgit v1.2.3 From a8c287d1920aec5339b609e9aa3ce297a8f7847d Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Tue, 5 Aug 2014 22:57:14 +0200 Subject: supplemental change to lp:inkscape rev13492 (ignore arc segments when start and endpoint are equal (within error range) Fixed bugs: - https://launchpad.net/bugs/1330295 (bzr r13493) --- src/2geom/svg-path-parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/2geom/svg-path-parser.cpp b/src/2geom/svg-path-parser.cpp index 811a04c3c..932f95829 100644 --- a/src/2geom/svg-path-parser.cpp +++ b/src/2geom/svg-path-parser.cpp @@ -128,7 +128,7 @@ private: void _arcTo(double rx, double ry, double angle, bool large_arc, bool sweep, Point p) { - if (_current == p) { + if (are_near(_current, p)) { return; } _quad_tangent = _cubic_tangent = _current = p; -- cgit v1.2.3 From 5ff454abb53a13499cce928b94cf7538d5ded631 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 6 Aug 2014 17:29:56 +0200 Subject: Fix bug #1241501, improve tooltip text on path parameter (bzr r13494) --- src/live_effects/parameter/path.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 44d414942..8095056b7 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -197,7 +197,7 @@ PathParam::param_newWidget() pButton->show(); pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click)); static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Link to path")); + pButton->set_tooltip_text(_("Link to path on clipboard")); static_cast(_widget)->show_all_children(); -- cgit v1.2.3 From 8622d1b422ae5305c54174e3e62fdfce9206ef38 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 6 Aug 2014 17:33:21 +0200 Subject: Fix bug #1241501, improve tooltip text on path parameter (bzr r13341.1.118) --- src/live_effects/parameter/path.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 44d414942..8095056b7 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -197,7 +197,7 @@ PathParam::param_newWidget() pButton->show(); pButton->signal_clicked().connect(sigc::mem_fun(*this, &PathParam::on_link_button_click)); static_cast(_widget)->pack_start(*pButton, true, true); - pButton->set_tooltip_text(_("Link to path")); + pButton->set_tooltip_text(_("Link to path on clipboard")); static_cast(_widget)->show_all_children(); -- cgit v1.2.3 From ae2a18ac114c2abc0b9358142ece9d7a93ae10be Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 6 Aug 2014 12:47:36 -0400 Subject: Fix for bug #1348375 (randomized stars change on translation) Fixed bugs: - https://launchpad.net/bugs/1348375 (bzr r13495) --- src/sp-star.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sp-star.cpp b/src/sp-star.cpp index eac33ed7b..712029468 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -513,10 +513,12 @@ void SPStar::snappoints(std::vector &p, Inkscape:: } } -Geom::Affine SPStar::set_transform(Geom::Affine const &xform) +Geom::Affine SPStar::set_transform(Geom::Affine const &tform) { + Geom::Affine xform = (randomized == 0 ? tform.withoutTranslation() : tform); + // Only set transform with proportional scaling - if (!xform.withoutTranslation().isUniformScale()) { + if (!xform.isUniformScale()) { return xform; } @@ -530,7 +532,7 @@ Geom::Affine SPStar::set_transform(Geom::Affine const &xform) /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ - Geom::Affine ret(Geom::Affine(xform).withoutTranslation()); + Geom::Affine ret(xform); gdouble const s = hypot(ret[0], ret[1]); if (s > 1e-9) { ret[0] /= s; -- cgit v1.2.3 From 0c91933becbe5bf17be180a0f897b4ec2b26c696 Mon Sep 17 00:00:00 2001 From: Tomasz Boczkowski Date: Wed, 6 Aug 2014 13:56:59 -0400 Subject: Fix for bug #1227193 (undo issues) Fixed bugs: - https://launchpad.net/bugs/1227193 (bzr r13496) --- src/document-undo.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 39c8a04a0..53e701648 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -255,6 +255,7 @@ gboolean Inkscape::DocumentUndo::undo(SPDocument *doc) Inkscape::Event *log=(Inkscape::Event *)doc->priv->undo->data; doc->priv->undo = g_slist_remove (doc->priv->undo, log); sp_repr_undo_log (log->event); + doc->_updateDocument(); doc->priv->redo = g_slist_prepend (doc->priv->redo, log); doc->setModifiedSinceSave(); -- cgit v1.2.3 From d495771e8e1b00845919fc77ca9b2e3894f8a21a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 6 Aug 2014 14:33:26 -0400 Subject: Fix for bug #1327267 (excessive calls to sp_style_read_from_prefs) Fixed bugs: - https://launchpad.net/bugs/1327267 (bzr r13497) --- src/widgets/text-toolbar.cpp | 45 ++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 64a7cd5e7..36a151c52 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -31,7 +31,6 @@ #include "libnrtype/font-lister.h" #include #include "text-toolbar.h" -#include "connection-pool.h" #include "desktop-handles.h" #include "desktop-style.h" #include "desktop.h" @@ -54,6 +53,7 @@ #include "toolbox.h" #include "ui/icon-names.h" #include "ui/tools/text-tool.h" +#include "ui/tools/tool-base.h" #include "verbs.h" #include "xml/repr.h" @@ -1200,6 +1200,7 @@ static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*p selection->setList(selectList); } +static void text_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); // Define all the "widgets" in the toolbar. void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) @@ -1622,31 +1623,35 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje // Is this necessary to call? Shouldn't hurt. sp_text_toolbox_selection_changed(sp_desktop_selection(desktop), holder); - // Watch selection - Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISTextToolboxGTK"); - - sigc::connection *c_selection_changed = - new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), holder))); - pool->add_connection ("selection-changed", c_selection_changed); - - sigc::connection *c_selection_modified = - new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_modified), holder))); - pool->add_connection ("selection-modified", c_selection_modified); - - sigc::connection *c_subselection_changed = - new sigc::connection (desktop->connectToolSubselectionChanged - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_subselection_changed), holder))); - pool->add_connection ("tool-subselection-changed", c_subselection_changed); - - Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(text_toolbox_watch_ec), holder)); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); } +static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) { + using sigc::connection; + using sigc::bind; + using sigc::ptr_fun; + static connection c_selection_changed; + static connection c_selection_modified; + static connection c_subselection_changed; + + if (SP_IS_TEXT_CONTEXT(ec)) { + // Watch selection + c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder)); + c_selection_modified = sp_desktop_selection (desktop)->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); + c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder)); + } else { + if (c_selection_changed) + c_selection_changed.disconnect(); + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_subselection_changed) + c_subselection_changed.disconnect(); + } +} /* Local Variables: mode:c++ -- cgit v1.2.3 From efcaaaf38289ebf771c0b8a0cec29a5976164f45 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 6 Aug 2014 15:27:37 -0400 Subject: Fix mistake introduced in r13495 (bzr r13498) --- src/sp-star.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-star.cpp b/src/sp-star.cpp index 712029468..a9bb946c2 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -516,7 +516,6 @@ void SPStar::snappoints(std::vector &p, Inkscape:: Geom::Affine SPStar::set_transform(Geom::Affine const &tform) { Geom::Affine xform = (randomized == 0 ? tform.withoutTranslation() : tform); - // Only set transform with proportional scaling if (!xform.isUniformScale()) { return xform; @@ -528,7 +527,7 @@ Geom::Affine SPStar::set_transform(Geom::Affine const &tform) } /* Calculate star start in parent coords. */ - Geom::Point pos( this->center * xform ); + Geom::Point pos( this->center * tform ); /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ -- cgit v1.2.3 From 0fea5bc6928fcd9b6b7ccc3434d4a7b3147c775f Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 6 Aug 2014 15:36:33 -0400 Subject: Fix another mistake introduced in r13495 (bzr r13499) --- src/sp-star.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/sp-star.cpp b/src/sp-star.cpp index a9bb946c2..a43d681ce 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -513,9 +513,8 @@ void SPStar::snappoints(std::vector &p, Inkscape:: } } -Geom::Affine SPStar::set_transform(Geom::Affine const &tform) +Geom::Affine SPStar::set_transform(Geom::Affine const &xform) { - Geom::Affine xform = (randomized == 0 ? tform.withoutTranslation() : tform); // Only set transform with proportional scaling if (!xform.isUniformScale()) { return xform; @@ -527,7 +526,7 @@ Geom::Affine SPStar::set_transform(Geom::Affine const &tform) } /* Calculate star start in parent coords. */ - Geom::Point pos( this->center * tform ); + Geom::Point pos( this->center * xform ); /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ -- cgit v1.2.3 From 2029349f5291ae10048202732a89f34c0a179130 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 6 Aug 2014 20:40:19 -0400 Subject: Add in some debugging code that will complain when deleted knots are accessed by snap handler (bzr r13341.1.120) --- src/CMakeLists.txt | 2 ++ src/Makefile_insert | 1 + src/knot-ptr.cpp | 25 +++++++++++++++++++++++++ src/knot-ptr.h | 8 ++++++++ src/knot.cpp | 3 +++ src/ui/tools/tool-base.cpp | 2 ++ 6 files changed, 41 insertions(+) create mode 100644 src/knot-ptr.cpp create mode 100644 src/knot-ptr.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a792af6b..94b4b8c85 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -218,6 +218,7 @@ set(inkscape_SRC knot-holder-entity.cpp knot.cpp knotholder.cpp + knot-ptr.cpp layer-fns.cpp layer-manager.cpp layer-model.cpp @@ -356,6 +357,7 @@ set(inkscape_SRC knot-holder-entity.h knot.h knotholder.h + knot-ptr.h layer-fns.h layer-manager.h layer-model.h diff --git a/src/Makefile_insert b/src/Makefile_insert index f191839a1..436ab26f9 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -80,6 +80,7 @@ ink_common_sources += \ knot-enums.h \ knotholder.cpp knotholder.h \ knot-holder-entity.h knot-holder-entity.cpp \ + knot-ptr.h knot-ptr.cpp \ layer-fns.cpp layer-fns.h \ layer-manager.cpp layer-manager.h \ layer-model.cpp layer-model.h \ diff --git a/src/knot-ptr.cpp b/src/knot-ptr.cpp new file mode 100644 index 000000000..de8118ba7 --- /dev/null +++ b/src/knot-ptr.cpp @@ -0,0 +1,25 @@ +#include +#include +#include +#include "knot-ptr.h" + +static std::list deleted_knots; + +void knot_deleted_callback(void* knot) { + if (std::find(deleted_knots.begin(), deleted_knots.end(), knot) == deleted_knots.end()) { + deleted_knots.push_back(knot); + } +} + +void knot_created_callback(void* knot) { + std::list::iterator it = std::find(deleted_knots.begin(), deleted_knots.end(), knot); + if (it != deleted_knots.end()) { + deleted_knots.erase(it); + } +} + +void check_if_knot_deleted(void* knot) { + if (std::find(deleted_knots.begin(), deleted_knots.end(), knot) != deleted_knots.end()) { + g_warning("Accessed knot after it was freed at %p", knot); + } +} diff --git a/src/knot-ptr.h b/src/knot-ptr.h new file mode 100644 index 000000000..5895dfd2e --- /dev/null +++ b/src/knot-ptr.h @@ -0,0 +1,8 @@ +#ifndef KNOT_PTR_DETECTOR +#define KNOT_PTR_DETECTOR + +void knot_deleted_callback(void* knot); +void knot_created_callback(void* knot); +void check_if_knot_deleted(void* knot); + +#endif diff --git a/src/knot.cpp b/src/knot.cpp index 2f8f55a2e..6205af26a 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -21,6 +21,7 @@ #include "desktop.h" #include "desktop-handles.h" #include "knot.h" +#include "knot-ptr.h" #include "document.h" #include "document-undo.h" #include "preferences.h" @@ -118,6 +119,7 @@ SPKnot::SPKnot(SPDesktop *desktop, gchar const *tip) this->_event_handler_id = g_signal_connect(G_OBJECT(this->item), "event", G_CALLBACK(sp_knot_handler), this); + knot_created_callback(this); } SPKnot::~SPKnot() { @@ -165,6 +167,7 @@ SPKnot::~SPKnot() { // FIXME: cannot snap to destroyed knot (lp:1309050) //sp_event_context_discard_delayed_snap_event(this->desktop->event_context); + knot_deleted_callback(this); } void SPKnot::startDragging(Geom::Point const &p, gint x, gint y, guint32 etime) { diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index f1d90f6c6..c23da87c0 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -58,6 +58,7 @@ #include "sp-guide.h" #include "color.h" #include "knot.h" +#include "knot-ptr.h" // globals for temporary switching to selector by space static bool selector_toggled = FALSE; @@ -1359,6 +1360,7 @@ gboolean sp_event_context_snap_watchdog_callback(gpointer data) { break; case DelayedSnapEvent::KNOT_HANDLER: { gpointer knot = dse->getItem2(); + check_if_knot_deleted(knot); if (knot && SP_IS_KNOT(knot)) { sp_knot_handler_request_position(dse->getEvent(), SP_KNOT(knot)); } -- cgit v1.2.3 From 7a0d091a5e5599ceff0eb4c20f7b6e818057e5c1 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 6 Aug 2014 21:45:33 -0400 Subject: Redo the fix for bug #1348375 (bzr r13500) --- src/sp-star.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sp-star.cpp b/src/sp-star.cpp index a43d681ce..97a690520 100644 --- a/src/sp-star.cpp +++ b/src/sp-star.cpp @@ -515,8 +515,9 @@ void SPStar::snappoints(std::vector &p, Inkscape:: Geom::Affine SPStar::set_transform(Geom::Affine const &xform) { + bool opt_trans = (randomized == 0); // Only set transform with proportional scaling - if (!xform.isUniformScale()) { + if (!xform.withoutTranslation().isUniformScale()) { return xform; } @@ -530,7 +531,7 @@ Geom::Affine SPStar::set_transform(Geom::Affine const &xform) /* This function takes care of translation and scaling, we return whatever parts we can't handle. */ - Geom::Affine ret(xform); + Geom::Affine ret(opt_trans ? xform.withoutTranslation() : xform); gdouble const s = hypot(ret[0], ret[1]); if (s > 1e-9) { ret[0] /= s; -- cgit v1.2.3 From 10f3e62a490f3942c0f5be3947d99c4a4f41ea1e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 7 Aug 2014 08:06:10 +0200 Subject: Connectors. Fix for Bug #1155046 (Assertion pathlen < 200 failed). Fixed bugs: - https://launchpad.net/bugs/1155046 (bzr r13501) --- src/libavoid/connector.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libavoid/connector.cpp b/src/libavoid/connector.cpp index b8c99a48c..40ded7498 100644 --- a/src/libavoid/connector.cpp +++ b/src/libavoid/connector.cpp @@ -845,7 +845,10 @@ bool ConnRef::generatePath(void) break; } // Check we don't have an apparent infinite connector path. - COLA_ASSERT(pathlen < 200); +//#ifdef PATHDEBUG + db_printf("Path length: %i\n", pathlen); +//#endif + COLA_ASSERT(pathlen < 10000); } std::vector path(pathlen); -- cgit v1.2.3 From 5a4eae28b6bd036a3ba87fdf90f8560cc1ca5c41 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Thu, 7 Aug 2014 13:43:16 -0400 Subject: refresh clip path when editing in XML editor (Bug 1349018) Fixed bugs: - https://launchpad.net/bugs/1349018 (bzr r13502) --- src/ui/dialog/xml-tree.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 55d0aff09..c87e42633 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -1033,6 +1033,7 @@ void XmlTree::cmd_set_attr() updated->updateRepr(); } + reinterpret_cast(current_desktop->currentLayer())->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); DocumentUndo::done(current_document, SP_VERB_DIALOG_XML_EDITOR, _("Change attribute")); -- cgit v1.2.3 From 0561be82a9285311360df88d61e31505073a2de3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 7 Aug 2014 16:31:25 -0400 Subject: Rendering performance. Optimize bezier cases, implement arc rendering via Cairo. (bzr r13341.1.121) --- src/display/cairo-utils.cpp | 90 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 5b358ade7..15ce35146 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -19,6 +19,7 @@ #include #include <2geom/pathvector.h> #include <2geom/bezier-curve.h> +#include <2geom/elliptical-arc.h> #include <2geom/hvlinesegment.h> #include <2geom/affine.h> #include <2geom/point.h> @@ -502,7 +503,17 @@ void Pixbuf::ensurePixelFormat(PixelFormat fmt) static void feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & trans, Geom::Rect view, bool optimize_stroke) { - if( is_straight_curve(c) ) + using Geom::X; + using Geom::Y; + + unsigned order = 0; + if (Geom::BezierCurve const* b = dynamic_cast(&c)) { + order = b->order(); + } + + // handle the three typical curve cases + switch (order) { + case 1: { Geom::Point end_tr = c.finalPoint() * trans; if (!optimize_stroke) { @@ -516,57 +527,96 @@ feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & tran } } } - else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast(&c)) { + break; + case 2: + { + Geom::QuadraticBezier const *quadratic_bezier = static_cast(&c); std::vector points = quadratic_bezier->points(); points[0] *= trans; points[1] *= trans; points[2] *= trans; + // degree-elevate to cubic Bezier, since Cairo doesn't do quadratic Beziers Geom::Point b1 = points[0] + (2./3) * (points[1] - points[0]); Geom::Point b2 = b1 + (1./3) * (points[2] - points[0]); if (!optimize_stroke) { - cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][0], points[2][1]); + cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][X], points[2][Y]); } else { Geom::Rect swept(points[0], points[2]); swept.expandTo(points[1]); if (swept.intersects(view)) { - cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][0], points[2][1]); + cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][X], points[2][Y]); } else { - cairo_move_to(cr, points[2][0], points[2][1]); + cairo_move_to(cr, points[2][X], points[2][Y]); } } } - else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast(&c)) { + break; + case 3: + { + Geom::CubicBezier const *cubic_bezier = static_cast(&c); std::vector points = cubic_bezier->points(); //points[0] *= trans; // don't do this one here for fun: it is only needed for optimized strokes points[1] *= trans; points[2] *= trans; points[3] *= trans; if (!optimize_stroke) { - cairo_curve_to(cr, points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]); + cairo_curve_to(cr, points[1][X], points[1][Y], points[2][X], points[2][Y], points[3][X], points[3][Y]); } else { points[0] *= trans; // didn't transform this point yet Geom::Rect swept(points[0], points[3]); swept.expandTo(points[1]); swept.expandTo(points[2]); if (swept.intersects(view)) { - cairo_curve_to(cr, points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]); + cairo_curve_to(cr, points[1][X], points[1][Y], points[2][X], points[2][Y], points[3][X], points[3][Y]); } else { - cairo_move_to(cr, points[3][0], points[3][1]); + cairo_move_to(cr, points[3][X], points[3][Y]); } } } -// else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast(c)) { -// //TODO: get at the innards and spit them out to cairo -// } - else { - //this case handles sbasis as well as all other curve types - Geom::Path sbasis_path = Geom::cubicbezierpath_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) { - feed_curve_to_cairo(cr, *iter, trans, view, optimize_stroke); + break; + default: + { + if (Geom::EllipticalArc const *a = dynamic_cast(&c)) { + if (!optimize_stroke || a->boundsFast().intersects(view)) { + Geom::Affine xform = a->unitCircleTransform() * trans; + bool sweep = a->sweep(); + Geom::Point ang(a->initialAngle().radians(), a->finalAngle().radians()); + // Apply the transformation to the current context + cairo_matrix_t cm; + cm.xx = xform[0]; + cm.xy = xform[2]; + cm.x0 = xform[4]; + cm.yx = xform[1]; + cm.yy = xform[3]; + cm.y0 = xform[5]; + + cairo_save(cr); + cairo_transform(cr, &cm); + + // Draw the circle + if (sweep) { + cairo_arc(cr, 0, 0, 1, ang[0], ang[1]); + } else { + cairo_arc_negative(cr, 0, 0, 1, ang[0], ang[1]); + } + + cairo_restore(cr); + } else { + cairo_move_to(cr, a->finalPoint()[X], a->finalPoint()[Y]); + } + } else { + // handles sbasis as well as all other curve types + // this is very slow + Geom::Path sbasis_path = Geom::cubicbezierpath_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) { + feed_curve_to_cairo(cr, *iter, trans, view, optimize_stroke); + } } } + break; + } } @@ -579,7 +629,7 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path) cairo_move_to(ct, path.initialPoint()[0], path.initialPoint()[1] ); - for(Geom::Path::const_iterator cit = path.begin(); cit != path.end_open(); ++cit) { + for (Geom::Path::const_iterator cit = path.begin(); cit != path.end_open(); ++cit) { feed_curve_to_cairo(ct, *cit, Geom::identity(), Geom::Rect(), false); // optimize_stroke is false, so the view rect is not used } -- cgit v1.2.3 From a8e25e6d4a86ffcfc6facb8efbba093f995fe8fc Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 7 Aug 2014 20:34:34 -0400 Subject: Fix small regression (bzr r13341.1.122) --- src/display/cairo-utils.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 15ce35146..d6ff7b2f0 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -539,12 +539,12 @@ feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & tran Geom::Point b1 = points[0] + (2./3) * (points[1] - points[0]); Geom::Point b2 = b1 + (1./3) * (points[2] - points[0]); if (!optimize_stroke) { - cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][X], points[2][Y]); + cairo_curve_to(cr, b1[X], b1[Y], b2[X], b2[Y], points[2][X], points[2][Y]); } else { Geom::Rect swept(points[0], points[2]); swept.expandTo(points[1]); if (swept.intersects(view)) { - cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][X], points[2][Y]); + cairo_curve_to(cr, b1[X], b1[Y], b2[X], b2[Y], points[2][X], points[2][Y]); } else { cairo_move_to(cr, points[2][X], points[2][Y]); } @@ -577,10 +577,10 @@ feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & tran default: { if (Geom::EllipticalArc const *a = dynamic_cast(&c)) { - if (!optimize_stroke || a->boundsFast().intersects(view)) { + //if (!optimize_stroke || a->boundsFast().intersects(view)) { Geom::Affine xform = a->unitCircleTransform() * trans; - bool sweep = a->sweep(); Geom::Point ang(a->initialAngle().radians(), a->finalAngle().radians()); + // Apply the transformation to the current context cairo_matrix_t cm; cm.xx = xform[0]; @@ -594,16 +594,17 @@ feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & tran cairo_transform(cr, &cm); // Draw the circle - if (sweep) { + if (a->sweep()) { cairo_arc(cr, 0, 0, 1, ang[0], ang[1]); } else { cairo_arc_negative(cr, 0, 0, 1, ang[0], ang[1]); } - + // Revert the current context cairo_restore(cr); - } else { - cairo_move_to(cr, a->finalPoint()[X], a->finalPoint()[Y]); - } + //} else { + // Geom::Point f = a->finalPoint() * trans; + // cairo_move_to(cr, f[X], f[Y]); + //} } else { // handles sbasis as well as all other curve types // this is very slow -- cgit v1.2.3 From 2c681a38a34a12162c713d1a923256433bf57e82 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 7 Aug 2014 21:35:14 -0400 Subject: Small tweak to bbox calculation (bzr r13341.1.123) --- src/helper/geom.cpp | 53 +++++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/helper/geom.cpp b/src/helper/geom.cpp index c9148a634..6eba6e949 100644 --- a/src/helper/geom.cpp +++ b/src/helper/geom.cpp @@ -168,24 +168,25 @@ bounds_exact_transformed(Geom::PathVector const & pv, Geom::Affine const & t) for (Geom::Path::const_iterator cit = it->begin(); cit != it->end_open(); ++cit) { Geom::Curve const &c = *cit; - if( is_straight_curve(c) ) - { - bbox.expandTo( c.finalPoint() * t ); - } - else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast(&c)) - { - Geom::Point c0 = (*cubic_bezier)[0] * t; - Geom::Point c1 = (*cubic_bezier)[1] * t; - Geom::Point c2 = (*cubic_bezier)[2] * t; - Geom::Point c3 = (*cubic_bezier)[3] * t; - cubic_bbox( c0[0], c0[1], - c1[0], c1[1], - c2[0], c2[1], - c3[0], c3[1], - bbox ); + unsigned order = 0; + if (Geom::BezierCurve const* b = dynamic_cast(&c)) { + order = b->order(); } - else - { + + if (order == 1) { // line segment + bbox.expandTo(c.finalPoint() * t); + + // TODO: we can make the case for quadratics faster by degree elevating them to + // cubic and then taking the bbox of that. + + } else if (order == 3) { // cubic bezier + Geom::CubicBezier const &cubic_bezier = static_cast(c); + Geom::Point c0 = cubic_bezier[0] * t; + Geom::Point c1 = cubic_bezier[1] * t; + Geom::Point c2 = cubic_bezier[2] * t; + Geom::Point c3 = cubic_bezier[3] * t; + cubic_bbox(c0[0], c0[1], c1[0], c1[1], c2[0], c2[1], c3[0], c3[1], bbox); + } else { // should handle all not-so-easy curves: Geom::Curve *ctemp = cit->transformed(t); bbox.unionWith( ctemp->boundsExact()); @@ -356,8 +357,11 @@ geom_curve_bbox_wind_distance(Geom::Curve const & c, Geom::Affine const &m, Geom::Coord tolerance, Geom::Rect const *viewbox, Geom::Point &p0) // pass p0 through as it represents the last endpoint added (the finalPoint of last curve) { - if( is_straight_curve(c) ) - { + unsigned order = 0; + if (Geom::BezierCurve const* b = dynamic_cast(&c)) { + order = b->order(); + } + if (order == 1) { Geom::Point pe = c.finalPoint() * m; if (bbox) { bbox->expandTo(pe); @@ -373,10 +377,11 @@ geom_curve_bbox_wind_distance(Geom::Curve const & c, Geom::Affine const &m, } p0 = pe; } - else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast(&c)) { - Geom::Point p1 = (*cubic_bezier)[1] * m; - Geom::Point p2 = (*cubic_bezier)[2] * m; - Geom::Point p3 = (*cubic_bezier)[3] * m; + else if (order == 3) { + Geom::CubicBezier const& cubic_bezier = static_cast(c); + Geom::Point p1 = cubic_bezier[1] * m; + Geom::Point p2 = cubic_bezier[2] * m; + Geom::Point p3 = cubic_bezier[3] * m; // get approximate bbox from handles (convex hull property of beziers): Geom::Rect swept(p0, p3); @@ -402,7 +407,7 @@ geom_curve_bbox_wind_distance(Geom::Curve const & c, Geom::Affine const &m, Geom::Path sbasis_path = Geom::cubicbezierpath_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) { + for (Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) { geom_curve_bbox_wind_distance(*iter, m, pt, bbox, wind, dist, tolerance, viewbox, p0); } } -- cgit v1.2.3 From d59ab0cc036239f5e2f6040b2f439ba7b55af4c3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 8 Aug 2014 09:47:46 -0400 Subject: Ponyscape feature: finish pen drawing on context switch (bzr r13090.1.101) --- src/ui/tools/pen-tool.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 9a73d497f..318591df5 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -239,7 +239,9 @@ void PenTool::finish() { sp_event_context_discard_delayed_snap_event(this); if (this->npoints != 0) { - this->_cancel(); + // switching context - finish path + this->ea = NULL; // unset end anchor if set (otherwise crashes) + this->_finish(false); } FreehandBase::finish(); -- cgit v1.2.3 From e9f9ba07739cdb52c649e8e10dca9de76c71114d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Fri, 8 Aug 2014 16:20:44 -0400 Subject: Massive performance improvment for basic node operations with thousands of nodes (bzr r13341.1.124) --- src/ui/tool/control-point-selection.cpp | 49 +++++++++++++++++++++++++++------ src/ui/tool/control-point-selection.h | 13 +++++---- src/ui/tool/multi-path-manipulator.cpp | 2 +- src/ui/tool/node.cpp | 32 ++++++++++++++++++++- src/ui/tool/path-manipulator.cpp | 10 +++++-- src/ui/tool/path-manipulator.h | 3 +- src/ui/tool/selectable-control-point.h | 1 + src/ui/tools/node-tool.cpp | 2 +- 8 files changed, 93 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index d10ed0f0d..998f74ee0 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -74,7 +74,7 @@ ControlPointSelection::~ControlPointSelection() } /** Add a control point to the selection. */ -std::pair ControlPointSelection::insert(const value_type &x) +std::pair ControlPointSelection::insert(const value_type &x, bool notify) { iterator found = _points.find(x); if (found != _points.end()) { @@ -86,6 +86,10 @@ std::pair ControlPointSelection::insert(c x->updateState(); _pointChanged(x, true); + if (notify) { + signal_selection_changed.emit(std::vector(1, x), true); + } + return std::pair(found, true); } @@ -97,47 +101,75 @@ void ControlPointSelection::erase(iterator pos) erased->updateState(); _pointChanged(erased, false); } -ControlPointSelection::size_type ControlPointSelection::erase(const key_type &k) +ControlPointSelection::size_type ControlPointSelection::erase(const key_type &k, bool notify) { iterator pos = _points.find(k); if (pos == _points.end()) return 0; erase(pos); + + if (notify) { + signal_selection_changed.emit(std::vector(1, k), false); + } return 1; } void ControlPointSelection::erase(iterator first, iterator last) { + std::vector out(first, last); while (first != last) erase(first++); + signal_selection_changed.emit(out, false); } /** Remove all points from the selection, making it empty. */ void ControlPointSelection::clear() { + std::vector out(begin(), end()); for (iterator i = begin(); i != end(); ) erase(i++); + if (!out.empty()) + signal_selection_changed.emit(out, false); } /** Select all points that this selection can contain. */ void ControlPointSelection::selectAll() { for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) { - insert(*i); + insert(*i, false); } + std::vector out(_all_points.begin(), _all_points.end()); + if (!out.empty()) + signal_selection_changed.emit(out, true); } /** Select all points inside the given rectangle (in desktop coordinates). */ void ControlPointSelection::selectArea(Geom::Rect const &r) { + std::vector out; for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) { - if (r.contains(**i)) - insert(*i); + if (r.contains(**i)) { + insert(*i, false); + out.push_back(*i); + } } + if (!out.empty()) + signal_selection_changed.emit(out, true); } /** Unselect all selected points and select all unselected points. */ void ControlPointSelection::invertSelection() { + std::vector in, out; for (set_type::iterator i = _all_points.begin(); i != _all_points.end(); ++i) { - if ((*i)->selected()) erase(*i); - else insert(*i); + if ((*i)->selected()) { + in.push_back(*i); + erase(*i); + } + else { + out.push_back(*i); + insert(*i, false); + } } + if (!in.empty()) + signal_selection_changed.emit(in, false); + if (!out.empty()) + signal_selection_changed.emit(out, true); } void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir) { @@ -166,6 +198,7 @@ void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir) if (match) { if (grow) insert(match); else erase(match); + signal_selection_changed.emit(std::vector(1, match), grow); } } @@ -389,7 +422,7 @@ void ControlPointSelection::_pointChanged(SelectableControlPoint *p, bool select _handles->rotationCenter().move(_bounds->midpoint()); } - signal_point_changed.emit(p, selected); + //signal_point_changed.emit(p, selected); } void ControlPointSelection::_mouseoverChanged() diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index a087e0455..2d812c0a3 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -62,18 +62,19 @@ public: const_iterator end() const { return _points.end(); } // insert - std::pair insert(const value_type& x); + std::pair insert(const value_type& x, bool notify = true); template void insert(InputIterator first, InputIterator last) { for (; first != last; ++first) { - insert(*first); + insert(*first, false); } + signal_selection_changed.emit(std::vector(first, last), true); } // erase void clear(); void erase(iterator pos); - size_type erase(const key_type& k); + size_type erase(const key_type& k, bool notify = true); void erase(iterator first, iterator last); // find @@ -108,7 +109,9 @@ public: void toggleTransformHandlesMode(); sigc::signal signal_update; - sigc::signal signal_point_changed; + // It turns out that emitting a signal after every point is selected or deselected is not too efficient, + // so this can be done in a massive group once the selection is finally changed. + sigc::signal, bool> signal_selection_changed; sigc::signal signal_commit; void getOriginalPoints(std::vector &pts); @@ -166,4 +169,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 68aaa77a5..b32bafdbf 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -122,7 +122,7 @@ MultiPathManipulator::MultiPathManipulator(PathSharedData &data, sigc::connectio { _selection.signal_commit.connect( sigc::mem_fun(*this, &MultiPathManipulator::_commit)); - _selection.signal_point_changed.connect( + _selection.signal_selection_changed.connect( sigc::hide( sigc::hide( signal_coords_changed.make_slot()))); } diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index ed0843b65..e38f82673 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -1623,7 +1623,37 @@ void NodeList::reverse() void NodeList::clear() { - for (iterator i = begin(); i != end();) erase (i++); + // ugly but more efficient clearing mechanism + std::vector to_clear; + std::vector > nodes; + long in = -1; + for (iterator i = begin(); i != end(); ++i) { + SelectableControlPoint *rm = static_cast(i._node); + if (std::find(to_clear.begin(), to_clear.end(), &rm->_selection) == to_clear.end()) { + to_clear.push_back(&rm->_selection); + ++in; + } + nodes.push_back(std::make_pair(rm, in)); + } + for (size_t i = 0, e = nodes.size(); i != e; ++i) { + to_clear[nodes[i].second]->erase(nodes[i].first, false); + } + std::vector > emission; + for (long i = 0, e = to_clear.size(); i != e; ++i) { + emission.push_back(std::vector()); + for (size_t j = 0, f = nodes.size(); j != f; ++j) { + if (nodes[j].second != i) + break; + emission[i].push_back(nodes[j].first); + } + } + + for (size_t i = 0, e = emission.size(); i != e; ++i) { + to_clear[i]->signal_selection_changed.emit(emission[i], false); + } + + for (iterator i = begin(); i != end();) + erase (i++); } NodeList::iterator NodeList::erase(iterator i) diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 9839be437..5f20aece7 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -140,8 +140,8 @@ PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, _selection.signal_update.connect( sigc::bind(sigc::mem_fun(*this, &PathManipulator::update), false)); - _selection.signal_point_changed.connect( - sigc::mem_fun(*this, &PathManipulator::_selectionChanged)); + _selection.signal_selection_changed.connect( + sigc::mem_fun(*this, &PathManipulator::_selectionChangedM)); _desktop->signal_zoom_changed.connect( sigc::hide( sigc::mem_fun(*this, &PathManipulator::_updateOutlineOnZoomChange))); @@ -1524,6 +1524,12 @@ bool PathManipulator::_handleClicked(Handle *h, GdkEventButton *event) return false; } +void PathManipulator::_selectionChangedM(std::vector pvec, bool selected) { + for (size_t n = 0, e = pvec.size(); n < e; ++n) { + _selectionChanged(pvec[n], selected); + } +} + void PathManipulator::_selectionChanged(SelectableControlPoint *p, bool selected) { if (selected) ++_num_selected; diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 151805c83..4d2bf4300 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -122,7 +122,8 @@ private: Glib::ustring _nodetypesKey(); Inkscape::XML::Node *_getXMLNode(); - void _selectionChanged(SelectableControlPoint *p, bool selected); + void _selectionChangedM(std::vector pvec, bool selected); + void _selectionChanged(SelectableControlPoint * p, bool selected); bool _nodeClicked(Node *, GdkEventButton *); void _handleGrabbed(); bool _handleClicked(Handle *, GdkEventButton *); diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h index 8acfc1168..362d4addc 100644 --- a/src/ui/tool/selectable-control-point.h +++ b/src/ui/tool/selectable-control-point.h @@ -28,6 +28,7 @@ public: virtual Geom::Rect bounds() const { return Geom::Rect(position(), position()); } + friend class NodeList; protected: diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index d2584ee74..d4d7b2c35 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -245,7 +245,7 @@ void NodeTool::setup() { ) ); - this->_selected_nodes->signal_point_changed.connect( + this->_selected_nodes->signal_selection_changed.connect( // Hide both signal parameters and bind the function parameter to 0 // sigc::signal // <=> -- cgit v1.2.3 From 6db5e5df6f051c44e3f0e7dcadd1587a0b7227f1 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 9 Aug 2014 14:46:44 -0400 Subject: Fix related to bug #1327267 -- don't bother to update gradient toolbar when not in gradient tool (bzr r13504) --- src/widgets/gradient-toolbar.cpp | 75 ++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index 4fda44c8d..f5a99f3e7 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -448,11 +448,6 @@ static void gr_defs_modified(SPObject * /*defs*/, guint /*flags*/, GtkWidget *wi gr_tb_selection_changed(NULL, (gpointer) widget); } -static void gr_disconnect_sigc(GObject * /*obj*/, sigc::connection *connection) { - connection->disconnect(); - delete connection; -} - static SPStop *get_selected_stop( GtkWidget *vb) { SPStop *stop = NULL; @@ -1018,6 +1013,9 @@ void check_renderer(GtkWidget *combo) g_object_set_data(G_OBJECT(combo), "renderers", renderer); } } + +static void gradient_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + /** * Gradient auxiliary toolbar construction and setup. * @@ -1229,34 +1227,51 @@ void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), !linkedmode ); } - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPDocument *document = sp_desktop_document(desktop); - g_object_set_data(holder, "desktop", desktop); - // connect to selection modified and changed signals - sigc::connection *conn1 = new sigc::connection( - selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), (gpointer) holder))); - sigc::connection *conn2 = new sigc::connection( - selection->connectModified(sigc::bind(sigc::ptr_fun(&gr_tb_selection_modified), (gpointer) holder))); - sigc::connection *conn3 = new sigc::connection( - desktop->connectToolSubselectionChanged( sigc::bind(sigc::ptr_fun(&gr_drag_selection_changed), (gpointer) holder))); - - // when holder is destroyed, disconnect - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1); - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2); - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3); - - // connect to release and modified signals of the defs (i.e. when someone changes gradient) - sigc::connection *release_connection = new sigc::connection(); - *release_connection = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), GTK_WIDGET(holder))); - sigc::connection *modified_connection = new sigc::connection(); - *modified_connection = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), GTK_WIDGET(holder))); - - // when holder is destroyed, disconnect - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection); - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(&gradient_toolbox_check_ec), holder)); +} + +// lp:1327267 +/** + * Checks the current tool and connects gradient aux toolbox signals if it happens to be the gradient tool. + * Called every time the current tool changes by signal emission. + */ +static void gradient_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection connChanged; + static sigc::connection connModified; + static sigc::connection connSubselectionChanged; + static sigc::connection connDefsRelease; + static sigc::connection connDefsModified; + + if (SP_IS_GRADIENT_CONTEXT(ec)) { + Inkscape::Selection *selection = sp_desktop_selection(desktop); + SPDocument *document = sp_desktop_document(desktop); + // connect to selection modified and changed signals + connChanged = selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), holder)); + connModified = selection->connectModified(sigc::bind(sigc::ptr_fun(&gr_tb_selection_modified), holder)); + connSubselectionChanged = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(&gr_drag_selection_changed), holder)); + + // Is this necessary? Couldn't hurt. + gr_tb_selection_changed(selection, holder); + + // connect to release and modified signals of the defs (i.e. when someone changes gradient) + connDefsRelease = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), GTK_WIDGET(holder))); + connDefsModified = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), GTK_WIDGET(holder))); + } else { + if (connChanged) + connChanged.disconnect(); + if (connModified) + connModified.disconnect(); + if (connSubselectionChanged) + connSubselectionChanged.disconnect(); + if (connDefsRelease) + connDefsRelease.disconnect(); + if (connDefsModified) + connDefsModified.disconnect(); + } } /* -- cgit v1.2.3 From 764f8e7612bbf000a5fab4eeed165432f4ff779b Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 9 Aug 2014 22:47:25 -0400 Subject: Further fixes related to bug #1327267, toolbars don't need to update when their context is not in use (bzr r13341.1.126) --- src/ui/tools/arc-tool.h | 2 +- src/widgets/arc-toolbar.cpp | 20 +++++++--- src/widgets/box3d-toolbar.cpp | 20 ++++++++-- src/widgets/lpe-toolbar.cpp | 32 ++++++++++------ src/widgets/mesh-toolbar.cpp | 88 ++++++++++++++++++++++--------------------- src/widgets/node-toolbar.cpp | 45 +++++++++++----------- src/widgets/rect-toolbar.cpp | 20 +++++++--- src/widgets/star-toolbar.cpp | 23 +++++++---- src/widgets/text-toolbar.cpp | 2 +- 9 files changed, 153 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/ui/tools/arc-tool.h b/src/ui/tools/arc-tool.h index c4c67660d..55cbaf78c 100644 --- a/src/ui/tools/arc-tool.h +++ b/src/ui/tools/arc-tool.h @@ -30,7 +30,7 @@ namespace Inkscape { } #define SP_ARC_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) -#define SP_IS_ARC_CONTEXT(obj) (dynamic_cast(const Inkscape::UI::Tools::ToolBase*(obj)) != NULL) +#define SP_IS_ARC_CONTEXT(obj) (dynamic_cast(obj) != NULL) namespace Inkscape { namespace UI { diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index ca6810c81..1005de70d 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -45,6 +45,7 @@ #include "toolbox.h" #include "ui/icon-names.h" #include "ui/uxmanager.h" +#include "ui/tools/arc-tool.h" #include "verbs.h" #include "widgets/spinbutton-events.h" #include "xml/node-event-vector.h" @@ -304,6 +305,7 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb } } +static void arc_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -402,14 +404,22 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec sp_arctb_sensitivize( holder, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); } - - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), G_OBJECT(holder))) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(arc_toolbox_check_ec), holder)); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); } +static void arc_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection changed; + + if (SP_IS_ARC_CONTEXT(ec)) { + changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder)); + sp_arc_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + } else { + if (changed) + changed.disconnect(); + } +} /* Local Variables: diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp index 6d6b86c4d..7629e8c24 100644 --- a/src/widgets/box3d-toolbar.cpp +++ b/src/widgets/box3d-toolbar.cpp @@ -43,6 +43,7 @@ #include "selection.h" #include "toolbox.h" #include "ui/icon-names.h" +#include "ui/tools/box3d-tool.h" #include "ui/uxmanager.h" #include "verbs.h" #include "xml/node-event-vector.h" @@ -280,6 +281,8 @@ static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_ang box3d_vp_state_changed(act, box3d_angle, Proj::Z); } +static void box3d_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -409,13 +412,22 @@ void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) ); } - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), G_OBJECT(holder))) - ); - g_signal_connect(holder, "destroy", G_CALLBACK(delete_connection), connection); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_check_ec), holder)); g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder); } +static void box3d_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection changed; + if (SP_IS_BOX3D_CONTEXT(ec)) { + changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder)); + box3d_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + } else { + if (changed) + changed.disconnect(); + } +} + /* Local Variables: mode:c++ diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index 94d42b5eb..9d1e0983f 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -276,6 +276,8 @@ static void lpetool_open_lpe_dialog(GtkToggleAction *act, gpointer data) gtk_toggle_action_set_active(act, false); } +static void lpetool_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); @@ -402,21 +404,27 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE ); } - //watch selection - Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISNodeToolbox"); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(lpetool_toolbox_watch_ec), holder)); +} - sigc::connection *c_selection_modified = - new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_lpetool_toolbox_sel_modified), holder))); - pool->add_connection ("selection-modified", c_selection_modified); +static void lpetool_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection c_selection_modified; + static sigc::connection c_selection_changed; - sigc::connection *c_selection_changed = - new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder))); - pool->add_connection ("selection-changed", c_selection_changed); + if (SP_IS_LPETOOL_CONTEXT(ec)) { + // Watch selection + c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder)); + c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)); + sp_lpetool_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + } else { + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_selection_changed) + c_selection_changed.disconnect(); + } } - /* Local Variables: mode:c++ @@ -426,4 +434,4 @@ void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GO fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 15dda94f0..73e450926 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -42,6 +42,7 @@ #include #include "ui/tools/gradient-tool.h" +#include "ui/tools/mesh-tool.h" #include "gradient-drag.h" #include "sp-mesh-gradient.h" #include "gradient-chemistry.h" @@ -49,17 +50,16 @@ #include "selection.h" #include "ui/icon-names.h" -#include "../ege-adjustment-action.h" -#include "../ege-output-action.h" -#include "../ege-select-one-action.h" -#include "../ink-action.h" -#include "../ink-comboboxentry-action.h" +#include "ege-adjustment-action.h" +#include "ege-output-action.h" +#include "ege-select-one-action.h" +#include "ink-action.h" +#include "ink-comboboxentry-action.h" #include "sp-stop.h" #include "svg/css-ostringstream.h" #include "svg/svg-color.h" #include "desktop-style.h" -#include "ui/tools/gradient-tool.h" #include "toolbox.h" @@ -67,7 +67,7 @@ using Inkscape::DocumentUndo; using Inkscape::UI::ToolboxFactory; using Inkscape::UI::PrefPusher; -static gboolean blocked = FALSE; +static bool blocked = false; //######################## //## Mesh ## @@ -116,22 +116,16 @@ static void ms_drag_selection_changed(gpointer /*dragger*/, gpointer data) } -static void ms_defs_release(SPObject * /*defs*/, GtkWidget *widget) +static void ms_defs_release(SPObject * /*defs*/, GObject *widget) { ms_tb_selection_changed(NULL, widget); } -static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GtkWidget *widget) +static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widget) { - ms_tb_selection_changed(NULL, (gpointer) widget); -} - -static void ms_disconnect_sigc(GObject * /*obj*/, sigc::connection *connection) { - connection->disconnect(); - delete connection; + ms_tb_selection_changed(NULL, widget); } - /* * Callback functions for user actions */ @@ -184,6 +178,8 @@ static void ms_col_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) blocked = FALSE; } +static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + /** * Mesh auxiliary toolbar construction and setup. * @@ -323,35 +319,43 @@ void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObj g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); } - - Inkscape::Selection *selection = sp_desktop_selection (desktop); - SPDocument *document = sp_desktop_document (desktop); - g_object_set_data(holder, "desktop", desktop); - // connect to selection modified and changed signals - sigc::connection *conn1 = new sigc::connection( - selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), (gpointer) holder))); - sigc::connection *conn2 = new sigc::connection( - selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), (gpointer) holder))); - sigc::connection *conn3 = new sigc::connection( - desktop->connectToolSubselectionChanged( sigc::bind(sigc::ptr_fun(&ms_drag_selection_changed), (gpointer) holder))); - - // when holder is destroyed, disconnect - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), conn1); - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), conn2); - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), conn3); - - // connect to release and modified signals of the defs (i.e. when someone changes mesh) - sigc::connection *release_connection = new sigc::connection(); - *release_connection = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&ms_defs_release), GTK_WIDGET(holder))); - sigc::connection *modified_connection = new sigc::connection(); - *modified_connection = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&ms_defs_modified), GTK_WIDGET(holder))); - - // when holder is destroyed, disconnect - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), release_connection); - g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(ms_disconnect_sigc), modified_connection); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(mesh_toolbox_watch_ec), holder)); +} +static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection c_selection_changed; + static sigc::connection c_selection_modified; + static sigc::connection c_subselection_changed; + static sigc::connection c_defs_release; + static sigc::connection c_defs_modified; + + if (SP_IS_MESH_CONTEXT(ec)) { + // connect to selection modified and changed signals + Inkscape::Selection *selection = sp_desktop_selection (desktop); + SPDocument *document = sp_desktop_document (desktop); + + c_selection_changed = selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), holder)); + c_selection_modified = selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), holder)); + c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(&ms_drag_selection_changed), holder)); + + c_defs_release = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&ms_defs_release), holder)); + c_defs_modified = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&ms_defs_modified), holder)); + ms_tb_selection_changed(selection, holder); + } else { + if (c_selection_changed) + c_selection_changed.disconnect(); + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_subselection_changed) + c_subselection_changed.disconnect(); + if (c_defs_release) + c_defs_release.disconnect(); + if (c_defs_modified) + c_defs_modified.disconnect(); + } } /* diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 38e3f4fbd..20bf2f7b9 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -322,7 +322,7 @@ static void sp_node_toolbox_sel_modified(Inkscape::Selection *selection, guint / sp_node_toolbox_sel_changed (selection, tbl); } - +static void node_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); //################################ //## Node Editing Toolbox ## @@ -615,32 +615,33 @@ void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje gtk_action_group_add_action( mainActions, act ); } - sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(node_toolbox_watch_ec), holder)); - //watch selection - Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISNodeToolbox"); - - sigc::connection *c_selection_changed = - new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_changed), holder))); - pool->add_connection ("selection-changed", c_selection_changed); - - sigc::connection *c_selection_modified = - new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_modified), holder))); - pool->add_connection ("selection-modified", c_selection_modified); - - sigc::connection *c_subselection_changed = - new sigc::connection (desktop->connectToolSubselectionChanged - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_coord_changed), holder))); - pool->add_connection ("tool-subselection-changed", c_subselection_changed); +} // end of sp_node_toolbox_prep() - Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool); +static void node_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection c_selection_changed; + static sigc::connection c_selection_modified; + static sigc::connection c_subselection_changed; - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} // end of sp_node_toolbox_prep() + if (INK_IS_NODE_TOOL(ec)) { + // watch selection + c_selection_changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder)); + c_selection_modified = sp_desktop_selection(desktop)->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder)); + c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_coord_changed), holder)); + sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder); + } else { + if (c_selection_changed) + c_selection_changed.disconnect(); + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_subselection_changed) + c_subselection_changed.disconnect(); + } +} /* diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index c9a09e908..48808fe70 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -44,6 +44,7 @@ #include "sp-rect.h" #include "toolbox.h" #include "ui/icon-names.h" +#include "ui/tools/rect-tool.h" #include "ui/uxmanager.h" #include "ui/widget/unit-tracker.h" #include "util/units.h" @@ -288,6 +289,7 @@ static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GO } } +static void rect_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -394,13 +396,21 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje g_object_set_data( holder, "single", GINT_TO_POINTER(TRUE) ); sp_rtb_sensitivize( holder ); - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(rect_toolbox_watch_ec), holder)); g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); } +static void rect_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection changed; + + if (SP_IS_RECT_CONTEXT(ec)) { + changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)); + } else { + if (changed) + changed.disconnect(); + } +} /* Local Variables: @@ -411,4 +421,4 @@ void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index 7a7d0dc71..0f8c31be8 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -42,6 +42,7 @@ #include "sp-star.h" #include "toolbox.h" #include "ui/icon-names.h" +#include "ui/tools/star-tool.h" #include "ui/uxmanager.h" #include "verbs.h" #include "widgets/../preferences.h" @@ -435,6 +436,7 @@ static void sp_stb_defaults( GtkWidget * /*widget*/, GObject *dataKludge ) gtk_adjustment_value_changed(adj); } +static void star_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { @@ -571,15 +573,22 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje } } - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder)) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(star_toolbox_watch_ec), holder)); + g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder); } +static void star_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection changed; - + if (dynamic_cast(ec) != NULL) { + changed = sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), holder)); + sp_star_toolbox_selection_changed(sp_desktop_selection(desktop), holder); + } else { + if (changed) + changed.disconnect(); + } +} /* Local Variables: @@ -590,4 +599,4 @@ void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 36a151c52..408babf06 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -1661,4 +1661,4 @@ static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : -- cgit v1.2.3 From 921006afdb0cd6c956df3a05328737b88ef115ed Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 9 Aug 2014 22:52:46 -0400 Subject: Nuke connection-pool.h (bzr r13341.1.127) --- src/CMakeLists.txt | 1 - src/Makefile_insert | 1 - src/connection-pool.h | 100 ------------------------------------------- src/widgets/lpe-toolbar.cpp | 1 - src/widgets/node-toolbar.cpp | 1 - 5 files changed, 104 deletions(-) delete mode 100644 src/connection-pool.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94b4b8c85..ab697d126 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -299,7 +299,6 @@ set(inkscape_SRC composite-undo-stack-observer.h conditions.h conn-avoid-ref.h - connection-pool.h console-output-undo-observer.h context-fns.h decimal-round.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 436ab26f9..8e45cb4e0 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -24,7 +24,6 @@ ink_common_sources += \ composite-undo-stack-observer.h \ conditions.cpp conditions.h \ conn-avoid-ref.cpp conn-avoid-ref.h \ - connection-pool.h \ console-output-undo-observer.h console-output-undo-observer.cpp \ context-fns.cpp context-fns.h \ decimal-round.h \ diff --git a/src/connection-pool.h b/src/connection-pool.h deleted file mode 100644 index 4637a3cc1..000000000 --- a/src/connection-pool.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Author: - * mderezynski - * - * Copyright (C) 2006 Author - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifndef CONNECTION_POOL_H -#define CONNECTION_POOL_H - -#include -#include - -#include -#include -#include -#include - -namespace Inkscape { - -/** - * @class ConnectionPool - * an auxilliary class to manage sigc::connections as if the referred object - * were a GObject; in that way, the class that holds a ConnectionPool does not - * need to also hold several sigc::connection objects - */ -class ConnectionPool { -public: - typedef std::map ConnectionMap; - - struct NameExistsException : public std::exception { - virtual const char* what() const throw() { return "Inkscape::ConnectionPool: name exists"; } - }; - struct NameDoesNotExistException : public std::exception { - virtual const char* what() const throw() { return "Inkscape::ConnectionPool: name doesn't exist"; } - }; - - void add_connection(std::string name, sigc::connection* connection) { - if (_map.find(name) != _map.end()) { - throw NameExistsException(); - } - _map.insert(std::make_pair(name, connection)); - } - - void del_connection(std::string name) { - ConnectionMap::iterator iter = _map.find(name); - if (iter == _map.end()) { - throw NameDoesNotExistException(); - } - sigc::connection* connection = (*iter).second; - connection->disconnect(); - delete connection; - } - - - static Inkscape::ConnectionPool* new_connection_pool(std::string name) { - return new ConnectionPool(name); - } - - static void del_connection_pool(ConnectionPool* pool) { - delete pool; - } - - static void connect_destroy(GObject *obj, ConnectionPool *pool) { - g_object_connect (obj, "swapped-signal::destroy", G_CALLBACK(del_connection_pool), pool, NULL); - } - - operator std::string() { - return _name; - } - -private: - ConnectionPool(std::string name) : _name(name) {} - virtual ~ConnectionPool() { - for (ConnectionMap::iterator iter = _map.begin(), end = _map.end(); iter != end; ++iter) { - sigc::connection* connection = (*iter).second; - connection->disconnect(); - delete connection; - } - } - - ConnectionMap _map; - std::string _name; -}; -} - -#endif - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp index 9d1e0983f..7ad88b856 100644 --- a/src/widgets/lpe-toolbar.cpp +++ b/src/widgets/lpe-toolbar.cpp @@ -30,7 +30,6 @@ #include "live_effects/lpe-line_segment.h" #include "lpe-toolbar.h" -#include "connection-pool.h" #include "desktop-handles.h" #include "desktop.h" #include "document-undo.h" diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp index 20bf2f7b9..ace78f8f5 100644 --- a/src/widgets/node-toolbar.cpp +++ b/src/widgets/node-toolbar.cpp @@ -31,7 +31,6 @@ #include "ui/tool/multi-path-manipulator.h" #include #include "node-toolbar.h" -#include "connection-pool.h" #include "desktop-handles.h" #include "desktop.h" #include "document-undo.h" -- cgit v1.2.3 From 305b26df745012b291f5ddaa41ea5da6487d3286 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 9 Aug 2014 23:34:42 -0400 Subject: Add meshes to Fill&Stroke paint selector (bzr r13341.1.128) --- src/widgets/gradient-selector.cpp | 6 ++--- src/widgets/gradient-selector.h | 3 +++ src/widgets/paint-selector.cpp | 55 +++++++++++++++++++++++++++++++++++---- src/widgets/paint-selector.h | 9 +++++++ 4 files changed, 65 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 871d1ee4c..511478111 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -20,9 +20,9 @@ #include #include "document.h" -#include "../document-undo.h" -#include "../document-private.h" -#include "../gradient-chemistry.h" +#include "document-undo.h" +#include "document-private.h" +#include "gradient-chemistry.h" #include "inkscape.h" #include "verbs.h" #include "helper/action.h" diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h index 1f58de2e4..ee8980be9 100644 --- a/src/widgets/gradient-selector.h +++ b/src/widgets/gradient-selector.h @@ -54,6 +54,9 @@ struct SPGradientSelector { enum SelectorMode { MODE_LINEAR, MODE_RADIAL, +#ifdef WITH_MESH + MODE_MESH, +#endif MODE_SWATCH }; diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 9466c875e..89cdd88ad 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -29,14 +29,15 @@ #endif #include "widgets/swatch-selector.h" -#include "../sp-pattern.h" +#include "sp-pattern.h" #include -#include "../widgets/icon.h" +#include "widgets/icon.h" #include "widgets/widget-sizes.h" #include "xml/repr.h" #include "sp-color-notebook.h" #include "sp-linear-gradient.h" +#include "sp-mesh-gradient.h" #include "sp-radial-gradient.h" /* fixme: Move it from dialogs to here */ #include "gradient-selector.h" @@ -113,10 +114,13 @@ static gchar const* modeStrings[] = { #endif -static bool isPaintModeGradient( SPPaintSelector::Mode mode ) +static bool isPaintModeGradient(SPPaintSelector::Mode mode) { bool isGrad = (mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (mode == SPPaintSelector::MODE_GRADIENT_RADIAL) || +#ifdef WITH_MESH + (mode == SPPaintSelector::MODE_GRADIENT_MESH) || +#endif (mode == SPPaintSelector::MODE_SWATCH); return isGrad; @@ -238,6 +242,10 @@ sp_paint_selector_init(SPPaintSelector *psel) SPPaintSelector::MODE_GRADIENT_LINEAR, _("Linear gradient")); psel->radial = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-radial"), SPPaintSelector::MODE_GRADIENT_RADIAL, _("Radial gradient")); +#ifdef WITH_MESH + psel->mesh = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-mesh"), + SPPaintSelector::MODE_GRADIENT_MESH, _("Mesh gradient")); +#endif psel->pattern = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-pattern"), SPPaintSelector::MODE_PATTERN, _("Pattern")); psel->swatch = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-swatch"), @@ -413,6 +421,9 @@ void SPPaintSelector::setMode(Mode mode) break; case MODE_GRADIENT_LINEAR: case MODE_GRADIENT_RADIAL: +#ifdef WITH_MESH + case MODE_GRADIENT_MESH: +#endif sp_paint_selector_set_mode_gradient(this, mode); break; case MODE_PATTERN: @@ -511,6 +522,21 @@ void SPPaintSelector::setGradientRadial(SPGradient *vector) gsel->setVector((vector) ? vector->document : 0, vector); } +#ifdef WITH_MESH +void SPPaintSelector::setGradientMesh(SPGradient *vector) +{ +#ifdef SP_PS_VERBOSE + g_print("PaintSelector set GRADIENT MESH\n"); +#endif + setMode(MODE_GRADIENT_RADIAL); + + SPGradientSelector *gsel = getGradientFromData(this); + + gsel->setMode(SPGradientSelector::MODE_MESH); + gsel->setVector((vector) ? vector->document : 0, vector); +} +#endif + void SPPaintSelector::setGradientProperties( SPGradientUnits units, SPGradientSpread spread ) { g_return_if_fail(isPaintModeGradient(mode)); @@ -728,9 +754,14 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe if (mode == SPPaintSelector::MODE_GRADIENT_LINEAR) { sp_paint_selector_set_style_buttons(psel, psel->gradient); - } else { + } else if (mode == SPPaintSelector::MODE_GRADIENT_RADIAL) { sp_paint_selector_set_style_buttons(psel, psel->radial); } +#ifdef WITH_MESH + else { + sp_paint_selector_set_style_buttons(psel, psel->mesh); + } +#endif gtk_widget_set_sensitive(psel->style, TRUE); if ((psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (psel->mode == SPPaintSelector::MODE_GRADIENT_RADIAL)) { @@ -756,10 +787,17 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_LINEAR); //sp_gradient_selector_set_mode(SP_GRADIENT_SELECTOR(gsel), SP_GRADIENT_SELECTOR_MODE_LINEAR); gtk_label_set_markup(GTK_LABEL(psel->label), _("Linear gradient")); - } else { + } else if (mode == SPPaintSelector::MODE_GRADIENT_LINEAR) { SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_RADIAL); gtk_label_set_markup(GTK_LABEL(psel->label), _("Radial gradient")); } +#ifdef WITH_MESH + else { + SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_RADIAL); + gtk_label_set_markup(GTK_LABEL(psel->label), _("Mesh gradient")); + } +#endif + #ifdef SP_PS_VERBOSE g_print("Gradient req\n"); #endif @@ -772,6 +810,9 @@ sp_paint_selector_set_style_buttons(SPPaintSelector *psel, GtkWidget *active) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->solid), (active == psel->solid)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->gradient), (active == psel->gradient)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->radial), (active == psel->radial)); +#ifdef WITH_MESH + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->radial), (active == psel->mesh)); +#endif gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->pattern), (active == psel->pattern)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->swatch), (active == psel->swatch)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->unset), (active == psel->unset)); @@ -1218,6 +1259,10 @@ SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, Fi mode = MODE_GRADIENT_LINEAR; } else if (SP_IS_RADIALGRADIENT(server)) { mode = MODE_GRADIENT_RADIAL; +#ifdef WITH_MESH + } else if (SP_IS_MESHGRADIENT(server)) { + mode = MODE_GRADIENT_MESH; +#endif } else if (SP_IS_PATTERN(server)) { mode = MODE_PATTERN; } else { diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index d6ad3f50c..a2a303a47 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -45,6 +45,9 @@ struct SPPaintSelector { MODE_COLOR_CMYK, MODE_GRADIENT_LINEAR, MODE_GRADIENT_RADIAL, +#ifdef WITH_MESH + MODE_GRADIENT_MESH, +#endif MODE_PATTERN, MODE_SWATCH, MODE_UNSET @@ -64,6 +67,9 @@ struct SPPaintSelector { GtkWidget *solid; GtkWidget *gradient; GtkWidget *radial; +#ifdef WITH_MESH + GtkWidget *mesh; +#endif GtkWidget *pattern; GtkWidget *swatch; GtkWidget *unset; @@ -88,6 +94,9 @@ struct SPPaintSelector { void setGradientLinear( SPGradient *vector ); void setGradientRadial( SPGradient *vector ); +#ifdef WITH_MESH + void setGradientMesh(SPGradient *vector); +#endif void setSwatch( SPGradient *vector ); void setGradientProperties( SPGradientUnits units, SPGradientSpread spread ); -- cgit v1.2.3 From f83624750df7b8d4bd1652d25553436b739ad618 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 9 Aug 2014 23:58:09 -0400 Subject: Add meshes to selected style widget (bzr r13341.1.129) --- src/ui/widget/selected-style.cpp | 21 +++++++++++++++++++++ src/ui/widget/selected-style.h | 11 +++++++++++ 2 files changed, 32 insertions(+) (limited to 'src') diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 042a6614e..85538c8c7 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -25,6 +25,7 @@ #include "desktop-style.h" #include "sp-namedview.h" #include "sp-linear-gradient.h" +#include "sp-mesh-gradient.h" #include "sp-radial-gradient.h" #include "sp-pattern.h" #include "ui/dialog/dialog-manager.h" @@ -209,6 +210,18 @@ SelectedStyle::SelectedStyle(bool /*layout*/) _gradient_box_r[i].pack_start(*(Glib::wrap(_gradient_preview_r[i]))); _gradient_box_r[i].show_all(); +#ifdef WITH_MESH + _mgradient[i].set_markup (_("M")); + sp_set_font_size_smaller (GTK_WIDGET(_mgradient[i].gobj())); + _mgradient[i].show_all(); + __mgradient[i] = (i == SS_FILL)? (_("Mesh gradient fill")) : (_("Mesh gradient stroke")); + + _gradient_preview_m[i] = GTK_WIDGET(sp_gradient_image_new (NULL)); + _gradient_box_m[i].pack_start(_mgradient[i]); + _gradient_box_m[i].pack_start(*(Glib::wrap(_gradient_preview_m[i]))); + _gradient_box_m[i].show_all(); +#endif + _many[i].set_markup (_("Different")); sp_set_font_size_smaller (GTK_WIDGET(_many[i].gobj())); _many[i].show_all(); @@ -1028,6 +1041,14 @@ SelectedStyle::update() place->add(_gradient_box_r[i]); place->set_tooltip_text(__rgradient[i]); _mode[i] = SS_RGRADIENT; +#ifdef WITH_MESH + } else if (SP_IS_MESHGRADIENT(server)) { + SPGradient *vector = SP_GRADIENT(server)->getVector(); + sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_m[i]), vector); + place->add(_gradient_box_m[i]); + place->set_tooltip_text(__mgradient[i]); + _mode[i] = SS_MGRADIENT; +#endif } else if (SP_IS_PATTERN (server)) { place->add(_pattern[i]); place->set_tooltip_text(__pattern[i]); diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index 9557a8d74..df0f41507 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -60,6 +60,9 @@ enum { SS_PATTERN, SS_LGRADIENT, SS_RGRADIENT, +#ifdef WITH_MESH + SS_MGRADIENT, +#endif SS_MANY, SS_COLOR }; @@ -186,6 +189,14 @@ protected: GtkWidget *_gradient_preview_r[2]; Gtk::HBox _gradient_box_r[2]; +#ifdef WITH_MESH + Gtk::Label _mgradient[2]; + Glib::ustring __mgradient[2]; + + GtkWidget *_gradient_preview_m[2]; + Gtk::HBox _gradient_box_m[2]; +#endif + Gtk::Label _many[2]; Glib::ustring __many[2]; -- cgit v1.2.3 From c1c6c69268bcb0f47f73821380c4061d459caedb Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 10 Aug 2014 00:04:15 -0400 Subject: Oops (bzr r13341.1.130) --- src/widgets/paint-selector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 89cdd88ad..f4ceee187 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -811,7 +811,7 @@ sp_paint_selector_set_style_buttons(SPPaintSelector *psel, GtkWidget *active) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->gradient), (active == psel->gradient)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->radial), (active == psel->radial)); #ifdef WITH_MESH - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->radial), (active == psel->mesh)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->mesh), (active == psel->mesh)); #endif gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->pattern), (active == psel->pattern)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(psel->swatch), (active == psel->swatch)); -- cgit v1.2.3 From 3511d63cc7b04e5fc5ae0ff8de616f0594c5dbcb Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 10 Aug 2014 00:07:19 -0400 Subject: Get gradient tool to shut up about invalid casts with meshes (bzr r13341.1.131) --- src/ui/tools/gradient-tool.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index a0bbfbaf1..4f9a7b59b 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -213,17 +213,20 @@ sp_gradient_context_is_over_line (GradientTool *rc, SPItem *item, Geom::Point ev //Translate mouse point into proper coord system rc->mousepoint_doc = desktop->w2d(event_p); - SPCtrlLine* line = SP_CTRLLINE(item); + if (SP_IS_CTRLLINE(item)) { + SPCtrlLine* line = SP_CTRLLINE(item); - Geom::LineSegment ls(line->s, line->e); - Geom::Point nearest = ls.pointAt(ls.nearestPoint(rc->mousepoint_doc)); - double dist_screen = Geom::L2 (rc->mousepoint_doc - nearest) * desktop->current_zoom(); + Geom::LineSegment ls(line->s, line->e); + Geom::Point nearest = ls.pointAt(ls.nearestPoint(rc->mousepoint_doc)); + double dist_screen = Geom::L2 (rc->mousepoint_doc - nearest) * desktop->current_zoom(); - double tolerance = (double) SP_EVENT_CONTEXT(rc)->tolerance; + double tolerance = (double) SP_EVENT_CONTEXT(rc)->tolerance; - bool close = (dist_screen < tolerance); + bool close = (dist_screen < tolerance); - return close; + return close; + } + return false; } static std::vector -- cgit v1.2.3 From 4436eae1a6810e3630679898f91fe1995d1fae7e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sun, 10 Aug 2014 15:29:46 +0200 Subject: Export. Fix for Bug #1166184 (XAML export not compatible with Silverlight). Fixed bugs: - https://launchpad.net/bugs/1166184 (bzr r13505) --- src/extension/implementation/xslt.cpp | 40 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/extension/implementation/xslt.cpp b/src/extension/implementation/xslt.cpp index bcea06cb5..85ae9efde 100644 --- a/src/extension/implementation/xslt.cpp +++ b/src/extension/implementation/xslt.cpp @@ -20,6 +20,7 @@ #include "xslt.h" #include "../extension.h" #include "../output.h" +#include "extension/input.h" #include "xml/repr.h" #include "io/sys.h" @@ -53,8 +54,7 @@ XSLT::XSLT(void) : { } -Glib::ustring -XSLT::solve_reldir(Inkscape::XML::Node *reprin) { +Glib::ustring XSLT::solve_reldir(Inkscape::XML::Node *reprin) { gchar const *s = reprin->attribute("reldir"); @@ -90,8 +90,7 @@ XSLT::solve_reldir(Inkscape::XML::Node *reprin) { return ""; } -bool -XSLT::check(Inkscape::Extension::Extension *module) +bool XSLT::check(Inkscape::Extension::Extension *module) { if (load(module)) { unload(module); @@ -101,8 +100,7 @@ XSLT::check(Inkscape::Extension::Extension *module) } } -bool -XSLT::load(Inkscape::Extension::Extension *module) +bool XSLT::load(Inkscape::Extension::Extension *module) { if (module->loaded()) { return true; } @@ -130,8 +128,7 @@ XSLT::load(Inkscape::Extension::Extension *module) return true; } -void -XSLT::unload(Inkscape::Extension::Extension *module) +void XSLT::unload(Inkscape::Extension::Extension *module) { if (!module->loaded()) { return; } xsltFreeStylesheet(_stylesheet); @@ -139,8 +136,8 @@ XSLT::unload(Inkscape::Extension::Extension *module) return; } -SPDocument * -XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename) +SPDocument * XSLT::open(Inkscape::Extension::Input */*module*/, + gchar const *filename) { xmlDocPtr filein = xmlParseFile(filename); if (filein == NULL) { return NULL; } @@ -184,8 +181,7 @@ XSLT::open(Inkscape::Extension::Input */*module*/, gchar const *filename) return doc; } -void -XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const *filename) +void XSLT::save(Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename) { /* TODO: Should we assume filename to be in utf8 or to be a raw filename? * See JavaFXOutput::save for discussion. */ @@ -214,10 +210,24 @@ XSLT::save(Inkscape::Extension::Output */*module*/, SPDocument *doc, gchar const return; } - const char * params[1]; - params[0] = NULL; + std::list params; + module->paramListString(params); + const int max_parameters = params.size() * 2; + const char * xslt_params[max_parameters+1] ; + + int count = 0; + for(std::list::iterator t=params.begin(); t != params.end(); ++t) { + std::size_t pos = t->find("="); + std::ostringstream parameter; + std::ostringstream value; + parameter << t->substr(2,pos-2); + value << t->substr(pos+1); + xslt_params[count++] = g_strdup_printf("%s", parameter.str().c_str()); + xslt_params[count++] = g_strdup_printf("'%s'", value.str().c_str()); + } + xslt_params[count] = NULL; - xmlDocPtr newdoc = xsltApplyStylesheet(_stylesheet, svgdoc, params); + xmlDocPtr newdoc = xsltApplyStylesheet(_stylesheet, svgdoc, xslt_params); //xmlSaveFile(filename, newdoc); int success = xsltSaveResultToFilename(filename, newdoc, _stylesheet, 0); -- cgit v1.2.3 From df69f3dfcda3daf6007802719b1d393fcdce4c13 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 11 Aug 2014 00:12:33 +0200 Subject: Better helper paths in simplify LPE sugested by suv (bzr r13341.1.132) --- src/live_effects/lpe-simplify.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 1a02375cd..7334c8588 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -209,7 +209,7 @@ LPESimplify::generateHelperPath(Geom::PathVector result) drawHandle((*cubic)[1]); drawHandle((*cubic)[2]); drawHandleLine((*cubic)[0],(*cubic)[1]); - drawHandleLine((*cubic)[2],(*cubic)[3]); + drawHandleLine((*cubic)[3],(*cubic)[2]); } } if(nodes){ @@ -224,7 +224,7 @@ LPESimplify::generateHelperPath(Geom::PathVector result) drawHandle((*cubic)[1]); drawHandle((*cubic)[2]); drawHandleLine((*cubic)[0],(*cubic)[1]); - drawHandleLine((*cubic)[2],(*cubic)[3]); + drawHandleLine((*cubic)[3],(*cubic)[2]); } } if(nodes){ @@ -238,13 +238,12 @@ LPESimplify::drawNode(Geom::Point p) { double r = helper_size/0.67; char const * svgd; - svgd = "M 0.999993,0.5 C 1.000065,0.7757576 0.7761859,1 0.4999926,1 0.2237994,1 -7.933901e-5,0.7757576 -7.339015e-6,0.5 -7.933901e-5,0.2242424 0.2237994,0 0.4999926,0 0.7761859,0 1.000065,0.2242424 0.999993,0.5 Z m -0.058561,0 C 0.9414949,0.74327 0.7438375,0.9416286 0.4999928,0.9416286 0.2561481,0.9416286 0.0584908,0.74327 0.0585543,0.5 0.0584908,0.25673 0.2561481,0.0583714 0.4999928,0.0583714 0.7438375,0.0583714 0.9414949,0.25673 0.9414313,0.5 Z m -0.3828447,0 c 8.5e-6,0.030303 -0.026228,0.060606 -0.058593,0.060606 -0.032366,0 -0.058603,-0.030303 -0.058593,-0.060606 -8.5e-6,-0.030303 0.026227,-0.060606 0.058593,-0.060606 0.032366,0 0.058603,0.030303 0.058593,0.060606 z"; + svgd = "M 0,-4.270368e-5 1,-4.270368e-5 1,0.9999573 0,0.9999573 Z M 0.5585873,0.5 C 0.5585958,0.530303 0.5323593,0.560606 0.4999943,0.560606 0.4676283,0.560606 0.4413913,0.530303 0.4414013,0.5 0.4413928,0.469697 0.4676283,0.439394 0.4999943,0.439394 0.5323603,0.439394 0.5585973,0.469697 0.5585873,0.5 Z""; Geom::PathVector pathv = sp_svg_read_pathv(svgd); pathv *= Geom::Affine(r,0,0,r,0,0); pathv += p - Geom::Point(0.5*r,0.5*r); hp.push_back(pathv[0]); hp.push_back(pathv[1]); - hp.push_back(pathv[2]); } void @@ -265,6 +264,11 @@ LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2) { Geom::Path path; path.start( p ); + if(helper_size > 0.0){ + double diameter = helper_size/0.67; + Geom::Ray ray2(p, p2); + p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); + } path.appendNew( p2 ); hp.push_back(path); } -- cgit v1.2.3 From e4b4e65a3ef6341de82cb314a1339167df2dec19 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 11 Aug 2014 00:31:26 +0200 Subject: fix bug pointed by suv (bzr r13341.1.133) --- src/live_effects/lpe-simplify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index 7334c8588..a001069b9 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -238,7 +238,7 @@ LPESimplify::drawNode(Geom::Point p) { double r = helper_size/0.67; char const * svgd; - svgd = "M 0,-4.270368e-5 1,-4.270368e-5 1,0.9999573 0,0.9999573 Z M 0.5585873,0.5 C 0.5585958,0.530303 0.5323593,0.560606 0.4999943,0.560606 0.4676283,0.560606 0.4413913,0.530303 0.4414013,0.5 0.4413928,0.469697 0.4676283,0.439394 0.4999943,0.439394 0.5323603,0.439394 0.5585973,0.469697 0.5585873,0.5 Z""; + svgd = "M 0,-4.270368e-5 1,-4.270368e-5 1,0.9999573 0,0.9999573 Z M 0.5585873,0.5 C 0.5585958,0.530303 0.5323593,0.560606 0.4999943,0.560606 0.4676283,0.560606 0.4413913,0.530303 0.4414013,0.5 0.4413928,0.469697 0.4676283,0.439394 0.4999943,0.439394 0.5323603,0.439394 0.5585973,0.469697 0.5585873,0.5 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); pathv *= Geom::Affine(r,0,0,r,0,0); pathv += p - Geom::Point(0.5*r,0.5*r); -- cgit v1.2.3 From 34efde17371ebac38ad634b81496fc578357fc1e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 11 Aug 2014 03:38:48 +0200 Subject: Simplify original paths on helper paths pointed by Liam. Also used arcs for handles pointed by suv (bzr r13341.1.134) --- src/live_effects/lpe-simplify.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index a001069b9..c4c2d449b 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -238,7 +238,7 @@ LPESimplify::drawNode(Geom::Point p) { double r = helper_size/0.67; char const * svgd; - svgd = "M 0,-4.270368e-5 1,-4.270368e-5 1,0.9999573 0,0.9999573 Z M 0.5585873,0.5 C 0.5585958,0.530303 0.5323593,0.560606 0.4999943,0.560606 0.4676283,0.560606 0.4413913,0.530303 0.4414013,0.5 0.4413928,0.469697 0.4676283,0.439394 0.4999943,0.439394 0.5323603,0.439394 0.5585973,0.469697 0.5585873,0.5 Z"; + svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); pathv *= Geom::Affine(r,0,0,r,0,0); pathv += p - Geom::Point(0.5*r,0.5*r); @@ -251,7 +251,7 @@ LPESimplify::drawHandle(Geom::Point p) { double r = helper_size/0.67; char const * svgd; - svgd = "M 0.6999623,0.35 C 0.7000128,0.5430303 0.5433044,0.7 0.3499775,0.7 0.1566506,0.7 -5.778776e-5,0.5430303 -7.344202e-6,0.35 -5.778776e-5,0.1569697 0.1566506,0 0.3499775,0 0.5433044,0 0.7000128,0.1569697 0.6999623,0.35 Z"; + svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); pathv *= Geom::Affine(r,0,0,r,0,0); pathv += p - Geom::Point(0.35*r,0.35*r); -- cgit v1.2.3 From 4d30762a61aa6975fd6ad2d0a3c97e41e0e8c1b7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 11 Aug 2014 04:42:02 +0200 Subject: Added reset modifier to knot in fillet chamfer (bzr r13341.1.135) --- .../parameter/filletchamferpointarray.cpp | 78 +++++++++++++--------- 1 file changed, 46 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index 457b68dd2..e9d1c0cd0 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -552,31 +552,40 @@ Point FilletChamferPointArrayParamKnotHolderEntity::knot_get() const void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) { if (state & GDK_CONTROL_MASK) { - using namespace Geom; - double type = _pparam->_vector.at(_index)[Y] + 1; - if (type > 4) { - type = 1; - } - _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], type); - _pparam->param_set_and_write_new_value(_pparam->_vector); - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); - const gchar *tip; - if (type == 3) { - tip = _("Chamfer: Ctrl+click toogle type, " - "Shift+click open dialog"); - } else if (type == 2) { - tip = _("Inverse Fillet: Ctrl+click toogle type, " - "Shift+click open dialog"); - } else if (type == 1) { - tip = _("Fillet: Ctrl+click toogle type, " - "Shift+click open dialog"); - } else { - tip = _("Double Chamfer: Ctrl+click toogle type, " - "Shift+click open dialog"); + if (state & GDK_MOD1_MASK) { + _pparam->_vector.at(_index) = Point(_index, _pparam->_vector.at(_index)[Y]); + _pparam->param_set_and_write_new_value(_pparam->_vector); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + }else{ + using namespace Geom; + double type = _pparam->_vector.at(_index)[Y] + 1; + if (type > 4) { + type = 1; + } + _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], type); + _pparam->param_set_and_write_new_value(_pparam->_vector); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + const gchar *tip; + if (type == 3) { + tip = _("Chamfer: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); + } else if (type == 2) { + tip = _("Inverse Fillet: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); + } else if (type == 1) { + tip = _("Fillet: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); + } else { + tip = _("Double Chamfer: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); + } + this->knot->tip = g_strdup(tip); + this->knot->show(); } - this->knot->tip = g_strdup(tip); - this->knot->show(); - //} } else if ((state & GDK_MOD1_MASK) || (state & GDK_SHIFT_MASK)) { Geom::Point offset = Geom::Point(_pparam->_vector.at(_index).x(), _pparam->_vector.at(_index).y()); @@ -619,18 +628,23 @@ void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, } const gchar *tip; if (_vector[i][Y] == 3) { - tip = _("Chamfer: Ctrl+click toogle type, " - "Shift+click open dialog"); + tip = _("Chamfer: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); } else if (_vector[i][Y] == 2) { - tip = _("Inverse Fillet: Ctrl+click toogle type, " - "Shift+click open dialog"); + tip = _("Inverse Fillet: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); } else if (_vector[i][Y] == 1) { - tip = _("Fillet: Ctrl+click toogle type, " - "Shift+click open dialog"); + tip = _("Fillet: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); } else { - tip = _("Double Chamfer: Ctrl+click toogle type, " - "Shift+click open dialog"); + tip = _("Double Chamfer: Ctrl+Click toogle type, " + "Shift+Click open dialog, " + "Ctrl+Alt+Click reset"); } + FilletChamferPointArrayParamKnotHolderEntity *e = new FilletChamferPointArrayParamKnotHolderEntity(this, i); e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _(tip), -- cgit v1.2.3 From 50ab28bfaaf986c4dd0cc363cc3c9cd0f15b82c2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 11 Aug 2014 05:11:03 +0200 Subject: Code refactor: now helper paths draw ok when handle is degenerate or cirle handle is biger then the distance to node. also remove code duplication at loop (bzr r13341.1.136) --- src/live_effects/lpe-simplify.cpp | 50 +++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index c4c2d449b..a817f30f1 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -202,33 +202,27 @@ LPESimplify::generateHelperPath(Geom::PathVector result) if(nodes){ drawNode(curve_it1->initialPoint()); } - while (curve_it2 != curve_endit) { - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - if(handles){ - drawHandle((*cubic)[1]); - drawHandle((*cubic)[2]); - drawHandleLine((*cubic)[0],(*cubic)[1]); - drawHandleLine((*cubic)[3],(*cubic)[2]); + while (curve_it1 != curve_endit) { + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + if(handles) { + if(!are_near((*cubic)[0],(*cubic)[1])){ + drawHandle((*cubic)[1]); + drawHandleLine((*cubic)[0],(*cubic)[1]); + } + if(!are_near((*cubic)[3],(*cubic)[2])){ + drawHandle((*cubic)[2]); + drawHandleLine((*cubic)[3],(*cubic)[2]); + } + } + } + if(nodes) { + drawNode(curve_it1->finalPoint()); + } + ++curve_it1; + if(curve_it2 != curve_endit){ + ++curve_it2; } - } - if(nodes){ - drawNode(curve_it1->finalPoint()); - } - ++curve_it1; - ++curve_it2; - } - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - if(handles){ - drawHandle((*cubic)[1]); - drawHandle((*cubic)[2]); - drawHandleLine((*cubic)[0],(*cubic)[1]); - drawHandleLine((*cubic)[3],(*cubic)[2]); - } - } - if(nodes){ - drawNode(curve_it1->finalPoint()); } } } @@ -264,8 +258,8 @@ LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2) { Geom::Path path; path.start( p ); - if(helper_size > 0.0){ - double diameter = helper_size/0.67; + double diameter = helper_size/0.67; + if(helper_size > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){ Geom::Ray ray2(p, p2); p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); } -- cgit v1.2.3 From 348b712e3fe2fff56c42b5571fc52503744cbb86 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 12 Aug 2014 01:31:31 +0200 Subject: fix a bug knots resetting in fillet-chamfer (bzr r13341.1.137) --- src/live_effects/parameter/filletchamferpointarray.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index e9d1c0cd0..147d6baa2 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -332,10 +332,10 @@ void FilletChamferPointArrayParam::recalculate_knots( result.push_back(Point(xPos, 0)); } ++curve_it1; - ++curve_it2; if (curve_it2 != curve_endit) { - counter++; + ++curve_it2; } + counter++; counterCurves++; } } -- cgit v1.2.3 From 96126a3b2946c788d4701e35becfb22a4c38012e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 13 Aug 2014 00:30:34 +0200 Subject: Add 'Show handles' LPE (bzr r13341.1.139) --- src/live_effects/CMakeLists.txt | 2 + src/live_effects/Makefile_insert | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 7 +- src/live_effects/lpe-show_handles.cpp | 211 ++++++++++++++++++++++++++++++++++ src/live_effects/lpe-show_handles.h | 61 ++++++++++ 6 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 src/live_effects/lpe-show_handles.cpp create mode 100644 src/live_effects/lpe-show_handles.h (limited to 'src') diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 3c64e5c8e..d126aca9f 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -31,6 +31,7 @@ set(live_effects_SRC lpe-recursiveskeleton.cpp lpe-rough-hatches.cpp lpe-ruler.cpp + lpe-show_handles.cpp lpe-simplify.cpp # lpe-skeleton.cpp lpe-sketch.cpp @@ -99,6 +100,7 @@ set(live_effects_SRC lpe-rough-hatches.h lpe-ruler.h lpe-simplify.h + lpe-show_handles.h lpe-skeleton.h lpe-sketch.h lpe-spiro.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 91651a7c8..e9609a4aa 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -48,6 +48,8 @@ ink_common_sources += \ live_effects/lpe-lattice2.h \ live_effects/lpe-roughen.cpp \ live_effects/lpe-roughen.h \ + live_effects/lpe-show_handles.cpp \ + live_effects/lpe-show_handles.h \ live_effects/lpe-simplify.cpp \ live_effects/lpe-simplify.h \ live_effects/lpe-envelope.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index dac44981c..bc77d65c3 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -30,6 +30,7 @@ enum EffectType { LATTICE, LATTICE2, ROUGHEN, + SHOW_HANDLES, SIMPLIFY, ENVELOPE, CONSTRUCT_GRID, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 387dd7b8d..dc61701df 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -28,6 +28,7 @@ #include "live_effects/lpe-lattice.h" #include "live_effects/lpe-lattice2.h" #include "live_effects/lpe-roughen.h" +#include "live_effects/lpe-show_handles.h" #include "live_effects/lpe-simplify.h" #include "live_effects/lpe-envelope.h" #include "live_effects/lpe-constructgrid.h" @@ -126,7 +127,8 @@ const Util::EnumData LPETypeData[] = { /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, - {ROUGHEN, N_("Roughen"), "roughen"}, + {SHOW_HANDLES, N_("Show handles"), "show_handles"}, + {ROUGHEN, N_("Roughen"), "roughen"}, {BSPLINE, N_("BSpline"), "bspline"}, {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, @@ -274,6 +276,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case ROUGHEN: neweffect = static_cast ( new LPERoughen(lpeobj) ); break; + case SHOW_HANDLES: + neweffect = static_cast ( new LPEShowHandles(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp new file mode 100644 index 000000000..7b2b445b7 --- /dev/null +++ b/src/live_effects/lpe-show_handles.cpp @@ -0,0 +1,211 @@ +/* + * Authors: + * Jabier Arraiza Cenoz +* +* Copyright (C) Jabier Arraiza Cenoz 2014 + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "live_effects/lpe-show_handles.h" +#include "live_effects/parameter/parameter.h" +#include <2geom/sbasis-to-bezier.h> +#include <2geom/svg-path-parser.h> +#include "helper/geom.h" +#include "desktop-style.h" +#include "style.h" +#include "svg/svg.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEShowHandles::LPEShowHandles(LivePathEffectObject *lpeobject) + : Effect(lpeobject), + nodes(_("Show nodes"), _("Show nodes"), "nodes", &wr, this, true), + handles(_("Show handles"), _("Show handles"), "handles", &wr, this, true), + originalPath(_("Show path"), _("Show path"), "originalPath", &wr, this, true), + scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10) +{ + registerParameter(dynamic_cast(&nodes)); + registerParameter(dynamic_cast(&handles)); + registerParameter(dynamic_cast(&originalPath)); + registerParameter(dynamic_cast(&scaleNodesAndHandles)); + scaleNodesAndHandles.param_set_range(0, 500.); + scaleNodesAndHandles.param_set_increments(1, 1); + scaleNodesAndHandles.param_set_digits(2); + strokeWidth = 1.0; +} + +bool LPEShowHandles::alertsOff = false; + +/** + * Sets default styles to element + * this permanently remove.some styles of the element + */ + +void LPEShowHandles::doOnApply(SPLPEItem const* lpeitem) +{ + if(!alertsOff) { + char *msg = _("The \"show handles\" path effect will remove any custom style on the object you are applying it to. If this is not what you want, click Cancel."); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true); + gint response = dialog.run(); + alertsOff = true; + if(response == GTK_RESPONSE_CANCEL) { + SPLPEItem* item = const_cast(lpeitem); + item->removeCurrentPathEffect(false); + return; + } + } + SPLPEItem* item = const_cast(lpeitem); + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, "stroke", "black"); + sp_repr_css_set_property (css, "stroke-width", "1"); + sp_repr_css_set_property (css, "stroke-linecap", "butt"); + sp_repr_css_set_property(css, "fill", "none"); + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); +} + +void LPEShowHandles::doBeforeEffect (SPLPEItem const* lpeitem) +{ + SPItem const* item = SP_ITEM(lpeitem); + strokeWidth = item->style->stroke_width.computed; +} + +std::vector LPEShowHandles::doEffect_path (std::vector const & path_in) +{ + std::vector path_out; + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); + if(originalPath) { + for (unsigned int i=0; i < path_in.size(); i++) { + path_out.push_back(path_in[i]); + } + } + if(!outlinepath.empty()) { + outlinepath.clear(); + } + generateHelperPath(original_pathv); + for (unsigned int i=0; i < outlinepath.size(); i++) { + path_out.push_back(outlinepath[i]); + } + return path_out; +} + +void +LPEShowHandles::generateHelperPath(Geom::PathVector result) +{ + if(!handles && !nodes) { + return; + } + + Geom::CubicBezier const *cubic = NULL; + for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) { + //Si está vacío... + if (path_it->empty()) { + continue; + } + //Itreadores + Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve + Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve + Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + + if (path_it->closed()) { + // if the path is closed, maybe we have to stop a bit earlier because the + // closing line segment has zerolength. + const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type + // Geom::LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + if(nodes) { + drawNode(curve_it1->initialPoint()); + } + while (curve_it1 != curve_endit) { + cubic = dynamic_cast(&*curve_it1); + if (cubic) { + if(handles) { + if(!are_near((*cubic)[0],(*cubic)[1])){ + drawHandle((*cubic)[1]); + drawHandleLine((*cubic)[0],(*cubic)[1]); + } + if(!are_near((*cubic)[3],(*cubic)[2])){ + drawHandle((*cubic)[2]); + drawHandleLine((*cubic)[3],(*cubic)[2]); + } + } + } + if(nodes) { + drawNode(curve_it1->finalPoint()); + } + ++curve_it1; + if(curve_it2 != curve_endit){ + ++curve_it2; + } + } + } +} + +void +LPEShowHandles::drawNode(Geom::Point p) +{ + if(strokeWidth * scaleNodesAndHandles > 0.0) { + double diameter = strokeWidth * scaleNodesAndHandles; + char const * svgd; + svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + pathv *= Geom::Affine(diameter,0,0,diameter,0,0); + pathv += p - Geom::Point(diameter/2,diameter/2); + outlinepath.push_back(pathv[0]); + outlinepath.push_back(pathv[1]); + } +} + +void +LPEShowHandles::drawHandle(Geom::Point p) +{ + if(strokeWidth * scaleNodesAndHandles > 0.0) { + double diameter = strokeWidth * scaleNodesAndHandles; + char const * svgd; + svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + pathv *= Geom::Affine(diameter,0,0,diameter,0,0); + pathv += p - Geom::Point(diameter * 0.35,diameter * 0.35); + outlinepath.push_back(pathv[0]); + } +} + + +void +LPEShowHandles::drawHandleLine(Geom::Point p,Geom::Point p2) +{ + Geom::Path path; + double diameter = strokeWidth * scaleNodesAndHandles; + if(diameter > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){ + Geom::Ray ray2(p, p2); + p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35)); + } + path.start( p ); + path.appendNew( p2 ); + outlinepath.push_back(path); +} + +}; //namespace LivePathEffect +}; /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-show_handles.h b/src/live_effects/lpe-show_handles.h new file mode 100644 index 000000000..278908bb5 --- /dev/null +++ b/src/live_effects/lpe-show_handles.h @@ -0,0 +1,61 @@ +#ifndef INKSCAPE_LPE_SHOW_HANDLES_H +#define INKSCAPE_LPE_SHOW_HANDLES_H + +/* + * Authors: + * Jabier Arraiza Cenoz +* +* Copyright (C) Jabier Arraiza Cenoz 2014 + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/lpegroupbbox.h" +#include "live_effects/parameter/bool.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEShowHandles : public Effect , GroupBBoxEffect { + +public: + LPEShowHandles(LivePathEffectObject *lpeobject); + virtual ~LPEShowHandles(){} + + virtual void doOnApply(SPLPEItem const* lpeitem); + + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + + virtual void generateHelperPath(Geom::PathVector result); + + virtual void drawNode(Geom::Point p); + + virtual void drawHandle(Geom::Point p); + + virtual void drawHandleLine(Geom::Point p,Geom::Point p2); + +protected: + + virtual std::vector doEffect_path (std::vector const & path_in); + +private: + + BoolParam nodes; + BoolParam handles; + BoolParam originalPath; + ScalarParam scaleNodesAndHandles; + double strokeWidth; + static bool alertsOff; + + Geom::PathVector outlinepath; + + LPEShowHandles(const LPEShowHandles &); + LPEShowHandles &operator=(const LPEShowHandles &); + +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape +#endif + +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- cgit v1.2.3 From c73ebf3c732e19f665de2d490a915eabf425905e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Wed, 13 Aug 2014 08:24:04 +0200 Subject: Printing. Fix for Bug #264831 (Print settings not persistent). Printing. Fix for Bug #508529 (Printing rastered image offsets the page). Fixed bugs: - https://launchpad.net/bugs/264831 - https://launchpad.net/bugs/508529 (bzr r13509) --- src/ui/dialog/print.cpp | 8 +++++++- src/ui/widget/rendering-options.cpp | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 03ac9dc64..4d8d512df 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -18,6 +18,7 @@ #include #endif +#include "preferences.h" #include "print.h" #include @@ -44,14 +45,18 @@ static void draw_page( gint /*page_nr*/, gpointer user_data) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data; //printf("%s %d\n",__FUNCTION__, page_nr); if (junk->_tab->as_bitmap()) { // Render as exported PNG + prefs->setBool("/dialogs/printing/asbitmap", true); gdouble width = (junk->_doc)->getWidth().value("px"); gdouble height = (junk->_doc)->getHeight().value("px"); gdouble dpi = junk->_tab->bitmap_dpi(); + prefs->setDouble("/dialogs/printing/dpi", dpi); + std::string tmp_png; std::string tmp_base = "inkscape-print-png-XXXXXX"; @@ -92,7 +97,7 @@ static void draw_page( cairo_get_matrix(cr, &m); cairo_scale(cr, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi, Inkscape::Util::Quantity::convert(1, "in", "pt") / dpi); // FIXME: why is the origin offset?? - cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0); + cairo_set_source_surface(cr, png->cobj(), 0, 0); cairo_paint(cr); cairo_set_matrix(cr, &m); } @@ -106,6 +111,7 @@ static void draw_page( } else { // Render as vectors + prefs->setBool("/dialogs/printing/asbitmap", false); Inkscape::Extension::Internal::CairoRenderer renderer; Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext(); diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp index d6248df69..511b0375c 100644 --- a/src/ui/widget/rendering-options.cpp +++ b/src/ui/widget/rendering-options.cpp @@ -12,6 +12,7 @@ # include #endif +#include "preferences.h" #include "rendering-options.h" #include "util/units.h" #include @@ -38,6 +39,7 @@ RenderingOptions::RenderingOptions () : Glib::ustring(""), Glib::ustring(""), false) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); // set up tooltips _radio_vector.set_tooltip_text( _("Render using Cairo vector operations. " @@ -52,15 +54,21 @@ RenderingOptions::RenderingOptions () : set_border_width(2); - // default to vector operations - _radio_vector.set_active (true); Gtk::RadioButtonGroup group = _radio_vector.get_group (); _radio_bitmap.set_group (group); _radio_bitmap.signal_toggled().connect(sigc::mem_fun(*this, &RenderingOptions::_toggled)); - + + // default to vector operations + if (prefs->getBool("/dialogs/printing/asbitmap", false)) { + _radio_bitmap.set_active(); + } else { + _radio_vector.set_active(); + } + // configure default DPI _dpi.setRange(Inkscape::Util::Quantity::convert(1, "in", "pt"),2400.0); - _dpi.setValue(Inkscape::Util::Quantity::convert(1, "in", "pt")); + _dpi.setValue(prefs->getDouble("/dialogs/printing/dpi", + Inkscape::Util::Quantity::convert(1, "in", "pt"))); _dpi.setIncrements(1.0,10.0); _dpi.setDigits(0); _dpi.update(); -- cgit v1.2.3 From 9d5529ca1b43a144f825fc58d6aa37911a4ac7f6 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 13 Aug 2014 09:12:45 -0400 Subject: Fix build (bzr r13510) --- src/libnrtype/font-lister.cpp | 6 +++++ src/libnrtype/font-lister.h | 7 +---- src/ui/dialog/print.cpp | 4 ++- src/ui/widget/rendering-options.cpp | 2 ++ src/widgets/toolbox.cpp | 52 ++++++++++++++++++------------------- 5 files changed, 38 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 43c3045b1..3c21e62e4 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -268,6 +268,12 @@ namespace Inkscape font_list_store->thaw_notify(); } +Inkscape::FontLister* FontLister::get_instance () +{ + static Inkscape::FontLister* instance = new Inkscape::FontLister(); + return instance; +} + void FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index c89dab550..09be16f24 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -149,12 +149,7 @@ namespace Inkscape update_font_list_recursive( SPObject *r, std::list *l ); public: - static Inkscape::FontLister* - get_instance () - { - static Inkscape::FontLister* instance = new Inkscape::FontLister(); - return instance; - } + static Inkscape::FontLister* get_instance (); /** Takes a hand written font spec and returns a Pango generated one in * standard form. diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index 4d8d512df..ed39ebb32 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -13,14 +13,16 @@ #ifdef HAVE_CONFIG_H # include #endif + #ifdef WIN32 #include #include #endif +#include + #include "preferences.h" #include "print.h" -#include #include "extension/internal/cairo-render-context.h" #include "extension/internal/cairo-renderer.h" diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp index 511b0375c..837387f7b 100644 --- a/src/ui/widget/rendering-options.cpp +++ b/src/ui/widget/rendering-options.cpp @@ -12,6 +12,8 @@ # include #endif +#include + #include "preferences.h" #include "rendering-options.h" #include "util/units.h" diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 939546f78..c7d72f0b8 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -39,35 +39,35 @@ #include #include -#include "../desktop.h" -#include "../desktop-handles.h" -#include "../desktop-style.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "desktop-style.h" #include "document-undo.h" -#include "../ege-adjustment-action.h" -#include "../ege-output-action.h" -#include "../ege-select-one-action.h" -#include "../graphlayout.h" -#include "../helper/action.h" -#include "../helper/action-context.h" +#include "ege-adjustment-action.h" +#include "ege-output-action.h" +#include "ege-select-one-action.h" +#include "graphlayout.h" +#include "helper/action.h" +#include "helper/action-context.h" #include "icon.h" -#include "../ink-action.h" -#include "../ink-comboboxentry-action.h" -#include "../inkscape.h" -#include "../interface.h" -#include "../shortcuts.h" -#include "../sp-namedview.h" -#include "../tools-switch.h" -#include "../ui/icon-names.h" -#include "../ui/widget/style-swatch.h" -#include "../verbs.h" -#include "../widgets/button.h" -#include "../widgets/spinbutton-events.h" +#include "ink-action.h" +#include "ink-comboboxentry-action.h" +#include "inkscape.h" +#include "interface.h" +#include "shortcuts.h" +#include "sp-namedview.h" +#include "tools-switch.h" +#include "ui/icon-names.h" +#include "ui/widget/style-swatch.h" +#include "verbs.h" +#include "widgets/button.h" +#include "widgets/spinbutton-events.h" #include "ui/widget/spinbutton.h" -#include "../widgets/spw-utilities.h" -#include "../widgets/widget-sizes.h" -#include "../xml/attribute-record.h" -#include "../xml/node-event-vector.h" -#include "../xml/repr.h" +#include "widgets/spw-utilities.h" +#include "widgets/widget-sizes.h" +#include "xml/attribute-record.h" +#include "xml/node-event-vector.h" +#include "xml/repr.h" #include "ui/uxmanager.h" -- cgit v1.2.3 From ce41e6c128161e245d9523c0b0cbbba8e12823c7 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Wed, 13 Aug 2014 09:15:28 -0400 Subject: Revert unintentional changes (bzr r13511) --- src/libnrtype/font-lister.cpp | 6 ----- src/libnrtype/font-lister.h | 7 +++++- src/widgets/toolbox.cpp | 52 +++++++++++++++++++++---------------------- 3 files changed, 32 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 3c21e62e4..43c3045b1 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -268,12 +268,6 @@ namespace Inkscape font_list_store->thaw_notify(); } -Inkscape::FontLister* FontLister::get_instance () -{ - static Inkscape::FontLister* instance = new Inkscape::FontLister(); - return instance; -} - void FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index 09be16f24..c89dab550 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -149,7 +149,12 @@ namespace Inkscape update_font_list_recursive( SPObject *r, std::list *l ); public: - static Inkscape::FontLister* get_instance (); + static Inkscape::FontLister* + get_instance () + { + static Inkscape::FontLister* instance = new Inkscape::FontLister(); + return instance; + } /** Takes a hand written font spec and returns a Pango generated one in * standard form. diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index c7d72f0b8..939546f78 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -39,35 +39,35 @@ #include #include -#include "desktop.h" -#include "desktop-handles.h" -#include "desktop-style.h" +#include "../desktop.h" +#include "../desktop-handles.h" +#include "../desktop-style.h" #include "document-undo.h" -#include "ege-adjustment-action.h" -#include "ege-output-action.h" -#include "ege-select-one-action.h" -#include "graphlayout.h" -#include "helper/action.h" -#include "helper/action-context.h" +#include "../ege-adjustment-action.h" +#include "../ege-output-action.h" +#include "../ege-select-one-action.h" +#include "../graphlayout.h" +#include "../helper/action.h" +#include "../helper/action-context.h" #include "icon.h" -#include "ink-action.h" -#include "ink-comboboxentry-action.h" -#include "inkscape.h" -#include "interface.h" -#include "shortcuts.h" -#include "sp-namedview.h" -#include "tools-switch.h" -#include "ui/icon-names.h" -#include "ui/widget/style-swatch.h" -#include "verbs.h" -#include "widgets/button.h" -#include "widgets/spinbutton-events.h" +#include "../ink-action.h" +#include "../ink-comboboxentry-action.h" +#include "../inkscape.h" +#include "../interface.h" +#include "../shortcuts.h" +#include "../sp-namedview.h" +#include "../tools-switch.h" +#include "../ui/icon-names.h" +#include "../ui/widget/style-swatch.h" +#include "../verbs.h" +#include "../widgets/button.h" +#include "../widgets/spinbutton-events.h" #include "ui/widget/spinbutton.h" -#include "widgets/spw-utilities.h" -#include "widgets/widget-sizes.h" -#include "xml/attribute-record.h" -#include "xml/node-event-vector.h" -#include "xml/repr.h" +#include "../widgets/spw-utilities.h" +#include "../widgets/widget-sizes.h" +#include "../xml/attribute-record.h" +#include "../xml/node-event-vector.h" +#include "../xml/repr.h" #include "ui/uxmanager.h" -- cgit v1.2.3 From 9fdd8f25ee0f04d337864c7ec5e3216dae727e3c Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Thu, 14 Aug 2014 22:09:10 +0200 Subject: Fix some transformation center regressions, related to the viewbox/units changes (bzr r13512) --- src/selection-chemistry.cpp | 7 ++----- src/sp-item-group.cpp | 8 +------- src/sp-item.cpp | 26 +++++++++++++++++++++----- src/ui/dialog/document-properties.cpp | 7 ++++--- 4 files changed, 28 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index f058189d3..868a9d743 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1621,13 +1621,10 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->doWriteTransform(item->getRepr(), item->transform, NULL, compensate); } - // if we're transforming the actual object, not just updating the repr, we can transform the + // if we're moving the actual object, not just updating the repr, we can transform the // center by the same matrix (only necessary for non-translations) if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { - // If there's a viewbox, we might have an affine with a translation component; - // we will only apply the scaling/skewing components, not the translations - // because otherwise the center will move relative to the item - item->setCenter(old_center * affine.withoutTranslation()); + item->setCenter(old_center * affine); item->updateRepr(); } } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 657aca692..bb52b0c55 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -660,12 +660,6 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p) Geom::Translate const s(p); Geom::Affine final = s.inverse() * sc * s; - Geom::Point old_center(0,0); - if (item->isCenterSet()) { - item->scaleCenter(sc.inverse()); // Convert the old relative center position to the new coordinates already now - old_center = item->getCenter(); // because getCenter() will use the bbox midpoint, which is also already in the new coordinates - } - gchar const *conn_type = NULL; if (SP_IS_TEXT_TEXTPATH(item)) { SP_TEXT(item)->optimizeTextpathText(); @@ -710,7 +704,7 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p) } if (item->isCenterSet() && !(final.isTranslation() || final.isIdentity())) { - item->setCenter(old_center * final); + item->scaleCenter(sc); // All coordinates have been scaled, so also the center must be scaled item->updateRepr(); } } diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 0cacc86b1..428f9555e 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -228,18 +228,25 @@ void SPItem::setExplicitlyHidden(bool val) { } /** - * Sets the transform_center_x and transform_center_y properties to retain the rotation centre - */ + * Sets the transform_center_x and transform_center_y properties to retain the rotation center +*/ void SPItem::setCenter(Geom::Point const &object_centre) { document->ensureUpToDate(); + // Copied from DocumentProperties::onDocUnitChange() + gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width(); + gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); + // FIXME this is seriously wrong Geom::OptRect bbox = desktopGeometricBounds(); if (bbox) { - transform_center_x = object_centre[Geom::X] - bbox->midpoint()[Geom::X]; + // object centre is document coordinates (i.e. in pixels), so we need to consider the viewbox + // to translate to user units; transform_center_x/y is in user units + transform_center_x = (object_centre[Geom::X] - bbox->midpoint()[Geom::X])/viewscale; if (Geom::are_near(transform_center_x, 0)) // rounding error transform_center_x = 0; - transform_center_y = object_centre[Geom::Y] - bbox->midpoint()[Geom::Y]; + transform_center_y = (object_centre[Geom::Y] - bbox->midpoint()[Geom::Y])/viewscale; if (Geom::are_near(transform_center_y, 0)) // rounding error transform_center_y = 0; } @@ -255,16 +262,25 @@ bool SPItem::isCenterSet() const { return (transform_center_x != 0 || transform_center_y != 0); } +// Get the item's transformation center in document coordinates (i.e. in pixels) Geom::Point SPItem::getCenter() const { document->ensureUpToDate(); + // Copied from DocumentProperties::onDocUnitChange() + gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width(); + gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); + // FIXME this is seriously wrong Geom::OptRect bbox = desktopGeometricBounds(); if (bbox) { - return bbox->midpoint() + Geom::Point (transform_center_x, transform_center_y); + // transform_center_x/y are stored in user units, so we have to take the viewbox into account to translate to document coordinates + return bbox->midpoint() + Geom::Point (transform_center_x*viewscale, transform_center_y*viewscale); + } else { return Geom::Point(0, 0); // something's wrong! } + } void diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 9141b2268..4e4616724 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -45,6 +45,7 @@ #include "widgets/icon.h" #include "xml/node-event-vector.h" #include "xml/repr.h" +#include // std::min #include "rdf.h" #include "ui/widget/entity-entry.h" @@ -1735,9 +1736,9 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale) - viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); + gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); + gdouble viewscale = std::min(viewscale_h, viewscale_w); gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, -- cgit v1.2.3 From 527aea8e906f12c1b5e6072321fa48f09d60bab5 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Thu, 14 Aug 2014 18:10:29 -0400 Subject: Clone Original -> Fill Between Many (bzr r13090.1.104) --- src/selection-chemistry.cpp | 85 ++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 1d7d76609..33279c0e7 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2793,54 +2793,53 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) if (desktop == NULL) { return; } - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - SPItem *item = selection->singleItem(); - if (g_slist_length(const_cast(selection->itemList())) != 1 || !item) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select one path to clone.")); - return; - } - if ( !(SP_IS_SHAPE(item) || SP_IS_TEXT(item)) ) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select one path to clone.")); - return; - } - - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - Inkscape::XML::Node *parent = item->getRepr()->parent(); - - // create the LPE - Inkscape::XML::Node *lpe_repr = xml_doc->createElement("inkscape:path-effect"); - { - lpe_repr->setAttribute("effect", "clone_original"); - gchar *href = g_strdup_printf("#%s", item->getRepr()->attribute("id")); - lpe_repr->setAttribute("linkedpath", href); - g_free(href); - desktop->doc()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to and assigns the 'id' attribute - } - const gchar * lpe_id = lpe_repr->attribute("id"); - Inkscape::GC::release(lpe_repr); - - // create the new path - Inkscape::XML::Node *clone = xml_doc->createElement("svg:path"); - { - clone->setAttribute("d", "M 0 0", false); - // add the new clone to the top of the original's parent - parent->appendChild(clone); - SPObject *clone_obj = desktop->doc()->getObjectById(clone->attribute("id")); - if (SP_IS_LPE_ITEM(clone_obj)) { - gchar *href = g_strdup_printf("#%s", lpe_id); - SP_LPE_ITEM(clone_obj)->addPathEffect( href, false ); - g_free(href); + + Inkscape::SVGOStringStream os; + SPObject * firstItem = NULL; + for (const GSList * item = desktop->selection->itemList(); item != NULL; item = item->next) { + if (SP_IS_SHAPE(item->data) || SP_IS_TEXT(item->data)) { + if (firstItem) { + os << "|"; + } else { + firstItem = SP_ITEM(item->data); + } + os << "#" << SP_ITEM(item->data)->getId() << ",0"; } } + if (firstItem) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + SPObject *parent = firstItem->parent; - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, - _("Clone original path")); + // create the LPE + Inkscape::XML::Node *lpe_repr = xml_doc->createElement("inkscape:path-effect"); + { + lpe_repr->setAttribute("effect", "fill_between_many"); + lpe_repr->setAttribute("linkedpaths", os.str().c_str()); + desktop->doc()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to and assigns the 'id' attribute + } + const gchar * lpe_id = lpe_repr->attribute("id"); + Inkscape::GC::release(lpe_repr); - // select the new object: - selection->set(clone); + // create the new path + Inkscape::XML::Node *clone = xml_doc->createElement("svg:path"); + { + clone->setAttribute("d", "M 0 0", false); + // add the new clone to the top of the original's parent + parent->appendChildRepr(clone); + SPObject *clone_obj = desktop->doc()->getObjectById(clone->attribute("id")); + if (SP_IS_LPE_ITEM(clone_obj)) { + gchar *href = g_strdup_printf("#%s", lpe_id); + //sp_lpe_item_add_path_effect( SP_LPE_ITEM(clone_obj), href, false ); + SP_LPE_ITEM(clone_obj)->addPathEffect(href, false); + g_free(href); + } + } - Inkscape::GC::release(clone); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, + _("Fill between strokes")); + } else { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to fill.")); + } } void sp_selection_to_marker(SPDesktop *desktop, bool apply) -- cgit v1.2.3 From 2f2df21d0c1d977644578c74ac466bcb330f71e5 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Thu, 14 Aug 2014 22:27:49 -0700 Subject: Set pre-release version to 0.91pre2 (bzr r13513) --- src/inkscape-x64.rc | 8 ++++---- src/inkscape.rc | 8 ++++---- src/inkview-x64.rc | 8 ++++---- src/inkview.rc | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/inkscape-x64.rc b/src/inkscape-x64.rc index ce286c2ca..47dbcb2bc 100644 --- a/src/inkscape-x64.rc +++ b/src/inkscape-x64.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest-x64.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91pre2,0,0 + PRODUCTVERSION 0,91pre2,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkscape" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkscape" VALUE "LegalCopyright", " 2014 Inkscape" VALUE "ProductName", "Inkscape" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" diff --git a/src/inkscape.rc b/src/inkscape.rc index 395ef39e1..2c2c0112b 100644 --- a/src/inkscape.rc +++ b/src/inkscape.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91pre2,0,0 + PRODUCTVERSION 0,91pre2,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkscape" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkscape" VALUE "LegalCopyright", " 2014 Inkscape" VALUE "ProductName", "Inkscape" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" diff --git a/src/inkview-x64.rc b/src/inkview-x64.rc index 2de16060b..f23fe84c9 100644 --- a/src/inkview-x64.rc +++ b/src/inkview-x64.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkview-manifest-x64.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91,0,0 + PRODUCTVERSION 0,91,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkview" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkview" VALUE "LegalCopyright", " 2014 Inkscape" VALUE "ProductName", "Inkview" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" diff --git a/src/inkview.rc b/src/inkview.rc index fd7eb50a1..efbe2568b 100644 --- a/src/inkview.rc +++ b/src/inkview.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkview-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,48,0,9 - PRODUCTVERSION 0,48,0,9 + FILEVERSION 0,91pre2,0,0 + PRODUCTVERSION 0,91pre2,0,0 BEGIN BLOCK "StringFileInfo" BEGIN @@ -13,11 +13,11 @@ BEGIN VALUE "Comments", "Published under the GNU GPL" VALUE "CompanyName", "inkscape.org" VALUE "FileDescription", "Inkview" - VALUE "FileVersion", "0.48+devel" + VALUE "FileVersion", "0.91pre2" VALUE "InternalName", "Inkview" VALUE "LegalCopyright", " 2014 Inkscape" VALUE "ProductName", "Inkview" - VALUE "ProductVersion", "0.48+devel" + VALUE "ProductVersion", "0.91pre2" END END BLOCK "VarFileInfo" -- cgit v1.2.3 From 940176d1a9959328f186cb21c22bf43d4cfed4fc Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Fri, 15 Aug 2014 08:43:45 +0200 Subject: Preferences. Fix for Bug #184499 (Inkscape Preferences dialog does not remember tabs/pages). Fixed bugs: - https://launchpad.net/bugs/184499 (bzr r13517) --- src/ui/dialog/inkscape-preferences.cpp | 8 ++++++-- src/ui/dialog/inkscape-preferences.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index f1a29e971..5d065dc60 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -76,7 +76,8 @@ InkscapePreferences::InkscapePreferences() : UI::Widget::Panel ("", "/dialogs/preferences", SP_VERB_DIALOG_DISPLAY), _max_dialog_width(0), _max_dialog_height(0), - _current_page(0) + _current_page(0), + _init(true) { //get the width of a spinbutton Inkscape::UI::Widget::SpinButton* sb = new Inkscape::UI::Widget::SpinButton; @@ -2000,6 +2001,7 @@ bool InkscapePreferences::PresentPage(const Gtk::TreeModel::iterator& iter) Gtk::TreeModel::Row row = *iter; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int desired_page = prefs->getInt("/dialogs/preferences/page", 0); + _init = false; if (desired_page == row[_page_list_columns._col_id]) { if (desired_page >= PREFS_PAGE_TOOLS && desired_page <= PREFS_PAGE_TOOLS_CONNECTOR) @@ -2049,7 +2051,9 @@ void InkscapePreferences::on_pagelist_selection_changed() Gtk::TreeModel::Row row = *iter; _current_page = row[_page_list_columns._col_page]; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + if (!_init) { + prefs->setInt("/dialogs/preferences/page", row[_page_list_columns._col_id]); + } _page_title.set_markup("" + row[_page_list_columns._col_name] + ""); _page_frame.add(*_current_page); _current_page->show(); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 1c2151605..9f37626ed 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -532,6 +532,7 @@ private: InkscapePreferences(); InkscapePreferences(InkscapePreferences const &d); InkscapePreferences operator=(InkscapePreferences const &d); + bool _init; }; } // namespace Dialog -- cgit v1.2.3 From f0d21a859fd6c3594e46339030e7209e0138da04 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Fri, 15 Aug 2014 15:11:41 +0200 Subject: suppress compiler warning (bzr r13519) --- src/sp-solid-color.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/sp-solid-color.cpp b/src/sp-solid-color.cpp index 1f606d176..9f6692f98 100644 --- a/src/sp-solid-color.cpp +++ b/src/sp-solid-color.cpp @@ -72,7 +72,7 @@ Inkscape::XML::Node* SPSolidColor::write(Inkscape::XML::Document* xml_doc, Inksc return repr; } -cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const &bbox, double opacity) { +cairo_pattern_t* SPSolidColor::pattern_new(cairo_t * /*ct*/, Geom::OptRect const & /*bbox*/, double opacity) { SPIColor *c = &(this->style->solid_color); cairo_pattern_t *cp = cairo_pattern_create_rgba ( c->value.color.v.c[0], c->value.color.v.c[1], c->value.color.v.c[2], SP_SCALE24_TO_FLOAT(this->style->solid_opacity.value) * opacity ); -- cgit v1.2.3 From ab9df1bf462c32d785e0b146228d5711a0599114 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Fri, 15 Aug 2014 15:14:32 +0200 Subject: memleak fix (Bug #1293827: LivePathEffect memory leak ) (bzr r13520) --- src/live_effects/parameter/parameter.cpp | 8 +++++++- src/live_effects/parameter/parameter.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index a5de2169e..ad2960cd9 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -36,13 +36,19 @@ Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip, { } - void Parameter::param_write_to_repr(const char * svgd) { param_effect->getRepr()->setAttribute(param_key.c_str(), svgd); } +void Parameter::write_to_SVG(void) +{ + gchar * str = param_getSVGValue(); + param_write_to_repr(str); + g_free(str); +} + /*########################################### * REAL PARAM */ diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index 785ada92e..2e6cae49f 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -49,7 +49,7 @@ public: virtual bool param_readSVGValue(const gchar * strvalue) = 0; // returns true if new value is valid / accepted. virtual gchar * param_getSVGValue() const = 0; - void write_to_SVG() { param_write_to_repr(param_getSVGValue()); } + void write_to_SVG(); virtual void param_set_default() = 0; -- cgit v1.2.3 From 13db4e8d7c2250a8b5a88beca4a5800ef90b7f54 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 16 Aug 2014 22:54:37 +0200 Subject: Fix shift of transformation center on pasting Fixed bugs: - https://launchpad.net/bugs/1247799 (bzr r13521) --- src/file.cpp | 6 +++--- src/selection-chemistry.cpp | 14 ++++++++------ src/selection-chemistry.h | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index 51e629c7d..580c93c9e 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1087,9 +1087,9 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) Inkscape::Selection *selection = sp_desktop_selection(desktop); selection->setReprList(pasted_objects); - // invers apply parent transform + // Apply inverse of parent transform Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false); + sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); // Update (among other things) all curves in paths, for bounds() to work target_document->ensureUpToDate(); @@ -1226,7 +1226,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // c2p is identity matrix at this point unless ensureUpToDate is called doc->ensureUpToDate(); Geom::Affine affine = doc->getRoot()->c2p * SP_ITEM(place_to_insert)->i2doc_affine().inverse(); - sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false); + sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false, false); // move to mouse pointer { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 868a9d743..01ce20509 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1466,7 +1466,7 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live that case, items are already in the new position, but the repr is in the old, and this function then simply updates the repr from item->transform. */ -void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d, bool compensate) +void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center) { if (selection->isEmpty()) return; @@ -1621,11 +1621,13 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->doWriteTransform(item->getRepr(), item->transform, NULL, compensate); } - // if we're moving the actual object, not just updating the repr, we can transform the - // center by the same matrix (only necessary for non-translations) - if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { - item->setCenter(old_center * affine); - item->updateRepr(); + if (adjust_transf_center) { // The transformation center should not be touched in case of pasting or importing, which is allowed by this if clause + // if we're moving the actual object, not just updating the repr, we can transform the + // center by the same matrix (only necessary for non-translations) + if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { + item->setCenter(old_center * affine); + item->updateRepr(); + } } } } diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index d76a67a9d..01c35d65a 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -104,7 +104,7 @@ void sp_selection_to_next_layer( SPDesktop *desktop, bool suppressDone = false ) void sp_selection_to_prev_layer( SPDesktop *desktop, bool suppressDone = false ); void sp_selection_to_layer( SPDesktop *desktop, SPObject *layer, bool suppressDone = false ); -void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true); +void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true, bool adjust_transf_center = true); void sp_selection_remove_transform (SPDesktop *desktop); void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1); void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale); -- cgit v1.2.3 From 38b8b56f7a45878b6aea857f8bcc15064f44200d Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sat, 16 Aug 2014 20:23:01 -0400 Subject: Fix grid jumping (bug #1342238). Fixed bugs: - https://launchpad.net/bugs/1342238 (bzr r13522) --- src/display/canvas-axonomgrid.cpp | 3 +++ src/util/units.cpp | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 312a8d655..592c962a6 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -387,6 +387,9 @@ _wr.setUpdating (false); _rcp_gmcol->setRgba32 (empcolor); _rsi->setValue (empspacing); + _rsu_ox->setProgrammatically = false; + _rsu_oy->setProgrammatically = false; + return table; } diff --git a/src/util/units.cpp b/src/util/units.cpp index d2053f60b..eb4a313e0 100644 --- a/src/util/units.cpp +++ b/src/util/units.cpp @@ -291,11 +291,15 @@ Quantity UnitTable::parseQuantity(Glib::ustring const &q) const std::istringstream tmp_v(match_info.fetch(0)); tmp_v >> value; } + int start_pos, end_pos; + match_info.fetch_pos(0, end_pos, start_pos); + end_pos = q.size() - start_pos; + Glib::ustring u = q.substr(start_pos, end_pos); // Extract unit abbreviation Glib::ustring abbr; Glib::RefPtr unit_regex = Glib::Regex::create("[A-z%]+"); - if (unit_regex->match(q, match_info)) { + if (unit_regex->match(u, match_info)) { abbr = match_info.fetch(0); } -- cgit v1.2.3 From 06b2a7b43586148d32f546ad82e6a47ba2a597fd Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Aug 2014 22:43:35 -0400 Subject: Work around for upstream GTK bug #734915 (speeds launch times) (bzr r13523) --- src/ink-comboboxentry-action.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp index ebd238edc..6579c8ff8 100644 --- a/src/ink-comboboxentry-action.cpp +++ b/src/ink-comboboxentry-action.cpp @@ -383,6 +383,15 @@ GtkWidget* create_tool_item( GtkAction* action ) g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action ); + // Optionally add separator function... + if( ink_comboboxentry_action->separator_func != NULL ) { + gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, + GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), + NULL, NULL ); + } + + gtk_widget_show_all (comboBoxEntry); + // Optionally add formatting... if( ink_comboboxentry_action->cell_data_func != NULL ) { GtkCellRenderer *cell = gtk_cell_renderer_text_new(); @@ -393,13 +402,6 @@ GtkWidget* create_tool_item( GtkAction* action ) NULL, NULL ); } - // Optionally add separator function... - if( ink_comboboxentry_action->separator_func != NULL ) { - gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, - GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), - NULL, NULL ); - } - // Optionally widen the combobox width... which widens the drop-down list in list mode. if( ink_comboboxentry_action->extra_width > 0 ) { GtkRequisition req; -- cgit v1.2.3 From 2a2db8af11c2e518bd7bfe520e2f88a7e439d939 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 16 Aug 2014 22:47:53 -0400 Subject: Merge in font-speedup branch to improve launch times (bzr r13341.1.140) --- src/ink-comboboxentry-action.cpp | 18 +- src/libnrtype/FontFactory.cpp | 76 ++ src/libnrtype/FontFactory.h | 10 +- src/libnrtype/font-lister.cpp | 1697 +++++++++++++++++++------------------- src/libnrtype/font-lister.h | 556 ++++++------- src/ui/dialog/text-edit.cpp | 6 +- src/widgets/font-selector.cpp | 4 +- src/widgets/text-toolbar.cpp | 10 +- 8 files changed, 1239 insertions(+), 1138 deletions(-) (limited to 'src') diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp index ebd238edc..6ae2a8485 100644 --- a/src/ink-comboboxentry-action.cpp +++ b/src/ink-comboboxentry-action.cpp @@ -383,6 +383,17 @@ GtkWidget* create_tool_item( GtkAction* action ) g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action ); + // Optionally add separator function... + if( ink_comboboxentry_action->separator_func != NULL ) { + gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, + GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), + NULL, NULL ); + } + + // FIXME: once gtk3 migration is done this can be removed + // https://bugzilla.gnome.org/show_bug.cgi?id=734915 + gtk_widget_show_all (comboBoxEntry); + // Optionally add formatting... if( ink_comboboxentry_action->cell_data_func != NULL ) { GtkCellRenderer *cell = gtk_cell_renderer_text_new(); @@ -393,13 +404,6 @@ GtkWidget* create_tool_item( GtkAction* action ) NULL, NULL ); } - // Optionally add separator function... - if( ink_comboboxentry_action->separator_func != NULL ) { - gtk_combo_box_set_row_separator_func( ink_comboboxentry_action->combobox, - GtkTreeViewRowSeparatorFunc (ink_comboboxentry_action->separator_func), - NULL, NULL ); - } - // Optionally widen the combobox width... which widens the drop-down list in list mode. if( ink_comboboxentry_action->extra_width > 0 ) { GtkRequisition req; diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 6859a4a5c..c5e68e264 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -513,6 +513,82 @@ static bool StyleNameCompareInternal(const StyleNames &style1, const StyleNames return( StyleNameValue( style1.CssName ) < StyleNameValue( style2.CssName ) ); } +static bool ustringPairSort(std::pair const& first, std::pair const& second) +{ + // well, this looks weird. + return first.second < second.second; +} + +void font_factory::GetUIFamilies(std::vector& out) +{ + // Gather the family names as listed by Pango + PangoFontFamily** families = NULL; + int numFamilies = 0; + pango_font_map_list_families(fontServer, &families, &numFamilies); + + std::vector > sorted; + + // not size_t + for (int currentFamily = 0; currentFamily < numFamilies; ++currentFamily) { + const char* displayName = pango_font_family_get_name(families[currentFamily]); + + if (displayName == 0 || *displayName == '\0') { + continue; + } + sorted.push_back(std::make_pair(families[currentFamily], displayName)); + } + + std::sort(sorted.begin(), sorted.end(), ustringPairSort); + + for (size_t i = 0; i < sorted.size(); ++i) { + out.push_back(sorted[i].first); + } +} + +GList* font_factory::GetUIStyles(PangoFontFamily * in) +{ + GList* ret = NULL; + // Gather the styles for this family + PangoFontFace** faces = NULL; + int numFaces = 0; + pango_font_family_list_faces(in, &faces, &numFaces); + + for (int currentFace = 0; currentFace < numFaces; currentFace++) { + + // If the face has a name, describe it, and then use the + // description to get the UI family and face strings + const gchar* displayName = pango_font_face_get_face_name(faces[currentFace]); + if (displayName == NULL || *displayName == '\0') { + continue; + } + + PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]); + if (faceDescr) { + Glib::ustring familyUIName = GetUIFamilyString(faceDescr); + Glib::ustring styleUIName = GetUIStyleString(faceDescr); + + // Disable synthesized (faux) font faces except for CSS generic faces + if (pango_font_face_is_synthesized(faces[currentFace]) ) { + if (familyUIName.compare( "sans-serif" ) != 0 && + familyUIName.compare( "serif" ) != 0 && + familyUIName.compare( "monospace" ) != 0 && + familyUIName.compare( "fantasy" ) != 0 && + familyUIName.compare( "cursive" ) != 0 ) { + continue; + } + } + + if (!familyUIName.empty() && !styleUIName.empty()) { + // Add the style information + ret = g_list_append(ret, new StyleNames(styleUIName, displayName)); + } + } + pango_font_description_free(faceDescr); + } + g_free(faces); + return ret; +} + void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) { g_assert(map); diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 513ee4bf7..c48ae831a 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -23,7 +23,7 @@ #include "nr-type-primitives.h" #include "nr-type-pos-def.h" #include "font-style-to-pos.h" -#include "../style.h" +#include "style.h" /* Freetype */ #ifdef USE_PANGO_WIN32 @@ -123,7 +123,13 @@ public: // Gathers all strings needed for UI while storing pango information in // fontInstanceMap and fontStringMap + // don't use this function, it's too slow void GetUIFamiliesAndStyles(FamilyToStylesMap *map); + + // Helpfully inserts all font families into the provided vector + void GetUIFamilies(std::vector& out); + // Retrieves style information about a family in a newly allocated GList. + GList* GetUIStyles(PangoFontFamily * in); /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information font_instance* FaceFromStyle(SPStyle const *style); @@ -177,4 +183,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 43c3045b1..07c80054d 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -1,5 +1,5 @@ #ifdef HAVE_CONFIG_H -# include +#include #endif #include @@ -27,410 +27,432 @@ // CSS dictates that font family names are case insensitive. // This should really implement full Unicode case unfolding. -bool familyNamesAreEqual( const Glib::ustring &a, const Glib::ustring &b ) { +bool familyNamesAreEqual(const Glib::ustring &a, const Glib::ustring &b) +{ + return (a.casefold().compare(b.casefold()) == 0); +} - return( a.casefold().compare( b.casefold() ) == 0 ); +static const char* sp_font_family_get_name(PangoFontFamily* family) +{ + const char* name = pango_font_family_get_name(family); + if (strncmp(name, "Sans", 4) == 0 && strlen(name) == 4) + return "sans-serif"; + if (strncmp(name, "Serif", 5) == 0 && strlen(name) == 5) + return "serif"; + if (strncmp(name, "Monospace", 9) == 0 && strlen(name) == 9) + return "monospace"; + return name; } -namespace Inkscape +namespace Inkscape { + +FontLister::FontLister() { - FontLister::FontLister () - { - font_list_store = Gtk::ListStore::create (FontList); - font_list_store->freeze_notify(); - - FamilyToStylesMap familyStyleMap; - font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap); - - // Grab the family names into a list and then sort them - std::list familyList; - for (FamilyToStylesMap::iterator iter = familyStyleMap.begin(); - iter != familyStyleMap.end(); - ++iter) { - familyList.push_back((*iter).first); + font_list_store = Gtk::ListStore::create(FontList); + font_list_store->freeze_notify(); + + /* Create default styles for use when font-family is unknown on system. */ + default_styles = g_list_append(NULL, new StyleNames("Normal")); + default_styles = g_list_append(default_styles, new StyleNames("Italic")); + default_styles = g_list_append(default_styles, new StyleNames("Bold")); + default_styles = g_list_append(default_styles, new StyleNames("Bold Italic")); + + // Get sorted font families from Pango + std::vector familyVector; + font_factory::Default()->GetUIFamilies(familyVector); + + // Traverse through the family names and set up the list store + for (size_t i = 0; i < familyVector.size(); ++i) { + const char* displayName = sp_font_family_get_name(familyVector[i]); + + if (displayName == 0 || *displayName == '\0') { + continue; } - familyList.sort(); - // Traverse through the family names and set up the list store (note that - // the styles list that are the map's values are already sorted) - while (!familyList.empty()) { - Glib::ustring familyName = familyList.front(); - familyList.pop_front(); - - if (!familyName.empty()) { - Gtk::TreeModel::iterator treeModelIter = font_list_store->append(); - //(*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup(familyName.c_str())); - (*treeModelIter)[FontList.family] = familyName; - - // Now go through the styles - GList *styles = NULL; - std::list &styleStrings = familyStyleMap[familyName]; - for (std::list::iterator it=styleStrings.begin(); - it != styleStrings.end(); - ++it) { - // Our own copy - StyleNames *copy = new StyleNames( *it ); - styles = g_list_append(styles, copy); - } - - (*treeModelIter)[FontList.styles] = styles; - (*treeModelIter)[FontList.onSystem] = true; - } + Glib::ustring familyName = displayName; + if (!familyName.empty()) { + Gtk::TreeModel::iterator treeModelIter = font_list_store->append(); + (*treeModelIter)[FontList.family] = familyName; + + // we don't set this now (too slow) but the style will be cached if the user + // ever decides to use this font + (*treeModelIter)[FontList.styles] = NULL; + // store the pango representation for generating the style + (*treeModelIter)[FontList.pango_family] = familyVector[i]; + (*treeModelIter)[FontList.onSystem] = true; } - current_family_row = 0; - current_family = "sans-serif"; - current_style = "Normal"; - current_fontspec = "sans-serif"; // Empty style -> Normal - current_fontspec_system = "Sans"; - - /* Create default styles for use when font-family is unknown on system. */ - default_styles = g_list_append( NULL, new StyleNames( "Normal" ) ); - default_styles = g_list_append( default_styles, new StyleNames( "Italic" ) ); - default_styles = g_list_append( default_styles, new StyleNames( "Bold" ) ); - default_styles = g_list_append( default_styles, new StyleNames( "Bold Italic" ) ); - - font_list_store->thaw_notify(); - - style_list_store = Gtk::ListStore::create (FontStyleList); - - // Initialize style store with defaults - style_list_store->freeze_notify(); - style_list_store->clear(); - for (GList *l=default_styles; l; l = l->next) { - Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; - (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; + } + + current_family_row = 0; + current_family = "sans-serif"; + current_style = "Normal"; + current_fontspec = "sans-serif"; // Empty style -> Normal + current_fontspec_system = "Sans"; + + font_list_store->thaw_notify(); + + style_list_store = Gtk::ListStore::create(FontStyleList); + + // Initialize style store with defaults + style_list_store->freeze_notify(); + style_list_store->clear(); + for (GList *l = default_styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)l->data)->DisplayName; + } + style_list_store->thaw_notify(); +} + +FontLister::~FontLister() +{ + // Delete default_styles + for (GList *l = default_styles; l; l = l->next) { + delete ((StyleNames *)l->data); + } + + // Delete other styles + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter; + GList *styles = row[FontList.styles]; + for (GList *l = styles; l; l = l->next) { + delete ((StyleNames *)l->data); } - style_list_store->thaw_notify(); + ++iter; } +} - FontLister::~FontLister() { +FontLister *FontLister::get_instance() +{ + static Inkscape::FontLister *instance = new Inkscape::FontLister(); + return instance; +} - // Delete default_styles - for (GList *l=default_styles; l; l = l->next) { - delete ((StyleNames*)l->data); +void FontLister::ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iterator) +{ + Gtk::TreeIter iter(model, iterator); + Gtk::TreeModel::Row row = *iter; + if (!row[FontList.styles]) { + if (row[FontList.pango_family]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); } + } +} - // Delete other styles - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter; - GList *styles = row[FontList.styles]; - for (GList *l=styles; l; l = l->next) { - delete ((StyleNames*)l->data); +// Example of how to use "foreach_iter" +// bool +// FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { +// Gtk::TreeModel::Row row = *iter; +// if( !row[FontList.onSystem] ) { +// std::cout << " Not on system: " << row[FontList.family] << std::endl; +// return false; +// } +// return true; +// } +// font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); + +/* Used to insert a font that was not in the document and not on the system into the font list. */ +void FontLister::insert_font_family(Glib::ustring new_family) +{ + GList *styles = default_styles; + + /* In case this is a fallback list, check if first font-family on system. */ + std::vector tokens = Glib::Regex::split_simple(",", new_family); + if (!tokens.empty() && !tokens[0].empty()) { + Gtk::TreeModel::iterator iter2 = font_list_store->get_iter("0"); + while (iter2 != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter2; + if (row[FontList.onSystem] && familyNamesAreEqual(tokens[0], row[FontList.family])) { + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } + styles = row[FontList.styles]; + break; } - ++iter; + ++iter2; } } - // Example of how to use "foreach_iter" - // bool - // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { - // Gtk::TreeModel::Row row = *iter; - // if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.family] << std::endl; - // return false; - // } - // return true; - // } - // font_list_store->foreach_iter( sigc::mem_fun(*this, &FontLister::print_document_font )); - - /* Used to insert a font that was not in the document and not on the system into the font list. */ - void - FontLister::insert_font_family( Glib::ustring new_family ) { - - GList *styles = default_styles; - - /* In case this is a fallback list, check if first font-family on system. */ - std::vector tokens = Glib::Regex::split_simple(",", new_family ); - if( !tokens.empty() && !tokens[0].empty() ) { - - Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); - while( iter2 != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { - styles = row[FontList.styles]; + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.family] = new_family; + (*treeModelIter)[FontList.styles] = styles; + (*treeModelIter)[FontList.onSystem] = false; +} + +void FontLister::update_font_list(SPDocument *document) +{ + SPObject *r = document->getRoot(); + if (!r) { + return; + } + + font_list_store->freeze_notify(); + + /* Find if current row is in document or system part of list */ + gboolean row_is_system = false; + if (current_family_row > -1) { + Gtk::TreePath path; + path.push_back(current_family_row); + Gtk::TreeModel::iterator iter = font_list_store->get_iter(path); + if (iter) { + row_is_system = (*iter)[FontList.onSystem]; + // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl; + } + } + + /* Clear all old document font-family entries */ + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter; + if (!row[FontList.onSystem]) { + // std::cout << " Not on system: " << row[FontList.family] << std::endl; + iter = font_list_store->erase(iter); + } else { + // std::cout << " First on system: " << row[FontList.family] << std::endl; break; - } - ++iter2; } - } + } + + /* Get "font-family"s used in document. */ + std::list fontfamilies; + update_font_list_recursive(r, &fontfamilies); + + fontfamilies.sort(); + fontfamilies.unique(); + fontfamilies.reverse(); + - Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup(new_family.c_str())); - (*treeModelIter)[FontList.styles] = styles; - (*treeModelIter)[FontList.onSystem] = false; + /* Insert separator */ + if (!fontfamilies.empty()) { + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.family] = "#"; + (*treeModelIter)[FontList.onSystem] = false; } - void - FontLister::update_font_list( SPDocument* document ) { - - SPObject *r = document->getRoot(); - if( !r ) { - return; - } - - font_list_store->freeze_notify(); - - /* Find if current row is in document or system part of list */ - gboolean row_is_system = false; - if( current_family_row > -1 ) { - Gtk::TreePath path; - path.push_back( current_family_row ); - Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); - if( iter ) { - row_is_system = (*iter)[FontList.onSystem]; - // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl; - } - } - - /* Clear all old document font-family entries */ - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter; - if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.family] << std::endl; - iter = font_list_store->erase( iter ); - } else { - // std::cout << " First on system: " << row[FontList.family] << std::endl; - break; - } - } - - /* Get "font-family"s used in document. */ - std::list fontfamilies; - update_font_list_recursive( r, &fontfamilies ); - - fontfamilies.sort(); - fontfamilies.unique(); - fontfamilies.reverse(); - - /* Insert separator */ - if( !fontfamilies.empty() ) { - Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.family] = "#"; - (*treeModelIter)[FontList.onSystem] = false; - } - - /* Insert font-family's in document. */ - std::list::iterator i; - for( i = fontfamilies.begin(); i != fontfamilies.end(); ++i) { - - GList *styles = default_styles; + /* Insert font-family's in document. */ + std::list::iterator i; + for (i = fontfamilies.begin(); i != fontfamilies.end(); ++i) { + + GList *styles = default_styles; /* See if font-family (or first in fallback list) is on system. If so, get styles. */ - std::vector tokens = Glib::Regex::split_simple(",", *i ); - if( !tokens.empty() && !tokens[0].empty() ) { - - Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); - while( iter2 != font_list_store->children().end() ) { - Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && familyNamesAreEqual( tokens[0], row[FontList.family] ) ) { - styles = row[FontList.styles]; - break; - } - ++iter2; - } - } - - Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup((*i).c_str())); - (*treeModelIter)[FontList.styles] = styles; - (*treeModelIter)[FontList.onSystem] = false; - } - - /* Now we do a song and dance to find the correct row as the row corresponding - * to the current_family may have changed. We can't simply search for the - * family name in the list since it can occur twice, once in the document - * font family part and once in the system font family part. Above we determined - * which part it is in. - */ - if( current_family_row > -1 ) { - int start = 0; - if( row_is_system ) start = fontfamilies.size(); - int length = font_list_store->children().size(); - for( int i = 0; i < length; ++i ) { - int row = i + start; - if( row >= length ) row -= length; - Gtk::TreePath path; - path.push_back( row ); - Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); - if( iter ) { - if( familyNamesAreEqual( current_family, (*iter)[FontList.family] ) ) { - current_family_row = row; - break; - } - } - } - } - // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl; - - font_list_store->thaw_notify(); + std::vector tokens = Glib::Regex::split_simple(",", *i); + if (!tokens.empty() && !tokens[0].empty()) { + + Gtk::TreeModel::iterator iter2 = font_list_store->get_iter("0"); + while (iter2 != font_list_store->children().end()) { + Gtk::TreeModel::Row row = *iter2; + if (row[FontList.onSystem] && familyNamesAreEqual(tokens[0], row[FontList.family])) { + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } + styles = row[FontList.styles]; + break; + } + ++iter2; + } + } + + Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); + (*treeModelIter)[FontList.family] = reinterpret_cast(g_strdup((*i).c_str())); + (*treeModelIter)[FontList.styles] = styles; + (*treeModelIter)[FontList.onSystem] = false; + } - void - FontLister::update_font_list_recursive( SPObject *r, std::list *l ) { + /* Now we do a song and dance to find the correct row as the row corresponding + * to the current_family may have changed. We can't simply search for the + * family name in the list since it can occur twice, once in the document + * font family part and once in the system font family part. Above we determined + * which part it is in. + */ + if (current_family_row > -1) { + int start = 0; + if (row_is_system) + start = fontfamilies.size(); + int length = font_list_store->children().size(); + for (int i = 0; i < length; ++i) { + int row = i + start; + if (row >= length) + row -= length; + Gtk::TreePath path; + path.push_back(row); + Gtk::TreeModel::iterator iter = font_list_store->get_iter(path); + if (iter) { + if (familyNamesAreEqual(current_family, (*iter)[FontList.family])) { + current_family_row = row; + break; + } + } + } + } + // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl; - const gchar *font_family = r->style->font_family.value; - if( font_family ) { - l->push_back( Glib::ustring( font_family ) ); - } + font_list_store->thaw_notify(); +} - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - update_font_list_recursive( child, l ); - } +void FontLister::update_font_list_recursive(SPObject *r, std::list *l) +{ + const gchar *font_family = r->style->font_family.value; + if (font_family) { + l->push_back(Glib::ustring(font_family)); } - Glib::ustring - FontLister::canonize_fontspec( Glib::ustring fontspec ) { - - // Pass fontspec to and back from Pango to get a the fontspec in - // canonical form. -inkscape-font-specification relies on the - // Pango constructed fontspec not changing form. If it does, - // this is the place to fix it. - PangoFontDescription *descr = pango_font_description_from_string( fontspec.c_str() ); - gchar* canonized = pango_font_description_to_string ( descr ); - Glib::ustring Canonized = canonized; - g_free( canonized ); - pango_font_description_free( descr ); - - // Pango canonized strings remove space after comma between family names. Put it back. - size_t i = 0; - while( (i = Canonized.find(",", i)) != std::string::npos) { - Canonized.replace(i, 1, ", "); - i += 2; - } - - return Canonized; + for (SPObject *child = r->firstChild(); child; child = child->getNext()) { + update_font_list_recursive(child, l); } +} + +Glib::ustring FontLister::canonize_fontspec(Glib::ustring fontspec) +{ - Glib::ustring - FontLister::system_fontspec( Glib::ustring fontspec ) { + // Pass fontspec to and back from Pango to get a the fontspec in + // canonical form. -inkscape-font-specification relies on the + // Pango constructed fontspec not changing form. If it does, + // this is the place to fix it. + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + gchar *canonized = pango_font_description_to_string(descr); + Glib::ustring Canonized = canonized; + g_free(canonized); + pango_font_description_free(descr); + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while ((i = Canonized.find(",", i)) != std::string::npos) { + Canonized.replace(i, 1, ", "); + i += 2; + } - // Find what Pango thinks is the closest match. - Glib::ustring out = fontspec; + return Canonized; +} - PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); - font_instance *res = (font_factory::Default())->Face(descr); - if (res->pFont) { +Glib::ustring FontLister::system_fontspec(Glib::ustring fontspec) +{ + + // Find what Pango thinks is the closest match. + Glib::ustring out = fontspec; + + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + font_instance *res = (font_factory::Default())->Face(descr); + if (res->pFont) { PangoFontDescription *nFaceDesc = pango_font_describe(res->pFont); out = sp_font_description_get_family(nFaceDesc); - } - pango_font_description_free(descr); - - return out; } + pango_font_description_free(descr); + + return out; +} - std::pair - FontLister::ui_from_fontspec( Glib::ustring fontspec ) { - - PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); - const gchar* family = pango_font_description_get_family(descr); - if(!family) - family = "sans-serif"; - Glib::ustring Family = family; - - // PANGO BUG... - // A font spec of Delicious, 500 Italic should result in a family of 'Delicious' - // and a style of 'Medium Italic'. It results instead with: a family of - // 'Delicious, 500' with a style of 'Medium Italic'. We chop of any weight numbers - // at the end of the family: match ",[1-9]00^". - Glib::RefPtr weight = Glib::Regex::create(",[1-9]00$"); - Family = weight->replace( Family, 0, "", Glib::REGEX_MATCH_PARTIAL ); - - // Pango canonized strings remove space after comma between family names. Put it back. - size_t i = 0; - while( (i = Family.find(",", i)) != std::string::npos) { - Family.replace(i, 1, ", "); - i += 2; - } - - pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY); - gchar* style = pango_font_description_to_string( descr ); - Glib::ustring Style = style; - pango_font_description_free(descr); - g_free( style ); - - return std::make_pair( Family, Style ); +std::pair FontLister::ui_from_fontspec(Glib::ustring fontspec) +{ + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + const gchar *family = pango_font_description_get_family(descr); + if (!family) + family = "sans-serif"; + Glib::ustring Family = family; + + // PANGO BUG... + // A font spec of Delicious, 500 Italic should result in a family of 'Delicious' + // and a style of 'Medium Italic'. It results instead with: a family of + // 'Delicious, 500' with a style of 'Medium Italic'. We chop of any weight numbers + // at the end of the family: match ",[1-9]00^". + Glib::RefPtr weight = Glib::Regex::create(",[1-9]00$"); + Family = weight->replace(Family, 0, "", Glib::REGEX_MATCH_PARTIAL); + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while ((i = Family.find(",", i)) != std::string::npos) { + Family.replace(i, 1, ", "); + i += 2; } - std::pair - FontLister::selection_update () { + pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY); + gchar *style = pango_font_description_to_string(descr); + Glib::ustring Style = style; + pango_font_description_free(descr); + g_free(style); + + return std::make_pair(Family, Style); +} + +std::pair FontLister::selection_update() +{ #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::selection_update: entrance" << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::selection_update: entrance" << std::endl; #endif - // Get fontspec from a selection, preferences, or thin air. - Glib::ustring fontspec; - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - - // Directly from stored font specification. - int result = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - //std::cout << " Attempting selected style" << std::endl; - if( result != QUERY_STYLE_NOTHING && query->font_specification.set ) { - fontspec = query->font_specification.value; - //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; - } - - // From style - if( fontspec.empty() ) { + // Get fontspec from a selection, preferences, or thin air. + Glib::ustring fontspec; + SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + + // Directly from stored font specification. + int result = + sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + + //std::cout << " Attempting selected style" << std::endl; + if (result != QUERY_STYLE_NOTHING && query->font_specification.set) { + fontspec = query->font_specification.value; + //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; + } + + // From style + if (fontspec.empty()) { //std::cout << " Attempting desktop style" << std::endl; - int rfamily = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int rstyle = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - - // Must have text in selection - if( rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING ) { - fontspec = fontspec_from_style( query ); - } - //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; - } - - // From preferences - if( fontspec.empty() ) { + int rfamily = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int rstyle = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + + // Must have text in selection + if (rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING) { + fontspec = fontspec_from_style(query); + } + //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; + } + + // From preferences + if (fontspec.empty()) { //std::cout << " Attempting preferences" << std::endl; sp_style_read_from_prefs(query, "/tools/text"); - fontspec = fontspec_from_style( query ); - //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; - } - sp_style_unref(query); + fontspec = fontspec_from_style(query); + //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; + } + sp_style_unref(query); - // From thin air - if( fontspec.empty() ) { + // From thin air + if (fontspec.empty()) { //std::cout << " Attempting thin air" << std::endl; - fontspec = current_family + ", " + current_style; - //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl; - } - - // Do we really need? Removes spaces between font-families. - //current_fontspec = canonize_fontspec( fontspec ); - current_fontspec = fontspec; // Ignore for now + fontspec = current_family + ", " + current_style; + //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl; + } + + // Do we really need? Removes spaces between font-families. + //current_fontspec = canonize_fontspec( fontspec ); + current_fontspec = fontspec; // Ignore for now - current_fontspec_system = system_fontspec( current_fontspec ); + current_fontspec_system = system_fontspec(current_fontspec); - std::pair ui = ui_from_fontspec( current_fontspec ); - set_font_family( ui.first ); - set_font_style( ui.second ); + std::pair ui = ui_from_fontspec(current_fontspec); + set_font_family(ui.first); + set_font_style(ui.second); #ifdef DEBUG_FONT - std::cout << " family_row: :" << current_family_row << ":" << std::endl; - std::cout << " canonized: :" << current_fontspec << ":" << std::endl; - std::cout << " system: :" << current_fontspec_system << ":" << std::endl; - std::cout << " family: :" << current_family << ":" << std::endl; - std::cout << " style: :" << current_style << ":" << std::endl; - std::cout << "FontLister::selection_update: exit" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << " family_row: :" << current_family_row << ":" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::selection_update: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return std::make_pair( current_family, current_style ); - } - + return std::make_pair(current_family, current_style); +} + // Set fontspec. If check is false, best style match will not be done. -void FontLister::set_fontspec(Glib::ustring new_fontspec, gboolean /*check*/) +void FontLister::set_fontspec(Glib::ustring new_fontspec, bool /*check*/) { - std::pair ui = ui_from_fontspec( new_fontspec ); + std::pair ui = ui_from_fontspec(new_fontspec); Glib::ustring new_family = ui.first; Glib::ustring new_style = ui.second; @@ -439,13 +461,13 @@ void FontLister::set_fontspec(Glib::ustring new_fontspec, gboolean /*check*/) << " style:" << new_style << std::endl; #endif - set_font_family( new_family, false ); - set_font_style( new_style ); + set_font_family(new_family, false); + set_font_style(new_style); } // TODO: use to determine font-selector best style -std::pair FontLister::new_font_family (Glib::ustring new_family, gboolean /*check_style*/ ) +std::pair FontLister::new_font_family(Glib::ustring new_family, bool /*check_style*/) { #ifdef DEBUG_FONT std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; @@ -453,12 +475,12 @@ std::pair FontLister::new_font_family (Glib::ustri #endif // No need to do anything if new family is same as old family. - if ( familyNamesAreEqual( new_family, current_family ) ) { + if (familyNamesAreEqual(new_family, current_family)) { #ifdef DEBUG_FONT - std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return std::make_pair( current_family, current_style ); + return std::make_pair(current_family, current_style); } // We need to do two things: @@ -466,596 +488,597 @@ std::pair FontLister::new_font_family (Glib::ustri // 2. Select best valid style match to old style. // For finding style list, use list of first family in font-family list. - GList* styles = NULL; - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { + GList *styles = NULL; + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { - Gtk::TreeModel::Row row = *iter; + Gtk::TreeModel::Row row = *iter; - if( familyNamesAreEqual( new_family, row[FontList.family] ) ) { + if (familyNamesAreEqual(new_family, row[FontList.family])) { + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } styles = row[FontList.styles]; break; - } - ++iter; + } + ++iter; } // Newly typed in font-family may not yet be in list... use default list. // TODO: if font-family is list, check if first family in list is on system // and set style accordingly. - if( styles == NULL ) { - styles = default_styles; + if (styles == NULL) { + styles = default_styles; } - + // Update style list. style_list_store->freeze_notify(); style_list_store->clear(); - for (GList *l=styles; l; l = l->next) { - Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); - (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames*)l->data)->CssName; - (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames*)l->data)->DisplayName; + for (GList *l = styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.cssStyle] = ((StyleNames *)l->data)->CssName; + (*treeModelIter)[FontStyleList.displayStyle] = ((StyleNames *)l->data)->DisplayName; } style_list_store->thaw_notify(); - + // Find best match to the style from the old font-family to the // styles available with the new font. // TODO: Maybe check if an exact match exists before using Pango. - Glib::ustring best_style = get_best_style_match( new_family, current_style ); + Glib::ustring best_style = get_best_style_match(new_family, current_style); #ifdef DEBUG_FONT std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl; std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return std::make_pair( new_family, best_style ); + return std::make_pair(new_family, best_style); } - - std::pair - FontLister::set_font_family (Glib::ustring new_family, gboolean check_style) { + +std::pair FontLister::set_font_family(Glib::ustring new_family, bool check_style) +{ #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::set_font_family: " << new_family << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family: " << new_family << std::endl; #endif - std::pair ui = new_font_family( new_family, check_style ); - current_family = ui.first; - current_style = ui.second; - current_fontspec = canonize_fontspec( current_family + ", " + current_style ); - current_fontspec_system = system_fontspec( current_fontspec ); + std::pair ui = new_font_family(new_family, check_style); + current_family = ui.first; + current_style = ui.second; + current_fontspec = canonize_fontspec(current_family + ", " + current_style); + current_fontspec_system = system_fontspec(current_fontspec); #ifdef DEBUG_FONT - std::cout << " family_row: :" << current_family_row << ":" << std::endl; - std::cout << " canonized: :" << current_fontspec << ":" << std::endl; - std::cout << " system: :" << current_fontspec_system << ":" << std::endl; - std::cout << " family: :" << current_family << ":" << std::endl; - std::cout << " style: :" << current_style << ":" << std::endl; - std::cout << "FontLister::set_font_family: end" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << " family_row: :" << current_family_row << ":" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::set_font_family: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return ui; - } - + return ui; +} - std::pair - FontLister::set_font_family (int row, gboolean check_style) { + +std::pair FontLister::set_font_family(int row, bool check_style) +{ #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::set_font_family( row ): " << row << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family( row ): " << row << std::endl; #endif - current_family_row = row; - Gtk::TreePath path; - path.push_back( row ); - Glib::ustring new_family = current_family; - Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); - if( iter ) { - new_family = (*iter)[FontList.family]; - } + current_family_row = row; + Gtk::TreePath path; + path.push_back(row); + Glib::ustring new_family = current_family; + Gtk::TreeModel::iterator iter = font_list_store->get_iter(path); + if (iter) { + new_family = (*iter)[FontList.family]; + } - std::pair ui = set_font_family( new_family, check_style ); + std::pair ui = set_font_family(new_family, check_style); #ifdef DEBUG_FONT - std::cout << "FontLister::set_font_family( row ): end" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << "FontLister::set_font_family( row ): end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif - return ui; - } + return ui; +} - void - FontLister::set_font_style (Glib::ustring new_style) { +void FontLister::set_font_style(Glib::ustring new_style) +{ - // TODO: Validate input using Pango. If Pango doesn't recognize a style it will - // attach the "invalid" style to the font-family. +// TODO: Validate input using Pango. If Pango doesn't recognize a style it will +// attach the "invalid" style to the font-family. #ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister:set_font_style: " << new_style << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister:set_font_style: " << new_style << std::endl; #endif - current_style = new_style; - current_fontspec = canonize_fontspec( current_family + ", " + current_style ); - current_fontspec_system = system_fontspec( current_fontspec ); + current_style = new_style; + current_fontspec = canonize_fontspec(current_family + ", " + current_style); + current_fontspec_system = system_fontspec(current_fontspec); #ifdef DEBUG_FONT - std::cout << " canonized: :" << current_fontspec << ":" << std::endl; - std::cout << " system: :" << current_fontspec_system << ":" << std::endl; - std::cout << " family: " << current_family << std::endl; - std::cout << " style: " << current_style << std::endl; - std::cout << "FontLister::set_font_style: end" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: " << current_family << std::endl; + std::cout << " style: " << current_style << std::endl; + std::cout << "FontLister::set_font_style: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; #endif +} + + +// We do this ourselves as we can't rely on FontFactory. +void FontLister::fill_css(SPCSSAttr *css, Glib::ustring fontspec) +{ + + if (fontspec.empty()) { + fontspec = current_fontspec; + } + std::pair ui = ui_from_fontspec(fontspec); + + Glib::ustring family = ui.first; + + + // Font spec is single quoted... for the moment + Glib::ustring fontspec_quoted(fontspec); + css_quote(fontspec_quoted); + sp_repr_css_set_property(css, "-inkscape-font-specification", fontspec_quoted.c_str()); + + // Font families needs to be properly quoted in CSS (used unquoted in font-lister) + css_font_family_quote(family); + sp_repr_css_set_property(css, "font-family", family.c_str()); + + PangoFontDescription *desc = pango_font_description_from_string(fontspec.c_str()); + PangoWeight weight = pango_font_description_get_weight(desc); + switch (weight) { + case PANGO_WEIGHT_THIN: + sp_repr_css_set_property(css, "font-weight", "100"); + break; + case PANGO_WEIGHT_ULTRALIGHT: + sp_repr_css_set_property(css, "font-weight", "200"); + break; + case PANGO_WEIGHT_LIGHT: + sp_repr_css_set_property(css, "font-weight", "300"); + break; + case PANGO_WEIGHT_BOOK: + sp_repr_css_set_property(css, "font-weight", "380"); + break; + case PANGO_WEIGHT_NORMAL: + sp_repr_css_set_property(css, "font-weight", "normal"); + break; + case PANGO_WEIGHT_MEDIUM: + sp_repr_css_set_property(css, "font-weight", "500"); + break; + case PANGO_WEIGHT_SEMIBOLD: + sp_repr_css_set_property(css, "font-weight", "600"); + break; + case PANGO_WEIGHT_BOLD: + sp_repr_css_set_property(css, "font-weight", "bold"); + break; + case PANGO_WEIGHT_ULTRABOLD: + sp_repr_css_set_property(css, "font-weight", "800"); + break; + case PANGO_WEIGHT_HEAVY: + sp_repr_css_set_property(css, "font-weight", "900"); + break; + case PANGO_WEIGHT_ULTRAHEAVY: + sp_repr_css_set_property(css, "font-weight", "1000"); + break; + } + + PangoStyle style = pango_font_description_get_style(desc); + switch (style) { + case PANGO_STYLE_NORMAL: + sp_repr_css_set_property(css, "font-style", "normal"); + break; + case PANGO_STYLE_OBLIQUE: + sp_repr_css_set_property(css, "font-style", "oblique"); + break; + case PANGO_STYLE_ITALIC: + sp_repr_css_set_property(css, "font-style", "italic"); + break; } + PangoStretch stretch = pango_font_description_get_stretch(desc); + switch (stretch) { + case PANGO_STRETCH_ULTRA_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "ultra-condensed"); + break; + case PANGO_STRETCH_EXTRA_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "extra-condensed"); + break; + case PANGO_STRETCH_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "condensed"); + break; + case PANGO_STRETCH_SEMI_CONDENSED: + sp_repr_css_set_property(css, "font-stretch", "semi-condensed"); + break; + case PANGO_STRETCH_NORMAL: + sp_repr_css_set_property(css, "font-stretch", "normal"); + break; + case PANGO_STRETCH_SEMI_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "semi-expanded"); + break; + case PANGO_STRETCH_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "expanded"); + break; + case PANGO_STRETCH_EXTRA_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "extra-expanded"); + break; + case PANGO_STRETCH_ULTRA_EXPANDED: + sp_repr_css_set_property(css, "font-stretch", "ultra-expanded"); + break; + } - // We do this ourselves as we can't rely on FontFactory. - void - FontLister::fill_css( SPCSSAttr *css, Glib::ustring fontspec ) { - - if( fontspec.empty() ) { - fontspec = current_fontspec; - } - std::pair ui = ui_from_fontspec( fontspec ); - - Glib::ustring family = ui.first; - - - // Font spec is single quoted... for the moment - Glib::ustring fontspec_quoted( fontspec ); - css_quote( fontspec_quoted ); - sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec_quoted.c_str() ); - - // Font families needs to be properly quoted in CSS (used unquoted in font-lister) - css_font_family_quote( family ); - sp_repr_css_set_property (css, "font-family", family.c_str() ); - - PangoFontDescription *desc = pango_font_description_from_string( fontspec.c_str() ); - PangoWeight weight = pango_font_description_get_weight( desc ); - switch ( weight ) { - case PANGO_WEIGHT_THIN: - sp_repr_css_set_property (css, "font-weight", "100" ); - break; - case PANGO_WEIGHT_ULTRALIGHT: - sp_repr_css_set_property (css, "font-weight", "200" ); - break; - case PANGO_WEIGHT_LIGHT: - sp_repr_css_set_property (css, "font-weight", "300" ); - break; - case PANGO_WEIGHT_BOOK: - sp_repr_css_set_property (css, "font-weight", "380" ); - break; - case PANGO_WEIGHT_NORMAL: - sp_repr_css_set_property (css, "font-weight", "normal" ); - break; - case PANGO_WEIGHT_MEDIUM: - sp_repr_css_set_property (css, "font-weight", "500" ); - break; - case PANGO_WEIGHT_SEMIBOLD: - sp_repr_css_set_property (css, "font-weight", "600" ); - break; - case PANGO_WEIGHT_BOLD: - sp_repr_css_set_property (css, "font-weight", "bold" ); - break; - case PANGO_WEIGHT_ULTRABOLD: - sp_repr_css_set_property (css, "font-weight", "800" ); - break; - case PANGO_WEIGHT_HEAVY: - sp_repr_css_set_property (css, "font-weight", "900" ); - break; - case PANGO_WEIGHT_ULTRAHEAVY: - sp_repr_css_set_property (css, "font-weight", "1000" ); - break; - } - - PangoStyle style = pango_font_description_get_style( desc ); - switch ( style ) { - case PANGO_STYLE_NORMAL: - sp_repr_css_set_property (css, "font-style", "normal" ); - break; - case PANGO_STYLE_OBLIQUE: - sp_repr_css_set_property (css, "font-style", "oblique" ); - break; - case PANGO_STYLE_ITALIC: - sp_repr_css_set_property (css, "font-style", "italic" ); - break; - } - - PangoStretch stretch = pango_font_description_get_stretch( desc ); - switch ( stretch ) { - case PANGO_STRETCH_ULTRA_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "ultra-condensed" ); - break; - case PANGO_STRETCH_EXTRA_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "extra-condensed" ); - break; - case PANGO_STRETCH_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "condensed" ); - break; - case PANGO_STRETCH_SEMI_CONDENSED: - sp_repr_css_set_property (css, "font-stretch", "semi-condensed" ); - break; - case PANGO_STRETCH_NORMAL: - sp_repr_css_set_property (css, "font-stretch", "normal" ); - break; - case PANGO_STRETCH_SEMI_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "semi-expanded" ); - break; - case PANGO_STRETCH_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "expanded" ); - break; - case PANGO_STRETCH_EXTRA_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "extra-expanded" ); - break; - case PANGO_STRETCH_ULTRA_EXPANDED: - sp_repr_css_set_property (css, "font-stretch", "ultra-expanded" ); - break; - } - - PangoVariant variant = pango_font_description_get_variant( desc ); - switch ( variant ) { - case PANGO_VARIANT_NORMAL: - sp_repr_css_set_property (css, "font-variant", "normal" ); - break; - case PANGO_VARIANT_SMALL_CAPS: - sp_repr_css_set_property (css, "font-variant", "small-caps" ); - break; - } + PangoVariant variant = pango_font_description_get_variant(desc); + switch (variant) { + case PANGO_VARIANT_NORMAL: + sp_repr_css_set_property(css, "font-variant", "normal"); + break; + case PANGO_VARIANT_SMALL_CAPS: + sp_repr_css_set_property(css, "font-variant", "small-caps"); + break; } +} - // We do this ourselves as we can't rely on FontFactory. - Glib::ustring - FontLister::fontspec_from_style (SPStyle* style) { +// We do this ourselves as we can't rely on FontFactory. +Glib::ustring FontLister::fontspec_from_style(SPStyle *style) +{ - //std::cout << "FontLister:fontspec_from_style: " << std::endl; + //std::cout << "FontLister:fontspec_from_style: " << std::endl; - Glib::ustring fontspec; - if (style) { + Glib::ustring fontspec; + if (style) { - // First try to use the font specification if it is set - if (style->font_specification.set - && style->font_specification.value - && *style->font_specification.value) { + // First try to use the font specification if it is set + if (style->font_specification.set && style->font_specification.value && *style->font_specification.value) { - fontspec = style->font_specification.value; + fontspec = style->font_specification.value; } else { - fontspec = style->font_family.value; - fontspec += ","; - - // Use weight names as defined by Pango - switch (style->font_weight.computed) { + fontspec = style->font_family.value; + fontspec += ","; - case SP_CSS_FONT_WEIGHT_100: - fontspec += " Thin"; - break; - - case SP_CSS_FONT_WEIGHT_200: - fontspec += " Ultra-Light"; - break; + // Use weight names as defined by Pango + switch (style->font_weight.computed) { - case SP_CSS_FONT_WEIGHT_300: - fontspec += " Light"; - break; + case SP_CSS_FONT_WEIGHT_100: + fontspec += " Thin"; + break; - case SP_CSS_FONT_WEIGHT_400: - case SP_CSS_FONT_WEIGHT_NORMAL: - //fontspec += " normal"; - break; - - case SP_CSS_FONT_WEIGHT_500: - fontspec += " Medium"; - break; - - case SP_CSS_FONT_WEIGHT_600: - fontspec += " Semi-Bold"; - break; - - case SP_CSS_FONT_WEIGHT_700: - case SP_CSS_FONT_WEIGHT_BOLD: - fontspec += " Bold"; - break; - - case SP_CSS_FONT_WEIGHT_800: - fontspec += " Ultra-Bold"; - break; - - case SP_CSS_FONT_WEIGHT_900: - fontspec += " Heavy"; - break; - - case SP_CSS_FONT_WEIGHT_LIGHTER: - case SP_CSS_FONT_WEIGHT_BOLDER: - default: - g_warning("Unrecognized font_weight.computed value"); - break; - } - - switch (style->font_style.computed) { - case SP_CSS_FONT_STYLE_ITALIC: - fontspec += " italic"; - break; - - case SP_CSS_FONT_STYLE_OBLIQUE: - fontspec += " oblique"; - break; - - case SP_CSS_FONT_STYLE_NORMAL: - default: - //fontspec += " normal"; - break; - } - - switch (style->font_stretch.computed) { - - case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: - fontspec += " extra-condensed"; - break; - - case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: - fontspec += " extra-condensed"; - break; - - case SP_CSS_FONT_STRETCH_CONDENSED: - case SP_CSS_FONT_STRETCH_NARROWER: - fontspec += " condensed"; - break; - - case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: - fontspec += " semi-condensed"; - break; - - case SP_CSS_FONT_STRETCH_NORMAL: - //fontspec += " normal"; - break; - - case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: - fontspec += " semi-expanded"; - break; - - case SP_CSS_FONT_STRETCH_EXPANDED: - case SP_CSS_FONT_STRETCH_WIDER: - fontspec += " expanded"; - break; - - case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: - fontspec += " extra-expanded"; - break; - - case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: - fontspec += " ultra-expanded"; - break; - - default: - //fontspec += " normal"; - break; - } - - switch (style->font_variant.computed) { - - case SP_CSS_FONT_VARIANT_SMALL_CAPS: - fontspec += "small-caps"; - break; - - default: - //fontspec += "normal"; - break; - } - } - } - return canonize_fontspec( fontspec ); - } + case SP_CSS_FONT_WEIGHT_200: + fontspec += " Ultra-Light"; + break; + case SP_CSS_FONT_WEIGHT_300: + fontspec += " Light"; + break; - Gtk::TreeModel::Row - FontLister::get_row_for_font (Glib::ustring family) - { - Gtk::TreePath path; + case SP_CSS_FONT_WEIGHT_400: + case SP_CSS_FONT_WEIGHT_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_WEIGHT_500: + fontspec += " Medium"; + break; + + case SP_CSS_FONT_WEIGHT_600: + fontspec += " Semi-Bold"; + break; - Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); - while( iter != font_list_store->children().end() ) { + case SP_CSS_FONT_WEIGHT_700: + case SP_CSS_FONT_WEIGHT_BOLD: + fontspec += " Bold"; + break; - Gtk::TreeModel::Row row = *iter; + case SP_CSS_FONT_WEIGHT_800: + fontspec += " Ultra-Bold"; + break; - if( familyNamesAreEqual( family, row[FontList.family] ) ) { - return row; - } + case SP_CSS_FONT_WEIGHT_900: + fontspec += " Heavy"; + break; - ++iter; - } + case SP_CSS_FONT_WEIGHT_LIGHTER: + case SP_CSS_FONT_WEIGHT_BOLDER: + default: + g_warning("Unrecognized font_weight.computed value"); + break; + } - throw FAMILY_NOT_FOUND; - } + switch (style->font_style.computed) { + case SP_CSS_FONT_STYLE_ITALIC: + fontspec += " italic"; + break; - Gtk::TreePath - FontLister::get_path_for_font (Glib::ustring family) - { - return font_list_store->get_path( get_row_for_font ( family ) ); + case SP_CSS_FONT_STYLE_OBLIQUE: + fontspec += " oblique"; + break; + + case SP_CSS_FONT_STYLE_NORMAL: + default: + //fontspec += " normal"; + break; + } + + switch (style->font_stretch.computed) { + + case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: + fontspec += " extra-condensed"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: + fontspec += " extra-condensed"; + break; + + case SP_CSS_FONT_STRETCH_CONDENSED: + case SP_CSS_FONT_STRETCH_NARROWER: + fontspec += " condensed"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: + fontspec += " semi-condensed"; + break; + + case SP_CSS_FONT_STRETCH_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: + fontspec += " semi-expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXPANDED: + case SP_CSS_FONT_STRETCH_WIDER: + fontspec += " expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: + fontspec += " extra-expanded"; + break; + + case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: + fontspec += " ultra-expanded"; + break; + + default: + //fontspec += " normal"; + break; + } + + switch (style->font_variant.computed) { + + case SP_CSS_FONT_VARIANT_SMALL_CAPS: + fontspec += "small-caps"; + break; + + default: + //fontspec += "normal"; + break; + } + } } + return canonize_fontspec(fontspec); +} - Gtk::TreeModel::Row - FontLister::get_row_for_style (Glib::ustring style) - { - Gtk::TreePath path; - Gtk::TreeModel::iterator iter = style_list_store->get_iter( "0" ); - while( iter != style_list_store->children().end() ) { +Gtk::TreeModel::Row FontLister::get_row_for_font(Glib::ustring family) +{ + Gtk::TreePath path; - Gtk::TreeModel::Row row = *iter; + Gtk::TreeModel::iterator iter = font_list_store->get_iter("0"); + while (iter != font_list_store->children().end()) { - if( familyNamesAreEqual( style, row[FontStyleList.cssStyle] ) ) { - return row; - } + Gtk::TreeModel::Row row = *iter; - ++iter; - } + if (familyNamesAreEqual(family, row[FontList.family])) { + return row; + } - throw STYLE_NOT_FOUND; + ++iter; } - static gint - compute_distance (const PangoFontDescription *a, - const PangoFontDescription *b ) { - - // Weight: multiples of 100 - gint distance = abs( pango_font_description_get_weight( a ) - - pango_font_description_get_weight( b ) ); - - distance += 10000 * abs( pango_font_description_get_stretch( a ) - - pango_font_description_get_stretch( b ) ); - - PangoStyle style_a = pango_font_description_get_style( a ); - PangoStyle style_b = pango_font_description_get_style( b ); - if( style_a != style_b ) { - if( (style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) || - (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC) ) { - distance += 1000; // Oblique and italic are almost the same - } else { - distance += 100000; // Normal vs oblique/italic, not so similar - } - } - - // Normal vs small-caps - distance += 1000000 * abs( pango_font_description_get_variant( a ) - - pango_font_description_get_variant( b ) ); - return distance; + throw FAMILY_NOT_FOUND; +} + +Gtk::TreePath FontLister::get_path_for_font(Glib::ustring family) +{ + return font_list_store->get_path(get_row_for_font(family)); +} + +Gtk::TreeModel::Row FontLister::get_row_for_style(Glib::ustring style) +{ + Gtk::TreePath path; + + Gtk::TreeModel::iterator iter = style_list_store->get_iter("0"); + while (iter != style_list_store->children().end()) { + + Gtk::TreeModel::Row row = *iter; + + if (familyNamesAreEqual(style, row[FontStyleList.cssStyle])) { + return row; + } + + ++iter; } - // This is inspired by pango_font_description_better_match, but that routine - // always returns false if variant or stretch are different. This means, for - // example, that PT Sans Narrow with style Bold Condensed is never matched - // to another font-family with Bold style. - gboolean - font_description_better_match( PangoFontDescription* target, - PangoFontDescription* old_desc, - PangoFontDescription* new_desc ) { + throw STYLE_NOT_FOUND; +} + +static gint compute_distance(const PangoFontDescription *a, const PangoFontDescription *b) +{ - if( old_desc == NULL ) return true; - if( new_desc == NULL ) return false; + // Weight: multiples of 100 + gint distance = abs(pango_font_description_get_weight(a) - + pango_font_description_get_weight(b)); - int old_distance = compute_distance( target, old_desc ); - int new_distance = compute_distance( target, new_desc ); - //std::cout << "font_description_better_match: old: " << old_distance << std::endl; - //std::cout << " new: " << new_distance << std::endl; + distance += 10000 * abs(pango_font_description_get_stretch(a) - + pango_font_description_get_stretch(b)); - return (new_distance < old_distance ); + PangoStyle style_a = pango_font_description_get_style(a); + PangoStyle style_b = pango_font_description_get_style(b); + if (style_a != style_b) { + if ((style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) || + (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC)) { + distance += 1000; // Oblique and italic are almost the same + } else { + distance += 100000; // Normal vs oblique/italic, not so similar + } } - // void - // font_description_dump( PangoFontDescription* target ) { - // std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl; - // std::cout << " style: " << pango_font_description_get_style( target ) << std::endl; - // std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl; - // std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl; - // std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl; - // std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl; - // } - - /* Returns style string */ - // TODO: Remove or turn into function to be used by new_font_family. - Glib::ustring - FontLister::get_best_style_match (Glib::ustring family, Glib::ustring target_style) { + // Normal vs small-caps + distance += 1000000 * abs(pango_font_description_get_variant(a) - + pango_font_description_get_variant(b)); + return distance; +} -#ifdef DEBUG_FONT - std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; - std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl; -#endif +// This is inspired by pango_font_description_better_match, but that routine +// always returns false if variant or stretch are different. This means, for +// example, that PT Sans Narrow with style Bold Condensed is never matched +// to another font-family with Bold style. +gboolean font_description_better_match(PangoFontDescription *target, PangoFontDescription *old_desc, PangoFontDescription *new_desc) +{ + if (old_desc == NULL) + return true; + if (new_desc == NULL) + return false; + + int old_distance = compute_distance(target, old_desc); + int new_distance = compute_distance(target, new_desc); + //std::cout << "font_description_better_match: old: " << old_distance << std::endl; + //std::cout << " new: " << new_distance << std::endl; - Glib::ustring fontspec = family + ", " + target_style; - - Gtk::TreeModel::Row row; - try { - row = get_row_for_font( family ); - } catch (...) { - //std::cout << " ERROR: can't find family: " << family << std::endl; - return (target_style); - } - - PangoFontDescription* target = pango_font_description_from_string( fontspec.c_str() ); - PangoFontDescription* best = NULL; - - //font_description_dump( target ); - - GList* styles = row[FontList.styles]; - for (GList *l=styles; l; l = l->next) { - Glib::ustring fontspec = family + ", " + (char*)l->data; - PangoFontDescription* candidate = pango_font_description_from_string( fontspec.c_str() ); - //font_description_dump( candidate ); - //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl; - if( font_description_better_match( target, best, candidate ) ) { - pango_font_description_free( best ); - best = candidate; - //std::cout << " ... better: " << std::endl; - } else { - pango_font_description_free( candidate ); - //std::cout << " ... not better: " << std::endl; - } - } - - Glib::ustring best_style = target_style; - if( best ) { - pango_font_description_unset_fields( best, PANGO_FONT_MASK_FAMILY ); - best_style = pango_font_description_to_string( best ); - } - - if( target ) pango_font_description_free( target ); - if( best ) pango_font_description_free( best ); + return (new_distance < old_distance); +} +// void +// font_description_dump( PangoFontDescription* target ) { +// std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl; +// std::cout << " style: " << pango_font_description_get_style( target ) << std::endl; +// std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl; +// std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl; +// std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl; +// std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl; +// } + +/* Returns style string */ +// TODO: Remove or turn into function to be used by new_font_family. +Glib::ustring FontLister::get_best_style_match(Glib::ustring family, Glib::ustring target_style) +{ #ifdef DEBUG_FONT - std::cout << " Returning: " << best_style << std::endl; - std::cout << "FontLister::get_best_style_match: exit" << std::endl; - std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl; #endif - return best_style; - } - const Glib::RefPtr - FontLister::get_font_list () const + Glib::ustring fontspec = family + ", " + target_style; + + Gtk::TreeModel::Row row; + try { - return font_list_store; + row = get_row_for_font(family); } - - const Glib::RefPtr - FontLister::get_style_list () const + catch (...) { - return style_list_store; + //std::cout << " ERROR: can't find family: " << family << std::endl; + return (target_style); } + + PangoFontDescription *target = pango_font_description_from_string(fontspec.c_str()); + PangoFontDescription *best = NULL; + + //font_description_dump( target ); + + if (!row[FontList.styles]) { + row[FontList.styles] = font_factory::Default()->GetUIStyles(row[FontList.pango_family]); + } + GList *styles = row[FontList.styles]; + for (GList *l = styles; l; l = l->next) { + Glib::ustring fontspec = family + ", " + (char *)l->data; + PangoFontDescription *candidate = pango_font_description_from_string(fontspec.c_str()); + //font_description_dump( candidate ); + //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl; + if (font_description_better_match(target, best, candidate)) { + pango_font_description_free(best); + best = candidate; + //std::cout << " ... better: " << std::endl; + } else { + pango_font_description_free(candidate); + //std::cout << " ... not better: " << std::endl; + } + } + + Glib::ustring best_style = target_style; + if (best) { + pango_font_description_unset_fields(best, PANGO_FONT_MASK_FAMILY); + best_style = pango_font_description_to_string(best); + } + + if (target) + pango_font_description_free(target); + if (best) + pango_font_description_free(best); + + +#ifdef DEBUG_FONT + std::cout << " Returning: " << best_style << std::endl; + std::cout << "FontLister::get_best_style_match: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return best_style; } +const Glib::RefPtr FontLister::get_font_list() const +{ + return font_list_store; +} + +const Glib::RefPtr FontLister::get_style_list() const +{ + return style_list_store; +} + +} // namespace Inkscape + // Helper functions // Separator function (if true, a separator will be drawn) -gboolean font_lister_separator_func(GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/) +gboolean font_lister_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) { - gchar* text = 0; - gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.family - return (text && strcmp(text,"#") == 0); + gchar *text = 0; + gtk_tree_model_get(model, iter, 0, &text, -1); // Column 0: FontList.family + return (text && strcmp(text, "#") == 0); } -void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/) +void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/) { gchar *family; gboolean onSystem = false; gtk_tree_model_get(model, iter, 0, &family, 2, &onSystem, -1); - Glib::ustring family_escaped = g_markup_escape_text(family, -1); + gchar* family_escaped = g_markup_escape_text(family, -1); //g_free(family); Glib::ustring markup; - if( !onSystem ) { + if (!onSystem) { markup = ""; /* See if font-family on system */ - std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", family_escaped ); - for( size_t i=0; i < tokens.size(); ++i ) { + std::vector tokens = Glib::Regex::split_simple("\\s*,\\s*", family_escaped); + for (size_t i = 0; i < tokens.size(); ++i) { Glib::ustring token = tokens[i]; @@ -1064,17 +1087,17 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, gchar *family = 0; gboolean onSystem = true; gboolean found = false; - for( valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(model), &iter ); + for (valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter); valid; - valid = gtk_tree_model_iter_next( GTK_TREE_MODEL(model), &iter ) ) { + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter)) { gtk_tree_model_get(model, &iter, 0, &family, 2, &onSystem, -1); - if( onSystem && familyNamesAreEqual( token, family ) ) { + if (onSystem && familyNamesAreEqual(token, family)) { found = true; break; } } - if( found ) { + if (found) { markup += g_markup_escape_text(token.c_str(), -1); markup += ", "; } else { @@ -1085,13 +1108,13 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, } } // Remove extra comma and space from end. - if( markup.size() >= 2 ) { - markup.resize( markup.size()-2 ); + if (markup.size() >= 2) { + markup.resize(markup.size() - 2); } markup += ""; // std::cout << markup << std::endl; } else { - markup = family_escaped; + markup = family_escaped; } Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1099,7 +1122,7 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, if (show_sample) { Glib::ustring sample = prefs->getString("/tools/text/font_sample"); - Glib::ustring sample_escaped = g_markup_escape_text(sample.data(), -1); + Glib::ustring sample_escaped = Glib::Markup::escape_text(sample); markup += " - new_font_family (Glib::ustring family, gboolean check_style = true); - - /** Sets font-family, updating style list and attempting - * to find closest style to old current_style. - * New font-family and style returned. - * Updates current_family and current_style. - * Calls new_font_family(). - * (For use in text-toolbar where update is immediate.) - */ - std::pair - set_font_family (Glib::ustring family, gboolean check_style = true); - - /** Sets font-family from row in list store. - * The row can be used to determine if we are in the - * document or system part of the font-family list. - * This is needed to handle scrolling through the - * font-family list correctly. - * Calls set_font_family(). - */ - std::pair - set_font_family (int row, gboolean check_style = true); - - Glib::ustring - get_font_family () - { - return current_family; - } - - int - get_font_family_row () - { - return current_family_row; - } - - /** Sets style. Does not validate style for family. - */ - void - set_font_style (Glib::ustring style); - - Glib::ustring - get_font_style () - { - return current_style; - } - - Glib::ustring - fontspec_from_style (SPStyle* style); - - /** Fill css using current_fontspec. - */ - void - fill_css( SPCSSAttr *css, Glib::ustring fontspec = "" ); - - Gtk::TreeModel::Row - get_row_for_font (Glib::ustring family); - - Gtk::TreePath - get_path_for_font (Glib::ustring family); - - Gtk::TreeModel::Row - get_row_for_style (Glib::ustring style); - - Gtk::TreePath - get_path_for_style (Glib::ustring style); - - std::pair - get_paths (Glib::ustring family, Glib::ustring style); - - /** Return best style match for new font given style for old font. - */ - Glib::ustring - get_best_style_match (Glib::ustring family, Glib::ustring style); - - /* Not Used */ - const NRNameList - get_name_list () const - { - return families; - } - - private: - - FontLister (); - - NRNameList families; - - Glib::RefPtr font_list_store; - Glib::RefPtr style_list_store; - - /** Info for currently selected font (what is shown in the UI). - * May include font-family lists and fonts not on system. - */ - int current_family_row; - Glib::ustring current_family; - Glib::ustring current_style; - Glib::ustring current_fontspec; - - /** fontspec of system font closest to current_fontspec. - * (What the system will use to display current_fontspec.) - */ - Glib::ustring current_fontspec_system; - - /** If a font-family is not on system, this list of styles is used. - */ - GList *default_styles; - }; -} +namespace Inkscape { + +/** + * This class enumerates fonts using libnrtype into reusable data stores and + * allows for random access to the font-family list and the font-style list. + * Setting the font-family updates the font-style list. "Style" in this case + * refers to everything but family and size (e.g. italic/oblique, weight). + * + * This class handles font-family lists and fonts that are not on the system, + * where there is not an entry in the fontInstanceMap. + * + * This class uses the idea of "font_spec". This is a plain text string as used by + * Pango. It is similar to the CSS font shorthand except that font-family comes + * first and in this class the font-size is not used. + * + * This class uses the FontFactory class to get a list of system fonts + * and to find best matches via Pango. The Pango interface is only setup + * to deal with fonts that are on the system so care must be taken. For + * example, best matches should only be done with the first font-family + * in a font-family list. If the first font-family is not on the system + * then a generic font-family should be used (sans-serif -> Sans). + * + * This class is used by the UI interface (text-toolbar, font-select, etc.). + * + * "Font" includes family and style. It should not be used when one + * means font-family. + */ + +class FontLister { +public: + enum Exceptions { + FAMILY_NOT_FOUND, + STYLE_NOT_FOUND + }; + + virtual ~FontLister(); + + /** + * GtkTreeModelColumnRecord for the font-family list Gtk::ListStore + */ + struct FontListClass : public Gtk::TreeModelColumnRecord { + /** + * Column containing the family name + */ + Gtk::TreeModelColumn family; + + /** + * Column containing the styles for each family name. + */ + Gtk::TreeModelColumn styles; + + /** + * Column containing flag if font is on system + */ + Gtk::TreeModelColumn onSystem; + + /** + * Not actually a column. + * Necessary for quick initialization of FontLister, + * we initially store the pango family and if the + * font style is actually used we'll cache it in + * %styles. + */ + Gtk::TreeModelColumn pango_family; + + FontListClass() + { + add(family); + add(styles); + add(onSystem); + add(pango_family); + } + }; + + FontListClass FontList; + + struct FontStyleListClass : public Gtk::TreeModelColumnRecord { + /** + * Column containing the styles as Font designer used. + */ + Gtk::TreeModelColumn displayStyle; + + /** + * Column containing the styles in CSS/Pango format. + */ + Gtk::TreeModelColumn cssStyle; + + FontStyleListClass() + { + add(cssStyle); + add(displayStyle); + } + }; + + FontStyleListClass FontStyleList; + + /** + * @return the ListStore with the family names + * + * The return is const and the function is declared as const. + * The ListStore is ready to be used after class instantiation + * and should not be modified. + */ + const Glib::RefPtr get_font_list() const; + + /** + * @return the ListStore with the styles + */ + const Glib::RefPtr get_style_list() const; + + /** + * Inserts a font family or font-fallback list (for use when not + * already in document or on system). + */ + void insert_font_family(Glib::ustring new_family); + + /** + * Updates font list to include fonts in document. + */ + void update_font_list(SPDocument *document); + +public: + static Inkscape::FontLister *get_instance(); + + /** + * Takes a hand written font spec and returns a Pango generated one in + * standard form. + */ + Glib::ustring canonize_fontspec(Glib::ustring fontspec); + + /** + * Find closest system font to given font. + */ + Glib::ustring system_fontspec(Glib::ustring fontspec); + + /** + * Gets font-family and style from fontspec. + * font-family and style returned. + */ + std::pair ui_from_fontspec(Glib::ustring fontspec); + + /** + * Sets font-family and style after a selection change. + * New font-family and style returned. + */ + std::pair selection_update(); + + /** + * Sets current_fontspec, etc. If check is false, won't + * try to find best style match (assumes style in fontspec + * valid for given font-family). + */ + void set_fontspec(Glib::ustring fontspec, bool check = true); + + Glib::ustring get_fontspec() + { + return current_fontspec; + } + + /** + * Changes font-family, updating style list and attempting to find + * closest style to current_style style (if check_style is true). + * New font-family and style returned. + * Does NOT update current_family and current_style. + * (For potential use in font-selector which doesn't update until + * "Apply" button clicked.) + */ + std::pair new_font_family(Glib::ustring family, bool check_style = true); + + /** + * Sets font-family, updating style list and attempting + * to find closest style to old current_style. + * New font-family and style returned. + * Updates current_family and current_style. + * Calls new_font_family(). + * (For use in text-toolbar where update is immediate.) + */ + std::pair set_font_family(Glib::ustring family, bool check_style = true); + + /** + * Sets font-family from row in list store. + * The row can be used to determine if we are in the + * document or system part of the font-family list. + * This is needed to handle scrolling through the + * font-family list correctly. + * Calls set_font_family(). + */ + std::pair set_font_family(int row, bool check_style = true); + + Glib::ustring get_font_family() + { + return current_family; + } + + int get_font_family_row() + { + return current_family_row; + } + + /** + * Sets style. Does not validate style for family. + */ + void set_font_style(Glib::ustring style); + + Glib::ustring get_font_style() + { + return current_style; + } + + Glib::ustring fontspec_from_style(SPStyle *style); + + /** + * Fill css using current_fontspec. + */ + void fill_css(SPCSSAttr *css, Glib::ustring fontspec = ""); + + Gtk::TreeModel::Row get_row_for_font(Glib::ustring family); + + Gtk::TreePath get_path_for_font(Glib::ustring family); + + Gtk::TreeModel::Row get_row_for_style(Glib::ustring style); + + Gtk::TreePath get_path_for_style(Glib::ustring style); + + std::pair get_paths(Glib::ustring family, Glib::ustring style); + + /** + * Return best style match for new font given style for old font. + */ + Glib::ustring get_best_style_match(Glib::ustring family, Glib::ustring style); + + void ensureRowStyles(GtkTreeModel* model, GtkTreeIter const* iter); + +private: + FontLister(); + + void update_font_list_recursive(SPObject *r, std::list *l); + + Glib::RefPtr font_list_store; + Glib::RefPtr style_list_store; + + /** + * Info for currently selected font (what is shown in the UI). + * May include font-family lists and fonts not on system. + */ + int current_family_row; + Glib::ustring current_family; + Glib::ustring current_style; + Glib::ustring current_fontspec; + + /** + * fontspec of system font closest to current_fontspec. + * (What the system will use to display current_fontspec.) + */ + Glib::ustring current_fontspec_system; + + /** + * If a font-family is not on system, this list of styles is used. + */ + GList *default_styles; +}; + +} // namespace Inkscape // Helper functions gboolean font_lister_separator_func(GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/); + GtkTreeIter *iter, + gpointer /*data*/); -void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer /*data*/); +void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer /*data*/); #endif @@ -328,4 +314,4 @@ void font_lister_cell_data_func(GtkCellLayout */*cell_layout*/, fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index c1ebb32e0..e44809c65 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -344,9 +344,9 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - // This is done for us by text-toolbar. No need to do it twice. - // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); - // fontlister->selection_update(); + // This is normally done for us by text-toolbar but only when we are in text editing context + fontlister->update_font_list(sp_desktop_document(this->desktop)); + fontlister->selection_update(); Glib::ustring fontspec = fontlister->get_fontspec(); diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index ccaf93e55..c9a52ef11 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -303,6 +303,9 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, GtkTreeModel *model; GtkTreeIter iter; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; + + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + fontlister->ensureRowStyles(model, &iter); // Next get family name with its style list gchar *family; @@ -310,7 +313,6 @@ static void sp_font_selector_family_select_row(GtkTreeSelection *selection, gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1); // Find best style match for selected family with current style (e.g. of selected text). - Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); Glib::ustring style = fontlister->get_font_style(); Glib::ustring best = fontlister->get_best_style_match (family, style); diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 408babf06..88f698bc4 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -819,7 +819,7 @@ static void sp_text_set_sizes(GtkListStore* model_size, int unit) * It is called whenever a text selection is changed, including stepping cursor * through text, or setting focus to text. */ -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl) +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false) // don't bother to update font list if subsel changed { #ifdef DEBUG_TEXT static int count = 0; @@ -859,7 +859,9 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + if (!subselection) { + fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + } fontlister->selection_update(); // Update font list, but only if widget already created. @@ -1154,7 +1156,7 @@ static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, g static void sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) { - sp_text_toolbox_selection_changed (NULL, tbl); + sp_text_toolbox_selection_changed (NULL, tbl, true); } // TODO: possibly share with font-selector by moving most code to font-lister (passing family name) @@ -1640,7 +1642,7 @@ static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolB if (SP_IS_TEXT_CONTEXT(ec)) { // Watch selection - c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder)); + c_selection_changed = sp_desktop_selection(desktop)->connectChanged(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); c_selection_modified = sp_desktop_selection (desktop)->connectModified(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder)); } else { -- cgit v1.2.3 From be103a4ac9f4821db95601b84ffa70f73c49df65 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 10:10:57 -0400 Subject: Fix gtk3 build (bzr r13341.1.141) --- src/libnrtype/font-lister.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 07c80054d..1b4d9d256 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -1122,13 +1122,14 @@ void font_lister_cell_data_func(GtkCellLayout * /*cell_layout*/, if (show_sample) { Glib::ustring sample = prefs->getString("/tools/text/font_sample"); - Glib::ustring sample_escaped = Glib::Markup::escape_text(sample); + gchar* sample_escaped = g_markup_escape_text(sample.data(), -1); markup += " "; markup += sample_escaped; markup += ""; + g_free(sample_escaped); } g_object_set(G_OBJECT(cell), "markup", markup.c_str(), NULL); -- cgit v1.2.3 From ad180652b5f6b59b3f24d60677bbf8ec97827aed Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 10:33:11 -0400 Subject: Similar workaround to r13523 (text&font dialog not appearing quickly) (bzr r13525) --- src/widgets/font-selector.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index ccaf93e55..f00f05768 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -157,6 +157,10 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_container_add(GTK_CONTAINER(f), sw); fsel->family_treeview = gtk_tree_view_new (); + gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview), + GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func), + NULL, NULL ); + gtk_widget_show_all(GTK_WIDGET (fsel->family_treeview)); GtkTreeViewColumn *column = gtk_tree_view_column_new (); GtkCellRenderer *cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, FALSE); @@ -166,9 +170,6 @@ static void sp_font_selector_init(SPFontSelector *fsel) NULL, NULL ); gtk_tree_view_append_column (GTK_TREE_VIEW(fsel->family_treeview), column); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(fsel->family_treeview), FALSE); - gtk_tree_view_set_row_separator_func( GTK_TREE_VIEW(fsel->family_treeview), - GtkTreeViewRowSeparatorFunc ((gpointer)font_lister_separator_func), - NULL, NULL ); /* Muck with style, see text-toolbar.cpp */ gtk_widget_set_name( GTK_WIDGET(fsel->family_treeview), "font_selector_family" ); -- cgit v1.2.3 From 282a7ce3f988e792545c19854b5f55cff1291cbe Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 13:44:01 -0400 Subject: Fix gtk3 crash when using "close" button Fixed bugs: - https://launchpad.net/bugs/1090936 (bzr r13341.1.143) --- src/ui/dialog/dialog.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 645294bb5..22ba0b6fb 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -317,20 +317,7 @@ void Dialog::_apply() void Dialog::_close() { - GtkWidget *dlg = GTK_WIDGET(_behavior->gobj()); - - GdkEventAny event; - event.type = GDK_DELETE; - event.window = gtk_widget_get_window(dlg); - event.send_event = TRUE; - - if (event.window) - g_object_ref(G_OBJECT(event.window)); - - gtk_main_do_event ((GdkEvent*)&event); - - if (event.window) - g_object_unref(G_OBJECT(event.window)); + _behavior->hide(); } void Dialog::_defocus() -- cgit v1.2.3 From 14d13e15abbe4b955c0705c056cc082df7e82290 Mon Sep 17 00:00:00 2001 From: Adib Taraben Date: Sun, 17 Aug 2014 19:54:40 +0200 Subject: fix build problem for win32 due to syntax problem in .rc files after tagging pre2 (bzr r13526) --- src/inkscape-x64.rc | 4 ++-- src/inkscape.rc | 4 ++-- src/inkview.rc | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/inkscape-x64.rc b/src/inkscape-x64.rc index 47dbcb2bc..65a2b08b9 100644 --- a/src/inkscape-x64.rc +++ b/src/inkscape-x64.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest-x64.xml" 1 VERSIONINFO - FILEVERSION 0,91pre2,0,0 - PRODUCTVERSION 0,91pre2,0,0 + FILEVERSION 0,91,0,0 + PRODUCTVERSION 0,91,0,0 BEGIN BLOCK "StringFileInfo" BEGIN diff --git a/src/inkscape.rc b/src/inkscape.rc index 2c2c0112b..689653f74 100644 --- a/src/inkscape.rc +++ b/src/inkscape.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkscape-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,91pre2,0,0 - PRODUCTVERSION 0,91pre2,0,0 + FILEVERSION 0,91,0,0 + PRODUCTVERSION 0,91,0,0 BEGIN BLOCK "StringFileInfo" BEGIN diff --git a/src/inkview.rc b/src/inkview.rc index efbe2568b..43a63c725 100644 --- a/src/inkview.rc +++ b/src/inkview.rc @@ -3,8 +3,8 @@ APPLICATION_ICON ICON DISCARDABLE "../inkscape.ico" 1 24 DISCARDABLE "./inkview-manifest.xml" 1 VERSIONINFO - FILEVERSION 0,91pre2,0,0 - PRODUCTVERSION 0,91pre2,0,0 + FILEVERSION 0,91,0,0 + PRODUCTVERSION 0,91,0,0 BEGIN BLOCK "StringFileInfo" BEGIN -- cgit v1.2.3 From 2a04905eb339f85263babd7d668dd43f072f75b3 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 17 Aug 2014 14:13:20 -0400 Subject: Fix accidental regression in previous commit (bzr r13341.1.144) --- src/ui/dialog/dialog.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 22ba0b6fb..f2c63ed8d 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -318,6 +318,7 @@ void Dialog::_apply() void Dialog::_close() { _behavior->hide(); + _onDeleteEvent(NULL); } void Dialog::_defocus() -- cgit v1.2.3 From 96e024a5516072ab02cb3b7160c788cdce2523a2 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sun, 17 Aug 2014 20:31:38 +0200 Subject: Fix some issues with constrained snapping Fixed bugs: - https://launchpad.net/bugs/681286 - https://launchpad.net/bugs/1265026 (bzr r13527) --- src/snap.cpp | 85 +++++++++++++++++++++++++----------------------------------- 1 file changed, 36 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/snap.cpp b/src/snap.cpp index ea6322e37..5b795b22f 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -274,7 +274,7 @@ Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::SnapCandidatePoint /* See the documentation for constrainedSnap() directly above for more details. * The difference is that multipleConstrainedSnaps() will take a list of constraints instead of a single one, - * and will try to snap the SnapCandidatePoint to all of the provided constraints and see which one fits best + * and will try to snap the SnapCandidatePoint to only the closest constraint * \param p Source point to be snapped * \param constraints List of directions or lines along which snapping must occur * \param dont_snap If true then we will only apply the constraint, without snapping @@ -293,16 +293,11 @@ Inkscape::SnappedPoint SnapManager::multipleConstrainedSnaps(Inkscape::SnapCandi return no_snap; } - IntermSnapResults isr; - SnapperList const snappers = getSnappers(); - std::vector projections; - bool snapping_is_futile = !someSnapperMightSnap() || dont_snap; - - Inkscape::SnappedPoint result = no_snap; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool snap_mouse = prefs->getBool("/options/snapmousepointer/value", false); + // We haven't tried to snap yet; we will first determine which constraint is closest to where we are now, + // i.e. lets find out which of the constraints yields the closest projection of point p + // Project the mouse pointer on each of the constraints + std::vector projections; for (std::vector::const_iterator c = constraints.begin(); c != constraints.end(); ++c) { // Project the mouse pointer onto the constraint; In case we don't snap then we will // return the projection onto the constraint, such that the constraint is always enforced @@ -310,55 +305,47 @@ Inkscape::SnappedPoint SnapManager::multipleConstrainedSnaps(Inkscape::SnapCandi projections.push_back(pp); } - if (snap_mouse && p.isSingleHandle() && !dont_snap) { + // Select the closest constraint + no_snap.setPoint(projections.front()); + Inkscape::Snapper::SnapConstraint cc = constraints.front(); //closest constraint + + std::vector::const_iterator c = constraints.begin(); + std::vector::iterator pp = projections.begin(); + for (; pp != projections.end(); ++pp) { + if (Geom::L2(*pp - p.getPoint()) < Geom::L2(no_snap.getPoint() - p.getPoint())) { + no_snap.setPoint(*pp); // Remember the projection onto the closest constraint + cc = *c; // Remember the closest constraint itself + } + ++c; + } + + if (!someSnapperMightSnap() || dont_snap) { + return no_snap; + } + + IntermSnapResults isr; + SnapperList const snappers = getSnappers(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool snap_mouse = prefs->getBool("/options/snapmousepointer/value", false); + + Inkscape::SnappedPoint result = no_snap; + if (snap_mouse && p.isSingleHandle()) { // Snapping the mouse pointer instead of the constrained position of the knot allows // to snap to things which don't intersect with the constraint line; this is basically // then just a freesnap with the constraint applied afterwards // We'll only to this if we're dragging a single handle, and for example not when transforming an object in the selector tool result = freeSnap(p, bbox_to_snap); + // Now apply the constraint afterwards + result.setPoint(cc.projection(result.getPoint())); } else { - // Iterate over the constraints - for (std::vector::const_iterator c = constraints.begin(); c != constraints.end(); ++c) { - // Try to snap to the constraint - if (!snapping_is_futile) { - for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); ++i) { - (*i)->constrainedSnap(isr, p, bbox_to_snap, *c, &_items_to_ignore,_unselected_nodes); - } - } + // Try to snap along the closest constraint + for (SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); ++i) { + (*i)->constrainedSnap(isr, p, bbox_to_snap, cc, &_items_to_ignore,_unselected_nodes); } result = findBestSnap(p, isr, true); } - if (result.getSnapped()) { - if (snap_mouse) { - // If "snap_mouse" then we still have to apply the constraint, because so far we only tried a freeSnap - Geom::Point result_closest; - for (std::vector::const_iterator c = constraints.begin(); c != constraints.end(); ++c) { - // Project the mouse pointer onto the constraint; In case we don't snap then we will - // return the projection onto the constraint, such that the constraint is always enforced - Geom::Point result_p = (*c).projection(result.getPoint()); - if (c == constraints.begin() || (Geom::L2(result_p - p.getPoint()) < Geom::L2(result_closest - p.getPoint()))) { - result_closest = result_p; - } - } - result.setPoint(result_closest); - } - return result; - } - - // So we didn't snap, but we still need to return a point on one of the constraints - // Find out which of the constraints yielded the closest projection of point p - for (std::vector::iterator pp = projections.begin(); pp != projections.end(); ++pp) { - if (pp != projections.begin()) { - if (Geom::L2(*pp - p.getPoint()) < Geom::L2(no_snap.getPoint() - p.getPoint())) { - no_snap.setPoint(*pp); - } - } else { - no_snap.setPoint(projections.front()); - } - } - - return no_snap; + return result.getSnapped() ? result : no_snap; } Inkscape::SnappedPoint SnapManager::constrainedAngularSnap(Inkscape::SnapCandidatePoint const &p, -- cgit v1.2.3 From dce3466274e04364e25c47b0b71007a65c9cf9dd Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 18 Aug 2014 16:19:55 -0400 Subject: Code cleanup. (bzr r13341.1.145) --- src/attributes.cpp | 13 +- src/axis-manip.cpp | 6 +- src/display/curve.cpp | 16 +- src/display/curve.h | 20 +- src/extension/implementation/script.cpp | 44 ++-- src/extension/implementation/script.h | 80 +------ src/help.cpp | 21 +- src/help.h | 20 +- src/helper/gnome-utils.cpp | 148 +++++++------ src/helper/gnome-utils.h | 14 +- src/helper/window.cpp | 62 +++--- src/helper/window.h | 19 +- src/libnrtype/nr-type-primitives.cpp | 151 +++++++------ src/libnrtype/nr-type-primitives.h | 21 +- src/macros.h | 11 +- src/perspective-line.cpp | 6 +- src/proj_pt.cpp | 6 +- src/proj_pt.h | 12 +- src/sp-ellipse.cpp | 33 ++- src/sp-ellipse.h | 14 +- src/sp-glyph-kerning.cpp | 133 ++++++----- src/sp-glyph-kerning.h | 73 +++---- src/sp-glyph.cpp | 162 +++++++------- src/sp-glyph.h | 48 ++-- src/svg/svg-length.cpp | 13 +- src/svg/svg-length.h | 24 +- src/svg/svg-path.cpp | 51 ++--- src/uri-references.cpp | 6 +- src/uri-references.h | 8 +- src/widgets/button.cpp | 377 +++++++++++++++----------------- src/widgets/button.h | 19 +- src/widgets/font-selector.cpp | 6 +- src/widgets/font-selector.h | 4 +- src/widgets/gradient-image.cpp | 22 +- src/widgets/gradient-image.h | 27 ++- src/widgets/sp-xmlview-tree.cpp | 8 +- src/widgets/sp-xmlview-tree.h | 17 +- 37 files changed, 804 insertions(+), 911 deletions(-) (limited to 'src') diff --git a/src/attributes.cpp b/src/attributes.cpp index 2474e4abe..526476322 100644 --- a/src/attributes.cpp +++ b/src/attributes.cpp @@ -1,9 +1,4 @@ -#define __SP_ATTRIBUTES_C__ - -/** \file - * Lookup dictionary for attributes/properties. - */ -/* +/** * Author: * Lauris Kaplinski * @@ -25,6 +20,10 @@ typedef struct { gchar const *name; } SPStyleProp; +/** + * Lookup dictionary for attributes/properties. + */ + static SPStyleProp const props[] = { {SP_ATTR_INVALID, NULL}, /* SPObject */ @@ -539,4 +538,4 @@ sp_attribute_name(unsigned int id) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/axis-manip.cpp b/src/axis-manip.cpp index 1dfa0e6bf..1240d99e6 100644 --- a/src/axis-manip.cpp +++ b/src/axis-manip.cpp @@ -1,6 +1,4 @@ -#define __AXIS_MANIP_C__ - -/* +/** * Generic auxiliary routines for 3D axes * * Authors: @@ -44,4 +42,4 @@ get_remaining_axes (Axis axis) { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/display/curve.cpp b/src/display/curve.cpp index 50f4c8954..0a39a8e7f 100644 --- a/src/display/curve.cpp +++ b/src/display/curve.cpp @@ -1,10 +1,4 @@ -#define __CURVE_C__ - -/** \file - * Routines for SPCurve and for its Geom::PathVector - */ - -/* +/** * Authors: * Lauris Kaplinski * Johan Engelen @@ -14,7 +8,7 @@ * Copyright (C) 2002 Lauris Kaplinski * Copyright (C) 2008 Johan Engelen * - * Released under GNU GPL + * Released under GNU GPL, see file 'COPYING' for more information */ #include "display/curve.h" @@ -25,6 +19,10 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/point.h> +/** + * Routines for SPCurve and for its Geom::PathVector + */ + /* Constructors */ /** @@ -686,4 +684,4 @@ SPCurve::last_point_additive_move(Geom::Point const & p) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8: diff --git a/src/display/curve.h b/src/display/curve.h index 4866655c4..b3f1e3702 100644 --- a/src/display/curve.h +++ b/src/display/curve.h @@ -1,8 +1,5 @@ -#ifndef SEEN_DISPLAY_CURVE_H -#define SEEN_DISPLAY_CURVE_H - -/* - * Author: +/** + * Authors: * Lauris Kaplinski * * Copyright (C) 2000 Lauris Kaplinski @@ -10,17 +7,18 @@ * Copyright (C) 2002 Lauris Kaplinski * Copyright (C) 2008 Johan Engelen * - * Released under GNU GPL + * Released under GNU GPL, see file 'COPYING' for more information */ -#include +#ifndef SEEN_DISPLAY_CURVE_H +#define SEEN_DISPLAY_CURVE_H +#include #include <2geom/forward.h> - #include /** - * Wrapper around a Geom::PathVector objects. + * Wrapper around a Geom::PathVector object. */ class SPCurve { public: @@ -90,7 +88,7 @@ private: SPCurve& operator=(const SPCurve&); }; -#endif /* !SEEN_DISPLAY_CURVE_H */ +#endif // !SEEN_DISPLAY_CURVE_H /* Local Variables: @@ -101,4 +99,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index f0fd3711b..e7d6e64ce 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -1,28 +1,18 @@ -/** \file - * Code for handling extensions (i.e.\ scripts). - */ -/* +/** + * Code for handling extensions (i.e. scripts). + * * Authors: * Bryce Harrington * Ted Gould * Jon A. Cruz * Abhishek Sharma * - * Copyright (C) 2002-2005,2007 Authors + * Copyright (C) 2002-2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ -#define __INKSCAPE_EXTENSION_IMPLEMENTATION_SCRIPT_C__ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - +#include #include #include #include @@ -33,43 +23,37 @@ #include #include -#include -#include "ui/view/view.h" #include "desktop-handles.h" #include "desktop.h" -#include "selection.h" -#include "sp-namedview.h" -#include "io/sys.h" -#include "preferences.h" -#include "../system.h" +#include "dialogs/dialog-events.h" #include "extension/effect.h" #include "extension/output.h" #include "extension/input.h" #include "extension/db.h" -#include "script.h" -#include "dialogs/dialog-events.h" #include "inkscape.h" +#include "io/sys.h" +#include "preferences.h" +#include "script.h" +#include "selection.h" +#include "sp-namedview.h" +#include "system.h" +#include "ui/view/view.h" #include "xml/node.h" #include "xml/attribute-record.h" #include "util/glib-list-iterators.h" #include "path-prefix.h" - #ifdef WIN32 #include #include #include "registrytool.h" #endif - - /** This is the command buffer that gets allocated from the stack */ #define BUFSIZE (255) - - /* Namespaces */ namespace Inkscape { namespace Extension { @@ -1063,4 +1047,4 @@ int Script::execute (const std::list &in_command, fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/extension/implementation/script.h b/src/extension/implementation/script.h index 270c361af..6a7d0c3b8 100644 --- a/src/extension/implementation/script.h +++ b/src/extension/implementation/script.h @@ -22,81 +22,30 @@ namespace Inkscape { namespace XML { class Node; -} -} +} // namespace XML - -namespace Inkscape { namespace Extension { namespace Implementation { - /** * Utility class used for loading and launching script extensions */ class Script : public Implementation { - public: - /** - * - */ Script(void); - - /** - * - */ virtual ~Script(); - - - /** - * - */ virtual bool load(Inkscape::Extension::Extension *module); - - /** - * - */ virtual void unload(Inkscape::Extension::Extension *module); - - /** - * - */ virtual bool check(Inkscape::Extension::Extension *module); ImplementationDocumentCache * newDocCache(Inkscape::Extension::Extension * ext, Inkscape::UI::View::View * view); - /** - * - */ - virtual Gtk::Widget *prefs_input(Inkscape::Extension::Input *module, - gchar const *filename); - - /** - * - */ - virtual SPDocument *open(Inkscape::Extension::Input *module, - gchar const *filename); - - /** - * - */ + virtual Gtk::Widget *prefs_input(Inkscape::Extension::Input *module, gchar const *filename); + virtual SPDocument *open(Inkscape::Extension::Input *module, gchar const *filename); virtual Gtk::Widget *prefs_output(Inkscape::Extension::Output *module); - - /** - * - */ - virtual void save(Inkscape::Extension::Output *module, - SPDocument *doc, - gchar const *filename); - - /** - * - */ - virtual void effect(Inkscape::Extension::Effect *module, - Inkscape::UI::View::View *doc, - ImplementationDocumentCache * docCache); - + virtual void save(Inkscape::Extension::Output *module, SPDocument *doc, gchar const *filename); + virtual void effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View *doc, ImplementationDocumentCache * docCache); virtual bool cancelProcessing (void); private: @@ -105,7 +54,7 @@ private: Glib::RefPtr _main_loop; /** - * The command that has been dirived from + * The command that has been derived from * the configuration file with appropriate directories */ std::list command; @@ -117,13 +66,10 @@ private: */ Glib::ustring helper_extension; - std::string solve_reldir (Inkscape::XML::Node *reprin); - bool check_existence (const std::string &command); - void copy_doc (Inkscape::XML::Node * olddoc, - Inkscape::XML::Node * newdoc); - void checkStderr (const Glib::ustring &filename, - Gtk::MessageType type, - const Glib::ustring &message); + std::string solve_reldir(Inkscape::XML::Node *repr_in); + bool check_existence (std::string const& command); + void copy_doc(Inkscape::XML::Node * olddoc, Inkscape::XML::Node * newdoc); + void checkStderr (Glib::ustring const& filename, Gtk::MessageType type, Glib::ustring const& message); class file_listener { Glib::ustring _string; @@ -140,6 +86,7 @@ private: bool isDead () { return _dead; } + // TODO move these definitions into script.cpp void init (int fd, Glib::RefPtr main) { _channel = Glib::IOChannel::create_from_fd(fd); _channel->set_encoding(); @@ -202,11 +149,6 @@ private: std::string resolveInterpreterExecutable(const Glib::ustring &interpNameArg); }; // class Script - - - - - } // namespace Implementation } // namespace Extension } // namespace Inkscape diff --git a/src/help.cpp b/src/help.cpp index 02a1930f4..60e57abfc 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -1,6 +1,4 @@ -#define __SP_HELP_C__ - -/* +/** * Help/About window * * Authors: @@ -13,24 +11,19 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include -#include "ui/dialog/aboutbox.h" -#include "path-prefix.h" -#include "help.h" #include "file.h" +#include "help.h" +#include "path-prefix.h" +#include "ui/dialog/aboutbox.h" - -void -sp_help_about (void) +void sp_help_about() { Inkscape::UI::Dialog::AboutBox::show_about(); } -void -sp_help_open_tutorial(GtkMenuItem *, gpointer data) +void sp_help_open_tutorial(GtkMenuItem *, void* data) { gchar const *name = static_cast(data); gchar *c = g_build_filename(INKSCAPE_TUTORIALSDIR, name, NULL); diff --git a/src/help.h b/src/help.h index 3fce65fef..3f83e3367 100644 --- a/src/help.h +++ b/src/help.h @@ -1,6 +1,4 @@ -#ifndef SEEN_HELP_H -#define SEEN_HELP_H -/* +/** * Authors: * Lauris Kaplinski * @@ -10,18 +8,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include +#ifndef SEEN_HELP_H +#define SEEN_HELP_H + +typedef struct _GtkMenuItem GtkMenuItem; /** * Help/About window. */ -void sp_help_about(void); - -void sp_help_open_tutorial(GtkMenuItem *menuitem, gpointer data); - +void sp_help_about(); +void sp_help_open_tutorial(GtkMenuItem * /*unused*/, void* data); -#endif /* !SEEN_HELP_H */ +#endif // !SEEN_HELP_H /* Local Variables: @@ -32,4 +30,4 @@ void sp_help_open_tutorial(GtkMenuItem *menuitem, gpointer data); fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/helper/gnome-utils.cpp b/src/helper/gnome-utils.cpp index 957b7ea5e..3d2b333a2 100644 --- a/src/helper/gnome-utils.cpp +++ b/src/helper/gnome-utils.cpp @@ -1,9 +1,7 @@ -#define __GNOME_UTILS_C__ - -/* +/** * Helpers * - * Author: + * Authors: * Mitsuru Oka * Lauris Kaplinski * @@ -25,49 +23,48 @@ * Returns a GList containing strings allocated with g_malloc * that have been splitted from @uri-list. */ -GList* -gnome_uri_list_extract_uris (const gchar* uri_list) +GList *gnome_uri_list_extract_uris(const gchar *uri_list) { - const gchar *p, *q; - gchar *retval; - GList *result = NULL; - - g_return_val_if_fail (uri_list != NULL, NULL); - - p = uri_list; - - /* We don't actually try to validate the URI according to RFC - * 2396, or even check for allowed characters - we just ignore - * comments and trim whitespace off the ends. We also - * allow LF delimination as well as the specified CRLF. - */ - while (p) { - if (*p != '#') { - while (isspace(*p)) - p++; - - q = p; - while (*q && (*q != '\n') && (*q != '\r')) - q++; - - if (q > p) { - q--; - while (q > p && isspace(*q)) - q--; - - retval = (gchar*)g_malloc (q - p + 2); - strncpy (retval, p, q - p + 1); - retval[q - p + 1] = '\0'; - - result = g_list_prepend (result, retval); - } - } - p = strchr (p, '\n'); - if (p) - p++; - } - - return g_list_reverse (result); + const gchar *p, *q; + gchar *retval; + GList *result = NULL; + + g_return_val_if_fail(uri_list != NULL, NULL); + + p = uri_list; + + /* We don't actually try to validate the URI according to RFC + * 2396, or even check for allowed characters - we just ignore + * comments and trim whitespace off the ends. We also + * allow LF delimination as well as the specified CRLF. + */ + while (p) { + if (*p != '#') { + while (isspace(*p)) + p++; + + q = p; + while (*q && (*q != '\n') && (*q != '\r')) + q++; + + if (q > p) { + q--; + while (q > p && isspace(*q)) + q--; + + retval = (gchar *)g_malloc(q - p + 2); + strncpy(retval, p, q - p + 1); + retval[q - p + 1] = '\0'; + + result = g_list_prepend(result, retval); + } + } + p = strchr(p, '\n'); + if (p) + p++; + } + + return g_list_reverse(result); } /** @@ -80,29 +77,40 @@ gnome_uri_list_extract_uris (const gchar* uri_list) * Note that unlike gnome_uri_list_extract_uris() function, this * will discard any non-file uri from the result value. */ -GList* -gnome_uri_list_extract_filenames (const gchar* uri_list) +GList *gnome_uri_list_extract_filenames(const gchar *uri_list) { - g_return_val_if_fail (uri_list != NULL, NULL); - - GList *result = gnome_uri_list_extract_uris (uri_list); - - GList *tmp_list = result; - while (tmp_list) { - gchar *s = (gchar*)tmp_list->data; - - GList *node = tmp_list; - tmp_list = tmp_list->next; - - if (!strncmp (s, "file:", 5)) { - node->data = g_filename_from_uri (s, NULL, NULL); - /* not sure if this fallback is useful at all */ - if (!node->data) node->data = g_strdup (s+5); - } else { - result = g_list_remove_link(result, node); - g_list_free_1 (node); - } - g_free (s); - } - return result; + g_return_val_if_fail(uri_list != NULL, NULL); + + GList *result = gnome_uri_list_extract_uris(uri_list); + + GList *tmp_list = result; + while (tmp_list) { + gchar *s = (gchar *)tmp_list->data; + + GList *node = tmp_list; + tmp_list = tmp_list->next; + + if (!strncmp(s, "file:", 5)) { + node->data = g_filename_from_uri(s, NULL, NULL); + /* not sure if this fallback is useful at all */ + if (!node->data) + node->data = g_strdup(s + 5); + } else { + result = g_list_remove_link(result, node); + g_list_free_1(node); + } + g_free(s); + } + return result; } + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/helper/gnome-utils.h b/src/helper/gnome-utils.h index 3502b28df..6f2f28223 100644 --- a/src/helper/gnome-utils.h +++ b/src/helper/gnome-utils.h @@ -1,7 +1,7 @@ -/* +/** * GNOME Utils - Migration helper * - * Author: + * Authors: * GNOME Developer * Mitsuru Oka * Lauris Kaplinski @@ -11,17 +11,15 @@ * Released under GNU GPL */ - -#ifndef __GNOME_UTILS_H__ -#define __GNOME_UTILS_H__ +#ifndef SEEN_GNOME_UTILS_H +#define SEEN_GNOME_UTILS_H #include GList *gnome_uri_list_extract_uris(gchar const *uri_list); - GList *gnome_uri_list_extract_filenames(gchar const *uri_list); -#endif /* __GNOME_UTILS_H__ */ +#endif // !SEEN_GNOME_UTILS_H /* Local Variables: @@ -32,4 +30,4 @@ GList *gnome_uri_list_extract_filenames(gchar const *uri_list); fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/helper/window.cpp b/src/helper/window.cpp index 98fbef170..98e886a38 100644 --- a/src/helper/window.cpp +++ b/src/helper/window.cpp @@ -1,6 +1,4 @@ -#define __SP_WINDOW_C__ - -/* +/** * Generic window implementation * * Author: @@ -9,61 +7,61 @@ * This code is in public domain */ -#ifdef HAVE_CONFIG_H -# include -#endif - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - +#include #include +#include "desktop.h" #include "inkscape.h" #include "shortcuts.h" -#include "desktop.h" #include "ui/tools/tool-base.h" #include "window.h" -#include static bool on_window_key_press(GdkEventKey* event) { - unsigned int shortcut; - shortcut = Inkscape::UI::Tools::get_group0_keyval (event) | + unsigned shortcut = 0; + // FIXME why? + shortcut = Inkscape::UI::Tools::get_group0_keyval (event) | ( event->state & GDK_SHIFT_MASK ? SP_SHORTCUT_SHIFT_MASK : 0 ) | ( event->state & GDK_CONTROL_MASK ? SP_SHORTCUT_CONTROL_MASK : 0 ) | ( event->state & GDK_MOD1_MASK ? SP_SHORTCUT_ALT_MASK : 0 ); - return sp_shortcut_invoke (shortcut, SP_ACTIVE_DESKTOP); + return sp_shortcut_invoke (shortcut, SP_ACTIVE_DESKTOP); } -Gtk::Window * -Inkscape::UI::window_new (const gchar *title, unsigned int resizeable) +Gtk::Window * Inkscape::UI::window_new (const gchar *title, unsigned int resizeable) { - Gtk::Window *window = new Gtk::Window(Gtk::WINDOW_TOPLEVEL); - window->set_title (title); - window->set_resizable (resizeable); - window->signal_key_press_event().connect(sigc::ptr_fun(&on_window_key_press)); + Gtk::Window *window = new Gtk::Window(Gtk::WINDOW_TOPLEVEL); + window->set_title (title); + window->set_resizable (resizeable); + window->signal_key_press_event().connect(sigc::ptr_fun(&on_window_key_press)); - return window; + return window; } -static gboolean -sp_window_key_press(GtkWidget */*widget*/, GdkEventKey *event) +static gboolean sp_window_key_press(GtkWidget *, GdkEventKey *event) { return on_window_key_press(event); } -GtkWidget * -sp_window_new (const gchar *title, unsigned int resizeable) +GtkWidget * sp_window_new (const gchar *title, unsigned int resizeable) { - GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title ((GtkWindow *) window, title); - gtk_window_set_resizable ((GtkWindow *) window, resizeable); - g_signal_connect_after ((GObject *) window, "key_press_event", (GCallback) sp_window_key_press, NULL); + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title ((GtkWindow *) window, title); + gtk_window_set_resizable ((GtkWindow *) window, resizeable); + g_signal_connect_after ((GObject *) window, "key_press_event", (GCallback) sp_window_key_press, NULL); - return window; + return window; } +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/helper/window.h b/src/helper/window.h index c6807f9e5..a0efcd292 100644 --- a/src/helper/window.h +++ b/src/helper/window.h @@ -1,7 +1,7 @@ -#ifndef __SP_WINDOW_H__ -#define __SP_WINDOW_H__ +#ifndef SEEN_SP_WINDOW_H +#define SEEN_SP_WINDOW_H -/* +/** * Generic window implementation * * Author: @@ -17,10 +17,11 @@ namespace Gtk { class Window; } -/* - * This function is deprecated. Use Inkscape::UI::window_new instead. - */ -GtkWidget *sp_window_new (const gchar *title, unsigned int resizeable); +// Can we just get rid of this altogether? +#if defined(GCC_VERSION) || defined(__clang__) +__attribute__((deprecated)) +#endif +GtkWidget * sp_window_new (const gchar *title, unsigned int resizeable); namespace Inkscape { namespace UI { @@ -30,7 +31,7 @@ Gtk::Window *window_new (const gchar *title, unsigned int resizeable); } } -#endif +#endif // !SEEN_SP_WINDOW_H /* Local Variables: @@ -41,4 +42,4 @@ Gtk::Window *window_new (const gchar *title, unsigned int resizeable); fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/libnrtype/nr-type-primitives.cpp b/src/libnrtype/nr-type-primitives.cpp index 63a3abcc5..3ad4a3771 100644 --- a/src/libnrtype/nr-type-primitives.cpp +++ b/src/libnrtype/nr-type-primitives.cpp @@ -1,6 +1,4 @@ -#define __NR_TYPE_PRIMITIVES_C__ - -/* +/** * Typeface and script library * * Authors: @@ -12,26 +10,27 @@ /* This should be enough for approximately 10000 fonts */ #define NR_DICTSIZE 2777 -#include +#include #include #include + #include "nr-type-primitives.h" /** * An entry in a list of key->value pairs */ struct NRTDEntry { - NRTDEntry *next; - const gchar *key; - void *val; + NRTDEntry *next; + const gchar *key; + void *val; }; /** * Type Dictionary, consisting of size number of key-value entries */ struct NRTypeDict { - unsigned int size; - NRTDEntry **entries; + unsigned int size; + NRTDEntry **entries; }; static NRTDEntry *nr_td_entry_new (void); @@ -42,17 +41,17 @@ static NRTDEntry *nr_td_entry_new (void); void nr_name_list_release (NRNameList *list) { - if (list->destructor) { - list->destructor (list); - } + if (list->destructor) { + list->destructor (list); + } } void nr_style_list_release (NRStyleList *list) { - if (list->destructor) { - list->destructor (list); - } + if (list->destructor) { + list->destructor (list); + } } /** @@ -62,18 +61,18 @@ nr_style_list_release (NRStyleList *list) NRTypeDict * nr_type_dict_new (void) { - NRTypeDict *td; - int i; + NRTypeDict *td; + int i; - td = g_new (NRTypeDict, 1); + td = g_new (NRTypeDict, 1); - td->size = NR_DICTSIZE; - td->entries = g_new (NRTDEntry *, td->size); - for (i = 0; i < NR_DICTSIZE; i++) { - td->entries[i] = NULL; - } + td->size = NR_DICTSIZE; + td->entries = g_new (NRTDEntry *, td->size); + for (i = 0; i < NR_DICTSIZE; i++) { + td->entries[i] = NULL; + } - return td; + return td; } /** @@ -82,15 +81,15 @@ nr_type_dict_new (void) static unsigned int nr_str_hash (const gchar *p) { - unsigned int h; + unsigned int h; - h = *p; + h = *p; - if (h != 0) { - for (p += 1; *p; p++) h = (h << 5) - h + *p; - } + if (h != 0) { + for (p += 1; *p; p++) h = (h << 5) - h + *p; + } - return h; + return h; } /** @@ -99,25 +98,25 @@ nr_str_hash (const gchar *p) void nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val) { - if (key) { - NRTDEntry *tde; - unsigned int hval; - - hval = nr_str_hash (key) % td->size; - - for (tde = td->entries[hval]; tde; tde = tde->next) { - if (!strcmp (key, tde->key)) { - tde->val = val; - return; - } - } - - tde = nr_td_entry_new (); - tde->next = td->entries[hval]; - tde->key = key; - tde->val = val; - td->entries[hval] = tde; - } + if (key) { + NRTDEntry *tde; + unsigned int hval; + + hval = nr_str_hash (key) % td->size; + + for (tde = td->entries[hval]; tde; tde = tde->next) { + if (!strcmp (key, tde->key)) { + tde->val = val; + return; + } + } + + tde = nr_td_entry_new (); + tde->next = td->entries[hval]; + tde->key = key; + tde->val = val; + td->entries[hval] = tde; + } } /** @@ -126,16 +125,16 @@ nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val) void * nr_type_dict_lookup (NRTypeDict *td, const gchar *key) { - if (key) { - NRTDEntry *tde; - unsigned int hval; - hval = nr_str_hash (key) % td->size; - for (tde = td->entries[hval]; tde; tde = tde->next) { - if (!strcmp (key, tde->key)) return tde->val; - } - } - - return NULL; + if (key) { + NRTDEntry *tde; + unsigned int hval; + hval = nr_str_hash (key) % td->size; + for (tde = td->entries[hval]; tde; tde = tde->next) { + if (!strcmp (key, tde->key)) return tde->val; + } + } + + return NULL; } #define NR_TDE_BLOCK_SIZE 32 @@ -148,20 +147,30 @@ static NRTDEntry *nr_tde_free_list; static NRTDEntry * nr_td_entry_new (void) { - NRTDEntry *tde; + NRTDEntry *tde; - if (!nr_tde_free_list) { - int i; - nr_tde_free_list = g_new (NRTDEntry, NR_TDE_BLOCK_SIZE); - for (i = 0; i < (NR_TDE_BLOCK_SIZE - 1); i++) { - nr_tde_free_list[i].next = nr_tde_free_list + i + 1; - } - nr_tde_free_list[i].next = NULL; - } + if (!nr_tde_free_list) { + int i; + nr_tde_free_list = g_new (NRTDEntry, NR_TDE_BLOCK_SIZE); + for (i = 0; i < (NR_TDE_BLOCK_SIZE - 1); i++) { + nr_tde_free_list[i].next = nr_tde_free_list + i + 1; + } + nr_tde_free_list[i].next = NULL; + } - tde = nr_tde_free_list; - nr_tde_free_list = tde->next; + tde = nr_tde_free_list; + nr_tde_free_list = tde->next; - return tde; + return tde; } +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/libnrtype/nr-type-primitives.h b/src/libnrtype/nr-type-primitives.h index 9bb181c4b..863803433 100644 --- a/src/libnrtype/nr-type-primitives.h +++ b/src/libnrtype/nr-type-primitives.h @@ -1,12 +1,12 @@ -#ifndef __NR_TYPE_PRIMITIVES_H__ -#define __NR_TYPE_PRIMITIVES_H__ +#ifndef SEEN_NR_TYPE_PRIMITIVES_H +#define SEEN_NR_TYPE_PRIMITIVES_H -/* +/** * Typeface and script library * * Authors: * Lauris Kaplinski - * g++ port: Nathan Hurst + * c++ port: Nathan Hurst * * This code is in public domain */ @@ -47,4 +47,15 @@ void nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val); void *nr_type_dict_lookup (NRTypeDict *td, const gchar *key); -#endif +#endif // !SEEN_NR_TYPE_PRIMITIVES_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/macros.h b/src/macros.h index b221ebdc2..cbb9bca78 100644 --- a/src/macros.h +++ b/src/macros.h @@ -1,7 +1,7 @@ -#ifndef __MACROS_H__ -#define __MACROS_H__ +#ifndef SEEN_MACROS_H +#define SEEN_MACROS_H -/* +/** * Useful macros for inkscape * * Author: @@ -12,6 +12,9 @@ * Released under GNU GPL */ +// I'm of the opinion that this file should be removed, so I will in the future take the necessary steps to wipe it out. +// Macros are not in general bad, but these particular ones are rather ugly. Especially that sp_round one. --Liam + #ifdef SP_MACROS_SILENT #define SP_PRINT_MATRIX(s,m) #define SP_PRINT_TRANSFORM(s,t) @@ -51,4 +54,4 @@ fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/perspective-line.cpp b/src/perspective-line.cpp index 4fd68f8ed..e6c78403b 100644 --- a/src/perspective-line.cpp +++ b/src/perspective-line.cpp @@ -1,6 +1,4 @@ -#define __PERSPECTIVE_LINE_C__ - -/* +/** * Perspective line for 3D perspectives * * Authors: @@ -40,4 +38,4 @@ PerspectiveLine::PerspectiveLine (Geom::Point const &pt, Proj::Axis const axis, fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/proj_pt.cpp b/src/proj_pt.cpp index 28286948d..f5cca8fca 100644 --- a/src/proj_pt.cpp +++ b/src/proj_pt.cpp @@ -1,6 +1,4 @@ -#define __PROJ_PT_C__ - -/* +/** * 3x4 transformation matrix to map points from projective 3-space into the projective plane * * Authors: @@ -117,4 +115,4 @@ Pt3::coord_string() { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/proj_pt.h b/src/proj_pt.h index 90b9df201..226c182cc 100644 --- a/src/proj_pt.h +++ b/src/proj_pt.h @@ -1,7 +1,4 @@ -#ifndef __PROJ_PT_H__ -#define __PROJ_PT_H__ - -/* +/** * 3x4 transformation matrix to map points from projective 3-space into the projective plane * * Authors: @@ -12,6 +9,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_PROJ_PT_H +#define SEEN_PROJ_PT_H + #include <2geom/point.h> #include @@ -157,7 +157,7 @@ private: } // namespace Proj -#endif /* __PROJ_PT_H__ */ +#endif // !SEEN_PROJ_PT_H /* Local Variables: @@ -168,4 +168,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp index cda59e057..b5c6e4af8 100644 --- a/src/sp-ellipse.cpp +++ b/src/sp-ellipse.cpp @@ -14,26 +14,25 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "svg/svg.h" -#include "svg/path-string.h" -#include "xml/repr.h" -#include "attributes.h" -#include "style.h" -#include "display/curve.h" +#include #include + #include <2geom/angle.h> #include <2geom/ellipse.h> -#include <2geom/transforms.h> -#include <2geom/pathvector.h> #include <2geom/path-sink.h> +#include <2geom/pathvector.h> +#include <2geom/transforms.h> + +#include "attributes.h" +#include "display/curve.h" #include "document.h" -#include "sp-ellipse.h" #include "preferences.h" #include "snap-candidate.h" +#include "sp-ellipse.h" +#include "style.h" +#include "svg/svg.h" +#include "svg/path-string.h" +#include "xml/repr.h" #include "sp-factory.h" @@ -42,21 +41,21 @@ SPObject *create_ellipse() { SPGenericEllipse *ellipse = new SPGenericEllipse(); ellipse->type = SP_GENERIC_ELLIPSE_ELLIPSE; - return (SPObject*)ellipse; + return ellipse; } SPObject *create_circle() { SPGenericEllipse *circle = new SPGenericEllipse(); circle->type = SP_GENERIC_ELLIPSE_CIRCLE; - return (SPObject*)circle; + return circle; } SPObject *create_arc() { SPGenericEllipse *arc = new SPGenericEllipse(); arc->type = SP_GENERIC_ELLIPSE_ARC; - return (SPObject*)arc; + return arc; } bool ellipse_registered = SPFactory::instance().registerObject("svg:ellipse", create_ellipse); @@ -695,4 +694,4 @@ bool SPGenericEllipse::_isSlice() const fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index cb988b8bb..e575b8761 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -1,7 +1,4 @@ -#ifndef __SP_ELLIPSE_H__ -#define __SP_ELLIPSE_H__ - -/* +/** * SVG and related implementations * * Authors: @@ -16,12 +13,15 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_SP_ELLIPSE_H +#define SEEN_SP_ELLIPSE_H + #include "svg/svg-length.h" #include "sp-shape.h" /* Common parent class */ -#define SP_GENERICELLIPSE(obj) (dynamic_cast((SPObject*)obj)) -#define SP_IS_GENERICELLIPSE(obj) (dynamic_cast((SPObject*)obj) != NULL) +#define SP_GENERICELLIPSE(obj) (dynamic_cast(obj)) +#define SP_IS_GENERICELLIPSE(obj) (dynamic_cast((obj)) != NULL) enum GenericEllipseType { SP_GENERIC_ELLIPSE_UNDEFINED, @@ -98,4 +98,4 @@ protected: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/sp-glyph-kerning.cpp b/src/sp-glyph-kerning.cpp index be47c7621..f33d3c509 100644 --- a/src/sp-glyph-kerning.cpp +++ b/src/sp-glyph-kerning.cpp @@ -1,18 +1,12 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#define __SP_ANCHOR_C__ - -/* +/** * SVG and elements implementation * W3C SVG 1.1 spec, page 476, section 20.7 * - * Author: + * Authors: * Felipe C. da S. Sanches * Abhishek Sharma * - * Copyright (C) 2008, Felipe C. da S. Sanches + * Copyright (C) 2008 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -26,45 +20,49 @@ #include -SPGlyphKerning::SPGlyphKerning() : SPObject() { +SPGlyphKerning::SPGlyphKerning() + : SPObject() //TODO: correct these values: - this->u1 = NULL; - this->g1 = NULL; - this->u2 = NULL; - this->g2 = NULL; - this->k = 0; -} - -SPGlyphKerning::~SPGlyphKerning() { + , u1(NULL) + , g1(NULL) + , u2(NULL) + , g2(NULL) + , k(0) +{ } -void SPGlyphKerning::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPObject::build(document, repr); +void SPGlyphKerning::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + SPObject::build(document, repr); - this->readAttr( "u1" ); - this->readAttr( "g1" ); - this->readAttr( "u2" ); - this->readAttr( "g2" ); - this->readAttr( "k" ); + this->readAttr( "u1" ); + this->readAttr( "g1" ); + this->readAttr( "u2" ); + this->readAttr( "g2" ); + this->readAttr( "k" ); } -void SPGlyphKerning::release() { - SPObject::release(); +void SPGlyphKerning::release() +{ + SPObject::release(); } -GlyphNames::GlyphNames(const gchar* value){ +GlyphNames::GlyphNames(const gchar* value) +{ if (value) { - this->names = strdup(value); + names = g_strdup(value); } } -GlyphNames::~GlyphNames(){ - if (this->names) { - g_free(this->names); +GlyphNames::~GlyphNames() +{ + if (names) { + g_free(names); } } -bool GlyphNames::contains(const char* name){ +bool GlyphNames::contains(const char* name) +{ if (!(this->names) || !name) { return false; } @@ -75,14 +73,15 @@ bool GlyphNames::contains(const char* name){ while (is >> str) { if (str == s) { - return true; + return true; } } return false; } -void SPGlyphKerning::set(unsigned int key, const gchar *value) { +void SPGlyphKerning::set(unsigned int key, const gchar *value) +{ switch (key) { case SP_ATTR_U1: { @@ -143,15 +142,16 @@ void SPGlyphKerning::set(unsigned int key, const gchar *value) { } /** - * * Receives update notifications. - * */ -void SPGlyphKerning::update(SPCtx *ctx, guint flags) { + * Receives update notifications. + */ +void SPGlyphKerning::update(SPCtx *ctx, guint flags) +{ if (flags & SP_OBJECT_MODIFIED_FLAG) { /* do something to trigger redisplay, updates? */ - this->readAttr( "u1" ); - this->readAttr( "u2" ); - this->readAttr( "g2" ); - this->readAttr( "k" ); + this->readAttr( "u1" ); + this->readAttr( "u2" ); + this->readAttr( "g2" ); + this->readAttr( "k" ); } SPObject::update(ctx, flags); @@ -159,37 +159,26 @@ void SPGlyphKerning::update(SPCtx *ctx, guint flags) { #define COPY_ATTR(rd,rs,key) (rd)->setAttribute((key), rs->attribute(key)); -Inkscape::XML::Node* SPGlyphKerning::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:glyphkerning");//fix this! - } - - /* I am commenting out this part because I am not certain how does it work. I will have to study it later. Juca - repr->setAttribute("unicode", glyph->unicode); - repr->setAttribute("glyph-name", glyph->glyph_name); - repr->setAttribute("d", glyph->d); - sp_repr_set_svg_double(repr, "orientation", (double) glyph->orientation); - sp_repr_set_svg_double(repr, "arabic-form", (double) glyph->arabic_form); - repr->setAttribute("lang", glyph->lang); - sp_repr_set_svg_double(repr, "horiz-adv-x", glyph->horiz_adv_x); - sp_repr_set_svg_double(repr, "vert-origin-x", glyph->vert_origin_x); - sp_repr_set_svg_double(repr, "vert-origin-y", glyph->vert_origin_y); - sp_repr_set_svg_double(repr, "vert-adv-y", glyph->vert_adv_y); - */ - if (repr != this->getRepr()) { - // All the COPY_ATTR functions below use - // XML Tree directly, while they shouldn't. - COPY_ATTR(repr, this->getRepr(), "u1"); - COPY_ATTR(repr, this->getRepr(), "g1"); - COPY_ATTR(repr, this->getRepr(), "u2"); - COPY_ATTR(repr, this->getRepr(), "g2"); - COPY_ATTR(repr, this->getRepr(), "k"); - } - - SPObject::write(xml_doc, repr, flags); - - return repr; +Inkscape::XML::Node* SPGlyphKerning::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("svg:glyphkerning"); // fix this! + } + + if (repr != this->getRepr()) { + // All the COPY_ATTR functions below use + // XML Tree directly, while they shouldn't. + COPY_ATTR(repr, this->getRepr(), "u1"); + COPY_ATTR(repr, this->getRepr(), "g1"); + COPY_ATTR(repr, this->getRepr(), "u2"); + COPY_ATTR(repr, this->getRepr(), "g2"); + COPY_ATTR(repr, this->getRepr(), "k"); + } + SPObject::write(xml_doc, repr, flags); + + return repr; } + /* Local Variables: mode:c++ diff --git a/src/sp-glyph-kerning.h b/src/sp-glyph-kerning.h index 5cae6b9dd..52413f8a7 100644 --- a/src/sp-glyph-kerning.h +++ b/src/sp-glyph-kerning.h @@ -1,10 +1,3 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef __SP_GLYPH_KERNING_H__ -#define __SP_GLYPH_KERNING_H__ - /* * SVG and elements implementation * @@ -16,41 +9,35 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_SP_GLYPH_KERNING_H +#define SEEN_SP_GLYPH_KERNING_H + #include "sp-object.h" #include "unicoderange.h" -//#define SP_HKERN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_HKERN, SPHkern)) -//#define SP_HKERN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_HKERN, SPGlyphKerningClass)) -//#define SP_IS_HKERN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_HKERN)) -//#define SP_IS_HKERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_HKERN)) +#define SP_HKERN(obj) (dynamic_cast(obj)) +#define SP_IS_HKERN(obj) (dynamic_cast(obj) != NULL) -#define SP_HKERN(obj) (dynamic_cast((SPObject*)obj)) -#define SP_IS_HKERN(obj) (dynamic_cast((SPObject*)obj) != NULL) - -//#define SP_VKERN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_VKERN, SPVkern)) -//#define SP_VKERN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_VKERN, SPGlyphKerningClass)) -//#define SP_IS_VKERN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_VKERN)) -//#define SP_IS_VKERN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_VKERN)) - -#define SP_VKERN(obj) (dynamic_cast((SPObject*)obj)) -#define SP_IS_VKERN(obj) (dynamic_cast((SPObject*)obj) != NULL) +#define SP_VKERN(obj) (dynamic_cast(obj)) +#define SP_IS_VKERN(obj) (dynamic_cast(obj) != NULL) // CPPIFY: These casting macros are buggy, as Vkern and Hkern aren't "real" classes. -class GlyphNames{ +class GlyphNames { public: -GlyphNames(const gchar* value); -~GlyphNames(); -bool contains(const char* name); + GlyphNames(const gchar* value); + ~GlyphNames(); + bool contains(const char* name); private: -gchar* names; + gchar* names; }; class SPGlyphKerning : public SPObject { public: - SPGlyphKerning(); - virtual ~SPGlyphKerning(); + SPGlyphKerning(); + virtual ~SPGlyphKerning() {} + // FIXME encapsulation UnicodeRange* u1; GlyphNames* g1; UnicodeRange* u2; @@ -58,22 +45,30 @@ public: double k; protected: - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void release(); - - virtual void set(unsigned int key, const gchar* value); - - virtual void update(SPCtx* ctx, unsigned int flags); - - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void release(); + virtual void set(unsigned int key, const gchar* value); + virtual void update(SPCtx* ctx, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); }; class SPHkern : public SPGlyphKerning { - + virtual ~SPHkern() {} }; class SPVkern : public SPGlyphKerning { - + virtual ~SPVkern() {} }; -#endif //#ifndef __SP_GLYPH_KERNING_H__ +#endif // !SEEN_SP_GLYPH_KERNING_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/sp-glyph.cpp b/src/sp-glyph.cpp index 695af03ba..eaa69d486 100644 --- a/src/sp-glyph.cpp +++ b/src/sp-glyph.cpp @@ -2,8 +2,6 @@ # include #endif -#define __SP_GLYPH_C__ - /* * SVG element implementation * @@ -25,46 +23,44 @@ #include "sp-factory.h" namespace { - SPObject* createGlyph() { - return new SPGlyph(); - } - - bool glyphRegistered = SPFactory::instance().registerObject("svg:glyph", createGlyph); + SPObject* createGlyph() { + return new SPGlyph(); + } + bool glyphRegistered = SPFactory::instance().registerObject("svg:glyph", createGlyph); } -SPGlyph::SPGlyph() : SPObject() { +SPGlyph::SPGlyph() + : SPObject() //TODO: correct these values: - - this->d = NULL; - this->orientation = GLYPH_ORIENTATION_BOTH; - this->arabic_form = GLYPH_ARABIC_FORM_INITIAL; - this->lang = NULL; - this->horiz_adv_x = 0; - this->vert_origin_x = 0; - this->vert_origin_y = 0; - this->vert_adv_y = 0; -} - -SPGlyph::~SPGlyph() { + , d(NULL) + , orientation(GLYPH_ORIENTATION_BOTH) + , arabic_form(GLYPH_ARABIC_FORM_INITIAL) + , lang(NULL) + , horiz_adv_x(0) + , vert_origin_x(0) + , vert_origin_y(0) + , vert_adv_y(0) +{ } -void SPGlyph::build(SPDocument *document, Inkscape::XML::Node *repr) { - SPObject::build(document, repr); +void SPGlyph::build(SPDocument *document, Inkscape::XML::Node *repr) +{ + SPObject::build(document, repr); - this->readAttr( "unicode" ); - this->readAttr( "glyph-name" ); - this->readAttr( "d" ); - this->readAttr( "orientation" ); - this->readAttr( "arabic-form" ); - this->readAttr( "lang" ); - this->readAttr( "horiz-adv-x" ); - this->readAttr( "vert-origin-x" ); - this->readAttr( "vert-origin-y" ); - this->readAttr( "vert-adv-y" ); + this->readAttr( "unicode" ); + this->readAttr( "glyph-name" ); + this->readAttr( "d" ); + this->readAttr( "orientation" ); + this->readAttr( "arabic-form" ); + this->readAttr( "lang" ); + this->readAttr( "horiz-adv-x" ); + this->readAttr( "vert-origin-x" ); + this->readAttr( "vert-origin-y" ); + this->readAttr( "vert-adv-y" ); } void SPGlyph::release() { - SPObject::release(); + SPObject::release(); } static glyphArabicForm sp_glyph_read_arabic_form(gchar const *value){ @@ -97,7 +93,8 @@ static glyphArabicForm sp_glyph_read_arabic_form(gchar const *value){ return GLYPH_ARABIC_FORM_INITIAL; //TODO: VERIFY DEFAULT! } -static glyphOrientation sp_glyph_read_orientation(gchar const *value){ +static glyphOrientation sp_glyph_read_orientation(gchar const *value) +{ if (!value) { return GLYPH_ORIENTATION_BOTH; } @@ -115,7 +112,8 @@ static glyphOrientation sp_glyph_read_orientation(gchar const *value){ return GLYPH_ORIENTATION_BOTH; } -void SPGlyph::set(unsigned int key, const gchar *value) { +void SPGlyph::set(unsigned int key, const gchar *value) +{ switch (key) { case SP_ATTR_UNICODE: { @@ -228,21 +226,22 @@ void SPGlyph::set(unsigned int key, const gchar *value) { } /** - * * Receives update notifications. - * */ -void SPGlyph::update(SPCtx *ctx, guint flags) { + * Receives update notifications. + */ +void SPGlyph::update(SPCtx *ctx, guint flags) +{ if (flags & SP_OBJECT_MODIFIED_FLAG) { /* do something to trigger redisplay, updates? */ - this->readAttr( "unicode" ); - this->readAttr( "glyph-name" ); - this->readAttr( "d" ); - this->readAttr( "orientation" ); - this->readAttr( "arabic-form" ); - this->readAttr( "lang" ); - this->readAttr( "horiz-adv-x" ); - this->readAttr( "vert-origin-x" ); - this->readAttr( "vert-origin-y" ); - this->readAttr( "vert-adv-y" ); + this->readAttr( "unicode" ); + this->readAttr( "glyph-name" ); + this->readAttr( "d" ); + this->readAttr( "orientation" ); + this->readAttr( "arabic-form" ); + this->readAttr( "lang" ); + this->readAttr( "horiz-adv-x" ); + this->readAttr( "vert-origin-x" ); + this->readAttr( "vert-origin-y" ); + this->readAttr( "vert-adv-y" ); } SPObject::update(ctx, flags); @@ -250,42 +249,45 @@ void SPGlyph::update(SPCtx *ctx, guint flags) { #define COPY_ATTR(rd,rs,key) (rd)->setAttribute((key), rs->attribute(key)); -Inkscape::XML::Node* SPGlyph::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) { - if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { - repr = xml_doc->createElement("svg:glyph"); - } +Inkscape::XML::Node* SPGlyph::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) +{ + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = xml_doc->createElement("svg:glyph"); + } - /* I am commenting out this part because I am not certain how does it work. I will have to study it later. Juca - repr->setAttribute("unicode", glyph->unicode); - repr->setAttribute("glyph-name", glyph->glyph_name); - repr->setAttribute("d", glyph->d); - sp_repr_set_svg_double(repr, "orientation", (double) glyph->orientation); - sp_repr_set_svg_double(repr, "arabic-form", (double) glyph->arabic_form); - repr->setAttribute("lang", glyph->lang); - sp_repr_set_svg_double(repr, "horiz-adv-x", glyph->horiz_adv_x); - sp_repr_set_svg_double(repr, "vert-origin-x", glyph->vert_origin_x); - sp_repr_set_svg_double(repr, "vert-origin-y", glyph->vert_origin_y); - sp_repr_set_svg_double(repr, "vert-adv-y", glyph->vert_adv_y); - */ - if (repr != this->getRepr()) { - // All the COPY_ATTR functions below use - // XML Tree directly while they shouldn't. - COPY_ATTR(repr, this->getRepr(), "unicode"); - COPY_ATTR(repr, this->getRepr(), "glyph-name"); - COPY_ATTR(repr, this->getRepr(), "d"); - COPY_ATTR(repr, this->getRepr(), "orientation"); - COPY_ATTR(repr, this->getRepr(), "arabic-form"); - COPY_ATTR(repr, this->getRepr(), "lang"); - COPY_ATTR(repr, this->getRepr(), "horiz-adv-x"); - COPY_ATTR(repr, this->getRepr(), "vert-origin-x"); - COPY_ATTR(repr, this->getRepr(), "vert-origin-y"); - COPY_ATTR(repr, this->getRepr(), "vert-adv-y"); - } + /* I am commenting out this part because I am not certain how does it work. I will have to study it later. Juca + repr->setAttribute("unicode", glyph->unicode); + repr->setAttribute("glyph-name", glyph->glyph_name); + repr->setAttribute("d", glyph->d); + sp_repr_set_svg_double(repr, "orientation", (double) glyph->orientation); + sp_repr_set_svg_double(repr, "arabic-form", (double) glyph->arabic_form); + repr->setAttribute("lang", glyph->lang); + sp_repr_set_svg_double(repr, "horiz-adv-x", glyph->horiz_adv_x); + sp_repr_set_svg_double(repr, "vert-origin-x", glyph->vert_origin_x); + sp_repr_set_svg_double(repr, "vert-origin-y", glyph->vert_origin_y); + sp_repr_set_svg_double(repr, "vert-adv-y", glyph->vert_adv_y); + */ - SPObject::write(xml_doc, repr, flags); + if (repr != this->getRepr()) { + // All the COPY_ATTR functions below use + // XML Tree directly while they shouldn't. + COPY_ATTR(repr, this->getRepr(), "unicode"); + COPY_ATTR(repr, this->getRepr(), "glyph-name"); + COPY_ATTR(repr, this->getRepr(), "d"); + COPY_ATTR(repr, this->getRepr(), "orientation"); + COPY_ATTR(repr, this->getRepr(), "arabic-form"); + COPY_ATTR(repr, this->getRepr(), "lang"); + COPY_ATTR(repr, this->getRepr(), "horiz-adv-x"); + COPY_ATTR(repr, this->getRepr(), "vert-origin-x"); + COPY_ATTR(repr, this->getRepr(), "vert-origin-y"); + COPY_ATTR(repr, this->getRepr(), "vert-adv-y"); + } - return repr; + SPObject::write(xml_doc, repr, flags); + + return repr; } + /* Local Variables: mode:c++ diff --git a/src/sp-glyph.h b/src/sp-glyph.h index 798d9ff2f..e92357c94 100644 --- a/src/sp-glyph.h +++ b/src/sp-glyph.h @@ -1,13 +1,4 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef __SP_GLYPH_H__ -#define __SP_GLYPH_H__ - -/* - * SVG element implementation - * +/** * Authors: * Felipe C. da S. Sanches * @@ -16,6 +7,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#ifndef SEEN_SP_GLYPH_H +#define SEEN_SP_GLYPH_H + #include "sp-object.h" #define SP_GLYPH(obj) (dynamic_cast((SPObject*)obj)) @@ -34,11 +28,16 @@ enum glyphOrientation { GLYPH_ORIENTATION_BOTH }; +/* + * SVG element + */ + class SPGlyph : public SPObject { public: - SPGlyph(); - virtual ~SPGlyph(); + SPGlyph(); + virtual ~SPGlyph() {} + // FIXME encapsulation Glib::ustring unicode; Glib::ustring glyph_name; char* d; @@ -51,14 +50,23 @@ public: double vert_adv_y; protected: - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void release(); - - virtual void set(unsigned int key, const gchar* value); + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void release(); + virtual void set(unsigned int key, const gchar* value); + virtual void update(SPCtx* ctx, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); - virtual void update(SPCtx* ctx, unsigned int flags); - - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); }; -#endif //#ifndef __SP_GLYPH_H__ +#endif // !SEEN_SP_GLYPH_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/svg/svg-length.cpp b/src/svg/svg-length.cpp index b9e8e6340..b9b475f4b 100644 --- a/src/svg/svg-length.cpp +++ b/src/svg/svg-length.cpp @@ -1,6 +1,4 @@ -#define __SP_SVG_LENGTH_C__ - -/* +/** * SVG data parser * * Authors: @@ -12,20 +10,15 @@ * This code is in public domain */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - +#include #include #include -#include #include #include "svg.h" #include "stringstream.h" #include "util/units.h" - static unsigned sp_svg_length_read_lff(gchar const *str, SVGLength::Unit *unit, float *val, float *computed, char **next); #ifndef MAX @@ -570,4 +563,4 @@ void SVGLength::readOrUnset(gchar const *str, Unit u, float v, float c) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/svg/svg-length.h b/src/svg/svg-length.h index 477b3ef81..c34905d07 100644 --- a/src/svg/svg-length.h +++ b/src/svg/svg-length.h @@ -1,11 +1,4 @@ -#ifndef SEEN_SP_SVG_LENGTH_H -#define SEEN_SP_SVG_LENGTH_H - /** - * \file src/svg/svg-length.h - * \brief SVG length type - */ -/* * Authors: * Lauris Kaplinski * Carl Hetherington @@ -16,10 +9,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#ifndef SEEN_SP_SVG_LENGTH_H +#define SEEN_SP_SVG_LENGTH_H -class SVGLength -{ +/** + * SVG length type + */ +class SVGLength { public: SVGLength(); @@ -57,9 +53,9 @@ public: return v; } - bool read(gchar const *str); - void readOrUnset(gchar const *str, Unit u = NONE, float v = 0, float c = 0); - bool readAbsolute(gchar const *str); + bool read(char const *str); + void readOrUnset(char const *str, Unit u = NONE, float v = 0, float c = 0); + bool readAbsolute(char const *str); void set(Unit u, float v, float c); void unset(Unit u = NONE, float v = 0, float c = 0); void update(double em, double ex, double scale); @@ -76,4 +72,4 @@ public: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/svg/svg-path.cpp b/src/svg/svg-path.cpp index 59dad9ead..9ba3c0ebd 100644 --- a/src/svg/svg-path.cpp +++ b/src/svg/svg-path.cpp @@ -1,41 +1,25 @@ -#define __SP_SVG_PARSE_C__ /* - svg-path.c: Parse SVG path element data into bezier path. - - Copyright (C) 2000 Eazel, Inc. - Copyright (C) 2000 Lauris Kaplinski - Copyright (C) 2001 Ximian, Inc. - Copyright (C) 2008 Johan Engelen - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Authors: - Johan Engelen - (old nartbpath code that has been deleted: Raph Levien ) - (old nartbpath code that has been deleted: Lauris Kaplinski ) -*/ + * svg-path.cpp: Parse SVG path element data into bezier path. + * Authors: + * Johan Engelen + * (old nartbpath code that has been deleted: Raph Levien ) + * (old nartbpath code that has been deleted: Lauris Kaplinski ) + * + * Copyright (C) 2000 Eazel, Inc. + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2008 Johan Engelen + * + * Copyright (C) 2000-2008 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ #include #include #include #include // g_assert() -#include "svg/svg.h" -#include "svg/path-string.h" - #include <2geom/pathvector.h> #include <2geom/path.h> #include <2geom/curves.h> @@ -45,6 +29,9 @@ #include <2geom/exception.h> #include <2geom/angle.h> +#include "svg/svg.h" +#include "svg/path-string.h" + /* * Parses the path in str. When an error is found in the pathstring, this method * returns a truncated path up to where the error was found in the pathstring. @@ -150,4 +137,4 @@ gchar * sp_svg_write_path(Geom::Path const &p) { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/uri-references.cpp b/src/uri-references.cpp index 6db2ed21f..b23bed74a 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -1,6 +1,4 @@ -#define __SP_URI_REFERENCES_C__ - -/* +/** * Helper methods for resolving URI References * * Authors: @@ -206,4 +204,4 @@ sp_uri_reference_resolve (SPDocument *document, const gchar *uri) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/uri-references.h b/src/uri-references.h index 631d440da..f68fe70c4 100644 --- a/src/uri-references.h +++ b/src/uri-references.h @@ -62,7 +62,7 @@ public: * @param rel_document document for relative URIs * @param uri the URI to watch */ - void attach(const URI &uri) throw(BadURIException); + void attach(URI const& uri) throw(BadURIException); /** * Detaches from the currently attached URI target, if any; @@ -105,7 +105,7 @@ public: * * @returns the currently attached URI, or NULL */ - const URI *getURI() const { + URI const* getURI() const { return _uri; } @@ -140,7 +140,7 @@ private: void _setObject(SPObject *object); void _release(SPObject *object); - void operator=(const URIReference &ref); + void operator=(URIReference const& ref); /* Private and definition-less to prevent accidental use. */ }; @@ -164,4 +164,4 @@ SPObject *sp_uri_reference_resolve (SPDocument *document, const gchar *uri); fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index a1bd9b792..04426e734 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -1,6 +1,4 @@ -#define __SP_BUTTON_C__ - -/* +/** * Generic button widget * * Authors: @@ -13,282 +11,255 @@ * This code is in public domain */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "button.h" +#include "helper/action-context.h" #include "icon.h" -#include "shortcuts.h" #include "interface.h" -#include "helper/action-context.h" +#include "shortcuts.h" #include -#include "button.h" - static void sp_button_dispose(GObject *object); -#if GTK_CHECK_VERSION(3,0,0) -static void sp_button_get_preferred_width(GtkWidget *widget, - gint *minimal_width, - gint *natural_width); +#if GTK_CHECK_VERSION(3, 0, 0) +static void sp_button_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width); -static void sp_button_get_preferred_height(GtkWidget *widget, - gint *minimal_height, - gint *natural_height); +static void sp_button_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height); #else -static void sp_button_size_request (GtkWidget *widget, GtkRequisition *requisition); +static void sp_button_size_request(GtkWidget *widget, GtkRequisition *requisition); #endif -static void sp_button_clicked (GtkButton *button); -static void sp_button_perform_action (SPButton *button, gpointer data); -static gint sp_button_process_event (SPButton *button, GdkEvent *event); +static void sp_button_clicked(GtkButton *button); +static void sp_button_perform_action(SPButton *button, gpointer data); +static gint sp_button_process_event(SPButton *button, GdkEvent *event); -static void sp_button_set_action (SPButton *button, SPAction *action); -static void sp_button_set_doubleclick_action (SPButton *button, SPAction *action); -static void sp_button_action_set_active (SPButton *button, bool active); -static void sp_button_set_composed_tooltip (GtkWidget *widget, SPAction *action); +static void sp_button_set_action(SPButton *button, SPAction *action); +static void sp_button_set_doubleclick_action(SPButton *button, SPAction *action); +static void sp_button_action_set_active(SPButton *button, bool active); +static void sp_button_set_composed_tooltip(GtkWidget *widget, SPAction *action); G_DEFINE_TYPE(SPButton, sp_button, GTK_TYPE_TOGGLE_BUTTON); -static void -sp_button_class_init (SPButtonClass *klass) +static void sp_button_class_init(SPButtonClass *klass) { - GObjectClass *object_class=G_OBJECT_CLASS(klass); - GtkWidgetClass *widget_class=GTK_WIDGET_CLASS(klass); - GtkButtonClass *button_class=GTK_BUTTON_CLASS(klass); - - object_class->dispose = sp_button_dispose; -#if GTK_CHECK_VERSION(3,0,0) - widget_class->get_preferred_width = sp_button_get_preferred_width; - widget_class->get_preferred_height = sp_button_get_preferred_height; + GObjectClass *object_class = G_OBJECT_CLASS(klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + GtkButtonClass *button_class = GTK_BUTTON_CLASS(klass); + + object_class->dispose = sp_button_dispose; +#if GTK_CHECK_VERSION(3, 0, 0) + widget_class->get_preferred_width = sp_button_get_preferred_width; + widget_class->get_preferred_height = sp_button_get_preferred_height; #else - widget_class->size_request = sp_button_size_request; + widget_class->size_request = sp_button_size_request; #endif - button_class->clicked = sp_button_clicked; + button_class->clicked = sp_button_clicked; } -static void -sp_button_init (SPButton *button) +static void sp_button_init(SPButton *button) { - button->action = NULL; - button->doubleclick_action = NULL; - new (&button->c_set_active) sigc::connection(); - new (&button->c_set_sensitive) sigc::connection(); + button->action = NULL; + button->doubleclick_action = NULL; + new (&button->c_set_active) sigc::connection(); + new (&button->c_set_sensitive) sigc::connection(); - gtk_container_set_border_width (GTK_CONTAINER (button), 0); + gtk_container_set_border_width(GTK_CONTAINER(button), 0); - gtk_widget_set_can_focus (GTK_WIDGET (button), FALSE); - gtk_widget_set_can_default (GTK_WIDGET (button), FALSE); + gtk_widget_set_can_focus(GTK_WIDGET(button), FALSE); + gtk_widget_set_can_default(GTK_WIDGET(button), FALSE); - g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (sp_button_perform_action), NULL); - g_signal_connect_after (G_OBJECT (button), "event", G_CALLBACK (sp_button_process_event), NULL); + g_signal_connect_after(G_OBJECT(button), "clicked", G_CALLBACK(sp_button_perform_action), NULL); + g_signal_connect_after(G_OBJECT(button), "event", G_CALLBACK(sp_button_process_event), NULL); } static void sp_button_dispose(GObject *object) { - SPButton *button = SP_BUTTON (object); + SPButton *button = SP_BUTTON(object); - if (button->action) { - sp_button_set_action (button, NULL); - } - if (button->doubleclick_action) { - sp_button_set_doubleclick_action (button, NULL); - } + if (button->action) { + sp_button_set_action(button, NULL); + } + if (button->doubleclick_action) { + sp_button_set_doubleclick_action(button, NULL); + } - button->c_set_active.~connection(); - button->c_set_sensitive.~connection(); + button->c_set_active.~connection(); + button->c_set_sensitive.~connection(); - (G_OBJECT_CLASS(sp_button_parent_class))->dispose(object); + (G_OBJECT_CLASS(sp_button_parent_class))->dispose(object); } - - -#if GTK_CHECK_VERSION(3,0,0) +#if GTK_CHECK_VERSION(3, 0, 0) static void sp_button_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width) { - GtkWidget *child = gtk_bin_get_child(GTK_BIN (widget)); - GtkStyle *style = gtk_widget_get_style(widget); - - if (child) { - gtk_widget_get_preferred_width(GTK_WIDGET(child), minimal_width, natural_width); - } else { - *minimal_width = 0; - *natural_width = 0; - } - - *minimal_width += 2 + 2 * MAX(2, style->xthickness); - *natural_width += 2 + 2 * MAX(2, style->xthickness); + GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); + GtkStyle *style = gtk_widget_get_style(widget); + + if (child) { + gtk_widget_get_preferred_width(GTK_WIDGET(child), minimal_width, natural_width); + } else { + *minimal_width = 0; + *natural_width = 0; + } + + *minimal_width += 2 + 2 * MAX(2, style->xthickness); + *natural_width += 2 + 2 * MAX(2, style->xthickness); } static void sp_button_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height) { - GtkWidget *child = gtk_bin_get_child(GTK_BIN (widget)); - GtkStyle *style = gtk_widget_get_style(widget); - - if (child) { - gtk_widget_get_preferred_height(GTK_WIDGET(child), minimal_height, natural_height); - } else { - *minimal_height = 0; - *natural_height = 0; - } + GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); + GtkStyle *style = gtk_widget_get_style(widget); - *minimal_height += 2 + 2 * MAX(2, style->ythickness); - *natural_height += 2 + 2 * MAX(2, style->ythickness); + if (child) { + gtk_widget_get_preferred_height(GTK_WIDGET(child), minimal_height, natural_height); + } else { + *minimal_height = 0; + *natural_height = 0; + } + *minimal_height += 2 + 2 * MAX(2, style->ythickness); + *natural_height += 2 + 2 * MAX(2, style->ythickness); } #else static void sp_button_size_request(GtkWidget *widget, GtkRequisition *requisition) { - GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget)); - GtkStyle *style = gtk_widget_get_style (widget); - - if (child) { - gtk_widget_size_request (GTK_WIDGET (child), requisition); - } else { - requisition->width = 0; - requisition->height = 0; - } - - requisition->width += 2 + 2 * MAX (2, style->xthickness); - requisition->height += 2 + 2 * MAX (2, style->ythickness); + GtkWidget *child = gtk_bin_get_child(GTK_BIN(widget)); + GtkStyle *style = gtk_widget_get_style(widget); + + if (child) { + gtk_widget_size_request(GTK_WIDGET(child), requisition); + } else { + requisition->width = 0; + requisition->height = 0; + } + + requisition->width += 2 + 2 * MAX(2, style->xthickness); + requisition->height += 2 + 2 * MAX(2, style->ythickness); } #endif -static void -sp_button_clicked (GtkButton *button) +static void sp_button_clicked(GtkButton *button) { - SPButton *sp_button=SP_BUTTON (button); + SPButton *sp_button = SP_BUTTON(button); - if (sp_button->type == SP_BUTTON_TYPE_TOGGLE) { - (GTK_BUTTON_CLASS(sp_button_parent_class))->clicked (button); - } + if (sp_button->type == SP_BUTTON_TYPE_TOGGLE) { + (GTK_BUTTON_CLASS(sp_button_parent_class))->clicked(button); + } } -static gint -sp_button_process_event (SPButton *button, GdkEvent *event) +static gint sp_button_process_event(SPButton *button, GdkEvent *event) { - switch (event->type) { - case GDK_2BUTTON_PRESS: - if (button->doubleclick_action) { - sp_action_perform (button->doubleclick_action, NULL); - } - return TRUE; - break; - default: - break; - } - - return FALSE; + switch (event->type) { + case GDK_2BUTTON_PRESS: + if (button->doubleclick_action) { + sp_action_perform(button->doubleclick_action, NULL); + } + return TRUE; + break; + default: + break; + } + + return FALSE; } -static void -sp_button_perform_action (SPButton *button, gpointer /*data*/) +static void sp_button_perform_action(SPButton *button, gpointer /*data*/) { - if (button->action) { - sp_action_perform (button->action, NULL); - } + if (button->action) { + sp_action_perform(button->action, NULL); + } } - -GtkWidget * -sp_button_new( Inkscape::IconSize size, SPButtonType type, SPAction *action, SPAction *doubleclick_action ) +GtkWidget *sp_button_new(Inkscape::IconSize size, SPButtonType type, SPAction *action, SPAction *doubleclick_action) { - SPButton *button = SP_BUTTON(g_object_new(SP_TYPE_BUTTON, NULL)); + SPButton *button = SP_BUTTON(g_object_new(SP_TYPE_BUTTON, NULL)); - button->type = type; - button->lsize = CLAMP( size, Inkscape::ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION ); + button->type = type; + button->lsize = CLAMP(size, Inkscape::ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION); - sp_button_set_action (button, action); - if (doubleclick_action) - sp_button_set_doubleclick_action (button, doubleclick_action); + sp_button_set_action(button, action); + if (doubleclick_action) + sp_button_set_doubleclick_action(button, doubleclick_action); - // The Inkscape style is no-relief buttons - gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + // The Inkscape style is no-relief buttons + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - return GTK_WIDGET(button); + return GTK_WIDGET(button); } -void -sp_button_toggle_set_down (SPButton *button, gboolean down) +void sp_button_toggle_set_down(SPButton *button, gboolean down) { - g_return_if_fail (button->type == SP_BUTTON_TYPE_TOGGLE); - g_signal_handlers_block_by_func (G_OBJECT (button), (gpointer)G_CALLBACK (sp_button_perform_action), NULL); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), (unsigned int)down); - g_signal_handlers_unblock_by_func (G_OBJECT (button), (gpointer)G_CALLBACK (sp_button_perform_action), NULL); + g_return_if_fail(button->type == SP_BUTTON_TYPE_TOGGLE); + g_signal_handlers_block_by_func(G_OBJECT(button), (gpointer)G_CALLBACK(sp_button_perform_action), NULL); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), (unsigned int)down); + g_signal_handlers_unblock_by_func(G_OBJECT(button), (gpointer)G_CALLBACK(sp_button_perform_action), NULL); } -static void -sp_button_set_doubleclick_action (SPButton *button, SPAction *action) +static void sp_button_set_doubleclick_action(SPButton *button, SPAction *action) { - if (button->doubleclick_action) { - g_object_unref (button->doubleclick_action); - } - button->doubleclick_action = action; - if (action) { - g_object_ref(action); - } - + if (button->doubleclick_action) { + g_object_unref(button->doubleclick_action); + } + button->doubleclick_action = action; + if (action) { + g_object_ref(action); + } } -static void -sp_button_set_action (SPButton *button, SPAction *action) +static void sp_button_set_action(SPButton *button, SPAction *action) { - GtkWidget *child; - - if (button->action) { - button->c_set_active.disconnect(); - button->c_set_sensitive.disconnect(); - child = gtk_bin_get_child (GTK_BIN (button)); - if (child) { - gtk_container_remove (GTK_CONTAINER (button), child); - } - g_object_unref(button->action); - } - button->action = action; - if (action) { - g_object_ref(action); - button->c_set_active = action->signal_set_active.connect( - sigc::bind<0>( - sigc::ptr_fun(&sp_button_action_set_active), - SP_BUTTON(button))); - button->c_set_sensitive = action->signal_set_sensitive.connect( - sigc::bind<0>( - sigc::ptr_fun(>k_widget_set_sensitive), - GTK_WIDGET(button))); - if (action->image) { - child = sp_icon_new (button->lsize, action->image); - gtk_widget_show (child); - gtk_container_add (GTK_CONTAINER (button), child); - } - } - - sp_button_set_composed_tooltip(GTK_WIDGET(button), action); + GtkWidget *child; + + if (button->action) { + button->c_set_active.disconnect(); + button->c_set_sensitive.disconnect(); + child = gtk_bin_get_child(GTK_BIN(button)); + if (child) { + gtk_container_remove(GTK_CONTAINER(button), child); + } + g_object_unref(button->action); + } + button->action = action; + if (action) { + g_object_ref(action); + button->c_set_active = action->signal_set_active.connect( + sigc::bind<0>(sigc::ptr_fun(&sp_button_action_set_active), SP_BUTTON(button))); + button->c_set_sensitive = action->signal_set_sensitive.connect( + sigc::bind<0>(sigc::ptr_fun(>k_widget_set_sensitive), GTK_WIDGET(button))); + if (action->image) { + child = sp_icon_new(button->lsize, action->image); + gtk_widget_show(child); + gtk_container_add(GTK_CONTAINER(button), child); + } + } + + sp_button_set_composed_tooltip(GTK_WIDGET(button), action); } -static void -sp_button_action_set_active (SPButton *button, bool active) +static void sp_button_action_set_active(SPButton *button, bool active) { - if (button->type != SP_BUTTON_TYPE_TOGGLE) { - return; - } - - /* temporarily lobotomized until SPActions are per-view */ - if (0 && !active != !SP_BUTTON_IS_DOWN (button)) { - sp_button_toggle_set_down (button, active); - } + if (button->type != SP_BUTTON_TYPE_TOGGLE) { + return; + } + + /* temporarily lobotomized until SPActions are per-view */ + if (0 && !active != !SP_BUTTON_IS_DOWN(button)) { + sp_button_toggle_set_down(button, active); + } } static void sp_button_set_composed_tooltip(GtkWidget *widget, SPAction *action) { if (action) { - unsigned int shortcut = sp_shortcut_get_primary (action->verb); + unsigned int shortcut = sp_shortcut_get_primary(action->verb); if (shortcut != GDK_KEY_VoidSymbol) { // there's both action and shortcut gchar *key = sp_shortcut_get_label(shortcut); - gchar *tip = g_strdup_printf ("%s (%s)", action->tip, key); + gchar *tip = g_strdup_printf("%s (%s)", action->tip, key); gtk_widget_set_tooltip_text(widget, tip); g_free(tip); g_free(key); @@ -302,18 +273,14 @@ static void sp_button_set_composed_tooltip(GtkWidget *widget, SPAction *action) } } -GtkWidget * -sp_button_new_from_data( Inkscape::IconSize size, - SPButtonType type, - Inkscape::UI::View::View *view, - const gchar *name, - const gchar *tip ) +GtkWidget *sp_button_new_from_data(Inkscape::IconSize size, SPButtonType type, Inkscape::UI::View::View *view, + const gchar *name, const gchar *tip) { - GtkWidget *button; - SPAction *action=sp_action_new(Inkscape::ActionContext(view), name, name, tip, name, 0); - button = sp_button_new (size, type, action, NULL); - g_object_unref(action); - return button; + GtkWidget *button; + SPAction *action = sp_action_new(Inkscape::ActionContext(view), name, name, tip, name, 0); + button = sp_button_new(size, type, action, NULL); + g_object_unref(action); + return button; } /* @@ -325,4 +292,4 @@ sp_button_new_from_data( Inkscape::IconSize size, fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/button.h b/src/widgets/button.h index 41863357d..d5e29da1a 100644 --- a/src/widgets/button.h +++ b/src/widgets/button.h @@ -1,7 +1,7 @@ -#ifndef __SP_BUTTON_H__ -#define __SP_BUTTON_H__ +#ifndef SEEN_SP_BUTTON_H +#define SEEN_SP_BUTTON_H -/* +/** * Generic button widget * * Author: @@ -61,6 +61,15 @@ GtkWidget *sp_button_new_from_data (Inkscape::IconSize size, const gchar *name, const gchar *tip); +#endif // !SEEN_SP_BUTTON_H - -#endif +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 327349844..d4a174a0d 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -1,6 +1,4 @@ -#define __SP_FONT_SELECTOR_C__ - -/* +/** * Font selection widgets * * Authors: @@ -554,4 +552,4 @@ double sp_font_selector_get_size(SPFontSelector *fsel) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/font-selector.h b/src/widgets/font-selector.h index 66715f048..ff5472d2d 100644 --- a/src/widgets/font-selector.h +++ b/src/widgets/font-selector.h @@ -54,7 +54,7 @@ Glib::ustring sp_font_selector_get_fontspec (SPFontSelector *fsel); double sp_font_selector_get_size (SPFontSelector *fsel); -#endif // SP_FONT_SELECTOR_H +#endif // !SP_FONT_SELECTOR_H /* Local Variables: @@ -65,4 +65,4 @@ double sp_font_selector_get_size (SPFontSelector *fsel); fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp index 64b058f62..2e2c5423b 100644 --- a/src/widgets/gradient-image.cpp +++ b/src/widgets/gradient-image.cpp @@ -1,6 +1,4 @@ -#define __SP_GRADIENT_IMAGE_C__ - -/* +/** * A simple gradient preview * * Author: @@ -12,14 +10,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "macros.h" +#include + #include "display/cairo-utils.h" #include "gradient-image.h" +#include "macros.h" #include "sp-gradient.h" -#include -#include - #define VBLOCK 16 static void sp_gradient_image_class_init (SPGradientImageClass *klass); @@ -269,3 +266,14 @@ sp_gradient_image_update (SPGradientImage *image) gtk_widget_queue_draw (GTK_WIDGET (image)); } } + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/gradient-image.h b/src/widgets/gradient-image.h index 904ce4cac..cd7e0ed70 100644 --- a/src/widgets/gradient-image.h +++ b/src/widgets/gradient-image.h @@ -1,7 +1,7 @@ -#ifndef __SP_GRADIENT_IMAGE_H__ -#define __SP_GRADIENT_IMAGE_H__ +#ifndef SEEN_SP_GRADIENT_IMAGE_H +#define SEEN_SP_GRADIENT_IMAGE_H -/* +/** * A simple gradient preview * * Author: @@ -29,15 +29,15 @@ class SPGradient; #define SP_IS_GRADIENT_IMAGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_GRADIENT_IMAGE)) struct SPGradientImage { - GtkWidget widget; - SPGradient *gradient; + GtkWidget widget; + SPGradient *gradient; - sigc::connection release_connection; - sigc::connection modified_connection; + sigc::connection release_connection; + sigc::connection modified_connection; }; struct SPGradientImageClass { - GtkWidgetClass parent_class; + GtkWidgetClass parent_class; }; GType sp_gradient_image_get_type (void); @@ -47,3 +47,14 @@ GdkPixbuf *sp_gradient_to_pixbuf (SPGradient *gr, int width, int height); void sp_gradient_image_set_gradient (SPGradientImage *gi, SPGradient *gr); #endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/sp-xmlview-tree.cpp b/src/widgets/sp-xmlview-tree.cpp index 43b7dc289..9b3775a34 100644 --- a/src/widgets/sp-xmlview-tree.cpp +++ b/src/widgets/sp-xmlview-tree.cpp @@ -1,6 +1,4 @@ -#define __SP_XMLVIEW_TREE_C__ - -/* +/** * Specialization of GtkTreeView for the XML tree view * * Authors: @@ -14,7 +12,7 @@ #include #include -#include "../xml/node-event-vector.h" +#include "xml/node-event-vector.h" #include "sp-xmlview-tree.h" struct NodeData { @@ -734,4 +732,4 @@ gboolean search_equal_func(GtkTreeModel *model, gint /*column*/, const gchar *ke fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/widgets/sp-xmlview-tree.h b/src/widgets/sp-xmlview-tree.h index 69228fa88..7ecbcb471 100644 --- a/src/widgets/sp-xmlview-tree.h +++ b/src/widgets/sp-xmlview-tree.h @@ -1,9 +1,4 @@ -#ifndef __SP_XMLVIEW_TREE_H__ -#define __SP_XMLVIEW_TREE_H__ - -/* - * Specialization of GtkTreeView for the XML editor - * +/** * Authors: * MenTaLguY * @@ -12,9 +7,15 @@ * Released under the GNU GPL; see COPYING for details */ +#ifndef SEEN_SP_XMLVIEW_TREE_H +#define SEEN_SP_XMLVIEW_TREE_H + #include #include +/** + * Specialization of GtkTreeView for the XML editor + */ #define SP_TYPE_XMLVIEW_TREE (sp_xmlview_tree_get_type ()) #define SP_XMLVIEW_TREE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_XMLVIEW_TREE, SPXMLViewTree)) @@ -49,7 +50,7 @@ Inkscape::XML::Node * sp_xmlview_tree_node_get_repr (GtkTreeModel *model, GtkTre gboolean sp_xmlview_tree_get_repr_node (SPXMLViewTree * tree, Inkscape::XML::Node * repr, GtkTreeIter *node); -#endif +#endif // !SEEN_SP_XMLVIEW_TREE_H /* Local Variables: @@ -60,4 +61,4 @@ gboolean sp_xmlview_tree_get_repr_node (SPXMLViewTree * tree, Inkscape::XML::Nod fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : -- cgit v1.2.3 From a5e84125b62bf41871b57d93e457db81ee139485 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 18 Aug 2014 17:18:05 -0400 Subject: Fix build (not pretty). (bzr r13341.1.146) --- src/desktop-style.cpp | 1 + src/display/cairo-templates.h | 3 ++- src/display/cairo-utils.h | 2 +- src/display/canvas-arena.cpp | 2 +- src/display/drawing-group.cpp | 3 ++- src/display/drawing-image.cpp | 4 +++- src/display/drawing-item.cpp | 6 ++++-- src/display/drawing-shape.cpp | 2 +- src/display/drawing-text.cpp | 7 +++++-- src/display/nr-filter-blend.cpp | 1 + src/display/nr-filter-primitive.h | 1 + src/display/nr-filter.cpp | 2 +- src/extension/implementation/script.cpp | 4 ++-- src/filter-chemistry.cpp | 2 ++ src/filter-enums.cpp | 1 + src/filter-enums.h | 2 ++ src/help.cpp | 6 +++++- src/sp-filter-primitive.cpp | 5 +++-- src/sp-filter.cpp | 5 ++--- src/sp-image.cpp | 1 + src/sp-mesh-array.cpp | 14 +++++++------- src/sp-mesh-gradient.cpp | 6 +++--- src/sp-pattern.cpp | 2 ++ src/svg-view-widget.cpp | 2 +- src/widgets/button.cpp | 4 ++-- src/widgets/gradient-image.cpp | 2 +- src/widgets/icon.h | 8 -------- 27 files changed, 57 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index f6347e5c0..91359983b 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -14,6 +14,7 @@ #include #include +#include #include "desktop.h" #include "color-rgba.h" diff --git a/src/display/cairo-templates.h b/src/display/cairo-templates.h index 57ec98f81..a49f925c3 100644 --- a/src/display/cairo-templates.h +++ b/src/display/cairo-templates.h @@ -16,6 +16,8 @@ #include "config.h" #endif +#include + #ifdef HAVE_OPENMP #include #include "preferences.h" @@ -25,7 +27,6 @@ static const int OPENMP_THRESHOLD = 2048; #include #include -#include #include #include "display/nr-3dutils.h" #include "display/cairo-utils.h" diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 505e2ca77..f252c4a44 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -14,7 +14,7 @@ #include //#include // workaround -#include +//#include #include //#include #include <2geom/forward.h> diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 25d35fc6b..e82b1b1c7 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -11,7 +11,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include #include "display/sp-canvas-util.h" #include "helper/sp-marshal.h" diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index 38ace001f..bce89d70e 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -9,13 +9,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "display/cairo-utils.h" #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-item.h" #include "display/drawing-group.h" #include "style.h" +#include "display/cairo-utils.h" + namespace Inkscape { DrawingGroup::DrawingGroup(Drawing &drawing) diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 00caef525..e56f3e58b 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -10,13 +10,15 @@ */ #include <2geom/bezier-curve.h> -#include "display/cairo-utils.h" + #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-image.h" #include "preferences.h" #include "style.h" +#include "display/cairo-utils.h" + namespace Inkscape { DrawingImage::DrawingImage(Drawing &drawing) diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index 80eb69546..bd6fb41d8 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -10,8 +10,7 @@ */ #include -#include "display/cairo-utils.h" -#include "display/cairo-templates.h" + #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-item.h" @@ -21,6 +20,9 @@ #include "preferences.h" #include "style.h" +#include "display/cairo-utils.h" +#include "display/cairo-templates.h" + namespace Inkscape { void set_cairo_blend_operator( DrawingContext &dc, unsigned blend_mode ) { diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index 1a41bdb3a..88506f2b9 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -9,7 +9,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include #include <2geom/curves.h> #include <2geom/pathvector.h> #include <2geom/path-sink.h> diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index 9f3b447df..97a8c23d3 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -9,8 +9,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "display/cairo-utils.h" -#include "display/canvas-bpath.h" // for SPWindRule (WTF!) +//#include "display/cairo-utils.h" +//#include "display/canvas-bpath.h" // for SPWindRule (WTF!) #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-surface.h" @@ -20,6 +20,9 @@ #include "style.h" #include "2geom/pathvector.h" +#include "display/cairo-utils.h" +#include "display/canvas-bpath.h" + namespace Inkscape { diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp index 25aea6f13..d0db6b42e 100644 --- a/src/display/nr-filter-blend.cpp +++ b/src/display/nr-filter-blend.cpp @@ -20,6 +20,7 @@ #include "config.h" #endif +#include #include "display/cairo-templates.h" #include "display/cairo-utils.h" #include "display/nr-filter-blend.h" diff --git a/src/display/nr-filter-primitive.h b/src/display/nr-filter-primitive.h index 214b2cfc5..62f350844 100644 --- a/src/display/nr-filter-primitive.h +++ b/src/display/nr-filter-primitive.h @@ -11,6 +11,7 @@ #ifndef SEEN_NR_FILTER_PRIMITIVE_H #define SEEN_NR_FILTER_PRIMITIVE_H +#include #include <2geom/forward.h> #include <2geom/rect.h> #include "display/nr-filter-types.h" diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 90b233fbc..dec5b1f57 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -9,7 +9,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "display/nr-filter-image.h" #include #include #include @@ -29,6 +28,7 @@ #include "display/nr-filter-component-transfer.h" #include "display/nr-filter-diffuselighting.h" #include "display/nr-filter-displacement-map.h" +#include "display/nr-filter-image.h" #include "display/nr-filter-flood.h" #include "display/nr-filter-gaussian.h" #include "display/nr-filter-merge.h" diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index e7d6e64ce..70a2ca672 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include "desktop-handles.h" #include "desktop.h" @@ -37,7 +37,7 @@ #include "script.h" #include "selection.h" #include "sp-namedview.h" -#include "system.h" +#include "extension/system.h" #include "ui/view/view.h" #include "xml/node.h" #include "xml/attribute-record.h" diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index 151480177..9298a1ffc 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -15,6 +15,8 @@ #include +#include + #include "style.h" #include "document-private.h" #include "desktop-style.h" diff --git a/src/filter-enums.cpp b/src/filter-enums.cpp index 09a1a7614..037c66922 100644 --- a/src/filter-enums.cpp +++ b/src/filter-enums.cpp @@ -9,6 +9,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include #include "filter-enums.h" diff --git a/src/filter-enums.h b/src/filter-enums.h index 3ced5ab94..e6d656f8a 100644 --- a/src/filter-enums.h +++ b/src/filter-enums.h @@ -12,6 +12,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + #include "display/nr-filter-blend.h" #include "display/nr-filter-colormatrix.h" #include "display/nr-filter-component-transfer.h" diff --git a/src/help.cpp b/src/help.cpp index 60e57abfc..643945a69 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -11,7 +11,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include #include "file.h" #include "help.h" diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index ceb91c984..1f85c8193 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -19,14 +19,15 @@ #include +#include "display/nr-filter-primitive.h" +#include "display/nr-filter-types.h" + #include "attributes.h" #include "style.h" #include "sp-filter-primitive.h" #include "xml/repr.h" #include "sp-filter.h" #include "sp-item.h" -#include "display/nr-filter-primitive.h" -#include "display/nr-filter-types.h" // CPPIFY: Make pure virtual. diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index e8319baca..9a184952c 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -22,8 +22,9 @@ using std::map; using std::pair; -#include +#include #include "attributes.h" +#include "display/nr-filter.h" #include "document.h" #include "sp-filter.h" #include "sp-filter-reference.h" @@ -37,8 +38,6 @@ using std::pair; #define SP_MACROS_SILENT #include "macros.h" -#include "display/nr-filter.h" - static void filter_ref_changed(SPObject *old_ref, SPObject *ref, SPFilter *filter); static void filter_ref_modified(SPObject *href, guint flags, SPFilter *filter); diff --git a/src/sp-image.cpp b/src/sp-image.cpp index cb8ede2b2..b6177fae6 100644 --- a/src/sp-image.cpp +++ b/src/sp-image.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include <2geom/rect.h> #include <2geom/transforms.h> diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index ab14e75d2..300f2ad19 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -37,6 +37,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +// For color picking +#include "display/drawing.h" +#include "display/drawing-context.h" +#include "display/cairo-utils.h" +#include "document.h" +#include "sp-root.h" + #include "sp-mesh-array.h" #include "sp-mesh-gradient.h" #include "sp-mesh-row.h" @@ -51,13 +58,6 @@ // For writing color/opacity to style #include "svg/css-ostringstream.h" -// For color picking -#include "display/drawing.h" -#include "display/drawing-context.h" -#include "display/cairo-utils.h" -#include "document.h" -#include "sp-root.h" - // For default color #include "style.h" #include "svg/svg-color.h" diff --git a/src/sp-mesh-gradient.cpp b/src/sp-mesh-gradient.cpp index eb5ed1bd0..1b04a6f8e 100644 --- a/src/sp-mesh-gradient.cpp +++ b/src/sp-mesh-gradient.cpp @@ -1,8 +1,8 @@ -#include "sp-mesh-gradient.h" - #include "attributes.h" -#include "xml/repr.h" #include "display/cairo-utils.h" +#include "xml/repr.h" + +#include "sp-mesh-gradient.h" #include "sp-factory.h" diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 9b7330a24..961ab0f84 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -18,7 +18,9 @@ #include #include +#include #include <2geom/transforms.h> + #include "macros.h" #include "svg/svg.h" #include "display/cairo-utils.h" diff --git a/src/svg-view-widget.cpp b/src/svg-view-widget.cpp index 567156fec..9174d1083 100644 --- a/src/svg-view-widget.cpp +++ b/src/svg-view-widget.cpp @@ -14,7 +14,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include #include "display/sp-canvas.h" #include "display/sp-canvas-group.h" #include "display/canvas-arena.h" diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index 04426e734..63bb390fb 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -11,10 +11,10 @@ * This code is in public domain */ -#include "button.h" +#include "icon.h" +#include "button.h" #include "helper/action-context.h" -#include "icon.h" #include "interface.h" #include "shortcuts.h" diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp index 2e2c5423b..1b7d4f8a1 100644 --- a/src/widgets/gradient-image.cpp +++ b/src/widgets/gradient-image.cpp @@ -10,7 +10,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include #include "display/cairo-utils.h" #include "gradient-image.h" diff --git a/src/widgets/icon.h b/src/widgets/icon.h index e1dae0d6a..5838d8de4 100644 --- a/src/widgets/icon.h +++ b/src/widgets/icon.h @@ -14,14 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include "icon-size.h" -- cgit v1.2.3 From e51ba41566f57ebd0a5458188373b837c4d6d55e Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Mon, 18 Aug 2014 18:11:21 -0400 Subject: Fix gtk3 build (bzr r13341.1.147) --- src/widgets/button.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index 63bb390fb..f97bba072 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -11,6 +11,7 @@ * This code is in public domain */ +#include #include "icon.h" #include "button.h" -- cgit v1.2.3 From 490eb1e7f52f50d9d9a531c2a54a5d9616ff50bf Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Tue, 19 Aug 2014 17:24:08 -0400 Subject: Clear the waiting cursor on the old desktop after creating a new one (bzr r13528) --- src/file.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/file.cpp b/src/file.cpp index 580c93c9e..200077de5 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -148,14 +148,14 @@ SPDesktop *sp_file_new(const std::string &templ) DocumentUndo::setUndoSensitive(doc, true); } - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - desktop->setWaitingCursor(); + SPDesktop *olddesktop = SP_ACTIVE_DESKTOP; + if (olddesktop) + olddesktop->setWaitingCursor(); SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); // TODO this will trigger broken link warnings, etc. g_return_val_if_fail(dtw != NULL, NULL); sp_create_window(dtw, TRUE); - desktop = static_cast(dtw->view); + SPDesktop* desktop = static_cast(dtw->view); doc->doUnref(); @@ -166,6 +166,8 @@ SPDesktop *sp_file_new(const std::string &templ) Inkscape::Extension::Dbus::dbus_init_desktop_interface(desktop); #endif + if (olddesktop) + olddesktop->clearWaitingCursor(); if (desktop) desktop->clearWaitingCursor(); -- cgit v1.2.3 From 8c009ccdce90c5198260e12ffac837bfdf9b26b7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 20 Aug 2014 13:51:41 +0200 Subject: Implement SVG2 marker 'orient' attribute value 'auto-start-reverse' (rendering only). (bzr r13341.1.148) --- src/extension/internal/cairo-renderer.cpp | 12 +++++---- src/marker.cpp | 41 +++++++++++++++++++------------ src/marker.h | 8 +++++- src/sp-shape.cpp | 20 ++++++++++----- 4 files changed, 53 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 6fbc85c05..0fec68c06 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -202,8 +202,10 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) if ( shape->_marker[i] ) { SPMarker* marker = SP_MARKER (shape->_marker[i]); Geom::Affine tr; - if (marker->orient_auto) { + if (marker->orient_mode == MARKER_ORIENT_AUTO) { tr = sp_shape_marker_get_transform_at_start(pathv.begin()->front()); + } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + tr = Geom::Rotate::from_degrees( 180.0 ) * sp_shape_marker_get_transform_at_start(pathv.begin()->front()); } else { tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(pathv.begin()->front().pointAt(0)); } @@ -220,7 +222,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) && ! ((path_it == (pathv.end()-1)) && (path_it->size_default() == 0)) ) // if this is the last path and it is a moveto-only, there is no mid marker there { Geom::Affine tr; - if (marker->orient_auto) { + if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_start(path_it->front()); } else { tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(path_it->front().pointAt(0)); @@ -237,7 +239,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) * Loop to end_default (so including closing segment), because when a path is closed, * there should be a midpoint marker between last segment and closing straight line segment */ Geom::Affine tr; - if (marker->orient_auto) { + if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform(*curve_it1, *curve_it2); } else { tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(curve_it1->pointAt(1)); @@ -253,7 +255,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) if ( path_it != (pathv.end()-1) && !path_it->empty()) { Geom::Curve const &lastcurve = path_it->back_default(); Geom::Affine tr; - if (marker->orient_auto) { + if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); @@ -277,7 +279,7 @@ static void sp_shape_render (SPItem *item, CairoRenderContext *ctx) Geom::Curve const &lastcurve = path_last[index]; Geom::Affine tr; - if (marker->orient_auto) { + if (marker->orient_mode != MARKER_ORIENT_ANGLE) { tr = sp_shape_marker_get_transform_at_end(lastcurve); } else { tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(lastcurve.pointAt(1)); diff --git a/src/marker.cpp b/src/marker.cpp index 7fee16ead..a4cbc30ca 100644 --- a/src/marker.cpp +++ b/src/marker.cpp @@ -52,7 +52,7 @@ SPMarker::SPMarker() : SPGroup(), SPViewBox() { this->markerUnits = 0; this->markerUnits_set = 0; - this->orient_auto = 0; + this->orient_mode = MARKER_ORIENT_ANGLE; this->orient_set = 0; this->orient = 0; @@ -158,16 +158,20 @@ void SPMarker::set(unsigned int key, const gchar* value) { case SP_ATTR_ORIENT: this->orient_set = FALSE; - this->orient_auto = FALSE; + this->orient_mode = MARKER_ORIENT_ANGLE; this->orient = 0.0; if (value) { - if (!strcmp (value, "auto")) { - this->orient_auto = TRUE; - this->orient_set = TRUE; - } else if (sp_svg_number_read_f (value, &this->orient)) { - this->orient_set = TRUE; - } + if (!strcmp (value, "auto")) { + this->orient_mode = MARKER_ORIENT_AUTO; + this->orient_set = TRUE; + } else if (!strcmp (value, "auto-start-reverse")) { + this->orient_mode = MARKER_ORIENT_AUTO_START_REVERSE; + this->orient_set = TRUE; + } else if (sp_svg_number_read_f (value, &this->orient)) { + this->orient_mode = MARKER_ORIENT_ANGLE; + this->orient_set = TRUE; + } } this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -264,15 +268,17 @@ Inkscape::XML::Node* SPMarker::write(Inkscape::XML::Document *xml_doc, Inkscape: } if (this->orient_set) { - if (this->orient_auto) { - repr->setAttribute("orient", "auto"); - } else { - sp_repr_set_css_double(repr, "orient", this->orient); - } + if (this->orient_mode == MARKER_ORIENT_AUTO) { + repr->setAttribute("orient", "auto"); + } else if (this->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + repr->setAttribute("orient", "auto-start-reverse"); + } else { + sp_repr_set_css_double(repr, "orient", this->orient); + } } else { - repr->setAttribute("orient", NULL); + repr->setAttribute("orient", NULL); } - + /* fixme: */ //XML Tree being used directly here while it shouldn't be.... repr->setAttribute("viewBox", this->getRepr()->attribute("viewBox")); @@ -381,7 +387,10 @@ sp_marker_show_instance ( SPMarker *marker, Inkscape::DrawingItem *parent, } if (v->items[pos]) { Geom::Affine m; - if (marker->orient_auto) { + if (marker->orient_mode == MARKER_ORIENT_AUTO) { + m = base; + } else if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + m = Geom::Rotate::from_degrees( 180.0 ) * base; m = base; } else { /* fixme: Orient units (Lauris) */ diff --git a/src/marker.h b/src/marker.h index 585615476..9eefcdf16 100644 --- a/src/marker.h +++ b/src/marker.h @@ -32,6 +32,12 @@ struct SPMarkerView; #include "uri-references.h" #include "viewbox.h" +enum markerOrient { + MARKER_ORIENT_ANGLE, + MARKER_ORIENT_AUTO, + MARKER_ORIENT_AUTO_START_REVERSE +}; + class SPMarker : public SPGroup, public SPViewBox { public: SPMarker(); @@ -51,7 +57,7 @@ public: /* orient */ unsigned int orient_set : 1; - unsigned int orient_auto : 1; + markerOrient orient_mode : 2; float orient; /* Private views */ diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp index de9103dee..d76bd9780 100644 --- a/src/sp-shape.cpp +++ b/src/sp-shape.cpp @@ -288,8 +288,13 @@ sp_shape_update_marker_view(SPShape *shape, Inkscape::DrawingItem *ai) Geom::Affine const m (sp_shape_marker_get_transform_at_start(pathv.begin()->front())); for (int i = 0; i < 2; i++) { // SP_MARKER_LOC and SP_MARKER_LOC_START if ( shape->_marker[i] ) { + Geom::Affine m_auto = m; + // Reverse start marker if necessary. + if (SP_MARKER(shape->_marker[i])->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + m_auto = Geom::Rotate::from_degrees( 180.0 ) * m; + } sp_marker_show_instance ((SPMarker* ) shape->_marker[i], ai, - ai->key() + i, counter[i], m, + ai->key() + i, counter[i], m_auto, shape->style->stroke_width.computed); counter[i]++; } @@ -425,7 +430,10 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker_item) { Geom::Affine tr(sp_shape_marker_get_transform_at_start(pathv.begin()->front())); - if (!marker->orient_auto) { + if (marker->orient_mode == MARKER_ORIENT_AUTO_START_REVERSE) { + // Reverse start marker if necessary + tr = Geom::Rotate::from_degrees( 180.0 ) * tr; + } else if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } @@ -463,7 +471,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox { Geom::Affine tr(sp_shape_marker_get_transform_at_start(path_it->front())); - if (!marker->orient_auto) { + if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } @@ -493,7 +501,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox if (marker_item) { Geom::Affine tr(sp_shape_marker_get_transform(*curve_it1, *curve_it2)); - if (!marker->orient_auto) { + if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } @@ -516,7 +524,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox Geom::Curve const &lastcurve = path_it->back_default(); Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve); - if (!marker->orient_auto) { + if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } @@ -551,7 +559,7 @@ Geom::OptRect SPShape::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox Geom::Affine tr = sp_shape_marker_get_transform_at_end(lastcurve); - if (!marker->orient_auto) { + if (marker->orient_mode == MARKER_ORIENT_ANGLE) { Geom::Point transl = tr.translation(); tr = Geom::Rotate::from_degrees(marker->orient) * Geom::Translate(transl); } -- cgit v1.2.3 From bec0a3b7e0a10473bdb3290b6e763969edc0b160 Mon Sep 17 00:00:00 2001 From: su_v Date: Wed, 20 Aug 2014 15:57:00 +0200 Subject: Reorg Resources folder: move inkscape's shared resources into Resources/share/inkscape (bzr r13506.1.26) --- src/path-prefix.h | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/path-prefix.h b/src/path-prefix.h index be57ae354..4c31b629c 100644 --- a/src/path-prefix.h +++ b/src/path-prefix.h @@ -66,23 +66,23 @@ extern "C" { # define CREATE_PALETTESDIR WIN32_DATADIR("create\\swatches") # define CREATE_PATTERNSDIR WIN32_DATADIR("create\\patterns\\vector") # elif defined ENABLE_OSX_APP_LOCATIONS -# define INKSCAPE_APPICONDIR "Contents/Resources/pixmaps" -# define INKSCAPE_ATTRRELDIR "Contents/Resources/attributes" -# define INKSCAPE_BINDDIR "Contents/Resources/bind" -# define INKSCAPE_EXAMPLESDIR "Contents/Resources/examples" -# define INKSCAPE_EXTENSIONDIR "Contents/Resources/extensions" -# define INKSCAPE_FILTERDIR "Contents/Resources/filters" -# define INKSCAPE_GRADIENTSDIR "Contents/Resources/gradients" -# define INKSCAPE_KEYSDIR "Contents/Resources/keys" -# define INKSCAPE_PIXMAPDIR "Contents/Resources/icons" -# define INKSCAPE_MARKERSDIR "Contents/Resources/markers" -# define INKSCAPE_PALETTESDIR "Contents/Resources/palettes" -# define INKSCAPE_PATTERNSDIR "Contents/Resources/patterns" -# define INKSCAPE_SCREENSDIR "Contents/Resources/screens" -# define INKSCAPE_SYMBOLSDIR "Contents/Resources/symbols" -# define INKSCAPE_TUTORIALSDIR "Contents/Resources/tutorials" -# define INKSCAPE_TEMPLATESDIR "Contents/Resources/templates" -# define INKSCAPE_UIDIR "Contents/Resources/ui" +# define INKSCAPE_APPICONDIR "Contents/Resources/share/pixmaps" +# define INKSCAPE_ATTRRELDIR "Contents/Resources/share/inkscape/attributes" +# define INKSCAPE_BINDDIR "Contents/Resources/share/inkscape/bind" +# define INKSCAPE_EXAMPLESDIR "Contents/Resources/share/inkscape/examples" +# define INKSCAPE_EXTENSIONDIR "Contents/Resources/share/inkscape/extensions" +# define INKSCAPE_FILTERDIR "Contents/Resources/share/inkscape/filters" +# define INKSCAPE_GRADIENTSDIR "Contents/Resources/share/inkscape/gradients" +# define INKSCAPE_KEYSDIR "Contents/Resources/share/inkscape/keys" +# define INKSCAPE_PIXMAPDIR "Contents/Resources/share/inkscape/icons" +# define INKSCAPE_MARKERSDIR "Contents/Resources/share/inkscape/markers" +# define INKSCAPE_PALETTESDIR "Contents/Resources/share/inkscape/palettes" +# define INKSCAPE_PATTERNSDIR "Contents/Resources/share/inkscape/patterns" +# define INKSCAPE_SCREENSDIR "Contents/Resources/share/inkscape/screens" +# define INKSCAPE_SYMBOLSDIR "Contents/Resources/share/inkscape/symbols" +# define INKSCAPE_TUTORIALSDIR "Contents/Resources/share/inkscape/tutorials" +# define INKSCAPE_TEMPLATESDIR "Contents/Resources/share/inkscape/templates" +# define INKSCAPE_UIDIR "Contents/Resources/share/inkscape/ui" //CREATE V0.1 support # define CREATE_GRADIENTSDIR "/Library/Application Support/create/gradients/gimp" # define CREATE_PALETTESDIR "/Library/Application Support/create/swatches" -- cgit v1.2.3 From ea13ae28b62fc00c08ff2bb74e849e7964bf8467 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 20 Aug 2014 23:53:23 +0200 Subject: Fix bug #1068987 LPE prespective_path crash inkscape (bzr r13529) --- src/live_effects/lpe-perspective_path.cpp | 102 +++++++++++++++++++++++++++++- src/live_effects/lpe-perspective_path.h | 3 + 2 files changed, 102 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index c255f8665..a2372131c 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -10,17 +10,18 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include #include #include "persp3d.h" //#include "transf_mat_3x4.h" #include "document.h" - +#include "document-private.h" #include "live_effects/lpe-perspective_path.h" #include "sp-item-group.h" #include "knot-holder-entity.h" #include "knotholder.h" +#include "desktop.h" #include "inkscape.h" @@ -41,6 +42,7 @@ public: } // namespace PP +static Glib::ustring perspectiveID = _("First perspective"); LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: @@ -59,9 +61,18 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : concatenate_before_pwd2 = true; // don't split the path into its subpaths _provides_knotholder_entities = true; - + unapply = false; Persp3D *persp = persp3d_document_first_persp(inkscape_active_document()); + if(persp == 0 ){ + char *msg = _("You need a BOX 3D object"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + unapply = true; + return; + } Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; + pmat = pmat * inkscape_active_desktop()->doc2dt(); pmat.copy_tmat(tmat); } @@ -74,8 +85,50 @@ void LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem, true); + if(unapply){ + SP_LPE_ITEM(lpeitem)->removeCurrentPathEffect(false); + return; + } } +void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { + perspectiveID = perspective->get_text(); + Persp3D *first = 0; + Persp3D *persp = 0; + for ( SPObject *child = inkscape_active_document()->getDefs()->firstChild(); child && !persp; child = child->getNext() ) { + if (SP_IS_PERSP3D(child) && first == 0) { + first = SP_PERSP3D(child); + } + if (SP_IS_PERSP3D(child) && strcmp(child->getId(), const_cast(perspectiveID.c_str())) == 0) { + persp = SP_PERSP3D(child); + break; + } + } + if(first == 0 ){ + char *msg = _("You need a BOX 3D object"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + return; + } + if(persp == 0){ + persp = first; + char *msg = _("First perspective selected"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + perspectiveID = _("First perspective"); + }else{ + char *msg = _("Perspective changed"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + } + Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; + pmat = pmat * inkscape_active_desktop()->doc2dt(); + pmat.copy_tmat(tmat); +}; + Geom::Piecewise > LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { @@ -139,6 +192,49 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > cons return output; } +Gtk::Widget * +LPEPerspectivePath::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + + vbox->set_border_width(5); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + Gtk::HBox * perspectiveId = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::Label* labelPerspective = Gtk::manage(new Gtk::Label("Perspective ID:", 0., 0.)); + Gtk::Entry* perspective = Gtk::manage(new Gtk::Entry()); + perspective->set_text(perspectiveID); + perspective->set_tooltip_text("Set the perspective ID to apply"); + perspectiveId->pack_start(*labelPerspective, true, true, 2); + perspectiveId->pack_start(*perspective, true, true, 2); + vbox->pack_start(*perspectiveId, true, true, 2); + Gtk::Button* apply3D = Gtk::manage(new Gtk::Button(Glib::ustring(_("Refresh perspective")))); + apply3D->set_alignment(0.0, 0.5); + apply3D->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this,&LPEPerspectivePath::refresh),perspective)); + Gtk::Widget* apply3DWidget = dynamic_cast(apply3D); + apply3DWidget->set_tooltip_text("Refresh perspective"); + vbox->pack_start(*apply3DWidget, true, true,2); + return dynamic_cast(vbox); +} + void LPEPerspectivePath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { KnotHolderEntity *e = new PP::KnotHolderEntityOffset(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index a9ee004f9..6ccac4a51 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -38,6 +38,8 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + virtual void refresh(Gtk::Entry* perspective); + virtual Gtk::Widget * newWidget(); /* the knotholder entity classes must be declared friends */ friend class PP::KnotHolderEntityOffset; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); @@ -52,6 +54,7 @@ private: BoolParam uses_plane_xy; // there are all kinds of parameters. Check the /live_effects/parameter directory which types exist! + bool unapply; Geom::Point orig; LPEPerspectivePath(const LPEPerspectivePath&); -- cgit v1.2.3 From dc57a722e203077e92d6b51c4721145dd8b3b5ec Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 20 Aug 2014 23:56:55 +0200 Subject: Fix bug #1068987 LPE prespective_path crash inkscape (bzr r13341.1.149) --- src/live_effects/lpe-perspective_path.cpp | 102 +++++++++++++++++++++++++++++- src/live_effects/lpe-perspective_path.h | 3 + 2 files changed, 102 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index c255f8665..a2372131c 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -10,17 +10,18 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include #include #include "persp3d.h" //#include "transf_mat_3x4.h" #include "document.h" - +#include "document-private.h" #include "live_effects/lpe-perspective_path.h" #include "sp-item-group.h" #include "knot-holder-entity.h" #include "knotholder.h" +#include "desktop.h" #include "inkscape.h" @@ -41,6 +42,7 @@ public: } // namespace PP +static Glib::ustring perspectiveID = _("First perspective"); LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: @@ -59,9 +61,18 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : concatenate_before_pwd2 = true; // don't split the path into its subpaths _provides_knotholder_entities = true; - + unapply = false; Persp3D *persp = persp3d_document_first_persp(inkscape_active_document()); + if(persp == 0 ){ + char *msg = _("You need a BOX 3D object"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + unapply = true; + return; + } Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; + pmat = pmat * inkscape_active_desktop()->doc2dt(); pmat.copy_tmat(tmat); } @@ -74,8 +85,50 @@ void LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem, true); + if(unapply){ + SP_LPE_ITEM(lpeitem)->removeCurrentPathEffect(false); + return; + } } +void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { + perspectiveID = perspective->get_text(); + Persp3D *first = 0; + Persp3D *persp = 0; + for ( SPObject *child = inkscape_active_document()->getDefs()->firstChild(); child && !persp; child = child->getNext() ) { + if (SP_IS_PERSP3D(child) && first == 0) { + first = SP_PERSP3D(child); + } + if (SP_IS_PERSP3D(child) && strcmp(child->getId(), const_cast(perspectiveID.c_str())) == 0) { + persp = SP_PERSP3D(child); + break; + } + } + if(first == 0 ){ + char *msg = _("You need a BOX 3D object"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + return; + } + if(persp == 0){ + persp = first; + char *msg = _("First perspective selected"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + perspectiveID = _("First perspective"); + }else{ + char *msg = _("Perspective changed"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + } + Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; + pmat = pmat * inkscape_active_desktop()->doc2dt(); + pmat.copy_tmat(tmat); +}; + Geom::Piecewise > LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { @@ -139,6 +192,49 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > cons return output; } +Gtk::Widget * +LPEPerspectivePath::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + + vbox->set_border_width(5); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = dynamic_cast(param->param_newWidget()); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + Gtk::HBox * perspectiveId = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::Label* labelPerspective = Gtk::manage(new Gtk::Label("Perspective ID:", 0., 0.)); + Gtk::Entry* perspective = Gtk::manage(new Gtk::Entry()); + perspective->set_text(perspectiveID); + perspective->set_tooltip_text("Set the perspective ID to apply"); + perspectiveId->pack_start(*labelPerspective, true, true, 2); + perspectiveId->pack_start(*perspective, true, true, 2); + vbox->pack_start(*perspectiveId, true, true, 2); + Gtk::Button* apply3D = Gtk::manage(new Gtk::Button(Glib::ustring(_("Refresh perspective")))); + apply3D->set_alignment(0.0, 0.5); + apply3D->signal_clicked().connect(sigc::bind(sigc::mem_fun(*this,&LPEPerspectivePath::refresh),perspective)); + Gtk::Widget* apply3DWidget = dynamic_cast(apply3D); + apply3DWidget->set_tooltip_text("Refresh perspective"); + vbox->pack_start(*apply3DWidget, true, true,2); + return dynamic_cast(vbox); +} + void LPEPerspectivePath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { KnotHolderEntity *e = new PP::KnotHolderEntityOffset(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index a9ee004f9..6ccac4a51 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -38,6 +38,8 @@ public: virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + virtual void refresh(Gtk::Entry* perspective); + virtual Gtk::Widget * newWidget(); /* the knotholder entity classes must be declared friends */ friend class PP::KnotHolderEntityOffset; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); @@ -52,6 +54,7 @@ private: BoolParam uses_plane_xy; // there are all kinds of parameters. Check the /live_effects/parameter directory which types exist! + bool unapply; Geom::Point orig; LPEPerspectivePath(const LPEPerspectivePath&); -- cgit v1.2.3 From 963a90531a042d793f0f2e0fddbe9df0de35bf6d Mon Sep 17 00:00:00 2001 From: su_v Date: Thu, 21 Aug 2014 19:18:39 +0200 Subject: add poppler data to bundle, fix relocation support (see bug #956282) (bzr r13506.1.40) --- src/extension/internal/pdfinput/pdf-input.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src') diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index 63581bd8a..cbdaf9d20 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -647,7 +647,31 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { // Initialize the globalParams variable for poppler if (!globalParams) { +#ifdef ENABLE_OSX_APP_LOCATIONS + // + // data files for poppler are not relocatable (loaded from + // path defined at build time). This fails to work with relocatable + // application bundles for OS X. + // + // Workaround: + // 1. define $POPPLER_DATADIR env variable in app launcher script + // 2. pass custom $POPPLER_DATADIR via poppler's GlobalParams() + // + // relevant poppler commit: + // + // + // FIXES: Inkscape bug #956282, #1264793 + // TODO: report RFE upstream (full relocation support for OS X packaging) + // + gchar const *poppler_datadir = g_getenv("POPPLER_DATADIR"); + if (poppler_datadir != NULL) { + globalParams = new GlobalParams(poppler_datadir); + } else { + globalParams = new GlobalParams(); + } +#else globalParams = new GlobalParams(); +#endif // ENABLE_OSX_APP_LOCATIONS } // poppler does not use glib g_open. So on win32 we must use unicode call. code was copied from glib gstdio.c #ifndef WIN32 -- cgit v1.2.3 From 549d5631f51d2f3948c7321d1e30e89688a50664 Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 23 Aug 2014 07:56:55 +0200 Subject: Fix skewing bug that could lead to infinite transforms Fixed bugs: - https://launchpad.net/bugs/1266499 (bzr r13530) --- src/seltrans.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/seltrans.cpp b/src/seltrans.cpp index 6b8cd19bb..e15249f94 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -9,7 +9,7 @@ * Abhishek Sharma * * Copyright (C) 1999-2002 Lauris Kaplinski - * Copyright (C) 1999-2008 Authors + * Copyright (C) 1999-2014 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -1109,10 +1109,17 @@ gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, Geom::P break; } + // _point and _origin are noisy, ranging from 1 to 1e-9 or even smaller; this is due to the + // limited SVG output precision, which can be arbitrarily set in the preferences Geom::Point const initial_delta = _point - _origin; - if (fabs(initial_delta[dim_a]) < 1e-15) { - return false; + // The handle and the origin shouldn't be too close to each other; let's check for that! + // Due to the limited resolution though (see above), we'd better use a relative error here + if (_bbox) { + Geom::Coord d = (*_bbox).dimensions()[dim_a]; + if (fabs(initial_delta[dim_a]/d) < 1e-4) { + return false; + } } // Calculate the scale factors, which can be either visual or geometric -- cgit v1.2.3 From d9ecb43350d4979423392b6c84255e38f9bb35c8 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 12:48:18 +0100 Subject: font-selector: Clean up GObject boilerplate & fix deprecation (bzr r13341.1.151) --- src/widgets/font-selector.cpp | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index d4a174a0d..943434868 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -36,7 +36,11 @@ struct SPFontSelector { +#if GTK_CHECK_VERSION(3,0,0) + GtkBox hbox; +#else GtkHBox hbox; +#endif unsigned int block_emit : 1; @@ -57,7 +61,11 @@ struct SPFontSelector struct SPFontSelectorClass { +#if GTK_CHECK_VERSION(3,0,0) + GtkBoxClass parent_class; +#else GtkHBoxClass parent_class; +#endif void (* font_set) (SPFontSelector *fsel, gchar *fontspec); }; @@ -67,8 +75,6 @@ enum { LAST_SIGNAL }; -static void sp_font_selector_class_init (SPFontSelectorClass *c); -static void sp_font_selector_init (SPFontSelector *fsel); static void sp_font_selector_dispose (GObject *object); static void sp_font_selector_family_select_row (GtkTreeSelection *selection, @@ -83,36 +89,18 @@ static void sp_font_selector_size_changed (GtkComboBox *combobo static void sp_font_selector_emit_set (SPFontSelector *fsel); static void sp_font_selector_set_sizes( SPFontSelector *fsel ); -static GtkHBoxClass *fs_parent_class = NULL; static guint fs_signals[LAST_SIGNAL] = { 0 }; -GType sp_font_selector_get_type() -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPFontSelectorClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_font_selector_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPFontSelector), - 0, // n_preallocs - (GInstanceInitFunc)sp_font_selector_init, - 0 // value_table - }; - type = g_type_register_static(GTK_TYPE_HBOX, "SPFontSelector", &info, static_cast(0)); - } - return type; -} +#if GTK_CHECK_VERSION(3,0,0) +G_DEFINE_TYPE(SPFontSelector, sp_font_selector, GTK_TYPE_BOX); +#else +G_DEFINE_TYPE(SPFontSelector, sp_font_selector, GTK_TYPE_HBOX); +#endif static void sp_font_selector_class_init(SPFontSelectorClass *c) { GObjectClass *object_class = G_OBJECT_CLASS(c); - fs_parent_class = (GtkHBoxClass* )g_type_class_peek_parent (c); - fs_signals[FONT_SET] = g_signal_new ("font_set", G_TYPE_FROM_CLASS(object_class), (GSignalFlags)G_SIGNAL_RUN_FIRST, @@ -283,8 +271,8 @@ static void sp_font_selector_dispose(GObject *object) fsel->styles.length = 0; } - if (G_OBJECT_CLASS(fs_parent_class)->dispose) { - G_OBJECT_CLASS(fs_parent_class)->dispose(object); + if (G_OBJECT_CLASS(sp_font_selector_parent_class)->dispose) { + G_OBJECT_CLASS(sp_font_selector_parent_class)->dispose(object); } } -- cgit v1.2.3 From c7d26fadeaa52705f35a2c8c0d3edc0cb0370686 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 13:00:29 +0100 Subject: gradient-selector: Clean up GObject boilerplate & fix deprecation (bzr r13341.1.152) --- src/widgets/gradient-selector.cpp | 44 +++++++++++---------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 511478111..e85c115a8 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -47,8 +47,6 @@ enum { }; -static void sp_gradient_selector_class_init (SPGradientSelectorClass *klass); -static void sp_gradient_selector_init (SPGradientSelector *selector); static void sp_gradient_selector_dispose(GObject *object); /* Signal handlers */ @@ -57,41 +55,18 @@ static void sp_gradient_selector_edit_vector_clicked (GtkWidget *w, SPGradientSe static void sp_gradient_selector_add_vector_clicked (GtkWidget *w, SPGradientSelector *sel); static void sp_gradient_selector_delete_vector_clicked (GtkWidget *w, SPGradientSelector *sel); - -static GtkVBoxClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; -GType sp_gradient_selector_get_type(void) -{ - static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof(SPGradientSelectorClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_gradient_selector_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(SPGradientSelector), - 0, /* n_preallocs */ - (GInstanceInitFunc) sp_gradient_selector_init, - 0, /* value_table */ - }; - - type = g_type_register_static( GTK_TYPE_VBOX, - "SPGradientSelector", - &info, - static_cast< GTypeFlags > (0) ); - } - return type; -} +#if GTK_CHECK_VERSION(3,0,0) +G_DEFINE_TYPE(SPGradientSelector, sp_gradient_selector, GTK_TYPE_BOX); +#else +G_DEFINE_TYPE(SPGradientSelector, sp_gradient_selector, GTK_TYPE_VBOX); +#endif static void sp_gradient_selector_class_init(SPGradientSelectorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); - parent_class = GTK_VBOX_CLASS(g_type_class_peek_parent (klass)); - signals[GRABBED] = g_signal_new ("grabbed", G_TYPE_FROM_CLASS(object_class), (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), @@ -128,6 +103,11 @@ static void sp_gradient_selector_init(SPGradientSelector *sel) { sel->safelyInit = true; sel->blocked = false; + +#if GTK_CHECK_VERSION(3,0,0) + gtk_orientable_set_orientation(GTK_ORIENTABLE(sel), GTK_ORIENTATION_VERTICAL); +#endif + new (&sel->nonsolid) std::vector(); new (&sel->swatch_widgets) std::vector(); @@ -269,8 +249,8 @@ static void sp_gradient_selector_dispose(GObject *object) sel->text_renderer = NULL; } - if ((G_OBJECT_CLASS(parent_class))->dispose) { - (* (G_OBJECT_CLASS(parent_class))->dispose) (object); + if ((G_OBJECT_CLASS(sp_gradient_selector_parent_class))->dispose) { + (G_OBJECT_CLASS(sp_gradient_selector_parent_class))->dispose(object); } } -- cgit v1.2.3 From 723df29f7c3b793b26f41bfa1dd6430cdd75ae07 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 13:20:14 +0100 Subject: gradient-vector: Clean up GObject boilerplate & fix deprecation (bzr r13341.1.153) --- src/widgets/gradient-vector.cpp | 46 ++++++++++++----------------------------- src/widgets/gradient-vector.h | 4 ++++ 2 files changed, 17 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 17ac887c4..68f40f80c 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -61,9 +61,6 @@ enum { LAST_SIGNAL }; -static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass *klass); -static void sp_gradient_vector_selector_init(SPGradientVectorSelector *gvs); - #if GTK_CHECK_VERSION(3,0,0) static void sp_gradient_vector_selector_destroy(GtkWidget *object); #else @@ -79,7 +76,6 @@ static SPStop *get_selected_stop( GtkWidget *vb); void gr_get_usage_counts(SPDocument *doc, std::map *mapUsageCount ); unsigned long sp_gradient_to_hhssll(SPGradient *gr); -static GtkVBoxClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; // TODO FIXME kill these globals!!! @@ -88,35 +84,15 @@ static win_data wd; static gint x = -1000, y = -1000, w = 0, h = 0; // impossible original values to make sure they are read from prefs static Glib::ustring const prefs_path = "/dialogs/gradienteditor/"; -GType sp_gradient_vector_selector_get_type(void) -{ - static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof(SPGradientVectorSelectorClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - reinterpret_cast(sp_gradient_vector_selector_class_init), - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(SPGradientVectorSelector), - 0, /* n_preallocs */ - reinterpret_cast(sp_gradient_vector_selector_init), - 0, /* value_table */ - }; - - type = g_type_register_static( GTK_TYPE_VBOX, - "SPGradientVectorSelector", - &info, - static_cast< GTypeFlags >(0) ); - } - return type; -} +#if GTK_CHECK_VERSION(3,0,0) +G_DEFINE_TYPE(SPGradientVectorSelector, sp_gradient_vector_selector, GTK_TYPE_BOX); +#else +G_DEFINE_TYPE(SPGradientVectorSelector, sp_gradient_vector_selector, GTK_TYPE_VBOX); +#endif static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - parent_class = static_cast(g_type_class_peek_parent(klass)); signals[VECTOR_SET] = g_signal_new( "vector_set", G_TYPE_FROM_CLASS(gobject_class), @@ -138,6 +114,10 @@ static void sp_gradient_vector_selector_class_init(SPGradientVectorSelectorClass static void sp_gradient_vector_selector_init(SPGradientVectorSelector *gvs) { +#if GTK_CHECK_VERSION(3,0,0) + gtk_orientable_set_orientation(GTK_ORIENTABLE(gvs), GTK_ORIENTATION_VERTICAL); +#endif + gvs->idlabel = TRUE; gvs->swatched = false; @@ -181,12 +161,12 @@ static void sp_gradient_vector_selector_destroy(GtkObject *object) gvs->tree_select_connection.~connection(); #if GTK_CHECK_VERSION(3,0,0) - if ((reinterpret_cast(parent_class))->destroy) { - (* (reinterpret_cast(parent_class))->destroy) (object); + if ((GTK_WIDGET_CLASS(sp_gradient_vector_selector_parent_class))->destroy) { + (GTK_WIDGET_CLASS(sp_gradient_vector_selector_parent_class))->destroy(object); } #else - if ((reinterpret_cast(parent_class))->destroy) { - (* (reinterpret_cast(parent_class))->destroy) (object); + if ((GTK_OBJECT_CLASS(sp_gradient_vector_selector_parent_class))->destroy) { + (GTK_OBJECT_CLASS(sp_gradient_vector_selector_parent_class))->destroy(object); } #endif } diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index b63120a6e..0b653b016 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -65,7 +65,11 @@ struct SPGradientVectorSelector { }; struct SPGradientVectorSelectorClass { +#if GTK_CHECK_VERSION(3,0,0) + GtkBoxClass parent_class; +#else GtkVBoxClass parent_class; +#endif void (* vector_set) (SPGradientVectorSelector *gvs, SPGradient *gr); }; -- cgit v1.2.3 From 62339f48161baf01b49d331b7c31ab9d8fb64ec6 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 14:54:39 +0200 Subject: fix Windows 64-bit build (bzr r13341.1.154) --- src/ui/dialog/print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index ed39ebb32..a015d28f9 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -14,13 +14,13 @@ # include #endif +#include + #ifdef WIN32 #include #include #endif -#include - #include "preferences.h" #include "print.h" -- cgit v1.2.3 From e469f1f4eb04e7cc1401c6679a41c217287ae888 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 15:17:43 +0200 Subject: fix Windows 64-bit build (bzr r13531) --- src/ui/dialog/print.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/print.cpp b/src/ui/dialog/print.cpp index ed39ebb32..a015d28f9 100644 --- a/src/ui/dialog/print.cpp +++ b/src/ui/dialog/print.cpp @@ -14,13 +14,13 @@ # include #endif +#include + #ifdef WIN32 #include #include #endif -#include - #include "preferences.h" #include "print.h" -- cgit v1.2.3 From a8d5997ca58774796bff56a69dad64260cbbc36a Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 18:39:36 +0200 Subject: To help the SVG WG discussion on powerstroke, a quick code-up of centripetal Catmull-Rom interpolation. The code probably needs a clean up pass, and more generally, the interpolation functions should move into 2geom or at least into a .cpp file. - Add Catmull-Rom interpolation to powerstroke interpolation options - Add LPE Interpolate points (bzr r13341.1.156) --- src/live_effects/Makefile_insert | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 6 ++ src/live_effects/lpe-powerstroke-interpolators.h | 81 +++++++++++++++++++++++- src/live_effects/lpe-powerstroke.cpp | 3 +- 5 files changed, 90 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index e9609a4aa..1b8f587e1 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -38,6 +38,8 @@ ink_common_sources += \ live_effects/lpe-gears.h \ live_effects/lpe-interpolate.cpp \ live_effects/lpe-interpolate.h \ + live_effects/lpe-interpolate_points.cpp \ + live_effects/lpe-interpolate_points.h \ live_effects/lpe-test-doEffect-stack.cpp \ live_effects/lpe-test-doEffect-stack.h \ live_effects/lpe-bspline.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index bc77d65c3..30dbf4092 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -45,6 +45,7 @@ enum EffectType { RULER, BOOLOPS, INTERPOLATE, + INTERPOLATE_POINTS, TEXT_LABEL, PATH_LENGTH, LINE_SEGMENT, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index dc61701df..540eb99d4 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -43,6 +43,7 @@ #include "live_effects/lpe-ruler.h" #include "live_effects/lpe-boolops.h" #include "live_effects/lpe-interpolate.h" +#include "live_effects/lpe-interpolate_points.h" #include "live_effects/lpe-text_label.h" #include "live_effects/lpe-path_length.h" #include "live_effects/lpe-line_segment.h" @@ -127,6 +128,7 @@ const Util::EnumData LPETypeData[] = { /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, +/* EXPERIMENTAL */ {SHOW_HANDLES, N_("Show handles"), "show_handles"}, {ROUGHEN, N_("Roughen"), "roughen"}, {BSPLINE, N_("BSpline"), "bspline"}, @@ -135,6 +137,7 @@ const Util::EnumData LPETypeData[] = { // TRANSLATORS: "Envelope Perspective" should be equivalent to "perspective transformation" {ENVELOPE_PERSPECTIVE, N_("Envelope Perspective"), "envelope-perspective"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, + {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -231,6 +234,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case INTERPOLATE: neweffect = static_cast ( new LPEInterpolate(lpeobj) ); break; + case INTERPOLATE_POINTS: + neweffect = static_cast ( new LPEInterpolatePoints(lpeobj) ); + break; case TEXT_LABEL: neweffect = static_cast ( new LPETextLabel(lpeobj) ); break; diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h index 6f5b75af8..f08259eb3 100644 --- a/src/live_effects/lpe-powerstroke-interpolators.h +++ b/src/live_effects/lpe-powerstroke-interpolators.h @@ -27,7 +27,8 @@ enum InterpolatorType { INTERP_LINEAR, INTERP_CUBICBEZIER, INTERP_CUBICBEZIER_JOHAN, - INTERP_SPIRO + INTERP_SPIRO, + INTERP_CENTRIPETAL_CATMULLROM }; class Interpolator { @@ -168,7 +169,81 @@ private: }; -Interpolator* +// Quick mockup for testing the behavior for powerstroke controlpoint interpolation +class CentripetalCatmullRomInterpolator : public Interpolator { +public: + CentripetalCatmullRomInterpolator() {}; + virtual ~CentripetalCatmullRomInterpolator() {}; + + virtual Path interpolateToPath(std::vector const &points) const { + unsigned int n_points = points.size(); + + Geom::Path fit(points.front()); + + if (n_points < 3) return fit; // TODO special cases for 0,1 and 2 input points + + // return n_points-1 cubic segments + + // duplicate first point + fit.append(calc_bezier(points[0],points[0],points[1],points[2])); + + for (std::size_t i = 0; i < n_points-2; ++i) { + Point p0 = points[i]; + Point p1 = points[i+1]; + Point p2 = points[i+2]; + Point p3 = (i < n_points-3) ? points[i+3] : points[i+2]; + + fit.append(calc_bezier(p0, p1, p2, p3)); + } + + return fit; + }; + +private: + CubicBezier calc_bezier(Point p0, Point p1, Point p2, Point p3) const { + // create interpolating bezier between p1 and p2 + + // calculate time coords (deltas) of points + double dt0 = powf(distanceSq(p0, p1), 0.25); + double dt1 = powf(distanceSq(p1, p2), 0.25); + double dt2 = powf(distanceSq(p2, p3), 0.25); + + // safety check for repeated points + double eps = Geom::EPSILON; + if (dt1 < eps) + dt1 = 1.0; + if (dt0 < eps) + dt0 = dt1; + if (dt2 < eps) + dt2 = dt1; + + // compute tangents when parameterized in [t1,t2] + Point tan1 = (p1 - p0) / dt0 - (p2 - p0) / (dt0 + dt1) + (p2 - p1) / dt1; + Point tan2 = (p2 - p1) / dt1 - (p3 - p1) / (dt1 + dt2) + (p3 - p2) / dt2; + // rescale tangents for parametrization in [0,1] + tan1 *= dt1; + tan2 *= dt1; + + // create bezier from tangents (this is already in 2geom somewhere, or should be moved to it) + // the tangent of a bezier curve is: B'(t) = 3(1-t)^2 (b1 - b0) + 6(1-t)t(b2-b1) + 3t^2(b3-b2) + // So we have to make sure that B'(0) = tan1 and B'(1) = tan2, and we already know that b0=p1 and b3=p2 + // tan1 = B'(0) = 3 (b1 - p1) --> p1 + (tan1)/3 = b1 + // tan2 = B'(1) = 3 (p2 - b2) --> p2 - (tan2)/3 = b2 + + Point b0 = p1; + Point b1 = p1 + tan1 / 3; + Point b2 = p2 - tan2 / 3; + Point b3 = p2; + + return CubicBezier(b0, b1, b2, b3); + } + + CentripetalCatmullRomInterpolator(const CentripetalCatmullRomInterpolator&); + CentripetalCatmullRomInterpolator& operator=(const CentripetalCatmullRomInterpolator&); +}; + + +inline Interpolator* Interpolator::create(InterpolatorType type) { switch (type) { case INTERP_LINEAR: @@ -179,6 +254,8 @@ Interpolator::create(InterpolatorType type) { return new Geom::Interpolate::CubicBezierJohan(); case INTERP_SPIRO: return new Geom::Interpolate::SpiroInterpolator(); + case INTERP_CENTRIPETAL_CATMULLROM: + return new Geom::Interpolate::CentripetalCatmullRomInterpolator(); default: return new Geom::Interpolate::Linear(); } diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 90b01aaa4..5bfe88ed1 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -188,7 +188,8 @@ static const Util::EnumData InterpolatorTypeData[] = { {Geom::Interpolate::INTERP_LINEAR , N_("Linear"), "Linear"}, {Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"}, {Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"}, - {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"} + {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"}, + {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"} }; static const Util::EnumDataConverter InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); -- cgit v1.2.3 From 3e213be1dff6514f965efce4604e47866eecf9f5 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 18:42:02 +0200 Subject: add missing files from last commit (bzr r13341.1.157) --- src/live_effects/lpe-interpolate_points.cpp | 94 +++++++++++++++++++++++++++++ src/live_effects/lpe-interpolate_points.h | 51 ++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 src/live_effects/lpe-interpolate_points.cpp create mode 100644 src/live_effects/lpe-interpolate_points.h (limited to 'src') diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp new file mode 100644 index 000000000..865b46ca7 --- /dev/null +++ b/src/live_effects/lpe-interpolate_points.cpp @@ -0,0 +1,94 @@ +/** \file + * LPE interpolate_points implementation + * Interpolates between knots of the input path. + */ +/* + * Authors: + * Johan Engelen + * + * Copyright (C) Johan Engelen 2014 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-interpolate_points.h" + +#include <2geom/path.h> + +#include "live_effects/lpe-powerstroke-interpolators.h" + +namespace Inkscape { +namespace LivePathEffect { + + +static const Util::EnumData InterpolatorTypeData[] = { + {Geom::Interpolate::INTERP_LINEAR , N_("Linear"), "Linear"}, + {Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"}, + {Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"}, + {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"}, + {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"} +}; +static const Util::EnumDataConverter InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); + + +LPEInterpolatePoints::LPEInterpolatePoints(LivePathEffectObject *lpeobject) + : Effect(lpeobject) + , interpolator_type( + _("Interpolator type:"), + _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), + "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM) +{ + show_orig_path = false; + + registerParameter( dynamic_cast(&interpolator_type) ); +} + +LPEInterpolatePoints::~LPEInterpolatePoints() +{ +} + + +Geom::PathVector +LPEInterpolatePoints::doEffect_path (Geom::PathVector const & path_in) +{ + Geom::PathVector path_out; + + std::auto_ptr interpolator( Geom::Interpolate::Interpolator::create(static_cast(interpolator_type.get_value())) ); + + for(Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { + if (path_it->empty()) + continue; + + if (path_it->closed()) { + g_warning("Interpolate points LPE currently ignores whether path is closed or not."); + } + + std::vector pts; + pts.push_back(path_it->initialPoint()); + + for (Geom::Path::const_iterator it = path_it->begin(), e = path_it->end_default(); it != e; ++it) { + pts.push_back((*it).finalPoint()); + } + + Geom::Path path = interpolator->interpolateToPath(pts); + + path_out.push_back(path); + } + + return path_out; +} + + +} //namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-interpolate_points.h b/src/live_effects/lpe-interpolate_points.h new file mode 100644 index 000000000..7a3364747 --- /dev/null +++ b/src/live_effects/lpe-interpolate_points.h @@ -0,0 +1,51 @@ +#ifndef INKSCAPE_LPE_INTERPOLATEPOINTS_H +#define INKSCAPE_LPE_INTERPOLATEPOINTS_H + +/** \file + * LPE interpolate_points implementation, see lpe-interpolate_points.cpp. + */ + +/* + * Authors: + * Johan Engelen + * + * Copyright (C) Johan Engelen 2014 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/enum.h" +#include "live_effects/effect.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEInterpolatePoints : public Effect { +public: + LPEInterpolatePoints(LivePathEffectObject *lpeobject); + virtual ~LPEInterpolatePoints(); + + virtual std::vector doEffect_path (std::vector const & path_in); + +private: + EnumParam interpolator_type; + + LPEInterpolatePoints(const LPEInterpolatePoints&); + LPEInterpolatePoints& operator=(const LPEInterpolatePoints&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif // INKSCAPE_LPE_INTERPOLATEPOINTS_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- cgit v1.2.3 From 9b86de418e536b38bdf0d95e75413d57fd8f76b5 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 23 Aug 2014 19:14:02 +0200 Subject: properly attribute code (bzr r13341.1.158) --- src/live_effects/lpe-powerstroke-interpolators.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h index f08259eb3..986bd3544 100644 --- a/src/live_effects/lpe-powerstroke-interpolators.h +++ b/src/live_effects/lpe-powerstroke-interpolators.h @@ -203,11 +203,18 @@ private: CubicBezier calc_bezier(Point p0, Point p1, Point p2, Point p3) const { // create interpolating bezier between p1 and p2 + // Part of the code comes from StackOverflow user eriatarka84 + // http://stackoverflow.com/a/23980479/2929337 + // calculate time coords (deltas) of points + // the factor 0.25 can be generalized for other Catmull-Rom interpolation types + // see alpha in Yuksel et al. "On the Parameterization of Catmull-Rom Curves", + // --> http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf double dt0 = powf(distanceSq(p0, p1), 0.25); double dt1 = powf(distanceSq(p1, p2), 0.25); double dt2 = powf(distanceSq(p2, p3), 0.25); + // safety check for repeated points double eps = Geom::EPSILON; if (dt1 < eps) -- cgit v1.2.3 From 97e4fa3e7310f0ec42e0d35cb33e244713f6ad48 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 19:38:31 +0100 Subject: paint-selector: Clean up GObject boilerplate & fix deprecation (bzr r13341.1.159) --- src/widgets/paint-selector.cpp | 46 ++++++++++++++---------------------------- src/widgets/paint-selector.h | 8 ++++++++ 2 files changed, 23 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index f4ceee187..190428d51 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -72,8 +72,6 @@ enum { LAST_SIGNAL }; -static void sp_paint_selector_class_init(SPPaintSelectorClass *klass); -static void sp_paint_selector_init(SPPaintSelector *slider); static void sp_paint_selector_dispose(GObject *object); static GtkWidget *sp_paint_selector_style_button_add(SPPaintSelector *psel, gchar const *px, SPPaintSelector::Mode mode, gchar const *tip); @@ -92,7 +90,6 @@ static void sp_paint_selector_set_mode_unset(SPPaintSelector *psel); static void sp_paint_selector_set_style_buttons(SPPaintSelector *psel, GtkWidget *active); -static GtkVBoxClass *parent_class; static guint psel_signals[LAST_SIGNAL] = {0}; #ifdef SP_PS_VERBOSE @@ -140,34 +137,17 @@ static SPGradientSelector *getGradientFromData(SPPaintSelector const *psel) return grad; } -GType sp_paint_selector_get_type(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPPaintSelectorClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_paint_selector_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPPaintSelector), - 0, // n_preallocs - (GInstanceInitFunc)sp_paint_selector_init, - 0 // value_table - }; - type = g_type_register_static(GTK_TYPE_VBOX, "SPPaintSelector", &info, static_cast(0)); - } - return type; -} +#if GTK_CHECK_VERSION(3,0,0) +G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_BOX); +#else +G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_HBOX); +#endif static void sp_paint_selector_class_init(SPPaintSelectorClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); - parent_class = GTK_VBOX_CLASS(g_type_class_peek_parent(klass)); - psel_signals[MODE_CHANGED] = g_signal_new("mode_changed", G_TYPE_FROM_CLASS(object_class), (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), @@ -220,6 +200,10 @@ sp_paint_selector_class_init(SPPaintSelectorClass *klass) static void sp_paint_selector_init(SPPaintSelector *psel) { +#if GTK_CHECK_VERSION(3,0,0) + gtk_orientable_set_orientation(GTK_ORIENTABLE(psel), GTK_ORIENTATION_VERTICAL); +#endif + psel->mode = static_cast(-1); // huh? do you mean 0xff? -- I think this means "not in the enum" /* Paint style button box */ @@ -322,8 +306,8 @@ static void sp_paint_selector_dispose(GObject *object) // clean up our long-living pattern menu g_object_set_data(G_OBJECT(psel),"patternmenu",NULL); - if ((G_OBJECT_CLASS(parent_class))->dispose) - (* (G_OBJECT_CLASS(parent_class))->dispose)(object); + if ((G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose) + (G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose(object); } static GtkWidget *sp_paint_selector_style_button_add(SPPaintSelector *psel, @@ -691,8 +675,8 @@ static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelec /* Create new color selector */ /* Create vbox */ #if GTK_CHECK_VERSION(3,0,0) - GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); - gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); + GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); #else GtkWidget *vb = gtk_vbox_new(FALSE, 4); #endif @@ -1045,8 +1029,8 @@ static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSel /* Create vbox */ #if GTK_CHECK_VERSION(3,0,0) - tbl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); - gtk_box_set_homogeneous(GTK_BOX(tbl), FALSE); + tbl = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + gtk_box_set_homogeneous(GTK_BOX(tbl), FALSE); #else tbl = gtk_vbox_new(FALSE, 4); #endif diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index a2a303a47..1e8ad6d2e 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -35,7 +35,11 @@ class SPStyle; * Generic paint selector widget. */ struct SPPaintSelector { +#if GTK_CHECK_VERSION(3,0,0) + GtkBox vbox; +#else GtkVBox vbox; +#endif enum Mode { MODE_EMPTY, @@ -118,7 +122,11 @@ enum {COMBO_COL_LABEL=0, COMBO_COL_STOCK=1, COMBO_COL_PATTERN=2, COMBO_COL_SEP=3 /// The SPPaintSelector vtable struct SPPaintSelectorClass { +#if GTK_CHECK_VERSION(3,0,0) + GtkBoxClass parent_class; +#else GtkVBoxClass parent_class; +#endif void (* mode_changed) (SPPaintSelector *psel, SPPaintSelector::Mode mode); -- cgit v1.2.3 From 2624981b81a9600464e43484fbc7a55531a8f755 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 19:46:19 +0100 Subject: sp-color-selector: Clean up GObject boilerplate & fix deprecation (bzr r13341.1.160) --- src/widgets/sp-color-selector.cpp | 42 ++++++++++----------------------------- src/widgets/sp-color-selector.h | 8 ++++++++ 2 files changed, 19 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp index 6d62acecd..e97c36431 100644 --- a/src/widgets/sp-color-selector.cpp +++ b/src/widgets/sp-color-selector.cpp @@ -22,42 +22,20 @@ enum { #define noDUMP_CHANGE_INFO #define FOO_NAME(x) g_type_name( G_TYPE_FROM_INSTANCE(x) ) -static void sp_color_selector_class_init( SPColorSelectorClass *klass ); -static void sp_color_selector_init( SPColorSelector *csel ); static void sp_color_selector_dispose(GObject *object); static void sp_color_selector_show_all( GtkWidget *widget ); static void sp_color_selector_hide( GtkWidget *widget ); -static GtkVBoxClass *parent_class; static guint csel_signals[LAST_SIGNAL] = {0}; double ColorSelector::_epsilon = 1e-4; -GType sp_color_selector_get_type( void ) -{ - static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof(SPColorSelectorClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_color_selector_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof(SPColorSelector), - 0, /* n_preallocs */ - (GInstanceInitFunc) sp_color_selector_init, - NULL - }; - - type = g_type_register_static( GTK_TYPE_VBOX, - "SPColorSelector", - &info, - static_cast(0) ); - } - return type; -} +#if GTK_CHECK_VERSION(3,0,0) +G_DEFINE_TYPE(SPColorSelector, sp_color_selector, GTK_TYPE_BOX); +#else +G_DEFINE_TYPE(SPColorSelector, sp_color_selector, GTK_TYPE_VBOX); +#endif void sp_color_selector_class_init( SPColorSelectorClass *klass ) { @@ -66,8 +44,6 @@ void sp_color_selector_class_init( SPColorSelectorClass *klass ) GtkWidgetClass *widget_class; widget_class = GTK_WIDGET_CLASS(klass); - parent_class = GTK_VBOX_CLASS( g_type_class_peek_parent(klass) ); - csel_signals[GRABBED] = g_signal_new( "grabbed", G_TYPE_FROM_CLASS(object_class), (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), @@ -109,6 +85,10 @@ void sp_color_selector_class_init( SPColorSelectorClass *klass ) void sp_color_selector_init( SPColorSelector *csel ) { +#if GTK_CHECK_VERSION(3,0,0) + gtk_orientable_set_orientation(GTK_ORIENTABLE(csel), GTK_ORIENTATION_VERTICAL); +#endif + if ( csel->base ) { csel->base->init(); @@ -125,8 +105,8 @@ void sp_color_selector_dispose(GObject *object) csel->base = 0; } - if ( (G_OBJECT_CLASS(parent_class))->dispose ) { - (* (G_OBJECT_CLASS(parent_class))->dispose)(object); + if ((G_OBJECT_CLASS(sp_color_selector_parent_class))->dispose ) { + (G_OBJECT_CLASS(sp_color_selector_parent_class))->dispose(object); } } diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h index 616d5a9e7..9d71a4a56 100644 --- a/src/widgets/sp-color-selector.h +++ b/src/widgets/sp-color-selector.h @@ -62,13 +62,21 @@ private: #define SP_COLOR_SELECTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SP_TYPE_COLOR_SELECTOR, SPColorSelectorClass)) struct SPColorSelector { +#if GTK_CHECK_VERSION(3,0,0) + GtkBox vbox; +#else GtkVBox vbox; +#endif ColorSelector* base; }; struct SPColorSelectorClass { +#if GTK_CHECK_VERSION(3,0,0) + GtkBoxClass parent_class; +#else GtkVBoxClass parent_class; +#endif const gchar **name; guint submode_count; -- cgit v1.2.3 From 8f245aa1c469be664b0811d6353c34a431a4e00d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 19:59:01 +0100 Subject: Fix gdk_display_get_n_screens deprecation (bzr r13341.1.161) --- src/debug/log-display-config.cpp | 6 ++++++ src/ege-color-prof-tracker.cpp | 9 +++++++++ 2 files changed, 15 insertions(+) (limited to 'src') diff --git a/src/debug/log-display-config.cpp b/src/debug/log-display-config.cpp index 07380b3ad..ecc05b7b7 100644 --- a/src/debug/log-display-config.cpp +++ b/src/debug/log-display-config.cpp @@ -10,6 +10,7 @@ */ #include +#include #include #include "debug/event-tracker.h" #include "debug/logger.h" @@ -58,11 +59,16 @@ public: Display() : ConfigurationEvent("display") {} void generateChildEvents() const { GdkDisplay *display=gdk_display_get_default(); +#if GTK_CHECK_VERSION(3,10,0) + GdkScreen *screen = gdk_display_get_screen(display, 0); + Logger::write(screen); +#else gint n_screens = gdk_display_get_n_screens(display); for ( gint i = 0 ; i < n_screens ; i++ ) { GdkScreen *screen = gdk_display_get_screen(display, i); Logger::write(screen); } +#endif } }; diff --git a/src/ege-color-prof-tracker.cpp b/src/ege-color-prof-tracker.cpp index eca90ecb7..78ee6b8b5 100644 --- a/src/ege-color-prof-tracker.cpp +++ b/src/ege-color-prof-tracker.cpp @@ -273,8 +273,13 @@ void ege_color_prof_tracker_get_profile_for( guint screenNum, guint monitor, gpo gpointer dataPos = 0; guint dataLen = 0; GdkDisplay* display = gdk_display_get_default(); + +#if GTK_CHECK_VERSION(3,10,0) + GdkScreen* screen = (screenNum < 1) ? gdk_display_get_screen(display, screenNum) : 0; +#else gint numScreens = gdk_display_get_n_screens(display); GdkScreen* screen = (screenNum < (guint)numScreens) ? gdk_display_get_screen(display, screenNum) : 0; +#endif if ( screen ) { GSList* curr = tracked_screens; @@ -494,7 +499,11 @@ GdkFilterReturn x11_win_filter(GdkXEvent *xevent, if ( stat ) { GdkDisplay* display = gdk_x11_lookup_xdisplay(native->xproperty.display); if ( display ) { +#if GTK_CHECK_VERSION(3,10,0) + gint screenCount = 1; +#else gint screenCount = gdk_display_get_n_screens(display); +#endif GdkScreen* targetScreen = 0; gint i = 0; for ( i = 0; i < screenCount; i++ ) { -- cgit v1.2.3 From 04e446028fadd0c810cc92b26cdcdf12d2ad15e4 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 20:23:04 +0100 Subject: icon: gtk_widget_get_state deprecation fix (bzr r13341.1.162) --- src/widgets/icon.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index a96f47124..a6e53d638 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -247,7 +247,11 @@ gboolean IconImpl::draw(GtkWidget *widget, cairo_t* cr) bool unref_image = false; /* copied from the expose function of GtkImage */ +#if GTK_CHECK_VERSION(3,0,0) + if (gtk_widget_get_state_flags (GTK_WIDGET(icon)) != GTK_STATE_FLAG_NORMAL && image) { +#else if (gtk_widget_get_state (GTK_WIDGET(icon)) != GTK_STATE_NORMAL && image) { +#endif GtkIconSource *source = gtk_icon_source_new(); gtk_icon_source_set_pixbuf(source, icon->pb); gtk_icon_source_set_size(source, GTK_ICON_SIZE_SMALL_TOOLBAR); // note: this is boilerplate and not used -- cgit v1.2.3 From f11a03029f602a7ca1faccb41bf565a4ff8a2b5b Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 20:26:01 +0100 Subject: spw-utilities: gtk_widget_modify_font deprecation fix (bzr r13341.1.163) --- src/widgets/spw-utilities.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index 9c0c8d7c6..96aae020a 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -238,7 +238,11 @@ sp_set_font_size_recursive (GtkWidget *w, gpointer font) PangoFontDescription* pan = pango_font_description_new (); pango_font_description_set_size (pan, size); +#if GTK_CHECK_VERSION(3,0,0) + gtk_widget_override_font (w, pan); +#else gtk_widget_modify_font (w, pan); +#endif if (GTK_IS_CONTAINER(w)) { gtk_container_foreach (GTK_CONTAINER(w), (GtkCallback) sp_set_font_size_recursive, font); -- cgit v1.2.3 From 05de4f998a3ff9cd14af7e3f0ca49e92cff8e40a Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 20:37:35 +0100 Subject: gtk_widget_set_margin_left/right deprecation fix (bzr r13341.1.164) --- src/widgets/sp-color-icc-selector.cpp | 6 ++++++ src/widgets/sp-color-notebook.cpp | 15 +++++++++++++++ src/widgets/sp-color-scales.cpp | 15 +++++++++++++++ src/widgets/sp-color-wheel-selector.cpp | 15 +++++++++++++++ src/widgets/spw-utilities.cpp | 7 +++++++ 5 files changed, 58 insertions(+) (limited to 'src') diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index 53e73dd57..ff34fefe0 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -205,8 +205,14 @@ void attachToGridOrTable(GtkWidget *parent, guint ypadding = YPAD) { #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start( child, xpadding ); + gtk_widget_set_margin_end( child, xpadding ); + #else gtk_widget_set_margin_left( child, xpadding ); gtk_widget_set_margin_right( child, xpadding ); + #endif + gtk_widget_set_margin_top( child, ypadding ); gtk_widget_set_margin_bottom( child, ypadding ); if (hexpand) { diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index e081f98e0..dcfd73742 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -289,8 +289,13 @@ void ColorNotebook::init() sp_set_font_size_smaller (_buttonbox); #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_buttonbox, XPAD); + gtk_widget_set_margin_end(_buttonbox, XPAD); + #else gtk_widget_set_margin_left(_buttonbox, XPAD); gtk_widget_set_margin_right(_buttonbox, XPAD); + #endif gtk_widget_set_margin_top(_buttonbox, YPAD); gtk_widget_set_margin_bottom(_buttonbox, YPAD); gtk_widget_set_hexpand(_buttonbox, TRUE); @@ -306,8 +311,13 @@ void ColorNotebook::init() row++; #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_book, XPAD*2); + gtk_widget_set_margin_end(_book, XPAD*2); + #else gtk_widget_set_margin_left(_book, XPAD*2); gtk_widget_set_margin_right(_book, XPAD*2); + #endif gtk_widget_set_margin_top(_book, YPAD); gtk_widget_set_margin_bottom(_book, YPAD); gtk_widget_set_hexpand(_book, TRUE); @@ -434,8 +444,13 @@ void ColorNotebook::init() #endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(rgbabox, XPAD); + gtk_widget_set_margin_end(rgbabox, XPAD); + #else gtk_widget_set_margin_left(rgbabox, XPAD); gtk_widget_set_margin_right(rgbabox, XPAD); + #endif gtk_widget_set_margin_top(rgbabox, YPAD); gtk_widget_set_margin_bottom(rgbabox, YPAD); gtk_grid_attach(GTK_GRID(table), rgbabox, 0, row, 2, 1); diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp index c3f9d511c..c98d7ce57 100644 --- a/src/widgets/sp-color-scales.cpp +++ b/src/widgets/sp-color-scales.cpp @@ -151,8 +151,13 @@ void ColorScales::init() gtk_widget_show (_l[i]); #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_l[i], XPAD); + gtk_widget_set_margin_end(_l[i], XPAD); + #else gtk_widget_set_margin_left(_l[i], XPAD); gtk_widget_set_margin_right(_l[i], XPAD); + #endif gtk_widget_set_margin_top(_l[i], YPAD); gtk_widget_set_margin_bottom(_l[i], YPAD); gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1); @@ -167,8 +172,13 @@ void ColorScales::init() gtk_widget_show (_s[i]); #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_s[i], XPAD); + gtk_widget_set_margin_end(_s[i], XPAD); + #else gtk_widget_set_margin_left(_s[i], XPAD); gtk_widget_set_margin_right(_s[i], XPAD); + #endif gtk_widget_set_margin_top(_s[i], YPAD); gtk_widget_set_margin_bottom(_s[i], YPAD); gtk_widget_set_hexpand(_s[i], TRUE); @@ -184,8 +194,13 @@ void ColorScales::init() gtk_widget_show (_b[i]); #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_b[i], XPAD); + gtk_widget_set_margin_end(_b[i], XPAD); + #else gtk_widget_set_margin_left(_b[i], XPAD); gtk_widget_set_margin_right(_b[i], XPAD); + #endif gtk_widget_set_margin_top(_b[i], YPAD); gtk_widget_set_margin_bottom(_b[i], YPAD); gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER); diff --git a/src/widgets/sp-color-wheel-selector.cpp b/src/widgets/sp-color-wheel-selector.cpp index 7c8bb1df7..cac78238d 100644 --- a/src/widgets/sp-color-wheel-selector.cpp +++ b/src/widgets/sp-color-wheel-selector.cpp @@ -142,8 +142,13 @@ void ColorWheelSelector::init() gtk_widget_show (_label); #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_label, XPAD); + gtk_widget_set_margin_end(_label, XPAD); + #else gtk_widget_set_margin_left(_label, XPAD); gtk_widget_set_margin_right(_label, XPAD); + #endif gtk_widget_set_margin_top(_label, YPAD); gtk_widget_set_margin_bottom(_label, YPAD); gtk_widget_set_halign(_label, GTK_ALIGN_FILL); @@ -162,8 +167,13 @@ void ColorWheelSelector::init() gtk_widget_show (_slider); #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_slider, XPAD); + gtk_widget_set_margin_end(_slider, XPAD); + #else gtk_widget_set_margin_left(_slider, XPAD); gtk_widget_set_margin_right(_slider, XPAD); + #endif gtk_widget_set_margin_top(_slider, YPAD); gtk_widget_set_margin_bottom(_slider, YPAD); gtk_widget_set_hexpand(_slider, TRUE); @@ -188,8 +198,13 @@ void ColorWheelSelector::init() gtk_widget_show (_sbtn); #if GTK_CHECK_VERSION(3,0,0) + #if GTK_CHECK_VERSION(3,12,0) + gtk_widget_set_margin_start(_sbtn, XPAD); + gtk_widget_set_margin_end(_sbtn, XPAD); + #else gtk_widget_set_margin_left(_sbtn, XPAD); gtk_widget_set_margin_right(_sbtn, XPAD); + #endif gtk_widget_set_margin_top(_sbtn, YPAD); gtk_widget_set_margin_bottom(_sbtn, YPAD); gtk_widget_set_halign(_sbtn, GTK_ALIGN_CENTER); diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index 96aae020a..f87889bb1 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -64,8 +64,15 @@ Gtk::Label * spw_label(Gtk::Table *table, const gchar *label_text, int col, int label_widget->set_hexpand(); label_widget->set_halign(Gtk::ALIGN_FILL); label_widget->set_valign(Gtk::ALIGN_CENTER); + + #if GTK_CHECK_VERSION(3,12,0) + label_widget->set_margin_start(4); + label_widget->set_margin_end(4); + #else label_widget->set_margin_left(4); label_widget->set_margin_right(4); + #endif + table->attach(*label_widget, col, row, 1, 1); #else table->attach(*label_widget, col, col+1, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 4, 0); -- cgit v1.2.3 From fd314c7cbec965ec702c3ea80e1e48d41302d687 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 21:30:32 +0100 Subject: Fix deprecated VBox use (bzr r13341.1.165) --- src/extension/internal/cdr-input.cpp | 6 +++--- src/extension/internal/vsd-input.cpp | 6 +++--- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 2 +- src/ui/dialog/new-from-template.cpp | 4 ++-- src/widgets/gradient-selector.h | 8 ++++++++ src/widgets/gradient-vector.h | 4 ++++ 6 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index 0111ed626..f4da79b79 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -139,9 +139,9 @@ CdrImportDialog::CdrImportDialog(const std::vector &vec) _labelTotalPages->set_use_markup(false); _labelTotalPages->set_selectable(false); vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); - this->get_vbox()->set_homogeneous(false); - this->get_vbox()->set_spacing(0); - this->get_vbox()->pack_start(*vbox2); + this->get_content_area()->set_homogeneous(false); + this->get_content_area()->set_spacing(0); + this->get_content_area()->pack_start(*vbox2); this->set_title(_("Page Selector")); this->set_modal(true); sp_transientize(GTK_WIDGET(this->gobj())); //Make transient diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 6fc79237b..65a07d48f 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -138,9 +138,9 @@ VsdImportDialog::VsdImportDialog(const std::vector &vec) _labelTotalPages->set_use_markup(false); _labelTotalPages->set_selectable(false); vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); - this->get_vbox()->set_homogeneous(false); - this->get_vbox()->set_spacing(0); - this->get_vbox()->pack_start(*vbox2); + this->get_content_area()->set_homogeneous(false); + this->get_content_area()->set_spacing(0); + this->get_content_area()->pack_start(*vbox2); this->set_title(_("Page Selector")); this->set_modal(true); sp_transientize(GTK_WIDGET(this->gobj())); //Make transient diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index a68c7ee08..c1e16495b 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -44,7 +44,7 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { - Gtk::Box *mainVBox = get_vbox(); + Gtk::Box *mainVBox = get_content_area(); mainVBox->set_homogeneous(false); _layout_table.set_spacings(4); _layout_table.resize(2, 2); diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index f326bb3ee..5ce96d10f 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -26,11 +26,11 @@ NewFromTemplate::NewFromTemplate() set_title(_("New From Template")); resize(400, 400); - get_vbox()->pack_start(_main_widget); + get_content_area()->pack_start(_main_widget); Gtk::Alignment *align; align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); - get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); + get_content_area()->pack_end(*align, Gtk::PACK_SHRINK); align->set_padding(0, 0, 0, 15); align->add(_create_template_button); diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h index ee8980be9..1a6468ad4 100644 --- a/src/widgets/gradient-selector.h +++ b/src/widgets/gradient-selector.h @@ -49,7 +49,11 @@ class SPGradient; struct SPGradientSelector { +#if GTK_CHECK_VERSION(3,0,0) + GtkBox vbox; +#else GtkVBox vbox; +#endif enum SelectorMode { MODE_LINEAR, @@ -131,7 +135,11 @@ struct SPGradientSelector { }; struct SPGradientSelectorClass { +#if GTK_CHECK_VERSION(3,0,0) + GtkBoxClass parent_class; +#else GtkVBoxClass parent_class; +#endif void (* grabbed) (SPGradientSelector *sel); void (* dragged) (SPGradientSelector *sel); diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index 0b653b016..fc85b0d9c 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -43,7 +43,11 @@ class SPGradient; class SPStop; struct SPGradientVectorSelector { +#if GTK_CHECK_VERSION(3,0,0) + GtkBox vbox; +#else GtkVBox vbox; +#endif guint idlabel : 1; -- cgit v1.2.3 From 918f35a25e33815f8e286488898269b90d2519db Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 23 Aug 2014 16:32:03 -0400 Subject: Turn on double-buffering of the canvas (bzr r13341.1.166) --- src/display/sp-canvas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 3dc4a7504..8434f6ae2 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1230,7 +1230,7 @@ static void sp_canvas_init(SPCanvas *canvas) { gtk_widget_set_has_window (GTK_WIDGET (canvas), TRUE); - gtk_widget_set_double_buffered (GTK_WIDGET (canvas), FALSE); + //gtk_widget_set_double_buffered (GTK_WIDGET (canvas), TRUE); gtk_widget_set_can_focus (GTK_WIDGET (canvas), TRUE); canvas->pick_event.type = GDK_LEAVE_NOTIFY; -- cgit v1.2.3 From 15e0c3e9f564677c12add77f7eec01e4e419b300 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 21:39:20 +0100 Subject: Fix deprecated GtkHBox use (bzr r13341.1.167) --- src/live_effects/parameter/togglebutton.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index 5658d238f..c5da8b858 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -5,10 +5,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include "ui/widget/registered-widget.h" #include -#include "ui/widget/registered-widget.h" #include "live_effects/parameter/togglebutton.h" #include "live_effects/effect.h" #include "svg/svg.h" @@ -75,7 +74,12 @@ ToggleButtonParam::param_newWidget() false, param_effect->getRepr(), param_effect->getSPDoc()) ); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget * boxButton = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous(GTK_BOX(boxButton), false); +#else GtkWidget * boxButton = gtk_hbox_new (false, 0); +#endif GtkWidget * labelButton = gtk_label_new (""); if (!param_label.empty()) { if(value || inactiveLabel.empty()){ -- cgit v1.2.3 From c94e03f5c17249c7ef2ebcbe96b2a353aef6d186 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 22:03:16 +0100 Subject: Fix orientable Gtkmm widgets (bzr r13341.1.168) --- src/live_effects/lpe-envelope-perspective.cpp | 15 ++++++++++++++- src/live_effects/lpe-roughen.cpp | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-envelope-perspective.cpp b/src/live_effects/lpe-envelope-perspective.cpp index 02cb67db3..5ada7a792 100644 --- a/src/live_effects/lpe-envelope-perspective.cpp +++ b/src/live_effects/lpe-envelope-perspective.cpp @@ -286,12 +286,20 @@ LPEEnvelopePerspective::newWidget() Gtk::Label* handles = Gtk::manage(new Gtk::Label(Glib::ustring(_("Handles:")),Gtk::ALIGN_START)); vbox->pack_start(*handles, false, false, 2); hboxUpHandles->pack_start(*widg, true, true, 2); +#if WITH_GTKMM_3_0 + hboxUpHandles->pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), Gtk::PACK_EXPAND_WIDGET); +#else hboxUpHandles->pack_start(*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_EXPAND_WIDGET); +#endif }else if(param->param_key == "Up_Right_Point"){ hboxUpHandles->pack_start(*widg, true, true, 2); }else if(param->param_key == "Down_Left_Point"){ hboxDownHandles->pack_start(*widg, true, true, 2); +#if WITH_GTKMM_3_0 + hboxDownHandles->pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), Gtk::PACK_EXPAND_WIDGET); +#else hboxDownHandles->pack_start(*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_EXPAND_WIDGET); +#endif }else{ hboxDownHandles->pack_start(*widg, true, true, 2); } @@ -320,8 +328,13 @@ LPEEnvelopePerspective::newWidget() } vbox->pack_start(*hboxUpHandles,true, true, 2); Gtk::HBox * hboxMiddle = Gtk::manage(new Gtk::HBox(true,2)); +#if WITH_GTKMM_3_0 + hboxMiddle->pack_start(*Gtk::manage(new Gtk::Separator()), Gtk::PACK_EXPAND_WIDGET); + hboxMiddle->pack_start(*Gtk::manage(new Gtk::Separator()), Gtk::PACK_EXPAND_WIDGET); +#else hboxMiddle->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); hboxMiddle->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); +#endif vbox->pack_start(*hboxMiddle, false, true, 2); vbox->pack_start(*hboxDownHandles, true, true, 2); Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); @@ -422,4 +435,4 @@ LPEEnvelopePerspective::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::v fill-column:99 End: */ -// vim: file_type=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 9af849530..5f6acd6f4 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -2,9 +2,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "live_effects/lpe-roughen.h" +#include + #include "display/curve.h" #include "live_effects/parameter/parameter.h" #include "helper/geom.h" @@ -82,7 +82,11 @@ Gtk::Widget *LPERoughen::newWidget() { Glib::ustring(_("Roughen unit")), Gtk::ALIGN_START)); unitLabel->set_use_markup(true); vbox->pack_start(*unitLabel, false, false, 2); +#if WITH_GTKMM_3_0 + vbox->pack_start(*Gtk::manage(new Gtk::Separator()), +#else vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), +#endif Gtk::PACK_EXPAND_WIDGET); } if (param->param_key == "method") { @@ -91,7 +95,11 @@ Gtk::Widget *LPERoughen::newWidget() { Gtk::ALIGN_START)); methodLabel->set_use_markup(true); vbox->pack_start(*methodLabel, false, false, 2); +#if WITH_GTKMM_3_0 + vbox->pack_start(*Gtk::manage(new Gtk::Separator()), +#else vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), +#endif Gtk::PACK_EXPAND_WIDGET); } if (param->param_key == "displaceX") { @@ -100,7 +108,11 @@ Gtk::Widget *LPERoughen::newWidget() { Gtk::ALIGN_START)); displaceXLabel->set_use_markup(true); vbox->pack_start(*displaceXLabel, false, false, 2); +#if WITH_GTKMM_3_0 + vbox->pack_start(*Gtk::manage(new Gtk::Separator()), +#else vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), +#endif Gtk::PACK_EXPAND_WIDGET); } Glib::ustring *tip = param->param_getTooltip(); -- cgit v1.2.3 From 6388fa1d00b2731feb0b9eedd03c2751d2efee84 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 22:35:35 +0100 Subject: Migrate more widgets to Gtk::Grid (bzr r13341.1.169) --- src/ui/dialog/grid-arrange-tab.h | 8 +++++--- src/ui/dialog/polar-arrange-tab.cpp | 32 ++++++++++++++++++++++++++++++++ src/ui/dialog/polar-arrange-tab.h | 19 ++++++++++++++++++- src/ui/widget/anchor-selector.cpp | 16 +++++++++++++++- src/ui/widget/anchor-selector.h | 20 ++++++++++++++++++-- 5 files changed, 88 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/grid-arrange-tab.h b/src/ui/dialog/grid-arrange-tab.h index 9d6700b39..a137d1694 100644 --- a/src/ui/dialog/grid-arrange-tab.h +++ b/src/ui/dialog/grid-arrange-tab.h @@ -17,14 +17,16 @@ #ifndef INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H #define INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H -#include - +#include "ui/widget/scalar-unit.h" #include "ui/dialog/arrange-tab.h" #include "ui/widget/anchor-selector.h" -#include "ui/widget/scalar-unit.h" #include "ui/widget/spinbutton.h" +#include +#include +#include + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index a00b8fc02..80579c9d3 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -25,6 +25,7 @@ #include "desktop.h" #include "sp-ellipse.h" #include "sp-item-transform.h" +#include namespace Inkscape { namespace UI { @@ -32,7 +33,11 @@ namespace Dialog { PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) : parent(parent_), +#if WITH_GTKMM_3_0 + parametersTable(), +#else parametersTable(3, 3, false), +#endif centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR), centerX("", "X coordinate of the center", centerY), radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR), @@ -76,7 +81,11 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) pack_start(arrangeOnParametersRadio, false, false); centerLabel.set_text(_("Center X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(centerLabel, 0, 0, 1, 1); +#else parametersTable.attach(centerLabel, 0, 1, 0, 1, Gtk::FILL); +#endif centerX.setDigits(2); centerX.setIncrements(0.2, 0); centerX.setRange(-10000, 10000); @@ -85,11 +94,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) centerY.setIncrements(0.2, 0); centerY.setRange(-10000, 10000); centerY.setValue(0, "px"); +#if WITH_GTKMM_3_0 + parametersTable.attach(centerX, 1, 0, 1, 1); + parametersTable.attach(centerY, 2, 0, 1, 1); +#else parametersTable.attach(centerX, 1, 2, 0, 1, Gtk::FILL); parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL); +#endif radiusLabel.set_text(_("Radius X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(radiusLabel, 0, 1, 1, 1); +#else parametersTable.attach(radiusLabel, 0, 1, 1, 2, Gtk::FILL); +#endif radiusX.setDigits(2); radiusX.setIncrements(0.2, 0); radiusX.setRange(0.001, 10000); @@ -98,11 +116,20 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) radiusY.setIncrements(0.2, 0); radiusY.setRange(0.001, 10000); radiusY.setValue(100, "px"); +#if WITH_GTKMM_3_0 + parametersTable.attach(radiusX, 1, 1, 1, 1); + parametersTable.attach(radiusY, 2, 1, 1, 1); +#else parametersTable.attach(radiusX, 1, 2, 1, 2, Gtk::FILL); parametersTable.attach(radiusY, 2, 3, 1, 2, Gtk::FILL); +#endif angleLabel.set_text(_("Angle X/Y:")); +#if WITH_GTKMM_3_0 + parametersTable.attach(angleLabel, 0, 2, 1, 1); +#else parametersTable.attach(angleLabel, 0, 1, 2, 3, Gtk::FILL); +#endif angleX.setDigits(2); angleX.setIncrements(0.2, 0); angleX.setRange(-10000, 10000); @@ -111,8 +138,13 @@ PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) angleY.setIncrements(0.2, 0); angleY.setRange(-10000, 10000); angleY.setValue(180, "°"); +#if WITH_GTKMM_3_0 + parametersTable.attach(angleX, 1, 2, 1, 1); + parametersTable.attach(angleY, 2, 2, 1, 1); +#else parametersTable.attach(angleX, 1, 2, 2, 3, Gtk::FILL); parametersTable.attach(angleY, 2, 3, 2, 3, Gtk::FILL); +#endif pack_start(parametersTable, false, false); rotateObjectsCheckBox.set_label(_("Rotate objects")); diff --git a/src/ui/dialog/polar-arrange-tab.h b/src/ui/dialog/polar-arrange-tab.h index f6c3b2906..f7d7bf11f 100644 --- a/src/ui/dialog/polar-arrange-tab.h +++ b/src/ui/dialog/polar-arrange-tab.h @@ -10,9 +10,22 @@ #ifndef INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H #define INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include "ui/widget/scalar-unit.h" #include "ui/widget/anchor-selector.h" #include "ui/dialog/arrange-tab.h" -#include "ui/widget/scalar-unit.h" + +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif namespace Inkscape { namespace UI { @@ -62,7 +75,11 @@ private: Gtk::RadioButton arrangeOnLastCircleRadio; Gtk::RadioButton arrangeOnParametersRadio; +#if WITH_GTKMM_3_0 + Gtk::Grid parametersTable; +#else Gtk::Table parametersTable; +#endif Gtk::Label centerLabel; Inkscape::UI::Widget::ScalarUnit centerY; diff --git a/src/ui/widget/anchor-selector.cpp b/src/ui/widget/anchor-selector.cpp index 82e27ee89..df00b786a 100644 --- a/src/ui/widget/anchor-selector.cpp +++ b/src/ui/widget/anchor-selector.cpp @@ -28,7 +28,11 @@ void AnchorSelector::setupButton(const Glib::ustring& icon, Gtk::ToggleButton& b AnchorSelector::AnchorSelector() : Gtk::Alignment(0.5, 0, 0, 0), +#if WITH_GTKMM_3_0 + _container() +#else _container(3, 3, true) +#endif { setupButton(INKSCAPE_ICON("boundingbox_top_left"), _buttons[0]); setupButton(INKSCAPE_ICON("boundingbox_top"), _buttons[1]); @@ -40,10 +44,20 @@ AnchorSelector::AnchorSelector() setupButton(INKSCAPE_ICON("boundingbox_bottom"), _buttons[7]); setupButton(INKSCAPE_ICON("boundingbox_bottom_right"), _buttons[8]); +#if WITH_GTKMM_3_0 + _container.set_row_homogeneous(); + _container.set_column_homogeneous(true); +#endif + for(int i = 0; i < 9; ++i) { _buttons[i].signal_clicked().connect( sigc::bind(sigc::mem_fun(*this, &AnchorSelector::btn_activated), i)); + +#if WITH_GTKMM_3_0 + _container.attach(_buttons[i], i % 3, i / 3, 1, 1); +#else _container.attach(_buttons[i], i % 3, i % 3+1, i / 3, i / 3+1, Gtk::FILL, Gtk::FILL); +#endif } _selection = 4; _buttons[4].set_active(); @@ -94,4 +108,4 @@ void AnchorSelector::setAlignment(int horizontal, int vertical) fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/widget/anchor-selector.h b/src/ui/widget/anchor-selector.h index 2263438e3..0a702d296 100644 --- a/src/ui/widget/anchor-selector.h +++ b/src/ui/widget/anchor-selector.h @@ -10,7 +10,18 @@ #ifndef ANCHOR_SELECTOR_H_ #define ANCHOR_SELECTOR_H_ -#include +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif namespace Inkscape { namespace UI { @@ -21,7 +32,12 @@ class AnchorSelector : public Gtk::Alignment private: Gtk::ToggleButton _buttons[9]; int _selection; + +#if WITH_GTKMM_3_0 + Gtk::Grid _container; +#else Gtk::Table _container; +#endif sigc::signal _selectionChanged; @@ -56,4 +72,4 @@ public: fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- cgit v1.2.3 From 81ae160f5d204d3841505a6c364c064f77f17f88 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Aug 2014 22:52:01 +0100 Subject: Finish Gtk::Grid migration (bzr r13341.1.170) --- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 13 +++++++++++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index c1e16495b..f5a554b36 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -46,18 +46,31 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() { Gtk::Box *mainVBox = get_content_area(); mainVBox->set_homogeneous(false); + +#if WITH_GTKMM_3_0 + _layout_table.set_row_spacing(4); + _layout_table.set_column_spacing(4); +#else _layout_table.set_spacings(4); _layout_table.resize(2, 2); +#endif // Layer name widgets _fillet_chamfer_position_entry.set_activates_default(true); _fillet_chamfer_position_label.set_label(_("Radius (pixels):")); _fillet_chamfer_position_label.set_alignment(1.0, 0.5); +#if WITH_GTKMM_3_0 + _layout_table.attach(_fillet_chamfer_position_label, 0, 0, 1, 1); + _layout_table.attach(_fillet_chamfer_position_entry, 1, 0, 1, 1); + _fillet_chamfer_position_entry.set_hexpand(); +#else _layout_table.attach(_fillet_chamfer_position_label, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); _layout_table.attach(_fillet_chamfer_position_entry, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); +#endif + _fillet_chamfer_type_fillet.set_label(_("Fillet")); _fillet_chamfer_type_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_inverse_fillet.set_label(_("Inverse fillet")); diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index d3e859bff..6667e5785 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -8,10 +8,24 @@ #ifndef INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H #define INKSCAPE_DIALOG_FILLET_CHAMFER_PROPERTIES_H +#if HAVE_CONFIG_H + #include "config.h" +#endif + #include <2geom/point.h> -#include #include "live_effects/parameter/filletchamferpointarray.h" +#include +#include +#include +#include + +#if WITH_GTKMM_3_0 + #include +#else + #include +#endif + class SPDesktop; namespace Inkscape { @@ -46,7 +60,12 @@ protected: Gtk::RadioButton _fillet_chamfer_type_chamfer; Gtk::RadioButton _fillet_chamfer_type_double_chamfer; +#if WITH_GTKMM_3_0 + Gtk::Grid _layout_table; +#else Gtk::Table _layout_table; +#endif + bool _position_visible; double _index; -- cgit v1.2.3 From a3e1d94ae50f769d2b1539307cf182ce5801e647 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 11:37:18 +0100 Subject: Fix Gtk+ 2 build (bzr r13341.1.171) --- src/extension/internal/cdr-input.cpp | 6 ++++++ src/extension/internal/vsd-input.cpp | 6 ++++++ src/live_effects/parameter/filletchamferpointarray.cpp | 4 ++-- src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 5 +++++ src/ui/dialog/lpe-fillet-chamfer-properties.h | 2 +- src/ui/dialog/new-from-template.cpp | 15 ++++++++++++++- 6 files changed, 34 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index f4da79b79..b8f429a87 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -139,9 +139,15 @@ CdrImportDialog::CdrImportDialog(const std::vector &vec) _labelTotalPages->set_use_markup(false); _labelTotalPages->set_selectable(false); vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); +#if WITH_GTKMM_3_0 this->get_content_area()->set_homogeneous(false); this->get_content_area()->set_spacing(0); this->get_content_area()->pack_start(*vbox2); +#else + this->get_vbox()->set_homogeneous(false); + this->get_vbox()->set_spacing(0); + this->get_vbox()->pack_start(*vbox2); +#endif this->set_title(_("Page Selector")); this->set_modal(true); sp_transientize(GTK_WIDGET(this->gobj())); //Make transient diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 65a07d48f..83bfb5a92 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -138,9 +138,15 @@ VsdImportDialog::VsdImportDialog(const std::vector &vec) _labelTotalPages->set_use_markup(false); _labelTotalPages->set_selectable(false); vbox2->pack_start(*_previewArea, Gtk::PACK_SHRINK, 0); +#if WITH_GTKMM_3_0 this->get_content_area()->set_homogeneous(false); this->get_content_area()->set_spacing(0); this->get_content_area()->pack_start(*vbox2); +#else + this->get_vbox()->set_homogeneous(false); + this->get_vbox()->set_spacing(0); + this->get_vbox()->pack_start(*vbox2); +#endif this->set_title(_("Page Selector")); this->set_modal(true); sp_transientize(GTK_WIDGET(this->gobj())); //Make transient diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index 147d6baa2..a89a6279b 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -8,12 +8,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "ui/dialog/lpe-fillet-chamfer-properties.h" +#include "live_effects/parameter/filletchamferpointarray.h" #include <2geom/piecewise.h> #include <2geom/sbasis-to-bezier.h> #include <2geom/sbasis-geometric.h> -#include "ui/dialog/lpe-fillet-chamfer-properties.h" -#include "live_effects/parameter/filletchamferpointarray.h" #include "live_effects/effect.h" #include "svg/svg.h" #include "svg/stringstream.h" diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index f5a554b36..eef32d10d 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -44,7 +44,12 @@ namespace Dialogs { FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() : _desktop(NULL), _knotpoint(NULL), _position_visible(false) { +#if WITH_GTKMM_3_0 Gtk::Box *mainVBox = get_content_area(); +#else + Gtk::Box *mainVBox = get_vbox(); +#endif + mainVBox->set_homogeneous(false); #if WITH_GTKMM_3_0 diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 6667e5785..9beca02e1 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -12,10 +12,10 @@ #include "config.h" #endif +#include #include <2geom/point.h> #include "live_effects/parameter/filletchamferpointarray.h" -#include #include #include #include diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index 5ce96d10f..e30b148bb 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -8,6 +8,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#if HAVE_CONFIG_H + #include "config.h" +#endif #include "new-from-template.h" #include "file.h" @@ -25,12 +28,22 @@ NewFromTemplate::NewFromTemplate() { set_title(_("New From Template")); resize(400, 400); - + +#if WITH_GTKMM_3_0 get_content_area()->pack_start(_main_widget); +#else + get_vbox()->pack_start(_main_widget); +#endif Gtk::Alignment *align; align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); + +#if WITH_GTKMM_3_0 get_content_area()->pack_end(*align, Gtk::PACK_SHRINK); +#else + get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); +#endif + align->set_padding(0, 0, 0, 15); align->add(_create_template_button); -- cgit v1.2.3 From 8920e3ea655df6447e2ed6f8b0b5621442d20cb5 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 12:31:46 +0100 Subject: Fix strict build with Gtk+ 2 (bzr r13341.1.172) --- src/libnrtype/font-lister.cpp | 2 +- src/ui/tools/tool-base.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 1b4d9d256..6f25ab5f9 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -2,8 +2,8 @@ #include #endif -#include #include +#include #include #include diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index c23da87c0..c28b86416 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -18,6 +18,8 @@ # include "config.h" #endif +#include "widgets/desktop-widget.h" + #if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H #include #endif @@ -40,7 +42,6 @@ #include "desktop-handles.h" #include "desktop-events.h" #include "desktop-style.h" -#include "widgets/desktop-widget.h" #include "sp-namedview.h" #include "selection.h" #include "interface.h" -- cgit v1.2.3 From 94b7715e1e82202aff812fa429d817e497ea8868 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 14:03:51 +0100 Subject: desktop-widget: GObject boilerplate reduction (bzr r13341.1.173) --- src/widgets/desktop-widget.cpp | 137 ++++++++++++++++++----------------------- src/widgets/desktop-widget.h | 41 ++++++------ 2 files changed, 84 insertions(+), 94 deletions(-) (limited to 'src') diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 1b4648286..9bc9958c7 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -98,7 +98,6 @@ enum { //--------------------------------------------------------------------- /* SPDesktopWidget */ -static void sp_desktop_widget_class_init (SPDesktopWidgetClass *klass); static void sp_desktop_widget_dispose(GObject *object); static void sp_desktop_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation); @@ -128,8 +127,6 @@ static void sp_dtw_zoom_drawing (GtkMenuItem *item, gpointer data); static void sp_dtw_zoom_selection (GtkMenuItem *item, gpointer data); static void sp_dtw_sticky_zoom_toggled (GtkMenuItem *item, gpointer data); -SPViewWidgetClass *dtw_parent_class; - class CMSPrefWatcher { public: CMSPrefWatcher() : @@ -268,31 +265,19 @@ SPDesktopWidget::window_get_pointer() static GTimer *overallTimer = 0; -/** - * Registers SPDesktopWidget class and returns its type number. - */ -GType SPDesktopWidget::getType(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPDesktopWidgetClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_desktop_widget_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPDesktopWidget), - 0, // n_preallocs - (GInstanceInitFunc)SPDesktopWidget::init, - 0 // value_table - }; - type = g_type_register_static(SP_TYPE_VIEW_WIDGET, "SPDesktopWidget", &info, static_cast(0)); - // Begin a timer to watch for the first desktop to appear on-screen - overallTimer = g_timer_new(); - } - return type; -} +struct SPDesktopWidgetPrivate +{ + GtkWidget *tool_toolbox; + GtkWidget *aux_toolbox; + GtkWidget *commands_toolbox; + GtkWidget *snap_toolbox; +}; + +G_DEFINE_TYPE_WITH_CODE(SPDesktopWidget, sp_desktop_widget, SP_TYPE_VIEW_WIDGET, + // Begin a timer to watch for the first desktop to appear on-screen + overallTimer = g_timer_new(); + G_ADD_PRIVATE(SPDesktopWidget); + ); /** * SPDesktopWidget vtable initialization @@ -300,8 +285,6 @@ GType SPDesktopWidget::getType(void) static void sp_desktop_widget_class_init (SPDesktopWidgetClass *klass) { - dtw_parent_class = SP_VIEW_WIDGET_CLASS(g_type_class_peek_parent(klass)); - GObjectClass *object_class = G_OBJECT_CLASS(klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); @@ -329,10 +312,12 @@ static void canvas_tbl_size_allocate(GtkWidget * /*widget*/, /** * Callback for SPDesktopWidget object initialization. */ -void SPDesktopWidget::init( SPDesktopWidget *dtw ) +void sp_desktop_widget_init( SPDesktopWidget *dtw ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + dtw->priv = reinterpret_cast(sp_desktop_widget_get_instance_private(dtw)); + new (&dtw->modified_connection) sigc::connection(); dtw->window = 0; @@ -377,19 +362,19 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_box_pack_end( GTK_BOX (dtw->vbox), dtw->hbox, TRUE, TRUE, 0 ); gtk_widget_show(dtw->hbox); - dtw->aux_toolbox = ToolboxFactory::createAuxToolbox(); - gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->aux_toolbox, FALSE, TRUE, 0); + dtw->priv->aux_toolbox = ToolboxFactory::createAuxToolbox(); + gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->priv->aux_toolbox, FALSE, TRUE, 0); - dtw->snap_toolbox = ToolboxFactory::createSnapToolbox(); - ToolboxFactory::setOrientation( dtw->snap_toolbox, GTK_ORIENTATION_VERTICAL ); - gtk_box_pack_end( GTK_BOX(dtw->hbox), dtw->snap_toolbox, FALSE, TRUE, 0 ); + dtw->priv->snap_toolbox = ToolboxFactory::createSnapToolbox(); + ToolboxFactory::setOrientation( dtw->priv->snap_toolbox, GTK_ORIENTATION_VERTICAL ); + gtk_box_pack_end( GTK_BOX(dtw->hbox), dtw->priv->snap_toolbox, FALSE, TRUE, 0 ); - dtw->commands_toolbox = ToolboxFactory::createCommandsToolbox(); - gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->commands_toolbox, FALSE, TRUE, 0); + dtw->priv->commands_toolbox = ToolboxFactory::createCommandsToolbox(); + gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->priv->commands_toolbox, FALSE, TRUE, 0); - dtw->tool_toolbox = ToolboxFactory::createToolToolbox(); - ToolboxFactory::setOrientation( dtw->tool_toolbox, GTK_ORIENTATION_VERTICAL ); - gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->tool_toolbox, FALSE, TRUE, 0 ); + dtw->priv->tool_toolbox = ToolboxFactory::createToolToolbox(); + ToolboxFactory::setOrientation( dtw->priv->tool_toolbox, GTK_ORIENTATION_VERTICAL ); + gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->priv->tool_toolbox, FALSE, TRUE, 0 ); /* Horizontal ruler */ GtkWidget *eventbox = gtk_event_box_new (); @@ -804,8 +789,8 @@ static void sp_desktop_widget_dispose(GObject *object) dtw->modified_connection.~connection(); - if (G_OBJECT_CLASS (dtw_parent_class)->dispose) { - (* G_OBJECT_CLASS (dtw_parent_class)->dispose) (object); + if (G_OBJECT_CLASS (sp_desktop_widget_parent_class)->dispose) { + G_OBJECT_CLASS (sp_desktop_widget_parent_class)->dispose(object); } } @@ -908,8 +893,8 @@ sp_desktop_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation) (allocation->y == widg_allocation.y) && (allocation->width == widg_allocation.width) && (allocation->height == widg_allocation.height)) { - if (GTK_WIDGET_CLASS (dtw_parent_class)->size_allocate) - GTK_WIDGET_CLASS (dtw_parent_class)->size_allocate (widget, allocation); + if (GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->size_allocate) + GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->size_allocate (widget, allocation); return; } @@ -917,8 +902,8 @@ sp_desktop_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation) Geom::Rect const area = dtw->desktop->get_display_area(); double zoom = dtw->desktop->current_zoom(); - if (GTK_WIDGET_CLASS(dtw_parent_class)->size_allocate) { - GTK_WIDGET_CLASS(dtw_parent_class)->size_allocate (widget, allocation); + if (GTK_WIDGET_CLASS(sp_desktop_widget_parent_class)->size_allocate) { + GTK_WIDGET_CLASS(sp_desktop_widget_parent_class)->size_allocate (widget, allocation); } if (SP_BUTTON_IS_DOWN(dtw->sticky_zoom)) { @@ -936,8 +921,8 @@ sp_desktop_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation) dtw->desktop->show_dialogs(); } else { - if (GTK_WIDGET_CLASS (dtw_parent_class)->size_allocate) { - GTK_WIDGET_CLASS (dtw_parent_class)->size_allocate (widget, allocation); + if (GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->size_allocate) { + GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->size_allocate (widget, allocation); } // this->size_allocate (widget, allocation); } @@ -952,8 +937,8 @@ sp_desktop_widget_realize (GtkWidget *widget) SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (widget); - if (GTK_WIDGET_CLASS (dtw_parent_class)->realize) - (* GTK_WIDGET_CLASS (dtw_parent_class)->realize) (widget); + if (GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->realize) + GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->realize(widget); Geom::Rect d = Geom::Rect::from_xywh(Geom::Point(0,0), (dtw->desktop->doc())->getDimensions()); @@ -998,8 +983,8 @@ sp_desktop_widget_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dt } } - if (GTK_WIDGET_CLASS (dtw_parent_class)->event) { - return (* GTK_WIDGET_CLASS (dtw_parent_class)->event) (widget, event); + if (GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->event) { + return GTK_WIDGET_CLASS (sp_desktop_widget_parent_class)->event(widget, event); } else { // The key press/release events need to be passed to desktop handler explicitly, // because otherwise the event contexts only receive key events when the mouse cursor @@ -1499,29 +1484,29 @@ void SPDesktopWidget::layoutWidgets() } if (!prefs->getBool(pref_root + "commands/state", true)) { - gtk_widget_hide (dtw->commands_toolbox); + gtk_widget_hide (dtw->priv->commands_toolbox); } else { - gtk_widget_show_all (dtw->commands_toolbox); + gtk_widget_show_all (dtw->priv->commands_toolbox); } if (!prefs->getBool(pref_root + "snaptoolbox/state", true)) { - gtk_widget_hide (dtw->snap_toolbox); + gtk_widget_hide (dtw->priv->snap_toolbox); } else { - gtk_widget_show_all (dtw->snap_toolbox); + gtk_widget_show_all (dtw->priv->snap_toolbox); } if (!prefs->getBool(pref_root + "toppanel/state", true)) { - gtk_widget_hide (dtw->aux_toolbox); + gtk_widget_hide (dtw->priv->aux_toolbox); } else { // we cannot just show_all because that will show all tools' panels; // this is a function from toolbox.cpp that shows only the current tool's panel - ToolboxFactory::showAuxToolbox(dtw->aux_toolbox); + ToolboxFactory::showAuxToolbox(dtw->priv->aux_toolbox); } if (!prefs->getBool(pref_root + "toolbox/state", true)) { - gtk_widget_hide (dtw->tool_toolbox); + gtk_widget_hide (dtw->priv->tool_toolbox); } else { - gtk_widget_show_all (dtw->tool_toolbox); + gtk_widget_show_all (dtw->priv->tool_toolbox); } if (!prefs->getBool(pref_root + "statusbar/state", true)) { @@ -1558,7 +1543,7 @@ void SPDesktopWidget::layoutWidgets() void SPDesktopWidget::setToolboxFocusTo (const gchar* label) { - gpointer hb = sp_search_by_data_recursive(aux_toolbox, (gpointer) label); + gpointer hb = sp_search_by_data_recursive(priv->aux_toolbox, (gpointer) label); if (hb && GTK_IS_WIDGET(hb)) { gtk_widget_grab_focus(GTK_WIDGET(hb)); @@ -1569,7 +1554,7 @@ void SPDesktopWidget::setToolboxAdjustmentValue (gchar const *id, double value) { GtkAdjustment *a = NULL; - gpointer hb = sp_search_by_data_recursive (aux_toolbox, (gpointer) id); + gpointer hb = sp_search_by_data_recursive (priv->aux_toolbox, (gpointer) id); if (hb && GTK_IS_WIDGET(hb)) { if (GTK_IS_SPIN_BUTTON(hb)) a = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(hb)); @@ -1586,7 +1571,7 @@ SPDesktopWidget::setToolboxAdjustmentValue (gchar const *id, double value) void SPDesktopWidget::setToolboxSelectOneValue (gchar const *id, int value) { - gpointer hb = sp_search_by_data_recursive(aux_toolbox, (gpointer) id); + gpointer hb = sp_search_by_data_recursive(priv->aux_toolbox, (gpointer) id); if (hb) { ege_select_one_action_set_active(EGE_SELECT_ONE_ACTION(hb), value); } @@ -1597,7 +1582,7 @@ bool SPDesktopWidget::isToolboxButtonActive (const gchar* id) { bool isActive = false; - gpointer thing = sp_search_by_data_recursive(aux_toolbox, (gpointer) id); + gpointer thing = sp_search_by_data_recursive(priv->aux_toolbox, (gpointer) id); if ( !thing ) { //g_message( "Unable to locate item for {%s}", id ); } else if ( GTK_IS_TOGGLE_BUTTON(thing) ) { @@ -1618,13 +1603,13 @@ void SPDesktopWidget::setToolboxPosition(Glib::ustring const& id, GtkPositionTyp // Note - later on these won't be individual member variables. GtkWidget* toolbox = 0; if (id == "ToolToolbar") { - toolbox = tool_toolbox; + toolbox = priv->tool_toolbox; } else if (id == "AuxToolbar") { - toolbox = aux_toolbox; + toolbox = priv->aux_toolbox; } else if (id == "CommandsToolbar") { - toolbox = commands_toolbox; + toolbox = priv->commands_toolbox; } else if (id == "SnapToolbar") { - toolbox = snap_toolbox; + toolbox = priv->snap_toolbox; } @@ -1697,10 +1682,10 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview) dtw->layoutWidgets(); std::vector toolboxes; - toolboxes.push_back(dtw->tool_toolbox); - toolboxes.push_back(dtw->aux_toolbox); - toolboxes.push_back(dtw->commands_toolbox); - toolboxes.push_back(dtw->snap_toolbox); + toolboxes.push_back(dtw->priv->tool_toolbox); + toolboxes.push_back(dtw->priv->aux_toolbox); + toolboxes.push_back(dtw->priv->commands_toolbox); + toolboxes.push_back(dtw->priv->snap_toolbox); dtw->panels->setDesktop( dtw->desktop ); @@ -1754,8 +1739,8 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) * * This should solve: https://bugs.launchpad.net/inkscape/+bug/362995 */ - if (GTK_IS_CONTAINER(aux_toolbox)) { - GList *ch = gtk_container_get_children (GTK_CONTAINER(aux_toolbox)); + if (GTK_IS_CONTAINER(priv->aux_toolbox)) { + GList *ch = gtk_container_get_children (GTK_CONTAINER(priv->aux_toolbox)); for (GList *i = ch; i != NULL; i = i->next) { if (GTK_IS_CONTAINER(i->data)) { GList *grch = gtk_container_get_children (GTK_CONTAINER(i->data)); @@ -1781,7 +1766,7 @@ void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags) gtk_widget_set_tooltip_text(this->vruler_box, gettext(nv->doc_units->name_plural.c_str())); sp_desktop_widget_update_rulers(this); - ToolboxFactory::updateSnapToolbox(this->desktop, 0, this->snap_toolbox); + ToolboxFactory::updateSnapToolbox(this->desktop, 0, priv->snap_toolbox); } } diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index a77d56fc3..9a4834d3d 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -34,15 +34,33 @@ typedef struct _EgeColorProfTracker EgeColorProfTracker; struct SPCanvas; class SPDesktop; struct SPDesktopWidget; +struct SPDesktopWidgetPrivate; class SPObject; +namespace Inkscape { + namespace Widgets { + class LayerSelector; + } -#define SP_TYPE_DESKTOP_WIDGET SPDesktopWidget::getType() -#define SP_DESKTOP_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_DESKTOP_WIDGET, SPDesktopWidget)) -#define SP_DESKTOP_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_DESKTOP_WIDGET, SPDesktopWidgetClass)) -#define SP_IS_DESKTOP_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_DESKTOP_WIDGET)) + namespace UI { + namespace Widget { + class SelectedStyle; + } + + namespace Dialogs { + class SwatchesPanel; + } + } +} + +#define SP_TYPE_DESKTOP_WIDGET (sp_desktop_widget_get_type ()) +#define SP_DESKTOP_WIDGET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_DESKTOP_WIDGET, SPDesktopWidget)) +#define SP_DESKTOP_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_DESKTOP_WIDGET, SPDesktopWidgetClass)) +#define SP_IS_DESKTOP_WIDGET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_DESKTOP_WIDGET)) #define SP_IS_DESKTOP_WIDGET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_DESKTOP_WIDGET)) +GType sp_desktop_widget_get_type(); + void sp_desktop_widget_show_decorations(SPDesktopWidget *dtw, gboolean show); void sp_desktop_widget_iconify(SPDesktopWidget *dtw); void sp_desktop_widget_maximize(SPDesktopWidget *dtw); @@ -62,12 +80,6 @@ bool sp_desktop_widget_color_prof_adj_enabled( SPDesktopWidget *dtw ); void sp_dtw_desktop_activate (SPDesktopWidget *dtw); void sp_dtw_desktop_deactivate (SPDesktopWidget *dtw); -namespace Inkscape { namespace Widgets { class LayerSelector; } } - -namespace Inkscape { namespace UI { namespace Widget { class SelectedStyle; } } } - -namespace Inkscape { namespace UI { namespace Dialogs { class SwatchesPanel; } } } - /// A GtkEventBox on an SPDesktop. struct SPDesktopWidget { SPViewWidget viewwidget; @@ -248,22 +260,15 @@ struct SPDesktopWidget { Inkscape::UI::Widget::Dock* getDock(); - static GType getType(); static SPDesktopWidget* createInstance(SPNamedView *namedview); void updateNamedview(); + SPDesktopWidgetPrivate *priv; private: - GtkWidget *tool_toolbox; - GtkWidget *aux_toolbox; - GtkWidget *commands_toolbox; - GtkWidget *snap_toolbox; - - static void init(SPDesktopWidget *widget); void layoutWidgets(); void namedviewModified(SPObject *obj, guint flags); - }; /// The SPDesktopWidget vtable -- cgit v1.2.3 From 4acd1d8939d4810eb23222638f4db0471f91b386 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 14:44:13 +0100 Subject: More GObject boilerplate reduction (bzr r13341.1.174) --- src/widgets/gradient-image.cpp | 34 +++++------------------------- src/widgets/gradient-image.h | 2 -- src/widgets/sp-color-icc-selector.cpp | 37 +++------------------------------ src/widgets/sp-color-notebook.cpp | 31 +++------------------------ src/widgets/sp-color-notebook.h | 3 --- src/widgets/sp-color-scales.cpp | 37 ++++----------------------------- src/widgets/sp-color-scales.h | 3 +-- src/widgets/sp-color-slider.cpp | 30 ++++---------------------- src/widgets/sp-color-slider.h | 5 ----- src/widgets/sp-color-wheel-selector.cpp | 37 ++++----------------------------- src/widgets/sp-color-wheel-selector.h | 4 +--- src/widgets/sp-xmlview-attr-list.cpp | 34 +++--------------------------- src/widgets/sp-xmlview-attr-list.h | 3 --- src/widgets/sp-xmlview-content.cpp | 34 +++--------------------------- src/widgets/sp-xmlview-content.h | 1 - src/widgets/sp-xmlview-tree.cpp | 34 +++--------------------------- 16 files changed, 34 insertions(+), 295 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-image.cpp b/src/widgets/gradient-image.cpp index 1b7d4f8a1..6901b8549 100644 --- a/src/widgets/gradient-image.cpp +++ b/src/widgets/gradient-image.cpp @@ -19,8 +19,6 @@ #define VBLOCK 16 -static void sp_gradient_image_class_init (SPGradientImageClass *klass); -static void sp_gradient_image_init (SPGradientImage *image); static void sp_gradient_image_size_request (GtkWidget *widget, GtkRequisition *requisition); #if GTK_CHECK_VERSION(3,0,0) @@ -42,35 +40,13 @@ static void sp_gradient_image_gradient_release (SPObject *, SPGradientImage *im) static void sp_gradient_image_gradient_modified (SPObject *, guint flags, SPGradientImage *im); static void sp_gradient_image_update (SPGradientImage *img); -static GtkWidgetClass *parent_class; - -GType sp_gradient_image_get_type(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (SPGradientImageClass), - NULL, NULL, - (GClassInitFunc) sp_gradient_image_class_init, - NULL, NULL, - sizeof (SPGradientImage), - 0, - (GInstanceInitFunc) sp_gradient_image_init, - NULL - }; - type = g_type_register_static (GTK_TYPE_WIDGET, "SPGradientImage", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPGradientImage, sp_gradient_image, GTK_TYPE_WIDGET); static void sp_gradient_image_class_init(SPGradientImageClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - parent_class = GTK_WIDGET_CLASS(g_type_class_peek_parent (klass)); #if GTK_CHECK_VERSION(3,0,0) -// GObjectClass *object_class = G_OBJECT_CLASS(klass); - widget_class->get_preferred_width = sp_gradient_image_get_preferred_width; widget_class->get_preferred_height = sp_gradient_image_get_preferred_height; widget_class->draw = sp_gradient_image_draw; @@ -113,11 +89,11 @@ static void sp_gradient_image_destroy(GtkObject *object) image->modified_connection.~connection(); #if GTK_CHECK_VERSION(3,0,0) - if (parent_class->destroy) - (* (parent_class)->destroy) (object); + if (GTK_WIDGET_CLASS(sp_gradient_image_parent_class)->destroy) + GTK_WIDGET_CLASS(sp_gradient_image_parent_class)->destroy(object); #else - if ((GTK_OBJECT_CLASS(parent_class))->destroy) - (* (GTK_OBJECT_CLASS(parent_class))->destroy) (object); + if (GTK_OBJECT_CLASS(sp_gradient_image_parent_class)->destroy) + GTK_OBJECT_CLASS(sp_gradient_image_parent_class)->destroy(object); #endif } diff --git a/src/widgets/gradient-image.h b/src/widgets/gradient-image.h index cd7e0ed70..6a9c89acf 100644 --- a/src/widgets/gradient-image.h +++ b/src/widgets/gradient-image.h @@ -18,8 +18,6 @@ class SPGradient; #include - -#include #include #define SP_TYPE_GRADIENT_IMAGE (sp_gradient_image_get_type ()) diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp index ff34fefe0..d0d302ff4 100644 --- a/src/widgets/sp-color-icc-selector.cpp +++ b/src/widgets/sp-color-icc-selector.cpp @@ -67,10 +67,7 @@ extern guint update_in_progress; G_BEGIN_DECLS -static void sp_color_icc_selector_class_init (SPColorICCSelectorClass *klass); -static void sp_color_icc_selector_init (SPColorICCSelector *cs); static void sp_color_icc_selector_dispose(GObject *object); - static void sp_color_icc_selector_show_all (GtkWidget *widget); static void sp_color_icc_selector_hide(GtkWidget *widget); @@ -161,9 +158,6 @@ public: #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) }; - -static SPColorSelectorClass *parent_class; - #define XPAD 4 #define YPAD 1 @@ -233,30 +227,7 @@ void attachToGridOrTable(GtkWidget *parent, } // namespace -GType sp_color_icc_selector_get_type(void) -{ - static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof (SPColorICCSelectorClass), - NULL, // base_init - NULL, // base_finalize - (GClassInitFunc) sp_color_icc_selector_class_init, - NULL, // class_finalize - NULL, // class_data - sizeof (SPColorICCSelector), - 0, // n_preallocs - (GInstanceInitFunc) sp_color_icc_selector_init, - 0, // value_table - }; - - type = g_type_register_static (SP_TYPE_COLOR_SELECTOR, - "SPColorICCSelector", - &info, - static_cast< GTypeFlags > (0) ); - } - return type; -} +G_DEFINE_TYPE(SPColorICCSelector, sp_color_icc_selector, SP_TYPE_COLOR_SELECTOR); static void sp_color_icc_selector_class_init(SPColorICCSelectorClass *klass) { @@ -265,8 +236,6 @@ static void sp_color_icc_selector_class_init(SPColorICCSelectorClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); - parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); - selector_class->name = nameset; selector_class->submode_count = 1; @@ -605,8 +574,8 @@ void ColorICCSelector::init() static void sp_color_icc_selector_dispose(GObject *object) { - if ((G_OBJECT_CLASS(parent_class))->dispose) { - (* (G_OBJECT_CLASS(parent_class))->dispose)(object); + if (G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose) { + G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose(object); } } diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index dcfd73742..9f927b51f 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -53,46 +53,21 @@ struct SPColorNotebookTracker { SPColorNotebook *backPointer; }; -static void sp_color_notebook_class_init (SPColorNotebookClass *klass); -static void sp_color_notebook_init (SPColorNotebook *colorbook); static void sp_color_notebook_dispose(GObject *object); static void sp_color_notebook_show_all (GtkWidget *widget); static void sp_color_notebook_hide(GtkWidget *widget); -static SPColorSelectorClass *parent_class; - #define XPAD 4 #define YPAD 1 -GType sp_color_notebook_get_type(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPColorNotebookClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_color_notebook_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPColorNotebook), - 0, // n_preallocs - (GInstanceInitFunc)sp_color_notebook_init, - 0 // value_table - }; - type = g_type_register_static(SP_TYPE_COLOR_SELECTOR, "SPColorNotebook", &info, static_cast(0)); - } - return type; -} +G_DEFINE_TYPE(SPColorNotebook, sp_color_notebook, SP_TYPE_COLOR_SELECTOR); static void sp_color_notebook_class_init(SPColorNotebookClass *klass) { GObjectClass *object_class = reinterpret_cast(klass); GtkWidgetClass *widget_class = reinterpret_cast(klass); - parent_class = SP_COLOR_SELECTOR_CLASS(g_type_class_peek_parent(klass)); - object_class->dispose = sp_color_notebook_dispose; widget_class->show_all = sp_color_notebook_show_all; @@ -472,8 +447,8 @@ void ColorNotebook::init() static void sp_color_notebook_dispose(GObject *object) { - if (((GObjectClass *) (parent_class))->dispose) - (* ((GObjectClass *) (parent_class))->dispose) (object); + if (G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose) + G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose(object); } ColorNotebook::~ColorNotebook() diff --git a/src/widgets/sp-color-notebook.h b/src/widgets/sp-color-notebook.h index 6e5111132..50c2bb2e7 100644 --- a/src/widgets/sp-color-notebook.h +++ b/src/widgets/sp-color-notebook.h @@ -13,13 +13,10 @@ */ #include -#include "../color.h" #include "sp-color-selector.h" #include - - struct SPColorNotebook; class ColorNotebook: public ColorSelector diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp index c98d7ce57..5fddacf59 100644 --- a/src/widgets/sp-color-scales.cpp +++ b/src/widgets/sp-color-scales.cpp @@ -10,6 +10,7 @@ #include #include "../dialogs/dialog-events.h" #include "sp-color-scales.h" +#include "sp-color-slider.h" #include "svg/svg-icc-color.h" #define CSC_CHANNEL_R (1 << 0) @@ -30,8 +31,6 @@ G_BEGIN_DECLS -static void sp_color_scales_class_init (SPColorScalesClass *klass); -static void sp_color_scales_init (SPColorScales *cs); static void sp_color_scales_dispose(GObject *object); static void sp_color_scales_show_all (GtkWidget *widget); @@ -41,38 +40,12 @@ static const gchar *sp_color_scales_hue_map (void); G_END_DECLS -static SPColorSelectorClass *parent_class; - #define XPAD 4 #define YPAD 1 #define noDUMP_CHANGE_INFO 1 -GType -sp_color_scales_get_type (void) -{ - static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof (SPColorScalesClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_color_scales_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPColorScales), - 0, /* n_preallocs */ - (GInstanceInitFunc) sp_color_scales_init, - NULL - }; - - type = g_type_register_static (SP_TYPE_COLOR_SELECTOR, - "SPColorScales", - &info, - static_cast< GTypeFlags > (0) ); - } - return type; -} +G_DEFINE_TYPE(SPColorScales, sp_color_scales, SP_TYPE_COLOR_SELECTOR); static void sp_color_scales_class_init (SPColorScalesClass *klass) @@ -82,8 +55,6 @@ sp_color_scales_class_init (SPColorScalesClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); - parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); - selector_class->name = nameset; selector_class->submode_count = 3; @@ -229,8 +200,8 @@ void ColorScales::init() static void sp_color_scales_dispose(GObject *object) { - if ((G_OBJECT_CLASS(parent_class))->dispose) - (* (G_OBJECT_CLASS(parent_class))->dispose) (object); + if (G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose) + G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose(object); } static void diff --git a/src/widgets/sp-color-scales.h b/src/widgets/sp-color-scales.h index 3b11bc05e..de6544d11 100644 --- a/src/widgets/sp-color-scales.h +++ b/src/widgets/sp-color-scales.h @@ -5,12 +5,11 @@ #include #include -#include #include - struct SPColorScales; struct SPColorScalesClass; +struct SPColorSlider; typedef enum { SP_COLOR_SCALES_MODE_NONE = 0, diff --git a/src/widgets/sp-color-slider.cpp b/src/widgets/sp-color-slider.cpp index 9b13ba1c5..ab7e2cd84 100644 --- a/src/widgets/sp-color-slider.cpp +++ b/src/widgets/sp-color-slider.cpp @@ -12,6 +12,7 @@ #include #include "sp-color-scales.h" +#include "sp-color-slider.h" #include "preferences.h" #define SLIDER_WIDTH 96 @@ -26,8 +27,6 @@ enum { LAST_SIGNAL }; -static void sp_color_slider_class_init (SPColorSliderClass *klass); -static void sp_color_slider_init (SPColorSlider *slider); static void sp_color_slider_dispose(GObject *object); static void sp_color_slider_realize (GtkWidget *widget); @@ -61,36 +60,15 @@ static const guchar *sp_color_slider_render_gradient (gint x0, gint y0, gint wid static const guchar *sp_color_slider_render_map (gint x0, gint y0, gint width, gint height, guchar *map, gint start, gint step, guint b0, guint b1, guint mask); -static GtkWidgetClass *parent_class; static guint slider_signals[LAST_SIGNAL] = {0}; -GType -sp_color_slider_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (SPColorSliderClass), - NULL, NULL, - (GClassInitFunc) sp_color_slider_class_init, - NULL, NULL, - sizeof (SPColorSlider), - 0, - (GInstanceInitFunc) sp_color_slider_init, - NULL - }; - type = g_type_register_static (GTK_TYPE_WIDGET, "SPColorSlider", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPColorSlider, sp_color_slider, GTK_TYPE_WIDGET); static void sp_color_slider_class_init(SPColorSliderClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - parent_class = GTK_WIDGET_CLASS(g_type_class_peek_parent(klass)); - slider_signals[GRABBED] = g_signal_new ("grabbed", G_TYPE_FROM_CLASS(object_class), (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), @@ -183,8 +161,8 @@ static void sp_color_slider_dispose(GObject *object) slider->adjustment = NULL; } - if ((G_OBJECT_CLASS(parent_class))->dispose) - (* (G_OBJECT_CLASS(parent_class))->dispose) (object); + if (G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose) + G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose (object); } static void diff --git a/src/widgets/sp-color-slider.h b/src/widgets/sp-color-slider.h index 591d8368a..85db01081 100644 --- a/src/widgets/sp-color-slider.h +++ b/src/widgets/sp-color-slider.h @@ -16,11 +16,6 @@ #include - - -struct SPColorSlider; -struct SPColorSliderClass; - #define SP_TYPE_COLOR_SLIDER (sp_color_slider_get_type ()) #define SP_COLOR_SLIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_SLIDER, SPColorSlider)) #define SP_COLOR_SLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_SLIDER, SPColorSliderClass)) diff --git a/src/widgets/sp-color-wheel-selector.cpp b/src/widgets/sp-color-wheel-selector.cpp index cac78238d..404874db7 100644 --- a/src/widgets/sp-color-wheel-selector.cpp +++ b/src/widgets/sp-color-wheel-selector.cpp @@ -7,14 +7,13 @@ #include "../dialogs/dialog-events.h" #include "sp-color-wheel-selector.h" #include "sp-color-scales.h" +#include "sp-color-slider.h" #include "sp-color-icc-selector.h" #include "../svg/svg-icc-color.h" #include "ui/widget/gimpcolorwheel.h" G_BEGIN_DECLS -static void sp_color_wheel_selector_class_init (SPColorWheelSelectorClass *klass); -static void sp_color_wheel_selector_init (SPColorWheelSelector *cs); static void sp_color_wheel_selector_dispose(GObject *object); static void sp_color_wheel_selector_show_all (GtkWidget *widget); @@ -23,36 +22,10 @@ static void sp_color_wheel_selector_hide(GtkWidget *widget); G_END_DECLS -static SPColorSelectorClass *parent_class; - #define XPAD 4 #define YPAD 1 -GType -sp_color_wheel_selector_get_type (void) -{ - static GType type = 0; - if (!type) { - static const GTypeInfo info = { - sizeof (SPColorWheelSelectorClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_color_wheel_selector_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPColorWheelSelector), - 0, /* n_preallocs */ - (GInstanceInitFunc) sp_color_wheel_selector_init, - 0, /* value_table */ - }; - - type = g_type_register_static (SP_TYPE_COLOR_SELECTOR, - "SPColorWheelSelector", - &info, - static_cast< GTypeFlags > (0) ); - } - return type; -} +G_DEFINE_TYPE(SPColorWheelSelector, sp_color_wheel_selector, SP_TYPE_COLOR_SELECTOR); static void sp_color_wheel_selector_class_init(SPColorWheelSelectorClass *klass) { @@ -61,8 +34,6 @@ static void sp_color_wheel_selector_class_init(SPColorWheelSelectorClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); - parent_class = SP_COLOR_SELECTOR_CLASS (g_type_class_peek_parent (klass)); - selector_class->name = nameset; selector_class->submode_count = 1; @@ -231,8 +202,8 @@ void ColorWheelSelector::init() static void sp_color_wheel_selector_dispose(GObject *object) { - if ((G_OBJECT_CLASS(parent_class))->dispose) - (* (G_OBJECT_CLASS(parent_class))->dispose) (object); + if (G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose) + G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose(object); } static void diff --git a/src/widgets/sp-color-wheel-selector.h b/src/widgets/sp-color-wheel-selector.h index bbd377422..23ac0050d 100644 --- a/src/widgets/sp-color-wheel-selector.h +++ b/src/widgets/sp-color-wheel-selector.h @@ -4,12 +4,10 @@ #include #include -#include "sp-color-slider.h" #include "sp-color-selector.h" - - typedef struct _GimpColorWheel GimpColorWheel; +struct SPColorSlider; struct SPColorWheelSelector; struct SPColorWheelSelectorClass; diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp index 47b0ebb9d..dd763aea5 100644 --- a/src/widgets/sp-xmlview-attr-list.cpp +++ b/src/widgets/sp-xmlview-attr-list.cpp @@ -20,9 +20,6 @@ #include "../xml/node-event-vector.h" #include "sp-xmlview-attr-list.h" -static void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass); -static void sp_xmlview_attr_list_init (SPXMLViewAttrList * list); - #if GTK_CHECK_VERSION(3,0,0) static void sp_xmlview_attr_list_destroy(GtkWidget * object); #else @@ -31,8 +28,6 @@ static void sp_xmlview_attr_list_destroy(GtkObject * object); static void event_attr_changed (Inkscape::XML::Node * repr, const gchar * name, const gchar * old_value, const gchar * new_value, bool is_interactive, gpointer data); -static GtkTreeViewClass * parent_class = NULL; - static Inkscape::XML::NodeEventVector repr_events = { NULL, /* child_added */ NULL, /* child_removed */ @@ -88,28 +83,7 @@ sp_xmlview_attr_list_set_repr (SPXMLViewAttrList * list, Inkscape::XML::Node * r } } -GType sp_xmlview_attr_list_get_type(void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof(SPXMLViewAttrListClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_xmlview_attr_list_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPXMLViewAttrList), - 0, // n_preallocs - (GInstanceInitFunc)sp_xmlview_attr_list_init, - 0 // value_table - }; - type = g_type_register_static(GTK_TYPE_TREE_VIEW, "SPXMLViewAttrList", &info, static_cast(0)); - } - - return type; -} +G_DEFINE_TYPE(SPXMLViewAttrList, sp_xmlview_attr_list, GTK_TYPE_TREE_VIEW); void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass) { @@ -121,8 +95,6 @@ void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass) object_class->destroy = sp_xmlview_attr_list_destroy; #endif - parent_class = GTK_TREE_VIEW_CLASS(g_type_class_peek_parent (klass)); - g_signal_new("row-value-changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST, @@ -154,9 +126,9 @@ void sp_xmlview_attr_list_destroy(GtkObject * object) sp_xmlview_attr_list_set_repr (list, NULL); #if GTK_CHECK_VERSION(3,0,0) - GTK_WIDGET_CLASS(parent_class)->destroy (object); + GTK_WIDGET_CLASS(sp_xmlview_attr_list_parent_class)->destroy (object); #else - GTK_OBJECT_CLASS(parent_class)->destroy (object); + GTK_OBJECT_CLASS(sp_xmlview_attr_list_parent_class)->destroy (object); #endif } diff --git a/src/widgets/sp-xmlview-attr-list.h b/src/widgets/sp-xmlview-attr-list.h index 367ef1a12..08b115bfa 100644 --- a/src/widgets/sp-xmlview-attr-list.h +++ b/src/widgets/sp-xmlview-attr-list.h @@ -12,10 +12,8 @@ * Released under the GNU GPL; see COPYING for details */ -#include #include - #define SP_TYPE_XMLVIEW_ATTR_LIST (sp_xmlview_attr_list_get_type ()) #define SP_XMLVIEW_ATTR_LIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_XMLVIEW_ATTR_LIST, SPXMLViewAttrList)) #define SP_IS_XMLVIEW_ATTR_LIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_XMLVIEW_ATTR_LIST)) @@ -23,7 +21,6 @@ struct SPXMLViewAttrList { - GtkTreeView list; GtkListStore *store; diff --git a/src/widgets/sp-xmlview-content.cpp b/src/widgets/sp-xmlview-content.cpp index ac64dabdb..9243760bd 100644 --- a/src/widgets/sp-xmlview-content.cpp +++ b/src/widgets/sp-xmlview-content.cpp @@ -23,9 +23,6 @@ using Inkscape::DocumentUndo; -static void sp_xmlview_content_class_init (SPXMLViewContentClass * klass); -static void sp_xmlview_content_init (SPXMLViewContent * text); - #if GTK_CHECK_VERSION(3,0,0) static void sp_xmlview_content_destroy(GtkWidget * object); #else @@ -36,8 +33,6 @@ void sp_xmlview_content_changed (GtkTextBuffer *tb, SPXMLViewContent *text); static void event_content_changed (Inkscape::XML::Node * repr, const gchar * old_content, const gchar * new_content, gpointer data); -static GtkTextViewClass * parent_class = NULL; - static Inkscape::XML::NodeEventVector repr_events = { NULL, /* child_added */ NULL, /* child_removed */ @@ -81,28 +76,7 @@ sp_xmlview_content_set_repr (SPXMLViewContent * text, Inkscape::XML::Node * repr } } -GType sp_xmlview_content_get_type(void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof(SPXMLViewContentClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_xmlview_content_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPXMLViewContent), - 0, // n_preallocs - (GInstanceInitFunc)sp_xmlview_content_init, - 0 // value_table - }; - type = g_type_register_static(GTK_TYPE_TEXT_VIEW, "SPXMLViewContent", &info, static_cast(0)); - } - - return type; -} +G_DEFINE_TYPE(SPXMLViewContent, sp_xmlview_content, GTK_TYPE_TEXT_VIEW); void sp_xmlview_content_class_init(SPXMLViewContentClass * klass) { @@ -113,8 +87,6 @@ void sp_xmlview_content_class_init(SPXMLViewContentClass * klass) GtkObjectClass * object_class = GTK_OBJECT_CLASS(klass); object_class->destroy = sp_xmlview_content_destroy; #endif - - parent_class = GTK_TEXT_VIEW_CLASS(g_type_class_peek_parent (klass)); } void @@ -135,9 +107,9 @@ void sp_xmlview_content_destroy(GtkObject * object) sp_xmlview_content_set_repr (text, NULL); #if GTK_CHECK_VERSION(3,0,0) - GTK_WIDGET_CLASS (parent_class)->destroy (object); + GTK_WIDGET_CLASS (sp_xmlview_content_parent_class)->destroy (object); #else - GTK_OBJECT_CLASS (parent_class)->destroy (object); + GTK_OBJECT_CLASS (sp_xmlview_content_parent_class)->destroy (object); #endif } diff --git a/src/widgets/sp-xmlview-content.h b/src/widgets/sp-xmlview-content.h index 8b1342c5e..a09d2d92d 100644 --- a/src/widgets/sp-xmlview-content.h +++ b/src/widgets/sp-xmlview-content.h @@ -13,7 +13,6 @@ */ #include -#include #include #include diff --git a/src/widgets/sp-xmlview-tree.cpp b/src/widgets/sp-xmlview-tree.cpp index 9b3775a34..5dff9adf3 100644 --- a/src/widgets/sp-xmlview-tree.cpp +++ b/src/widgets/sp-xmlview-tree.cpp @@ -23,9 +23,6 @@ struct NodeData { enum { STORE_TEXT_COL = 0, STORE_DATA_COL, STORE_REPR_COL, STORE_N_COLS }; -static void sp_xmlview_tree_class_init (SPXMLViewTreeClass * klass); -static void sp_xmlview_tree_init (SPXMLViewTree * tree); - #if GTK_CHECK_VERSION(3,0,0) static void sp_xmlview_tree_destroy(GtkWidget * object); #else @@ -90,8 +87,6 @@ static const Inkscape::XML::NodeEventVector pi_repr_events = { NULL /* order_changed */ }; -static GtkTreeViewClass * parent_class = NULL; - GtkWidget *sp_xmlview_tree_new(Inkscape::XML::Node * repr, void * /*factory*/, void * /*data*/) { SPXMLViewTree *tree = SP_XMLVIEW_TREE(g_object_new (SP_TYPE_XMLVIEW_TREE, NULL)); @@ -122,28 +117,7 @@ GtkWidget *sp_xmlview_tree_new(Inkscape::XML::Node * repr, void * /*factory*/, v return GTK_WIDGET(tree); } -GType -sp_xmlview_tree_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (SPXMLViewTreeClass), - NULL, NULL, - (GClassInitFunc) sp_xmlview_tree_class_init, - NULL, NULL, - sizeof (SPXMLViewTree), - 0, - (GInstanceInitFunc) sp_xmlview_tree_init, - NULL - }; - type = g_type_register_static (GTK_TYPE_TREE_VIEW, "SPXMLViewTree", &info, (GTypeFlags)0); - } - - - return type; -} +G_DEFINE_TYPE(SPXMLViewTree, sp_xmlview_tree, GTK_TYPE_TREE_VIEW); void sp_xmlview_tree_class_init(SPXMLViewTreeClass * klass) { @@ -155,8 +129,6 @@ void sp_xmlview_tree_class_init(SPXMLViewTreeClass * klass) object_class->destroy = sp_xmlview_tree_destroy; #endif - parent_class = GTK_TREE_VIEW_CLASS(g_type_class_peek_parent (klass)); - // Signal for when a tree drag and drop has completed g_signal_new ( "tree_move", G_TYPE_FROM_CLASS(klass), @@ -188,9 +160,9 @@ void sp_xmlview_tree_destroy(GtkObject * object) sp_xmlview_tree_set_repr (tree, NULL); #if GTK_CHECK_VERSION(3,0,0) - GTK_WIDGET_CLASS(parent_class)->destroy (object); + GTK_WIDGET_CLASS(sp_xmlview_tree_parent_class)->destroy (object); #else - GTK_OBJECT_CLASS(parent_class)->destroy (object); + GTK_OBJECT_CLASS(sp_xmlview_tree_parent_class)->destroy (object); #endif } -- cgit v1.2.3 From c2a65687bd392c251a320030b0a6a813e093dc9f Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 24 Aug 2014 16:20:54 +0100 Subject: More GObject boilerplate reduction (bzr r13341.1.175) --- src/display/canvas-arena.cpp | 33 +++------------- src/display/canvas-bpath.cpp | 34 +++-------------- src/display/canvas-grid.cpp | 36 +++--------------- src/display/canvas-text.cpp | 35 +++-------------- src/display/gnome-canvas-acetate.cpp | 29 ++------------ src/display/guideline.cpp | 34 ++--------------- src/display/sodipodi-ctrl.cpp | 37 +++--------------- src/display/sp-ctrlcurve.cpp | 41 +++++--------------- src/display/sp-ctrlcurve.h | 9 ++--- src/display/sp-ctrlline.cpp | 40 ++++---------------- src/display/sp-ctrlline.h | 6 +-- src/display/sp-ctrlpoint.cpp | 35 +++-------------- src/display/sp-ctrlquadr.cpp | 34 +++-------------- src/svg-view-widget.cpp | 46 ++++++----------------- src/ui/view/view-widget.cpp | 31 ++------------- src/widgets/sp-widget.cpp | 73 +++++++++++------------------------- src/widgets/sp-widget.h | 9 +---- 17 files changed, 103 insertions(+), 459 deletions(-) (limited to 'src') diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index e82b1b1c7..8738b93e4 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -30,8 +30,6 @@ enum { LAST_SIGNAL }; -static void sp_canvas_arena_class_init(SPCanvasArenaClass *klass); -static void sp_canvas_arena_init(SPCanvasArena *group); static void sp_canvas_arena_destroy(SPCanvasItem *object); static void sp_canvas_arena_item_deleted(SPCanvasArena *arena, Inkscape::DrawingItem *item); @@ -46,7 +44,6 @@ static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event); static void sp_canvas_arena_request_update (SPCanvasArena *ca, DrawingItem *item); static void sp_canvas_arena_request_render (SPCanvasArena *ca, Geom::IntRect const &area); -static SPCanvasItemClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; struct CachePrefObserver : public Inkscape::Preferences::Observer { @@ -70,33 +67,13 @@ struct CachePrefObserver : public Inkscape::Preferences::Observer { SPCanvasArena *_arena; }; -GType -sp_canvas_arena_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (SPCanvasArenaClass), - NULL, NULL, - (GClassInitFunc) sp_canvas_arena_class_init, - NULL, NULL, - sizeof (SPCanvasArena), - 0, - (GInstanceInitFunc) sp_canvas_arena_init, - NULL - }; - type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCanvasArena", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCanvasArena, sp_canvas_arena, SP_TYPE_CANVAS_ITEM); static void sp_canvas_arena_class_init (SPCanvasArenaClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - signals[ARENA_EVENT] = g_signal_new ("arena_event", G_TYPE_FROM_CLASS(item_class), G_SIGNAL_RUN_LAST, @@ -149,8 +126,8 @@ static void sp_canvas_arena_destroy(SPCanvasItem *object) delete arena->observer; arena->drawing.~Drawing(); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->destroy(object); } static void @@ -158,8 +135,8 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - if (((SPCanvasItemClass *) parent_class)->update) - (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->update(item, affine, flags); arena->ctx.ctm = affine; diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index ee9e14f10..328409e12 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -27,42 +27,18 @@ #include "helper/geom.h" #include "display/sp-canvas.h" -static void sp_canvas_bpath_class_init (SPCanvasBPathClass *klass); -static void sp_canvas_bpath_init (SPCanvasBPath *path); static void sp_canvas_bpath_destroy(SPCanvasItem *object); static void sp_canvas_bpath_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf); static double sp_canvas_bpath_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static SPCanvasItemClass *parent_class; - -GType -sp_canvas_bpath_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (SPCanvasBPathClass), - NULL, NULL, - (GClassInitFunc) sp_canvas_bpath_class_init, - NULL, NULL, - sizeof (SPCanvasBPath), - 0, - (GInstanceInitFunc) sp_canvas_bpath_init, - NULL - }; - type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCanvasBPath", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCanvasBPath, sp_canvas_bpath, SP_TYPE_CANVAS_ITEM); static void sp_canvas_bpath_class_init(SPCanvasBPathClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - item_class->destroy = sp_canvas_bpath_destroy; item_class->update = sp_canvas_bpath_update; item_class->render = sp_canvas_bpath_render; @@ -90,8 +66,8 @@ static void sp_canvas_bpath_destroy(SPCanvasItem *object) cbp->curve = cbp->curve->unref(); } - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_bpath_parent_class)->destroy) + (* SP_CANVAS_ITEM_CLASS(sp_canvas_bpath_parent_class)->destroy) (object); } static void sp_canvas_bpath_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags) @@ -100,8 +76,8 @@ static void sp_canvas_bpath_update(SPCanvasItem *item, Geom::Affine const &affin item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (reinterpret_cast(parent_class)->update) { - reinterpret_cast(parent_class)->update(item, affine, flags); + if (reinterpret_cast(sp_canvas_bpath_parent_class)->update) { + reinterpret_cast(sp_canvas_bpath_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds (item); diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 4b1dbd1ed..2eeaa7006 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -71,42 +71,16 @@ static gchar const *const grid_svgname[] = { // ########################################################## // Grid CanvasItem -static void grid_canvasitem_class_init (GridCanvasItemClass *klass); -static void grid_canvasitem_init (GridCanvasItem *grid); static void grid_canvasitem_destroy(SPCanvasItem *object); static void grid_canvasitem_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void grid_canvasitem_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass * parent_class; - -GType -grid_canvasitem_get_type (void) -{ - static GType grid_canvasitem_type = 0; - - if (!grid_canvasitem_type) { - GTypeInfo grid_canvasitem_info = { - sizeof (GridCanvasItemClass), - NULL, NULL, - (GClassInitFunc) grid_canvasitem_class_init, - NULL, NULL, - sizeof (GridCanvasItem), - 0, - (GInstanceInitFunc) grid_canvasitem_init, - NULL - }; - - grid_canvasitem_type = g_type_register_static(SPCanvasItem::getType(), "GridCanvasItem", &grid_canvasitem_info, GTypeFlags(0)); - } - return grid_canvasitem_type; -} +G_DEFINE_TYPE(GridCanvasItem, grid_canvasitem, SP_TYPE_CANVAS_ITEM); static void grid_canvasitem_class_init(GridCanvasItemClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - item_class->destroy = grid_canvasitem_destroy; item_class->update = grid_canvasitem_update; item_class->render = grid_canvasitem_render; @@ -123,8 +97,8 @@ static void grid_canvasitem_destroy(SPCanvasItem *object) g_return_if_fail (object != NULL); g_return_if_fail (INKSCAPE_IS_GRID_CANVASITEM (object)); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->destroy) + (* SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->destroy) (object); } /** @@ -145,8 +119,8 @@ grid_canvasitem_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned { GridCanvasItem *gridcanvasitem = INKSCAPE_GRID_CANVASITEM (item); - if (parent_class->update) - (* parent_class->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->update) + SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->update(item, affine, flags); if (gridcanvasitem->grid) { gridcanvasitem->grid->Update(affine, flags); diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index fe60d9c65..88812af0a 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -26,42 +26,17 @@ #include "color.h" #include "display/sp-canvas.h" -static void sp_canvastext_class_init (SPCanvasTextClass *klass); -static void sp_canvastext_init (SPCanvasText *canvastext); static void sp_canvastext_destroy(SPCanvasItem *object); static void sp_canvastext_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_canvastext_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class_ct; - -GType -sp_canvastext_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (SPCanvasTextClass), - NULL, NULL, - (GClassInitFunc) sp_canvastext_class_init, - NULL, NULL, - sizeof (SPCanvasText), - 0, - (GInstanceInitFunc) sp_canvastext_init, - NULL - }; - type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCanvasText", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCanvasText, sp_canvastext, SP_TYPE_CANVAS_ITEM); static void sp_canvastext_class_init(SPCanvasTextClass *klass) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - parent_class_ct = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(klass)); - item_class->destroy = sp_canvastext_destroy; item_class->update = sp_canvastext_update; item_class->render = sp_canvastext_render; @@ -101,8 +76,8 @@ static void sp_canvastext_destroy(SPCanvasItem *object) canvastext->text = NULL; canvastext->item = NULL; - if (SP_CANVAS_ITEM_CLASS(parent_class_ct)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class_ct)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->destroy(object); } static void @@ -151,8 +126,8 @@ sp_canvastext_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned i item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (parent_class_ct->update) - (* parent_class_ct->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->update(item, affine, flags); sp_canvas_item_reset_bounds (item); diff --git a/src/display/gnome-canvas-acetate.cpp b/src/display/gnome-canvas-acetate.cpp index 2cd0f296d..9147a1bbf 100644 --- a/src/display/gnome-canvas-acetate.cpp +++ b/src/display/gnome-canvas-acetate.cpp @@ -15,40 +15,17 @@ #include "gnome-canvas-acetate.h" -static void sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass); -static void sp_canvas_acetate_init (SPCanvasAcetate *acetate); static void sp_canvas_acetate_destroy(SPCanvasItem *object); static void sp_canvas_acetate_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static double sp_canvas_acetate_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static SPCanvasItemClass *parent_class; - -GType sp_canvas_acetate_get_type (void) -{ - static GType acetate_type = 0; - if (!acetate_type) { - GTypeInfo acetate_info = { - sizeof (SPCanvasAcetateClass), - NULL, NULL, - (GClassInitFunc) sp_canvas_acetate_class_init, - NULL, NULL, - sizeof (SPCanvasAcetate), - 0, - (GInstanceInitFunc) sp_canvas_acetate_init, - NULL - }; - acetate_type = g_type_register_static(SPCanvasItem::getType(), "SPCanvasAcetate", &acetate_info, GTypeFlags(0)); - } - return acetate_type; -} +G_DEFINE_TYPE(SPCanvasAcetate, sp_canvas_acetate, SP_TYPE_CANVAS_ITEM); static void sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - item_class->destroy = sp_canvas_acetate_destroy; item_class->update = sp_canvas_acetate_update; item_class->point = sp_canvas_acetate_point; @@ -64,8 +41,8 @@ static void sp_canvas_acetate_destroy(SPCanvasItem *object) g_return_if_fail (object != NULL); g_return_if_fail (GNOME_IS_CANVAS_ACETATE (object)); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_acetate_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_canvas_acetate_parent_class)->destroy(object); } static void sp_canvas_acetate_update( SPCanvasItem *item, Geom::Affine const &/*affine*/, unsigned int /*flags*/ ) diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 55c1ee495..44bbd14bd 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -29,8 +29,6 @@ using Inkscape::ControlManager; -static void sp_guideline_class_init(SPGuideLineClass *c); -static void sp_guideline_init(SPGuideLine *guideline); static void sp_guideline_destroy(SPCanvasItem *object); static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); @@ -40,34 +38,10 @@ static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem static void sp_guideline_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba); -static SPCanvasItemClass *parent_class; - -GType sp_guideline_get_type() -{ - static GType guideline_type = 0; - - if (!guideline_type) { - static GTypeInfo const guideline_info = { - sizeof (SPGuideLineClass), - NULL, NULL, - (GClassInitFunc) sp_guideline_class_init, - NULL, NULL, - sizeof (SPGuideLine), - 16, - (GInstanceInitFunc) sp_guideline_init, - NULL, - }; - - guideline_type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPGuideLine", &guideline_info, (GTypeFlags) 0); - } - - return guideline_type; -} +G_DEFINE_TYPE(SPGuideLine, sp_guideline, SP_TYPE_CANVAS_ITEM); static void sp_guideline_class_init(SPGuideLineClass *c) { - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(c)); - SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(c); item_class->destroy = sp_guideline_destroy; item_class->update = sp_guideline_update; @@ -108,7 +82,7 @@ static void sp_guideline_destroy(SPCanvasItem *object) g_free(gl->label); } - SP_CANVAS_ITEM_CLASS(parent_class)->destroy(object); + SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class)->destroy(object); } static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) @@ -197,8 +171,8 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, { SPGuideLine *gl = SP_GUIDELINE(item); - if ((SP_CANVAS_ITEM_CLASS(parent_class))->update) { - (SP_CANVAS_ITEM_CLASS(parent_class))->update(item, affine, flags); + if ((SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update) { + (SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update(item, affine, flags); } gl->affine = affine; diff --git a/src/display/sodipodi-ctrl.cpp b/src/display/sodipodi-ctrl.cpp index 3636319df..327fbce1f 100644 --- a/src/display/sodipodi-ctrl.cpp +++ b/src/display/sodipodi-ctrl.cpp @@ -25,9 +25,6 @@ enum { ARG_PIXBUF }; - -static void sp_ctrl_class_init (SPCtrlClass *klass); -static void sp_ctrl_init (SPCtrl *ctrl); static void sp_ctrl_destroy(SPCanvasItem *object); static void sp_ctrl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void sp_ctrl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); @@ -36,29 +33,7 @@ static void sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf); static double sp_ctrl_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static SPCanvasItemClass *parent_class; - -GType -sp_ctrl_get_type (void) -{ - static GType ctrl_type = 0; - if (!ctrl_type) { - static GTypeInfo const ctrl_info = { - sizeof (SPCtrlClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_ctrl_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPCtrl), - 0, /* n_preallocs */ - (GInstanceInitFunc) sp_ctrl_init, - NULL - }; - ctrl_type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCtrl", &ctrl_info, (GTypeFlags)0); - } - return ctrl_type; -} +G_DEFINE_TYPE(SPCtrl, sp_ctrl, SP_TYPE_CANVAS_ITEM); static void sp_ctrl_class_init (SPCtrlClass *klass) @@ -66,8 +41,6 @@ sp_ctrl_class_init (SPCtrlClass *klass) SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); GObjectClass *g_object_class = (GObjectClass *) klass; - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent (klass)); - g_object_class->set_property = sp_ctrl_set_property; g_object_class->get_property = sp_ctrl_get_property; @@ -239,8 +212,8 @@ static void sp_ctrl_destroy(SPCanvasItem *object) ctrl->cache = NULL; } - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->destroy(object); } static void @@ -251,8 +224,8 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla ctrl = SP_CTRL (item); - if ((SP_CANVAS_ITEM_CLASS(parent_class))->update) - (* (SP_CANVAS_ITEM_CLASS(parent_class))->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->update(item, affine, flags); sp_canvas_item_reset_bounds (item); diff --git a/src/display/sp-ctrlcurve.cpp b/src/display/sp-ctrlcurve.cpp index d9b687f2e..2e0e8105b 100644 --- a/src/display/sp-ctrlcurve.cpp +++ b/src/display/sp-ctrlcurve.cpp @@ -23,42 +23,18 @@ namespace { -static void sp_ctrlcurve_class_init(SPCtrlCurveClass *klass, gpointer data); -static void sp_ctrlcurve_init(SPCtrlCurve *ctrlcurve, gpointer g_class); static void sp_ctrlcurve_destroy(SPCanvasItem *object); static void sp_ctrlcurve_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlcurve_render(SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - } // namespace -GType SPCtrlCurve::getType() -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlCurveClass), - NULL, NULL, - reinterpret_cast(sp_ctrlcurve_class_init), - NULL, NULL, - sizeof(SPCtrlCurve), - 0, - reinterpret_cast(sp_ctrlcurve_init), - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlCurve", &info, static_cast(0)); - } - return type; -} +G_DEFINE_TYPE(SPCtrlCurve, sp_ctrlcurve, SP_TYPE_CANVAS_ITEM); -namespace { - -void sp_ctrlcurve_class_init(SPCtrlCurveClass *klass, gpointer /*g_class*/) +static void +sp_ctrlcurve_class_init(SPCtrlCurveClass *klass) { - parent_class = reinterpret_cast(g_type_class_peek_parent(klass)); - klass->destroy = sp_ctrlcurve_destroy; klass->update = sp_ctrlcurve_update; @@ -66,13 +42,14 @@ void sp_ctrlcurve_class_init(SPCtrlCurveClass *klass, gpointer /*g_class*/) } static void -sp_ctrlcurve_init(SPCtrlCurve *ctrlcurve, gpointer /*g_class*/) +sp_ctrlcurve_init(SPCtrlCurve *ctrlcurve) { // Points are initialized to 0,0 ctrlcurve->rgba = 0x0000ff7f; ctrlcurve->item=NULL; } +namespace { static void sp_ctrlcurve_destroy(SPCanvasItem *object) { @@ -83,8 +60,8 @@ sp_ctrlcurve_destroy(SPCanvasItem *object) ctrlcurve->item=NULL; - if (SP_CANVAS_ITEM_CLASS (parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS (parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->destroy(object); } static void @@ -125,8 +102,8 @@ sp_ctrlcurve_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int item->canvas->requestRedraw(item->x1, item->y1, item->x2, item->y2); - if (parent_class->update) - (* parent_class->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->update(item, affine, flags); sp_canvas_item_reset_bounds (item); diff --git a/src/display/sp-ctrlcurve.h b/src/display/sp-ctrlcurve.h index 90936185c..847944f38 100644 --- a/src/display/sp-ctrlcurve.h +++ b/src/display/sp-ctrlcurve.h @@ -19,14 +19,11 @@ class SPItem; -#define SP_TYPE_CTRLCURVE (SPCtrlCurve::getType()) +#define SP_TYPE_CTRLCURVE (sp_ctrlcurve_get_type()) #define SP_CTRLCURVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLCURVE, SPCtrlCurve)) #define SP_IS_CTRLCURVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLCURVE)) struct SPCtrlCurve : public SPCtrlLine { - - static GType getType(); - void setCoords( gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble x3, gdouble y3 ); @@ -36,9 +33,9 @@ struct SPCtrlCurve : public SPCtrlLine { Geom::Point p0, p1, p2, p3; }; -struct SPCtrlCurveClass : public SPCtrlLineClass{}; - +GType sp_ctrlcurve_get_type(); +struct SPCtrlCurveClass : public SPCtrlLineClass{}; #endif // SEEN_INKSCAPE_CTRLCURVE_H diff --git a/src/display/sp-ctrlline.cpp b/src/display/sp-ctrlline.cpp index aef284c1a..1bde540c0 100644 --- a/src/display/sp-ctrlline.cpp +++ b/src/display/sp-ctrlline.cpp @@ -30,55 +30,31 @@ namespace { -void sp_ctrlline_class_init(SPCtrlLineClass *klass, gpointer data); -void sp_ctrlline_init(SPCtrlLine *ctrlline, gpointer g_class); void sp_ctrlline_destroy(SPCanvasItem *object); void sp_ctrlline_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); void sp_ctrlline_render(SPCanvasItem *item, SPCanvasBuf *buf); -SPCanvasItemClass *parent_class = 0; - } // namespace -GType SPCtrlLine::getType() -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlLineClass), - NULL, NULL, - reinterpret_cast(sp_ctrlline_class_init), - NULL, NULL, - sizeof(SPCtrlLine), - 0, - reinterpret_cast(sp_ctrlline_init), - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlLine", &info, static_cast(0)); - } - return type; -} - -namespace { +G_DEFINE_TYPE(SPCtrlLine, sp_ctrlline, SP_TYPE_CANVAS_ITEM); -void sp_ctrlline_class_init(SPCtrlLineClass *klass, gpointer /*data*/) +static void sp_ctrlline_class_init(SPCtrlLineClass *klass) { - parent_class = reinterpret_cast(g_type_class_peek_parent(klass)); - klass->destroy = sp_ctrlline_destroy; klass->update = sp_ctrlline_update; klass->render = sp_ctrlline_render; } -void sp_ctrlline_init(SPCtrlLine *ctrlline, gpointer /*g_class*/) +static void sp_ctrlline_init(SPCtrlLine *ctrlline) { ctrlline->rgba = 0x0000ff7f; ctrlline->s[Geom::X] = ctrlline->s[Geom::Y] = ctrlline->e[Geom::X] = ctrlline->e[Geom::Y] = 0.0; ctrlline->item=NULL; } +namespace { void sp_ctrlline_destroy(SPCanvasItem *object) { g_return_if_fail(object != NULL); @@ -88,8 +64,8 @@ void sp_ctrlline_destroy(SPCanvasItem *object) ctrlline->item = NULL; - if(SP_CANVAS_ITEM_CLASS (parent_class)->destroy) { - (* SP_CANVAS_ITEM_CLASS (parent_class)->destroy)(object); + if(SP_CANVAS_ITEM_CLASS (sp_ctrlline_parent_class)->destroy) { + SP_CANVAS_ITEM_CLASS (sp_ctrlline_parent_class)->destroy(object); } } @@ -134,8 +110,8 @@ void sp_ctrlline_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned item->canvas->requestRedraw(item->x1, item->y1, item->x2, item->y2); - if (parent_class->update) { - (* parent_class->update)(item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlline_parent_class)->update) { + SP_CANVAS_ITEM_CLASS(sp_ctrlline_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds(item); diff --git a/src/display/sp-ctrlline.h b/src/display/sp-ctrlline.h index 12be03ca5..b2e222437 100644 --- a/src/display/sp-ctrlline.h +++ b/src/display/sp-ctrlline.h @@ -20,13 +20,11 @@ class SPItem; -#define SP_TYPE_CTRLLINE (SPCtrlLine::getType()) +#define SP_TYPE_CTRLLINE (sp_ctrlline_get_type()) #define SP_CTRLLINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLLINE, SPCtrlLine)) #define SP_IS_CTRLLINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLLINE)) struct SPCtrlLine : public SPCanvasItem { - static GType getType(); - void setRgba32(guint32 rgba); void setCoords(gdouble x0, gdouble y0, gdouble x1, gdouble y1); @@ -41,6 +39,8 @@ struct SPCtrlLine : public SPCanvasItem { Geom::Affine affine; }; +GType sp_ctrlline_get_type(); + struct SPCtrlLineClass : public SPCanvasItemClass{}; diff --git a/src/display/sp-ctrlpoint.cpp b/src/display/sp-ctrlpoint.cpp index 026cc7589..1082cb1b3 100644 --- a/src/display/sp-ctrlpoint.cpp +++ b/src/display/sp-ctrlpoint.cpp @@ -20,42 +20,17 @@ #include "display/cairo-utils.h" #include "display/sp-canvas.h" - -static void sp_ctrlpoint_class_init (SPCtrlPointClass *klass); -static void sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint); static void sp_ctrlpoint_destroy(SPCanvasItem *object); static void sp_ctrlpoint_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - -GType -sp_ctrlpoint_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlPointClass), - NULL, NULL, - (GClassInitFunc) sp_ctrlpoint_class_init, - NULL, NULL, - sizeof(SPCtrlPoint), - 0, - (GInstanceInitFunc) sp_ctrlpoint_init, - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlPoint", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCtrlPoint, sp_ctrlpoint, SP_TYPE_CANVAS_ITEM); static void sp_ctrlpoint_class_init(SPCtrlPointClass *klass) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(klass)); - item_class->destroy = sp_ctrlpoint_destroy; item_class->update = sp_ctrlpoint_update; item_class->render = sp_ctrlpoint_render; @@ -79,8 +54,8 @@ static void sp_ctrlpoint_destroy(SPCanvasItem *object) ctrlpoint->item=NULL; - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy(object); } static void @@ -111,8 +86,8 @@ static void sp_ctrlpoint_update(SPCanvasItem *item, Geom::Affine const &affine, item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (parent_class->update) { - (* parent_class->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update) { + SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds (item); diff --git a/src/display/sp-ctrlquadr.cpp b/src/display/sp-ctrlquadr.cpp index b6a0da109..760e93a6d 100644 --- a/src/display/sp-ctrlquadr.cpp +++ b/src/display/sp-ctrlquadr.cpp @@ -29,42 +29,18 @@ struct SPCtrlQuadr : public SPCanvasItem{ struct SPCtrlQuadrClass : public SPCanvasItemClass{}; -static void sp_ctrlquadr_class_init (SPCtrlQuadrClass *klass); -static void sp_ctrlquadr_init (SPCtrlQuadr *ctrlquadr); static void sp_ctrlquadr_destroy(SPCanvasItem *object); static void sp_ctrlquadr_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlquadr_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - -GType -sp_ctrlquadr_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlQuadrClass), - NULL, NULL, - (GClassInitFunc) sp_ctrlquadr_class_init, - NULL, NULL, - sizeof(SPCtrlQuadr), - 0, - (GInstanceInitFunc) sp_ctrlquadr_init, - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlQuadr", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCtrlQuadr, sp_ctrlquadr, SP_TYPE_CANVAS_ITEM); static void sp_ctrlquadr_class_init (SPCtrlQuadrClass *klass) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(klass)); - item_class->destroy = sp_ctrlquadr_destroy; item_class->update = sp_ctrlquadr_update; item_class->render = sp_ctrlquadr_render; @@ -85,8 +61,8 @@ static void sp_ctrlquadr_destroy(SPCanvasItem *object) g_return_if_fail (object != NULL); g_return_if_fail (SP_IS_CTRLQUADR (object)); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->destroy) + (* SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->destroy) (object); } static void @@ -139,8 +115,8 @@ static void sp_ctrlquadr_update(SPCanvasItem *item, Geom::Affine const &affine, item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (parent_class->update) { - (* parent_class->update)(item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->update) { + SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds (item); diff --git a/src/svg-view-widget.cpp b/src/svg-view-widget.cpp index 9174d1083..657ddb2bb 100644 --- a/src/svg-view-widget.cpp +++ b/src/svg-view-widget.cpp @@ -23,8 +23,6 @@ #include "svg-view-widget.h" #include "util/units.h" -static void sp_svg_view_widget_class_init (SPSVGSPViewWidgetClass *klass); -static void sp_svg_view_widget_init (SPSVGSPViewWidget *widget); static void sp_svg_view_widget_dispose(GObject *object); static void sp_svg_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation); @@ -42,28 +40,7 @@ static void sp_svg_view_widget_get_preferred_height(GtkWidget *widget, static void sp_svg_view_widget_view_resized (SPViewWidget *vw, Inkscape::UI::View::View *view, gdouble width, gdouble height); -static SPViewWidgetClass *widget_parent_class; - -GType sp_svg_view_widget_get_type(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPSVGSPViewWidgetClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_svg_view_widget_class_init, - 0, // class_finalize - 0, // class_data - sizeof(SPSVGSPViewWidget), - 0, // n_preallocs - (GInstanceInitFunc)sp_svg_view_widget_init, - 0 // value_table - }; - type = g_type_register_static(SP_TYPE_VIEW_WIDGET, "SPSVGSPViewWidget", &info, static_cast(0)); - } - return type; -} +G_DEFINE_TYPE(SPSVGSPViewWidget, sp_svg_view_widget, SP_TYPE_VIEW_WIDGET); /** * Callback to initialize SPSVGSPViewWidget vtable. @@ -74,8 +51,6 @@ static void sp_svg_view_widget_class_init(SPSVGSPViewWidgetClass *klass) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); SPViewWidgetClass *vw_class = SP_VIEW_WIDGET_CLASS (klass); - widget_parent_class = static_cast(g_type_class_peek_parent (klass)); - object_class->dispose = sp_svg_view_widget_dispose; widget_class->size_allocate = sp_svg_view_widget_size_allocate; @@ -142,8 +117,8 @@ static void sp_svg_view_widget_dispose(GObject *object) vw->canvas = NULL; - if (((GObjectClass *) (widget_parent_class))->dispose) { - (* ((GObjectClass *) (widget_parent_class))->dispose) (object); + if (G_OBJECT_CLASS(sp_svg_view_widget_parent_class)->dispose) { + G_OBJECT_CLASS(sp_svg_view_widget_parent_class)->dispose(object); } } @@ -156,17 +131,18 @@ static void sp_svg_view_widget_size_request(GtkWidget *widget, GtkRequisition *r Inkscape::UI::View::View *v = SP_VIEW_WIDGET_VIEW (widget); #if GTK_CHECK_VERSION(3,0,0) - if (((GtkWidgetClass *) (widget_parent_class))->get_preferred_width && ((GtkWidgetClass *) (widget_parent_class))->get_preferred_width) { + if (GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->get_preferred_width && + GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->get_preferred_height) { gint width_min, height_min, width_nat, height_nat; - (* ((GtkWidgetClass *) (widget_parent_class))->get_preferred_width) (widget, &width_min, &width_nat); - (* ((GtkWidgetClass *) (widget_parent_class))->get_preferred_height) (widget, &height_min, &height_nat); + GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->get_preferred_width(widget, &width_min, &width_nat); + GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->get_preferred_height(widget, &height_min, &height_nat); req->width=width_min; req->height=height_min; } #else - if (((GtkWidgetClass *) (widget_parent_class))->size_request) { - (* ((GtkWidgetClass *) (widget_parent_class))->size_request) (widget, req); + if (GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->size_request) { + GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->size_request(widget, req); } #endif @@ -220,8 +196,8 @@ static void sp_svg_view_widget_size_allocate(GtkWidget *widget, GtkAllocation *a { SPSVGSPViewWidget *svgvw = SP_SVG_VIEW_WIDGET (widget); - if (((GtkWidgetClass *) (widget_parent_class))->size_allocate) { - (* ((GtkWidgetClass *) (widget_parent_class))->size_allocate) (widget, allocation); + if (GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->size_allocate) { + GTK_WIDGET_CLASS(sp_svg_view_widget_parent_class)->size_allocate(widget, allocation); } if (!svgvw->resize) { diff --git a/src/ui/view/view-widget.cpp b/src/ui/view/view-widget.cpp index 5cb0df215..671a4afe6 100644 --- a/src/ui/view/view-widget.cpp +++ b/src/ui/view/view-widget.cpp @@ -15,32 +15,9 @@ //using namespace Inkscape::UI::View; // SPViewWidget - -static void sp_view_widget_class_init(SPViewWidgetClass *vwc); -static void sp_view_widget_init(SPViewWidget *widget); static void sp_view_widget_dispose(GObject *object); -static GtkEventBoxClass *widget_parent_class; - -GType sp_view_widget_get_type(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPViewWidgetClass), - NULL, NULL, - (GClassInitFunc) sp_view_widget_class_init, - NULL, NULL, - sizeof(SPViewWidget), - 0, - (GInstanceInitFunc) sp_view_widget_init, - NULL - }; - type = g_type_register_static (GTK_TYPE_EVENT_BOX, "SPViewWidget", &info, (GTypeFlags)0); - } - - return type; -} +G_DEFINE_TYPE(SPViewWidget, sp_view_widget, GTK_TYPE_EVENT_BOX); /** * Callback to initialize the SPViewWidget vtable. @@ -48,8 +25,6 @@ GType sp_view_widget_get_type(void) static void sp_view_widget_class_init(SPViewWidgetClass *vwc) { GObjectClass *object_class = G_OBJECT_CLASS(vwc); - - widget_parent_class = (GtkEventBoxClass*) g_type_class_peek_parent(vwc); object_class->dispose = sp_view_widget_dispose; } @@ -77,8 +52,8 @@ static void sp_view_widget_dispose(GObject *object) vw->view = NULL; } - if (((GObjectClass *) (widget_parent_class))->dispose) { - (* ((GObjectClass *) (widget_parent_class))->dispose)(object); + if (G_OBJECT_CLASS(sp_view_widget_parent_class)->dispose) { + G_OBJECT_CLASS(sp_view_widget_parent_class)->dispose(object); } Inkscape::GC::request_early_collection(); diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp index 0e2295e36..257d8ef30 100644 --- a/src/widgets/sp-widget.cpp +++ b/src/widgets/sp-widget.cpp @@ -36,8 +36,6 @@ public: SPWidgetImpl(SPWidget &target); ~SPWidgetImpl(); - static void classInit(SPWidgetClass *klass); - static void init(SPWidget *widget); static void dispose(GObject *object); static void show(GtkWidget *widget); static void hide(GtkWidget *widget); @@ -68,57 +66,20 @@ public: void setSelection(Application *inkscape, Selection *selection); private: - static GtkBinClass *parentClass; - static guint signals[LAST_SIGNAL]; - SPWidget &_target; }; - -GtkBinClass *SPWidgetImpl::parentClass = 0; -guint SPWidgetImpl::signals[LAST_SIGNAL] = {0}; - } // namespace Inkscape -GType SPWidget::getType() -{ - static GType type = 0; - if (!type) { - static GTypeInfo const info = { - sizeof(SPWidgetClass), - NULL, NULL, - reinterpret_cast(SPWidgetImpl::classInit), - NULL, NULL, - sizeof(SPWidget), - 0, - reinterpret_cast(SPWidgetImpl::init), - NULL - }; - type = g_type_register_static(GTK_TYPE_BIN, - "SPWidget", - &info, - static_cast(0)); - } - return type; -} +G_DEFINE_TYPE(SPWidget, sp_widget, GTK_TYPE_BIN); -namespace Inkscape { +static guint signals[LAST_SIGNAL] = {0}; -SPWidgetImpl::SPWidgetImpl(SPWidget &target) : - _target(target) -{ -} - -SPWidgetImpl::~SPWidgetImpl() -{ -} - -void SPWidgetImpl::classInit(SPWidgetClass *klass) +static void +sp_widget_class_init(SPWidgetClass *klass) { GObjectClass *object_class = reinterpret_cast(klass); GtkWidgetClass *widget_class = reinterpret_cast(klass); - parentClass = reinterpret_cast(g_type_class_peek_parent(klass)); - object_class->dispose = SPWidgetImpl::dispose; signals[CONSTRUCT] = g_signal_new ("construct", @@ -169,13 +130,23 @@ void SPWidgetImpl::classInit(SPWidgetClass *klass) widget_class->size_allocate = SPWidgetImpl::sizeAllocate; } -void SPWidgetImpl::init(SPWidget *spw) +static void sp_widget_init(SPWidget *spw) { spw->inkscape = NULL; - spw->_impl = new SPWidgetImpl(*spw); // ctor invoked after all other init } +namespace Inkscape { + +SPWidgetImpl::SPWidgetImpl(SPWidget &target) : + _target(target) +{ +} + +SPWidgetImpl::~SPWidgetImpl() +{ +} + void SPWidgetImpl::dispose(GObject *object) { SPWidget *spw = reinterpret_cast(object); @@ -194,8 +165,8 @@ void SPWidgetImpl::dispose(GObject *object) delete spw->_impl; spw->_impl = 0; - if (reinterpret_cast(parentClass)->dispose) { - (*reinterpret_cast(parentClass)->dispose)(object); + if (G_OBJECT_CLASS(sp_widget_parent_class)->dispose) { + G_OBJECT_CLASS(sp_widget_parent_class)->dispose(object); } } @@ -210,8 +181,8 @@ void SPWidgetImpl::show(GtkWidget *widget) g_signal_connect(spw->inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw); } - if (reinterpret_cast(parentClass)->show) { - (*reinterpret_cast(parentClass)->show)(widget); + if (GTK_WIDGET_CLASS(sp_widget_parent_class)->show) { + GTK_WIDGET_CLASS(sp_widget_parent_class)->show(widget); } } @@ -224,8 +195,8 @@ void SPWidgetImpl::hide(GtkWidget *widget) sp_signal_disconnect_by_data(spw->inkscape, spw); } - if (reinterpret_cast(parentClass)->hide) { - (*reinterpret_cast(parentClass)->hide)(widget); + if (GTK_WIDGET_CLASS(sp_widget_parent_class)->hide) { + GTK_WIDGET_CLASS(sp_widget_parent_class)->hide(widget); } } diff --git a/src/widgets/sp-widget.h b/src/widgets/sp-widget.h index 3a23a92c5..e23a6da4f 100644 --- a/src/widgets/sp-widget.h +++ b/src/widgets/sp-widget.h @@ -18,7 +18,7 @@ #include #include -#define SP_TYPE_WIDGET (SPWidget::getType()) +#define SP_TYPE_WIDGET (sp_widget_get_type()) #define SP_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_WIDGET, SPWidget)) #define SP_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_WIDGET, SPWidgetClass)) #define SP_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_WIDGET)) @@ -36,14 +36,9 @@ class SPWidgetImpl; struct SPWidget { friend class Inkscape::SPWidgetImpl; - static GType getType(); - - // - GtkBin bin; Inkscape::Application *inkscape; -private: Inkscape::SPWidgetImpl *_impl; }; @@ -58,7 +53,7 @@ struct SPWidgetClass { void (* set_selection) (SPWidget *spw, Inkscape::Selection *selection); }; -/* fixme: Think (Lauris) */ +GType sp_widget_get_type(); /** Generic constructor for global widget. */ GtkWidget *sp_widget_new_global(Inkscape::Application *inkscape); -- cgit v1.2.3 From be6f51a507f0fddb403255adb8b25002ae10f154 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 25 Aug 2014 17:34:11 +0200 Subject: fix bug coninuing existing paths whith no LPE in bspline/spiro modes (bzr r13341.1.176) --- src/ui/tools/freehand-base.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index aad924844..72250a550 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -610,13 +610,13 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) if (dc->sa) { SPCurve *s = dc->sa->curve; dc->white_curves = g_slist_remove(dc->white_curves, s); - if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || - prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ - s = dc->overwriteCurve; - } if (dc->sa->start) { s = reverse_then_unref(s); } + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + dc->overwriteCurve = s; + } s->append_continuous(c, 0.0625); c->unref(); c = s; -- cgit v1.2.3 From 02cc21e061a2862123ef4be7e7ad8aa35fbbbfd5 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Tue, 26 Aug 2014 02:27:45 +0200 Subject: remove gtkmm sub-headers (bzr r13341.1.177) --- src/live_effects/lpe-bspline.cpp | 21 +++++++-------------- src/live_effects/lpe-envelope-perspective.cpp | 3 +-- 2 files changed, 8 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index a004b8490..433696aab 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -1,5 +1,3 @@ -#define INKSCAPE_LPE_BSPLINE_C - /* * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -8,23 +6,19 @@ # include #endif -#if WITH_GLIBMM_2_32 && HAVE_GLIBMM_THREADS_H +#include + +#if WITH_GLIBMM_2_32 # include #endif -#include <2geom/bezier-curve.h> -#include <2geom/point.h> - -#include -#include -#include -#include -#include - #include #include + #include "display/curve.h" +#include <2geom/bezier-curve.h> +#include <2geom/point.h> #include "helper/geom-curves.h" #include "live_effects/lpe-bspline.h" #include "live_effects/lpeobject.h" @@ -48,8 +42,7 @@ #include "display/sp-canvas.h" #include #include - -// For handling non-contiguous paths: +// For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" #include "desktop.h" diff --git a/src/live_effects/lpe-envelope-perspective.cpp b/src/live_effects/lpe-envelope-perspective.cpp index 5ada7a792..3b91eb183 100644 --- a/src/live_effects/lpe-envelope-perspective.cpp +++ b/src/live_effects/lpe-envelope-perspective.cpp @@ -14,12 +14,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "live_effects/lpe-envelope-perspective.h" #include "helper/geom.h" #include "display/curve.h" #include "svg/svg.h" -#include -#include #include #include #include "desktop.h" -- cgit v1.2.3 From 14d2f47bd95482e500524dccc1b40445f7f44701 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Tue, 26 Aug 2014 09:43:41 +0200 Subject: UI. Fix for Bug #340723 "Interface inconsistency of tooltips". Translations. Translations template update. Fixed bugs: - https://launchpad.net/bugs/340723 (bzr r13532) --- src/extension/internal/bitmap/crop.cpp | 2 +- src/extension/internal/bitmap/opacity.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/extension/internal/bitmap/crop.cpp b/src/extension/internal/bitmap/crop.cpp index 0e633afd6..02d92668b 100644 --- a/src/extension/internal/bitmap/crop.cpp +++ b/src/extension/internal/bitmap/crop.cpp @@ -74,7 +74,7 @@ Crop::init(void) "\n" "\n" "\n" - "" N_("Crop selected bitmap(s).") "\n" + "" N_("Crop selected bitmap(s)") "\n" "\n" "\n", new Crop()); } diff --git a/src/extension/internal/bitmap/opacity.cpp b/src/extension/internal/bitmap/opacity.cpp index 742cb7019..f9b4bbc27 100644 --- a/src/extension/internal/bitmap/opacity.cpp +++ b/src/extension/internal/bitmap/opacity.cpp @@ -43,7 +43,7 @@ Opacity::init(void) "\n" "\n" "\n" - "" N_("Modify opacity channel(s) of selected bitmap(s).") "\n" + "" N_("Modify opacity channel(s) of selected bitmap(s)") "\n" "\n" "\n", new Opacity()); } -- cgit v1.2.3 From 4a6dfa29131adb8c7470ab66a839d144b02542e5 Mon Sep 17 00:00:00 2001 From: su_v Date: Tue, 26 Aug 2014 10:41:57 +0200 Subject: librevenge: update to latest patch from bug #1323592 (support old and new versions of libwpg, libcdr and libvisio ) (bzr r13398.1.7) --- src/extension/internal/cdr-input.cpp | 34 ++++++++++++++++++------ src/extension/internal/vsd-input.cpp | 35 +++++++++++++++++++------ src/extension/internal/wpg-input.cpp | 50 ++++++++++++++++++++++++++++-------- src/ui/dialog/symbols.cpp | 24 ++++++++++++++--- 4 files changed, 113 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index c4f251361..748bf4477 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -24,7 +24,21 @@ #include #include -#include + +// TODO: Drop this check when librevenge is widespread. +#if WITH_LIBCDR01 + #include + + using librevenge::RVNGString; + using librevenge::RVNGFileStream; + using librevenge::RVNGStringVector; +#else + #include + + typedef WPXString RVNGString; + typedef WPXFileStream RVNGFileStream; + typedef libcdr::CDRStringVector RVNGStringVector; +#endif #include #include @@ -60,7 +74,7 @@ namespace Internal { class CdrImportDialog : public Gtk::Dialog { public: - CdrImportDialog(const std::vector &vec); + CdrImportDialog(const std::vector &vec); virtual ~CdrImportDialog(); bool showDialog(); @@ -86,12 +100,12 @@ private: class Gtk::VBox * vbox2; class Gtk::Widget * _previewArea; - const std::vector &_vec; // Document to be imported + const std::vector &_vec; // Document to be imported unsigned _current_page; // Current selected page int _preview_width, _preview_height; // Size of the preview area }; -CdrImportDialog::CdrImportDialog(const std::vector &vec) +CdrImportDialog::CdrImportDialog(const std::vector &vec) : _vec(vec), _current_page(1) { int num_pages = _vec.size(); @@ -210,16 +224,20 @@ void CdrImportDialog::_setPreviewPage(unsigned page) SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - librevenge::RVNGFileStream input(uri); + RVNGFileStream input(uri); if (!libcdr::CDRDocument::isSupported(&input)) { return NULL; } - librevenge::RVNGStringVector output; + RVNGStringVector output; +#if WITH_LIBCDR01 librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); if (!libcdr::CDRDocument::parse(&input, &generator)) { +#else + if (!libcdr::CDRDocument::generateSVG(&input, output)) { +#endif return NULL; } @@ -227,9 +245,9 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } - std::vector tmpSVGOutput; + std::vector tmpSVGOutput; for (unsigned i=0; i\n\n"); + RVNGString tmpString("\n\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index b7e8669b8..674997d54 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -24,7 +24,22 @@ #include #include -#include + +// TODO: Drop this check when librevenge is widespread. +#if WITH_LIBVISIO01 + #include + + using librevenge::RVNGString; + using librevenge::RVNGFileStream; + using librevenge::RVNGStringVector; +#else + #include + + typedef WPXString RVNGString; + typedef WPXFileStream RVNGFileStream; + typedef libvisio::VSDStringVector RVNGStringVector; +#endif + #include #include @@ -59,7 +74,7 @@ namespace Internal { class VsdImportDialog : public Gtk::Dialog { public: - VsdImportDialog(const std::vector &vec); + VsdImportDialog(const std::vector &vec); virtual ~VsdImportDialog(); bool showDialog(); @@ -85,12 +100,12 @@ private: class Gtk::VBox * vbox2; class Gtk::Widget * _previewArea; - const std::vector &_vec; // Document to be imported + const std::vector &_vec; // Document to be imported unsigned _current_page; // Current selected page int _preview_width, _preview_height; // Size of the preview area }; -VsdImportDialog::VsdImportDialog(const std::vector &vec) +VsdImportDialog::VsdImportDialog(const std::vector &vec) : _vec(vec), _current_page(1) { int num_pages = _vec.size(); @@ -209,16 +224,20 @@ void VsdImportDialog::_setPreviewPage(unsigned page) SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - librevenge::RVNGFileStream input(uri); + RVNGFileStream input(uri); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - librevenge::RVNGStringVector output; + RVNGStringVector output; +#if WITH_LIBVISIO01 librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); if (!libvisio::VisioDocument::parse(&input, &generator)) { +#else + if (!libvisio::VisioDocument::generateSVG(&input, output)) { +#endif return NULL; } @@ -226,9 +245,9 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } - std::vector tmpSVGOutput; + std::vector tmpSVGOutput; for (unsigned i=0; i\n\n"); + RVNGString tmpString("\n\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } diff --git a/src/extension/internal/wpg-input.cpp b/src/extension/internal/wpg-input.cpp index c10926361..12d86a99a 100644 --- a/src/extension/internal/wpg-input.cpp +++ b/src/extension/internal/wpg-input.cpp @@ -52,8 +52,25 @@ #include "util/units.h" #include +// Take a guess and fallback to 0.2.x if no configure has run +#if !defined(WITH_LIBWPG03) && !defined(WITH_LIBWPG02) +#define WITH_LIBWPG02 1 +#endif + #include "libwpg/libwpg.h" -#include "librevenge-stream/librevenge-stream.h" +#if WITH_LIBWPG03 + #include + + using librevenge::RVNGString; + using librevenge::RVNGFileStream; + using librevenge::RVNGInputStream; +#else + #include "libwpd-stream/libwpd-stream.h" + + typedef WPXString RVNGString; + typedef WPXFileStream RVNGFileStream; + typedef WPXInputStream RVNGInputStream; +#endif using namespace libwpg; @@ -64,9 +81,15 @@ namespace Internal { SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - librevenge::RVNGInputStream* input = new librevenge::RVNGFileStream(uri); + RVNGInputStream* input = new RVNGFileStream(uri); +#if WITH_LIBWPG03 if (input->isStructured()) { - librevenge::RVNGInputStream* olestream = input->getSubStreamByName("PerfectOffice_MAIN"); + RVNGInputStream* olestream = input->getSubStreamByName("PerfectOffice_MAIN"); +#else + if (input->isOLEStream()) { + RVNGInputStream* olestream = input->getDocumentOLEStream("PerfectOffice_MAIN"); +#endif + if (olestream) { delete input; input = olestream; @@ -81,17 +104,24 @@ SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } - librevenge::RVNGStringVector vec; - librevenge::RVNGSVGDrawingGenerator generator(vec, ""); +#if WITH_LIBWPG03 + librevenge::RVNGStringVector vec; + librevenge::RVNGSVGDrawingGenerator generator(vec, ""); - if (!libwpg::WPGraphics::parse(input, &generator) || vec.empty() || vec[0].empty()) - { + if (!libwpg::WPGraphics::parse(input, &generator) || vec.empty() || vec[0].empty()) { delete input; return NULL; - } + } - librevenge::RVNGString output("\n\n"); - output.append(vec[0]); + RVNGString output("\n\n"); + output.append(vec[0]); +#else + RVNGString output; + if (!libwpg::WPGraphics::generateSVG(input, output)) { + delete input; + return NULL; + } +#endif //printf("I've got a doc: \n%s", painter.document.c_str()); diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index 27e40f552..a9cf8d068 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -62,8 +62,20 @@ #include "widgets/icon.h" #ifdef WITH_LIBVISIO -#include -#include + #include + + // TODO: Drop this check when librevenge is widespread. + #if WITH_LIBVISIO01 + #include + + using librevenge::RVNGFileStream; + using librevenge::RVNGStringVector; + #else + #include + + typedef WPXFileStream RVNGFileStream; + typedef libvisio::VSDStringVector RVNGStringVector; + #endif #endif #include "verbs.h" @@ -495,16 +507,20 @@ void SymbolsDialog::iconChanged() { // Read Visio stencil files SPDocument* read_vss( gchar* fullname, gchar* filename ) { - librevenge::RVNGFileStream input(fullname); + RVNGFileStream input(fullname); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - librevenge::RVNGStringVector output; + RVNGStringVector output; +#if WITH_LIBVISIO01 librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); if (!libvisio::VisioDocument::parseStencils(&input, &generator)) { +#else + if (!libvisio::VisioDocument::generateSVGStencils(&input, output)) { +#endif return NULL; } -- cgit v1.2.3 From f7dc148704c249dc33ffcf0f22ee34abeb0fd67c Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Aug 2014 11:17:11 +0100 Subject: Fix paint-selector orientation (bzr r13341.1.178) --- src/widgets/paint-selector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 190428d51..6ef910f61 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -140,7 +140,7 @@ static SPGradientSelector *getGradientFromData(SPPaintSelector const *psel) #if GTK_CHECK_VERSION(3,0,0) G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_BOX); #else -G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_HBOX); +G_DEFINE_TYPE(SPPaintSelector, sp_paint_selector, GTK_TYPE_VBOX); #endif static void -- cgit v1.2.3 From 2d1275f0337e3fe49ea493f58135c81d0e3af36d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Aug 2014 11:55:28 +0100 Subject: Standardise InkscapeApplication GObject implementation (namespace not supported properly) (bzr r13341.1.179) --- src/desktop.h | 5 +- src/dialogs/dialog-events.cpp | 2 +- src/dialogs/dialog-events.h | 6 +- src/document-undo.cpp | 2 +- src/document-undo.h | 5 +- src/inkscape.cpp | 124 ++++++++++------------------ src/inkscape.h | 15 ++-- src/inkview.cpp | 6 +- src/ui/dialog/align-and-distribute.cpp | 4 +- src/ui/dialog/clonetiler.cpp | 4 +- src/ui/dialog/clonetiler.h | 4 +- src/ui/dialog/desktop-tracker.cpp | 2 +- src/ui/dialog/desktop-tracker.h | 5 +- src/ui/dialog/dialog-manager.cpp | 4 +- src/ui/dialog/dialog.cpp | 2 +- src/ui/dialog/dialog.h | 4 +- src/ui/dialog/document-metadata.cpp | 4 +- src/ui/dialog/document-metadata.h | 4 +- src/ui/dialog/document-properties.cpp | 4 +- src/ui/dialog/document-properties.h | 4 +- src/ui/dialog/fill-and-stroke.h | 2 +- src/ui/dialog/grid-arrange-tab.cpp | 2 +- src/ui/dialog/panel-dialog.h | 12 +-- src/ui/dialog/transformation.cpp | 4 +- src/ui/widget/object-composite-settings.cpp | 4 +- src/ui/widget/object-composite-settings.h | 6 +- src/ui/widget/panel.cpp | 4 +- src/ui/widget/panel.h | 12 +-- src/widgets/sp-widget.cpp | 6 +- src/widgets/sp-widget.h | 8 +- 30 files changed, 116 insertions(+), 154 deletions(-) (limited to 'src') diff --git a/src/desktop.h b/src/desktop.h index ec240dd40..509f8a396 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -72,8 +72,9 @@ typedef struct _GdkEventAny GdkEventAny; struct _GdkEventWindowState; typedef struct _GdkEventWindowState GdkEventWindowState; +struct InkscapeApplication; + namespace Inkscape { - struct Application; class LayerModel; class MessageContext; class Selection; @@ -423,7 +424,7 @@ public: private: Inkscape::UI::View::EditWidgetInterface *_widget; - Inkscape::Application *_inkscape; + InkscapeApplication *_inkscape; Inkscape::MessageContext *_guides_message_context; bool _active; Geom::Affine _w2d; diff --git a/src/dialogs/dialog-events.cpp b/src/dialogs/dialog-events.cpp index a12e3eafc..cf3497c9b 100644 --- a/src/dialogs/dialog-events.cpp +++ b/src/dialogs/dialog-events.cpp @@ -187,7 +187,7 @@ void on_transientize (SPDesktop *desktop, win_data *wd ) } void -sp_transientize_callback ( Inkscape::Application * /*inkscape*/, +sp_transientize_callback ( InkscapeApplication * /*inkscape*/, SPDesktop *desktop, win_data *wd ) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); diff --git a/src/dialogs/dialog-events.h b/src/dialogs/dialog-events.h index 623058282..b33eb3f38 100644 --- a/src/dialogs/dialog-events.h +++ b/src/dialogs/dialog-events.h @@ -29,9 +29,7 @@ class Entry; class SPDesktop; -namespace Inkscape { -struct Application; -} // namespace Inkscape +struct InkscapeApplication; typedef struct { GtkWidget *win; @@ -55,7 +53,7 @@ void sp_transientize ( GtkWidget *win ); void on_transientize ( SPDesktop *desktop, win_data *wd ); -void sp_transientize_callback ( Inkscape::Application *inkscape, +void sp_transientize_callback ( InkscapeApplication *inkscape, SPDesktop *desktop, win_data *wd ); diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 53e701648..478266b7b 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -112,7 +112,7 @@ void Inkscape::DocumentUndo::done(SPDocument *doc, const unsigned int event_type maybeDone(doc, NULL, event_type, event_description); } -void Inkscape::DocumentUndo::resetKey( Inkscape::Application * /*inkscape*/, SPDesktop * /*desktop*/, GObject *base ) +void Inkscape::DocumentUndo::resetKey( InkscapeApplication * /*inkscape*/, SPDesktop * /*desktop*/, GObject *base ) { SPDocument *doc = reinterpret_cast(base); doc->actionkey.clear(); diff --git a/src/document-undo.h b/src/document-undo.h index 38e575a34..17b3de252 100644 --- a/src/document-undo.h +++ b/src/document-undo.h @@ -9,11 +9,10 @@ typedef struct _GObject GObject; class SPDesktop; class SPDocument; +struct InkscapeApplication; namespace Inkscape { -struct Application; - class DocumentUndo { public: @@ -42,7 +41,7 @@ public: static void maybeDone(SPDocument *document, const gchar *keyconst, unsigned int event_type, Glib::ustring const &event_description); - static void resetKey(Inkscape::Application *inkscape, SPDesktop *desktop, GObject *base); + static void resetKey(InkscapeApplication *inkscape, SPDesktop *desktop, GObject *base); static void cancel(SPDocument *document); diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 4b4c8c678..8ac87dadd 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -71,7 +71,7 @@ #include "helper/action-context.h" #include "helper/sp-marshal.h" -static Inkscape::Application *inkscape = NULL; +static InkscapeApplication *inkscape = NULL; /* Backbones of configuration xml data */ #include "menus-skeleton.h" @@ -99,16 +99,10 @@ enum { # FORWARD DECLARATIONS ################################*/ -namespace Inkscape { -struct ApplicationClass; -} - -static void inkscape_class_init (Inkscape::ApplicationClass *klass); -static void inkscape_init (SPObject *object); static void inkscape_dispose (GObject *object); -static void inkscape_activate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop); -static void inkscape_deactivate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop); +static void inkscape_activate_desktop_private (InkscapeApplication *inkscape, SPDesktop *desktop); +static void inkscape_deactivate_desktop_private (InkscapeApplication *inkscape, SPDesktop *desktop); class AppSelectionModel { Inkscape::LayerModel _layer_model; @@ -126,7 +120,7 @@ public: Inkscape::Selection *getSelection() const { return _selection; } }; -struct Inkscape::Application { +struct InkscapeApplication { GObject object; Inkscape::XML::Document *menus; std::map document_set; @@ -140,26 +134,25 @@ struct Inkscape::Application { guint trackalt; }; -struct Inkscape::ApplicationClass { +struct InkscapeApplicationClass { GObjectClass object_class; /* Signals */ - void (* change_selection) (Inkscape::Application * inkscape, Inkscape::Selection * selection); - void (* change_subselection) (Inkscape::Application * inkscape, SPDesktop *desktop); - void (* modify_selection) (Inkscape::Application * inkscape, Inkscape::Selection * selection, guint flags); - void (* set_selection) (Inkscape::Application * inkscape, Inkscape::Selection * selection); - void (* set_eventcontext) (Inkscape::Application * inkscape, Inkscape::UI::Tools::ToolBase * eventcontext); - void (* activate_desktop) (Inkscape::Application * inkscape, SPDesktop * desktop); - void (* deactivate_desktop) (Inkscape::Application * inkscape, SPDesktop * desktop); - void (* destroy_document) (Inkscape::Application *inkscape, SPDocument *doc); - void (* color_set) (Inkscape::Application *inkscape, SPColor *color, double opacity); - void (* shut_down) (Inkscape::Application *inkscape); - void (* dialogs_hide) (Inkscape::Application *inkscape); - void (* dialogs_unhide) (Inkscape::Application *inkscape); - void (* external_change) (Inkscape::Application *inkscape); + void (* change_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection); + void (* change_subselection) (InkscapeApplication * inkscape, SPDesktop *desktop); + void (* modify_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection, guint flags); + void (* set_selection) (InkscapeApplication * inkscape, Inkscape::Selection * selection); + void (* set_eventcontext) (InkscapeApplication * inkscape, Inkscape::UI::Tools::ToolBase * eventcontext); + void (* activate_desktop) (InkscapeApplication * inkscape, SPDesktop * desktop); + void (* deactivate_desktop) (InkscapeApplication * inkscape, SPDesktop * desktop); + void (* destroy_document) (InkscapeApplication *inkscape, SPDocument *doc); + void (* color_set) (InkscapeApplication *inkscape, SPColor *color, double opacity); + void (* shut_down) (InkscapeApplication *inkscape); + void (* dialogs_hide) (InkscapeApplication *inkscape); + void (* dialogs_unhide) (InkscapeApplication *inkscape); + void (* external_change) (InkscapeApplication *inkscape); }; -static GObjectClass * parent_class; static guint inkscape_signals[LAST_SIGNAL] = {0}; static void (* segv_handler) (int) = SIG_DFL; @@ -175,48 +168,21 @@ static void (* bus_handler) (int) = SIG_DFL; #define INKSCAPE_LEGACY_PROFILE_DIR ".inkscape" #define MENUS_FILE "menus.xml" - -/** - * Retrieves the GType for the Inkscape Application object. - */ -GType -inkscape_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (Inkscape::ApplicationClass), - NULL, NULL, - (GClassInitFunc) inkscape_class_init, - NULL, NULL, - sizeof (Inkscape::Application), - 4, - (GInstanceInitFunc) inkscape_init, - NULL - }; - type = g_type_register_static (G_TYPE_OBJECT, "Inkscape_Application", &info, (GTypeFlags)0); - } - return type; -} - +G_DEFINE_TYPE(InkscapeApplication, inkscape, G_TYPE_OBJECT); /** * Initializes the inkscape class, registering all of its signal handlers * and virtual functions */ static void -inkscape_class_init (Inkscape::ApplicationClass * klass) +inkscape_class_init (InkscapeApplicationClass * klass) { - GObjectClass * object_class; - - object_class = (GObjectClass *) klass; - - parent_class = (GObjectClass *)g_type_class_peek_parent (klass); + GObjectClass * object_class = G_OBJECT_CLASS(klass); inkscape_signals[MODIFY_SELECTION] = g_signal_new ("modify_selection", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, modify_selection), + G_STRUCT_OFFSET (InkscapeApplicationClass, modify_selection), NULL, NULL, sp_marshal_VOID__POINTER_UINT, G_TYPE_NONE, 2, @@ -224,7 +190,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass) inkscape_signals[CHANGE_SELECTION] = g_signal_new ("change_selection", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, change_selection), + G_STRUCT_OFFSET (InkscapeApplicationClass, change_selection), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, @@ -232,7 +198,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass) inkscape_signals[CHANGE_SUBSELECTION] = g_signal_new ("change_subselection", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, change_subselection), + G_STRUCT_OFFSET (InkscapeApplicationClass, change_subselection), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, @@ -240,7 +206,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass) inkscape_signals[SET_SELECTION] = g_signal_new ("set_selection", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, set_selection), + G_STRUCT_OFFSET (InkscapeApplicationClass, set_selection), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, @@ -248,7 +214,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass) inkscape_signals[SET_EVENTCONTEXT] = g_signal_new ("set_eventcontext", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, set_eventcontext), + G_STRUCT_OFFSET (InkscapeApplicationClass, set_eventcontext), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, @@ -256,7 +222,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass) inkscape_signals[ACTIVATE_DESKTOP] = g_signal_new ("activate_desktop", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, activate_desktop), + G_STRUCT_OFFSET (InkscapeApplicationClass, activate_desktop), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, @@ -264,7 +230,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass) inkscape_signals[DEACTIVATE_DESKTOP] = g_signal_new ("deactivate_desktop", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, deactivate_desktop), + G_STRUCT_OFFSET (InkscapeApplicationClass, deactivate_desktop), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, @@ -272,28 +238,28 @@ inkscape_class_init (Inkscape::ApplicationClass * klass) inkscape_signals[SHUTDOWN_SIGNAL] = g_signal_new ("shut_down", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, shut_down), + G_STRUCT_OFFSET (InkscapeApplicationClass, shut_down), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); inkscape_signals[DIALOGS_HIDE] = g_signal_new ("dialogs_hide", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, dialogs_hide), + G_STRUCT_OFFSET (InkscapeApplicationClass, dialogs_hide), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); inkscape_signals[DIALOGS_UNHIDE] = g_signal_new ("dialogs_unhide", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, dialogs_unhide), + G_STRUCT_OFFSET (InkscapeApplicationClass, dialogs_unhide), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); inkscape_signals[EXTERNAL_CHANGE] = g_signal_new ("external_change", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (Inkscape::ApplicationClass, external_change), + G_STRUCT_OFFSET (InkscapeApplicationClass, external_change), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -494,10 +460,10 @@ void inkscape_autosave_init() static void -inkscape_init (SPObject * object) +inkscape_init (InkscapeApplication * object) { if (!inkscape) { - inkscape = (Inkscape::Application *) object; + inkscape = (InkscapeApplication *) object; } else { g_assert_not_reached (); } @@ -515,7 +481,7 @@ inkscape_init (SPObject * object) static void inkscape_dispose (GObject *object) { - Inkscape::Application *inkscape = (Inkscape::Application *) object; + InkscapeApplication *inkscape = (InkscapeApplication *) object; g_assert (!inkscape->desktops); @@ -530,7 +496,7 @@ inkscape_dispose (GObject *object) inkscape->selection_models.~map(); inkscape->document_set.~map(); - G_OBJECT_CLASS (parent_class)->dispose (object); + G_OBJECT_CLASS (inkscape_parent_class)->dispose (object); gtk_main_quit (); } @@ -580,14 +546,14 @@ void inkscape_trackalt(guint trackvalue) static void -inkscape_activate_desktop_private (Inkscape::Application */*inkscape*/, SPDesktop *desktop) +inkscape_activate_desktop_private (InkscapeApplication */*inkscape*/, SPDesktop *desktop) { desktop->set_active (true); } static void -inkscape_deactivate_desktop_private (Inkscape::Application */*inkscape*/, SPDesktop *desktop) +inkscape_deactivate_desktop_private (InkscapeApplication */*inkscape*/, SPDesktop *desktop) { desktop->set_active (false); } @@ -835,7 +801,7 @@ private: void inkscape_application_init (const gchar *argv0, gboolean use_gui) { - inkscape = (Inkscape::Application *)g_object_new (SP_TYPE_INKSCAPE, NULL); + inkscape = (InkscapeApplication *)g_object_new (SP_TYPE_INKSCAPE, NULL); /* fixme: load application defaults */ segv_handler = signal (SIGSEGV, inkscape_crash_handler); @@ -904,9 +870,9 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui) } /** - * Returns the current Inkscape::Application global object + * Returns the current InkscapeApplication global object */ -Inkscape::Application * +InkscapeApplication * inkscape_get_instance() { return inkscape; @@ -921,7 +887,7 @@ gboolean inkscape_use_gui() * Menus management * */ -bool inkscape_load_menus( Inkscape::Application * inkscape ) +bool inkscape_load_menus( InkscapeApplication * inkscape ) { gchar *fn = profile_path(MENUS_FILE); gchar *menus_xml = 0; @@ -1391,7 +1357,7 @@ inkscape_action_context_for_document(SPDocument *doc) #####################*/ void -inkscape_refresh_display (Inkscape::Application *inkscape) +inkscape_refresh_display (InkscapeApplication *inkscape) { for (GSList *l = inkscape->desktops; l != NULL; l = l->next) { (static_cast(l->data))->requestRedraw(); @@ -1404,7 +1370,7 @@ inkscape_refresh_display (Inkscape::Application *inkscape) * saves the preferences if appropriate, and quits. */ void -inkscape_exit (Inkscape::Application */*inkscape*/) +inkscape_exit (InkscapeApplication */*inkscape*/) { g_assert (INKSCAPE); @@ -1546,7 +1512,7 @@ profile_path(const char *filename) } Inkscape::XML::Node * -inkscape_get_menus (Inkscape::Application * inkscape) +inkscape_get_menus (InkscapeApplication * inkscape) { Inkscape::XML::Node *repr = inkscape->menus->root(); g_assert (!(strcmp (repr->name(), "inkscape"))); diff --git a/src/inkscape.h b/src/inkscape.h index 823e7524f..3a9b85fc9 100644 --- a/src/inkscape.h +++ b/src/inkscape.h @@ -28,9 +28,10 @@ class ToolBase; } } +struct InkscapeApplication; + namespace Inkscape { class ActionContext; - struct Application; namespace XML { class Node; struct Document; @@ -46,11 +47,11 @@ void inkscape_application_init (const gchar *argv0, gboolean use_gui); bool inkscape_load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, const gchar *e_notsp, const gchar *warn); /* Menus */ -bool inkscape_load_menus (Inkscape::Application * inkscape); -bool inkscape_save_menus (Inkscape::Application * inkscape); -Inkscape::XML::Node *inkscape_get_menus (Inkscape::Application * inkscape); +bool inkscape_load_menus (InkscapeApplication * inkscape); +bool inkscape_save_menus (InkscapeApplication * inkscape); +Inkscape::XML::Node *inkscape_get_menus (InkscapeApplication * inkscape); -Inkscape::Application *inkscape_get_instance(); +InkscapeApplication *inkscape_get_instance(); gboolean inkscape_use_gui(); bool inkscapeIsCrashing(); @@ -108,13 +109,13 @@ bool inkscape_remove_document (SPDocument *document); * fixme: This has to be rethought */ -void inkscape_refresh_display (Inkscape::Application *inkscape); +void inkscape_refresh_display (InkscapeApplication *inkscape); /* * fixme: This also */ -void inkscape_exit (Inkscape::Application *inkscape); +void inkscape_exit (InkscapeApplication *inkscape); #endif diff --git a/src/inkview.cpp b/src/inkview.cpp index 82bd08e34..4188c832f 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -62,7 +62,7 @@ #include "inkscape-private.h" -Inkscape::Application *inkscape; +InkscapeApplication *inkscape; #include @@ -232,7 +232,7 @@ main (int argc, const char **argv) ss.view = NULL; ss.fullscreen = false; - inkscape = (Inkscape::Application *)g_object_new (SP_TYPE_INKSCAPE, NULL); + inkscape = (InkscapeApplication *)g_object_new (SP_TYPE_INKSCAPE, NULL); // starting at where the commandline options stopped parsing because // we want all the files to be in the list @@ -572,7 +572,7 @@ static void usage() #ifdef XXX /* TODO !!! make this temporary stub unnecessary */ -Inkscape::Application *inkscape_get_instance() { return NULL; } +InkscapeApplication *inkscape_get_instance() { return NULL; } void inkscape_ref (void) {} void inkscape_unref (void) {} void inkscape_add_document (SPDocument *document) {} diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index e02ccd3f1..8352de1e3 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -829,14 +829,14 @@ private : -static void on_tool_changed(Inkscape::Application */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) +static void on_tool_changed(InkscapeApplication */*inkscape*/, Inkscape::UI::Tools::ToolBase */*context*/, AlignAndDistribute *daad) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop && desktop->getEventContext()) daad->setMode(tools_active(desktop) == TOOLS_NODES); } -static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) +static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad) { daad->randomize_bbox = Geom::OptRect(); } diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index e5f18216c..d9e2c03ba 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1349,7 +1349,7 @@ void CloneTiler::on_picker_color_changed(guint rgba) is_updating = false; } -void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) +void CloneTiler::clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) { GtkWidget *buttons = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles")); GtkWidget *status = GTK_WIDGET(g_object_get_data (G_OBJECT(dlg), "status")); @@ -1378,7 +1378,7 @@ void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape* } } -void CloneTiler::clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg) +void CloneTiler::clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg) { clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); } diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index e2a0240ee..9bacc701d 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -58,8 +58,8 @@ protected: static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/); static void clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg); static void clonetiler_unclump(GtkWidget */*widget*/, void *); - static void clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); - static void clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg); + static void clonetiler_change_selection(InkscapeApplication * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); + static void clonetiler_external_change(InkscapeApplication * /*inkscape*/, GtkWidget *dlg); static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source); static void clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg); static guint clonetiler_number_of_clones(SPObject *obj); diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp index 8a359dd2d..3ed998252 100644 --- a/src/ui/dialog/desktop-tracker.cpp +++ b/src/ui/dialog/desktop-tracker.cpp @@ -94,7 +94,7 @@ sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slottrackActive) { self->setDesktop(desktop); diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h index 7da55cf2f..7b944ddfa 100644 --- a/src/ui/dialog/desktop-tracker.h +++ b/src/ui/dialog/desktop-tracker.h @@ -12,11 +12,10 @@ typedef struct _GtkWidget GtkWidget; class SPDesktop; +struct InkscapeApplication; namespace Inkscape { -struct Application; - namespace UI { namespace Dialog { @@ -37,7 +36,7 @@ public: sigc::connection connectDesktopChanged( const sigc::slot & slot ); private: - static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, DesktopTracker *self ); + static gboolean activateDesktopCB(InkscapeApplication *inkscape, SPDesktop *desktop, DesktopTracker *self ); static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self); void handleHierarchyChange(); diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 7e69e439a..0da638546 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -70,13 +70,13 @@ inline Dialog *create() { return PanelDialog::template create(); } /** * This class is provided as a container for Inkscape's various - * dialogs. This allows Inkscape::Application to treat the various + * dialogs. This allows InkscapeApplication to treat the various * dialogs it invokes, as abstractions. * * DialogManager is essentially a cache of dialogs. It lets us * initialize dialogs lazily - instead of constructing them during * application startup, they're constructed the first time they're - * actually invoked by Inkscape::Application. The constructed + * actually invoked by InkscapeApplication. The constructed * dialog is held here after that, so future invokations of the * dialog don't need to get re-constructed each time. The memory for * the dialogs are then reclaimed when the DialogManager is destroyed. diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index f2c63ed8d..4f0d9fbe1 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -41,7 +41,7 @@ namespace Inkscape { namespace UI { namespace Dialog { -void sp_retransientize(Inkscape::Application */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) +void sp_retransientize(InkscapeApplication */*inkscape*/, SPDesktop *desktop, gpointer dlgPtr) { Dialog *dlg = static_cast(dlgPtr); dlg->onDesktopActivated (desktop); diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h index ec5d203bc..ccff43a56 100644 --- a/src/ui/dialog/dialog.h +++ b/src/ui/dialog/dialog.h @@ -18,10 +18,10 @@ #include "floating-behavior.h" class SPDesktop; +struct InkscapeApplication; namespace Inkscape { class Selection; -struct Application; } namespace Inkscape { @@ -30,7 +30,7 @@ namespace Dialog { enum BehaviorType { FLOATING, DOCK }; -void sp_retransientize(Inkscape::Application *inkscape, SPDesktop *desktop, gpointer dlgPtr); +void sp_retransientize(InkscapeApplication *inkscape, SPDesktop *desktop, gpointer dlgPtr); gboolean sp_retransientize_again(gpointer dlgPtr); void sp_dialog_shutdown(GObject *object, gpointer dlgPtr); diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index 09c505860..77ea175d9 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -223,7 +223,7 @@ DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *) } void -DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) +DocumentMetadata::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); @@ -231,7 +231,7 @@ DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *des } void -DocumentMetadata::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) +DocumentMetadata::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h index 3b7ed1ec8..77084bc3d 100644 --- a/src/ui/dialog/document-metadata.h +++ b/src/ui/dialog/document-metadata.h @@ -56,8 +56,8 @@ protected: void init(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop); - void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop); + void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); Gtk::Notebook _notebook; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 4e4616724..5ad82644e 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1594,7 +1594,7 @@ void DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument update(); } -void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) +void DocumentProperties::_handleActivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); @@ -1603,7 +1603,7 @@ void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDeskt update(); } -void DocumentProperties::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) +void DocumentProperties::_handleDeactivateDesktop(InkscapeApplication *, SPDesktop *desktop) { Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index 495f3177d..ee7e88b18 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -94,8 +94,8 @@ protected: void save_default_metadata(); void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); - void _handleActivateDesktop(Inkscape::Application *application, SPDesktop *desktop); - void _handleDeactivateDesktop(Inkscape::Application *application, SPDesktop *desktop); + void _handleActivateDesktop(InkscapeApplication *application, SPDesktop *desktop); + void _handleDeactivateDesktop(InkscapeApplication *application, SPDesktop *desktop); Inkscape::XML::SignalObserver _emb_profiles_observer, _scripts_observer; Gtk::Notebook _notebook; diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index 340cb860f..35c98ef9c 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -41,7 +41,7 @@ public: virtual void setDesktop(SPDesktop *desktop); - void selectionChanged(Inkscape::Application *inkscape, + void selectionChanged(InkscapeApplication *inkscape, Inkscape::Selection *selection); void showPageFill(); diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index 72217c729..1417b39fa 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -572,7 +572,7 @@ void GridArrangeTab::updateSelection() ## Experimental ##########################*/ -static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) +static void updateSelectionCallback(InkscapeApplication */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) { dlg->updateSelection(); } diff --git a/src/ui/dialog/panel-dialog.h b/src/ui/dialog/panel-dialog.h index 1fefd811e..b4a355083 100644 --- a/src/ui/dialog/panel-dialog.h +++ b/src/ui/dialog/panel-dialog.h @@ -49,19 +49,19 @@ public: virtual UI::Widget::Panel &getPanel() { return _panel; } protected: - static void handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { + static void handle_deactivate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { g_return_if_fail(data != NULL); static_cast(data)->_propagateDesktopDeactivated(application, desktop); } - static void _handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) { + static void _handle_activate_desktop(InkscapeApplication *application, SPDesktop *desktop, void *data) { g_return_if_fail(data != NULL); static_cast(data)->_propagateDesktopActivated(application, desktop); } inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document); - inline virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *); - inline virtual void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *); + inline virtual void _propagateDesktopActivated(InkscapeApplication *, SPDesktop *); + inline virtual void _propagateDesktopDeactivated(InkscapeApplication *, SPDesktop *); UI::Widget::Panel &_panel; sigc::connection _document_replaced_connection; @@ -134,14 +134,14 @@ void PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument _panel.signalDocumentReplaced().emit(desktop, document); } -void PanelDialogBase::_propagateDesktopActivated(Inkscape::Application *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopActivated(InkscapeApplication *application, SPDesktop *desktop) { _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced)); _panel.signalActivateDesktop().emit(application, desktop); } -void PanelDialogBase::_propagateDesktopDeactivated(Inkscape::Application *application, SPDesktop *desktop) +void PanelDialogBase::_propagateDesktopDeactivated(InkscapeApplication *application, SPDesktop *desktop) { _document_replaced_connection.disconnect(); _panel.signalDeactiveDesktop().emit(application, desktop); diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index a7f0b068e..3e135b9b2 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -47,13 +47,13 @@ namespace Inkscape { namespace UI { namespace Dialog { -static void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) +static void on_selection_changed(InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, Transformation *daad) { int page = daad->getCurrentPage(); daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection); } -static void on_selection_modified( Inkscape::Application */*inkscape*/, +static void on_selection_modified( InkscapeApplication */*inkscape*/, Inkscape::Selection *selection, guint /*flags*/, Transformation *daad ) diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index 537db0fdd..e4cd76345 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -40,7 +40,7 @@ namespace UI { namespace Widget { /*void ObjectCompositeSettings::_on_desktop_activate( - Inkscape::Application *application, + InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w ) { @@ -50,7 +50,7 @@ namespace Widget { } void ObjectCompositeSettings::_on_desktop_deactivate( - Inkscape::Application *application, + InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w ) { diff --git a/src/ui/widget/object-composite-settings.h b/src/ui/widget/object-composite-settings.h index 19a6cb2a5..e375bf24a 100644 --- a/src/ui/widget/object-composite-settings.h +++ b/src/ui/widget/object-composite-settings.h @@ -30,9 +30,9 @@ #include "ui/widget/spinbutton.h" class SPDesktop; +struct InkscapeApplication; namespace Inkscape { -struct Application; namespace UI { namespace Widget { @@ -66,8 +66,8 @@ private: gulong _desktop_activated; sigc::connection _subject_changed; - static void _on_desktop_activate(Inkscape::Application *application, SPDesktop *desktop, ObjectCompositeSettings *w); - static void _on_desktop_deactivate(Inkscape::Application *application, SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_activate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); + static void _on_desktop_deactivate(InkscapeApplication *application, SPDesktop *desktop, ObjectCompositeSettings *w); void _subjectChanged(); void _blendBlurValueChanged(); void _opacityValueChanged(); diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp index b37137228..0abd81b16 100644 --- a/src/ui/widget/panel.cpp +++ b/src/ui/widget/panel.cpp @@ -643,13 +643,13 @@ Panel::signalDocumentReplaced() return _signal_document_replaced; } -sigc::signal & +sigc::signal & Panel::signalActivateDesktop() { return _signal_activate_desktop; } -sigc::signal & +sigc::signal & Panel::signalDeactiveDesktop() { return _signal_deactive_desktop; diff --git a/src/ui/widget/panel.h b/src/ui/widget/panel.h index 0c3d822b8..177314797 100644 --- a/src/ui/widget/panel.h +++ b/src/ui/widget/panel.h @@ -45,9 +45,9 @@ namespace Gtk { class MenuItem; } -namespace Inkscape { +struct InkscapeApplication; -struct Application; +namespace Inkscape { class Selection; namespace UI { @@ -116,8 +116,8 @@ public: void setResponseSensitive(int response_id, bool setting); virtual sigc::signal &signalDocumentReplaced(); - virtual sigc::signal &signalActivateDesktop(); - virtual sigc::signal &signalDeactiveDesktop(); + virtual sigc::signal &signalActivateDesktop(); + virtual sigc::signal &signalDeactiveDesktop(); protected: /** @@ -147,8 +147,8 @@ protected: sigc::signal _signal_response; sigc::signal _signal_present; sigc::signal _signal_document_replaced; - sigc::signal _signal_activate_desktop; - sigc::signal _signal_deactive_desktop; + sigc::signal _signal_activate_desktop; + sigc::signal _signal_deactive_desktop; private: void _init(); diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp index 257d8ef30..fdf5ec500 100644 --- a/src/widgets/sp-widget.cpp +++ b/src/widgets/sp-widget.cpp @@ -59,7 +59,7 @@ public: static void changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw); static void setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw); - static GtkWidget *constructGlobal(SPWidget *spw, Inkscape::Application *inkscape); + static GtkWidget *constructGlobal(SPWidget *spw, InkscapeApplication *inkscape); void modifySelection(Application *inkscape, Selection *selection, guint flags); void changeSelection(Application *inkscape, Selection *selection); @@ -264,7 +264,7 @@ void SPWidgetImpl::sizeAllocate(GtkWidget *widget, GtkAllocation *allocation) } } -GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, Inkscape::Application *inkscape) +GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, InkscapeApplication *inkscape) { g_return_val_if_fail(!spw->inkscape, NULL); @@ -316,7 +316,7 @@ void SPWidgetImpl::setSelection(Application * /*inkscape*/, Selection *selection // Methods -GtkWidget *sp_widget_new_global(Inkscape::Application *inkscape) +GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape) { SPWidget *spw = reinterpret_cast(g_object_new(SP_TYPE_WIDGET, NULL)); diff --git a/src/widgets/sp-widget.h b/src/widgets/sp-widget.h index e23a6da4f..b3cce32a6 100644 --- a/src/widgets/sp-widget.h +++ b/src/widgets/sp-widget.h @@ -24,20 +24,18 @@ #define SP_IS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_WIDGET)) #define SP_IS_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_WIDGET)) +struct InkscapeApplication; namespace Inkscape { - -struct Application; class Selection; class SPWidgetImpl; - } struct SPWidget { friend class Inkscape::SPWidgetImpl; GtkBin bin; - Inkscape::Application *inkscape; + InkscapeApplication *inkscape; Inkscape::SPWidgetImpl *_impl; }; @@ -56,7 +54,7 @@ struct SPWidgetClass { GType sp_widget_get_type(); /** Generic constructor for global widget. */ -GtkWidget *sp_widget_new_global(Inkscape::Application *inkscape); +GtkWidget *sp_widget_new_global(InkscapeApplication *inkscape); #endif // SEEN_SP_WIDGET_H /* -- cgit v1.2.3 From 5a4558e956e744287f638613c5907f83300b01b8 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Aug 2014 12:14:18 +0100 Subject: sp-canvas: GObject boilerplate reduction (bzr r13341.1.180) --- src/display/sp-canvas-item.h | 5 +- src/display/sp-canvas.cpp | 112 ++++++------------------------------------- 2 files changed, 17 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h index f34ec453c..6781be59c 100644 --- a/src/display/sp-canvas-item.h +++ b/src/display/sp-canvas-item.h @@ -37,7 +37,7 @@ struct SPCanvasGroup; typedef struct _SPCanvasItemClass SPCanvasItemClass; -#define SP_TYPE_CANVAS_ITEM (SPCanvasItem::getType()) +#define SP_TYPE_CANVAS_ITEM (sp_canvas_item_get_type()) #define SP_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_CANVAS_ITEM, SPCanvasItem)) #define SP_CANVAS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_CANVAS_ITEM, SPCanvasItemClass)) #define SP_IS_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_CANVAS_ITEM)) @@ -50,7 +50,6 @@ typedef struct _SPCanvasItemClass SPCanvasItemClass; */ struct SPCanvasItem { GInitiallyUnowned parent_instance; - static GType getType(); SPCanvas *canvas; SPCanvasItem *parent; @@ -73,6 +72,8 @@ struct SPCanvasItem { bool in_destruction; }; +GType sp_canvas_item_get_type(); + /** * The vtable of an SPCanvasItem. */ diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 8434f6ae2..e9892c684 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -61,8 +61,6 @@ struct SPCanvasGroupClass { * A group of Items. */ struct SPCanvasGroup { - static GType getType(); - /** * Adds an item to a canvas group. */ @@ -113,17 +111,8 @@ struct SPCanvasGroup { GList *items; GList *last; - - static SPCanvasItemClass *parentClass; }; -SPCanvasItemClass *SPCanvasGroup::parentClass; - -GType sp_canvas_group_get_type() -{ - return SPCanvasGroup::getType(); -} - /** * The SPCanvas vtable. */ @@ -161,19 +150,6 @@ enum { LAST_SIGNAL }; -void sp_canvas_item_base_class_init(SPCanvasItemClass *klass); -void sp_canvas_item_base_class_finalize(SPCanvasItemClass *klass); - -/** - * Initializes the SPCanvasItem vtable and the "event" signal. - */ -void sp_canvas_item_class_init(SPCanvasItemClass *klass); - -/** - * Callback for initialization of SPCanvasItem. - */ -void sp_canvas_item_init(SPCanvasItem *item, SPCanvasItemClass *klass); - /** * Callback that removes item from all referers and destroys it. */ @@ -181,7 +157,6 @@ void sp_canvas_item_dispose(GObject *object); void sp_canvas_item_finalize(GObject *object); void sp_canvas_item_real_destroy(SPCanvasItem *object); -static gpointer parent_class = NULL; static guint object_signals[LAST_SIGNAL] = { 0 }; /** @@ -358,45 +333,12 @@ public: static void requestCanvasUpdate(SPCanvas *canvas); }; -GType SPCanvasItem::getType() -{ - static GType object_type = 0; - - if (!object_type) { - static GTypeInfo const object_info = { - sizeof(SPCanvasItemClass), - reinterpret_cast(sp_canvas_item_base_class_init), - reinterpret_cast(sp_canvas_item_base_class_finalize), - reinterpret_cast(sp_canvas_item_class_init), - NULL, // class_finalize - NULL, // class_data - sizeof(SPCanvasItem), - 16, // n_preallocs - reinterpret_cast(sp_canvas_item_init), - NULL // value_table - }; - - object_type = g_type_register_static(G_TYPE_INITIALLY_UNOWNED, - "SPCanvasItem", &object_info, GTypeFlags(0)); - } - - return object_type; -} - -namespace { - -void sp_canvas_item_base_class_init(SPCanvasItemClass * /*klass*/) -{ -} - -void sp_canvas_item_base_class_finalize(SPCanvasItemClass * /*klass*/) -{ -} +G_DEFINE_TYPE(SPCanvasItem, sp_canvas_item, G_TYPE_INITIALLY_UNOWNED); -void sp_canvas_item_class_init(SPCanvasItemClass *klass) +static void +sp_canvas_item_class_init(SPCanvasItemClass *klass) { GObjectClass *gobject_class = (GObjectClass *) klass; - parent_class = g_type_class_ref (G_TYPE_OBJECT); item_signals[ITEM_EVENT] = g_signal_new ("event", G_TYPE_FROM_CLASS (klass), @@ -421,7 +363,8 @@ void sp_canvas_item_class_init(SPCanvasItemClass *klass) G_TYPE_NONE, 0); } -void sp_canvas_item_init(SPCanvasItem *item, SPCanvasItemClass * /*klass*/) +static void +sp_canvas_item_init(SPCanvasItem *item) { item->xform = Geom::Affine(Geom::identity()); item->ctrlType = Inkscape::CTRL_TYPE_UNKNOWN; @@ -434,15 +377,13 @@ void sp_canvas_item_init(SPCanvasItem *item, SPCanvasItemClass * /*klass*/) item->in_destruction = false; } -} // namespace - SPCanvasItem *sp_canvas_item_new(SPCanvasGroup *parent, GType type, gchar const *first_arg_name, ...) { va_list args; g_return_val_if_fail(parent != NULL, NULL); g_return_val_if_fail(SP_IS_CANVAS_GROUP(parent), NULL); - g_return_val_if_fail(g_type_is_a(type, SPCanvasItem::getType()), NULL); + g_return_val_if_fail(g_type_is_a(type, SP_TYPE_CANVAS_ITEM), NULL); SPCanvasItem *item = SP_CANVAS_ITEM(g_object_new(type, NULL)); @@ -554,7 +495,7 @@ void sp_canvas_item_dispose(GObject *object) item->in_destruction = false; } - G_OBJECT_CLASS(parent_class)->dispose(object); + G_OBJECT_CLASS(sp_canvas_item_parent_class)->dispose(object); } void sp_canvas_item_real_destroy(SPCanvasItem *object) @@ -574,7 +515,7 @@ void sp_canvas_item_finalize(GObject *gobject) "and must be removed with g_object_ref_sink()."); } - G_OBJECT_CLASS (parent_class)->finalize (gobject); + G_OBJECT_CLASS (sp_canvas_item_parent_class)->finalize (gobject); } } // namespace @@ -982,37 +923,12 @@ gint sp_canvas_item_order (SPCanvasItem * item) } // SPCanvasGroup +G_DEFINE_TYPE(SPCanvasGroup, sp_canvas_group, SP_TYPE_CANVAS_ITEM); -/** - * Registers SPCanvasGroup class with Gtk and returns its type number. - */ -GType SPCanvasGroup::getType(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCanvasGroupClass), - 0, // base_init - 0, // base_finalize - reinterpret_cast(SPCanvasGroup::classInit), - 0, // class_finalize - 0, // class_data - sizeof(SPCanvasGroup), - 0, // n_preallocs - reinterpret_cast(SPCanvasGroup::init), - 0 // value_table - }; - type = g_type_register_static(SPCanvasItem::getType(), "SPCanvasGroup", &info, static_cast(0)); - } - return type; -} - -void SPCanvasGroup::classInit(SPCanvasGroupClass *klass) +static void sp_canvas_group_class_init(SPCanvasGroupClass *klass) { SPCanvasItemClass *item_class = reinterpret_cast(klass); - parentClass = reinterpret_cast(g_type_class_peek_parent(klass)); - item_class->destroy = SPCanvasGroup::destroy; item_class->update = SPCanvasGroup::update; item_class->render = SPCanvasGroup::render; @@ -1020,7 +936,7 @@ void SPCanvasGroup::classInit(SPCanvasGroupClass *klass) item_class->viewbox_changed = SPCanvasGroup::viewboxChanged; } -void SPCanvasGroup::init(SPCanvasGroup * /*group*/) +static void sp_canvas_group_init(SPCanvasGroup * /*group*/) { // Nothing here } @@ -1040,8 +956,8 @@ void SPCanvasGroup::destroy(SPCanvasItem *object) sp_canvas_item_destroy(child); } - if (SP_CANVAS_ITEM_CLASS(parentClass)->destroy) { - (* SP_CANVAS_ITEM_CLASS(parentClass)->destroy)(object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy) { + (* SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy)(object); } } @@ -1238,7 +1154,7 @@ sp_canvas_init(SPCanvas *canvas) canvas->pick_event.crossing.y = 0; // Create the root item as a special case - canvas->root = SP_CANVAS_ITEM(g_object_new(SPCanvasGroup::getType(), NULL)); + canvas->root = SP_CANVAS_ITEM(g_object_new(SP_TYPE_CANVAS_GROUP, NULL)); canvas->root->canvas = canvas; g_object_ref (canvas->root); -- cgit v1.2.3 From d1dcf26b22837dfb501c165d15e95dcbd15d85ae Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Aug 2014 12:21:55 +0100 Subject: Complete reduction of GObject boilerplate (bzr r13341.1.181) --- src/display/sodipodi-ctrlrect.cpp | 38 ++++++-------------------------------- src/display/sodipodi-ctrlrect.h | 4 ++-- 2 files changed, 8 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp index e6e427047..75789ff50 100644 --- a/src/display/sodipodi-ctrlrect.cpp +++ b/src/display/sodipodi-ctrlrect.cpp @@ -26,45 +26,19 @@ * Corner coords can be in any order - i.e. x1 < x0 is allowed */ -static void sp_ctrlrect_class_init(SPCtrlRectClass *c); -static void sp_ctrlrect_init(CtrlRect *ctrlrect); static void sp_ctrlrect_destroy(SPCanvasItem *object); static void sp_ctrlrect_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlrect_render(SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - static const guint DASH_LENGTH = 4; -GType sp_ctrlrect_get_type() -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlRectClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_ctrlrect_class_init, - 0, // class_finalize - 0, // class_data - sizeof(CtrlRect), - 0, // n_preallocs - (GInstanceInitFunc)sp_ctrlrect_init, - 0 // value_table - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlRect", &info, static_cast(0)); - } - return type; -} +G_DEFINE_TYPE(CtrlRect, sp_ctrlrect, SP_TYPE_CANVAS_ITEM); -static void sp_ctrlrect_class_init(SPCtrlRectClass *c) +static void sp_ctrlrect_class_init(CtrlRectClass *c) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(c); - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(c)); - item_class->destroy = sp_ctrlrect_destroy; item_class->update = sp_ctrlrect_update; item_class->render = sp_ctrlrect_render; @@ -77,8 +51,8 @@ static void sp_ctrlrect_init(CtrlRect *cr) static void sp_ctrlrect_destroy(SPCanvasItem *object) { - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) { - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy)(object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class)->destroy) { + (* SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class)->destroy)(object); } } @@ -171,8 +145,8 @@ void CtrlRect::update(Geom::Affine const &affine, unsigned int flags) using Geom::X; using Geom::Y; - if ((SP_CANVAS_ITEM_CLASS(parent_class))->update) { - (SP_CANVAS_ITEM_CLASS(parent_class))->update(this, affine, flags); + if ((SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class))->update) { + (SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class))->update(this, affine, flags); } sp_canvas_item_reset_bounds(this); diff --git a/src/display/sodipodi-ctrlrect.h b/src/display/sodipodi-ctrlrect.h index 65a40a850..ff6c55b06 100644 --- a/src/display/sodipodi-ctrlrect.h +++ b/src/display/sodipodi-ctrlrect.h @@ -26,7 +26,7 @@ struct SPCanvasBuf; #define SP_TYPE_CTRLRECT (sp_ctrlrect_get_type ()) #define SP_CTRLRECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_CTRLRECT, CtrlRect)) -#define SP_CTRLRECT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), SP_TYPE_CTRLRECT, SPCtrlRectClass)) +#define SP_CTRLRECT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), SP_TYPE_CTRLRECT, CtrlRectClass)) #define SP_IS_CTRLRECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLRECT)) #define SP_IS_CTRLRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_CTRLRECT)) @@ -57,7 +57,7 @@ private: int _shadow; }; -struct SPCtrlRectClass : public SPCanvasItemClass {}; +struct CtrlRectClass : public SPCanvasItemClass {}; GType sp_ctrlrect_get_type(); -- cgit v1.2.3 From 604d6716361abbb6f0a71679c10a1f490d604541 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Tue, 26 Aug 2014 13:24:21 +0100 Subject: svg-view-widget: Gtk+ 3 fixes (bzr r13341.1.182) --- src/svg-view-widget.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/svg-view-widget.cpp b/src/svg-view-widget.cpp index 657ddb2bb..c568d3ca7 100644 --- a/src/svg-view-widget.cpp +++ b/src/svg-view-widget.cpp @@ -14,7 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "display/sp-canvas.h" #include "display/sp-canvas-group.h" #include "display/canvas-arena.h" @@ -69,7 +68,6 @@ static void sp_svg_view_widget_class_init(SPSVGSPViewWidgetClass *klass) */ static void sp_svg_view_widget_init(SPSVGSPViewWidget *vw) { - GtkStyle *style; SPCanvasItem *parent; /* Settings */ @@ -92,14 +90,22 @@ static void sp_svg_view_widget_init(SPSVGSPViewWidget *vw) vw->canvas = SPCanvas::createAA(); -#if !GTK_CHECK_VERSION(3,0,0) +#if GTK_CHECK_VERSION(3,0,0) + GdkRGBA white = {1,1,1,0}; + gtk_widget_override_background_color(vw->canvas, GTK_STATE_FLAG_NORMAL, &white); +#else gtk_widget_pop_colormap (); -#endif - - style = gtk_style_copy (gtk_widget_get_style (vw->canvas)); + GtkStyle *style = gtk_style_copy (gtk_widget_get_style (vw->canvas)); style->bg[GTK_STATE_NORMAL] = style->white; gtk_widget_set_style (vw->canvas, style); +#endif + +#if GTK_CHECK_VERSION(3,8,0) + gtk_container_add (GTK_CONTAINER (vw->sw), vw->canvas); +#else gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (vw->sw), vw->canvas); +#endif + gtk_widget_show (vw->canvas); /* View */ -- cgit v1.2.3 From 7fd8ede6c698136bfa675dd4f1d5da6f5803154f Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Tue, 26 Aug 2014 22:38:14 +0200 Subject: Fix rotation center regression caused by my own commit 13512 Fixed bugs: - https://launchpad.net/bugs/1360953 - https://launchpad.net/bugs/1360946 (bzr r13534) --- src/sp-item.cpp | 20 ++++++++++++++------ src/ui/dialog/document-properties.cpp | 10 +++++++--- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 428f9555e..19dc71785 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -234,9 +234,13 @@ void SPItem::setCenter(Geom::Point const &object_centre) { document->ensureUpToDate(); // Copied from DocumentProperties::onDocUnitChange() - gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width(); - gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height(); - gdouble viewscale = std::min(viewscale_h, viewscale_w); + gdouble viewscale = 1.0; + Geom::Rect vb = this->document->getRoot()->viewBox; + if ( !vb.hasZeroArea() ) { + gdouble viewscale_w = this->document->getWidth().value("px") / vb.width(); + gdouble viewscale_h = this->document->getHeight().value("px")/ vb.height(); + viewscale = std::min(viewscale_h, viewscale_w); + } // FIXME this is seriously wrong Geom::OptRect bbox = desktopGeometricBounds(); @@ -267,9 +271,13 @@ Geom::Point SPItem::getCenter() const { document->ensureUpToDate(); // Copied from DocumentProperties::onDocUnitChange() - gdouble viewscale_w = this->document->getWidth().value("px") / this->document->getRoot()->viewBox.width(); - gdouble viewscale_h = this->document->getHeight().value("px")/ this->document->getRoot()->viewBox.height(); - gdouble viewscale = std::min(viewscale_h, viewscale_w); + gdouble viewscale = 1.0; + Geom::Rect vb = this->document->getRoot()->viewBox; + if ( !vb.hasZeroArea() ) { + gdouble viewscale_w = this->document->getWidth().value("px") / vb.width(); + gdouble viewscale_h = this->document->getHeight().value("px")/ vb.height(); + viewscale = std::min(viewscale_h, viewscale_w); + } // FIXME this is seriously wrong Geom::OptRect bbox = desktopGeometricBounds(); diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 4e4616724..2757a0ec9 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1736,9 +1736,13 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); - gdouble viewscale_w = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); - gdouble viewscale_h = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); - gdouble viewscale = std::min(viewscale_h, viewscale_w); + gdouble viewscale = 1.0; + Geom::Rect vb = doc->getRoot()->viewBox; + if ( !vb.hasZeroArea() ) { + gdouble viewscale_w = doc->getWidth().value("px") / vb.width(); + gdouble viewscale_h = doc->getHeight().value("px")/ vb.height(); + viewscale = std::min(viewscale_h, viewscale_w); + } gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, -- cgit v1.2.3 From 65e028240540fafc4269bd43e66cdeaf41408b12 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sat, 30 Aug 2014 08:24:40 +0200 Subject: Translators list update (bzr r13536) --- src/ui/dialog/aboutbox.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index a66855b2a..7cd069132 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -482,6 +482,7 @@ void AboutBox::initStrings() { "Elias Norberg , 2009.\n" "Equipe de Tradução Inkscape Brasil , 2007.\n" "Fatih Demir , 2000.\n" +"Firas Hanife , 2014.\n" "Foppe Benedictus , 2007-2009.\n" "Francesc Dorca , 2003. Traducció sodipodi.\n" "Francisco Javier F. Serrador , 2003.\n" @@ -493,8 +494,9 @@ void AboutBox::initStrings() { "Hizkuntza Politikarako Sailburuordetza , 2005.\n" "Ilia Penev , 2006.\n" "Ivan Masár , 2006-2010. \n" +"Ivan Řihošek , 2014.\n" "Iñaki Larrañaga , 2006.\n" -"Jānis Eisaks , 2012, 2013.\n" +"Jānis Eisaks , 2012-2014.\n" "Jeffrey Steve Borbón Sanabria , 2005.\n" "Jesper Öqvist , 2010, 2011.\n" "Joaquim Perez i Noguer , 2008-2009.\n" @@ -516,7 +518,7 @@ void AboutBox::initStrings() { "Kingsley Turner , 2006.\n" "Kitae , 2006.\n" "Kjartan Maraas , 2000-2002.\n" -"Kris De Gussem , 2008-2013.\n" +"Kris De Gussem , 2008-2014.\n" "Lauris Kaplinski , 2000.\n" "Leandro Regueiro , 2006-2008, 2010.\n" "Liu Xiaoqin , 2008.\n" @@ -536,7 +538,7 @@ void AboutBox::initStrings() { "Muhammad Bashir Al-Noimi , 2008.\n" "Myckel Habets , 2008.\n" "Nguyen Dinh Trung , 2007, 2008.\n" -"Nicolas Dufour , 2008-2013.\n" +"Nicolas Dufour , 2008-2014.\n" "Pawan Chitrakar , 2006.\n" "Przemysław Loesch , 2005.\n" "Quico Llach , 2000. Traducció sodipodi.\n" -- cgit v1.2.3 From 9066e62e9f0cb4972f3b7988004393e96e55e09d Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 30 Aug 2014 12:00:43 +0100 Subject: Fix modelines (bzr r13341.1.183) --- src/livarot/PathStroke.cpp | 18 +++++++++--------- src/ui/dialog/aboutbox.cpp | 6 +++--- src/ui/dialog/aboutbox.h | 6 +++--- src/ui/dialog/inkscape-preferences.h | 4 ++-- src/ui/widget/button.cpp | 6 +++--- src/ui/widget/button.h | 6 +++--- src/ui/widget/entity-entry.cpp | 4 ++-- src/ui/widget/entity-entry.h | 4 ++-- src/ui/widget/licensor.cpp | 4 ++-- src/ui/widget/licensor.h | 4 ++-- src/ui/widget/notebook-page.cpp | 6 +++--- src/ui/widget/notebook-page.h | 6 +++--- src/ui/widget/page-sizer.cpp | 4 ++-- src/ui/widget/page-sizer.h | 4 ++-- src/ui/widget/preferences-widget.h | 4 ++-- src/ui/widget/registered-widget.cpp | 4 ++-- src/ui/widget/registered-widget.h | 4 ++-- src/ui/widget/registry.cpp | 4 ++-- src/ui/widget/registry.h | 4 ++-- src/ui/widget/rotateable.cpp | 6 +++--- src/ui/widget/rotateable.h | 4 ++-- src/ui/widget/selected-style.cpp | 4 ++-- src/ui/widget/selected-style.h | 6 +++--- src/ui/widget/spin-scale.cpp | 6 +++--- src/ui/widget/spin-scale.h | 6 +++--- src/ui/widget/spin-slider.cpp | 6 +++--- src/ui/widget/spin-slider.h | 6 +++--- src/ui/widget/spinbutton.cpp | 6 +++--- src/ui/widget/spinbutton.h | 6 +++--- src/ui/widget/style-swatch.cpp | 4 ++-- src/ui/widget/style-swatch.h | 6 +++--- src/ui/widget/tolerance-slider.cpp | 4 ++-- src/ui/widget/tolerance-slider.h | 4 ++-- src/ui/widget/unit-menu.cpp | 6 +++--- src/ui/widget/unit-menu.h | 4 ++-- 35 files changed, 93 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/livarot/PathStroke.cpp b/src/livarot/PathStroke.cpp index 50c335176..6ec7fa209 100644 --- a/src/livarot/PathStroke.cpp +++ b/src/livarot/PathStroke.cpp @@ -748,12 +748,12 @@ void Path::RecRound(Shape *dest, int sNo, int eNo, // start and end index } /* - Local Variables: -mode:c++ -c-file-style:"stroustrup" -c-file-offsets:((innamespace . 0)(inline-open . 0)) -indent-tabs-mode:nil -fill-column:99 -End: - */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index a66855b2a..44ed3b58f 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -941,13 +941,13 @@ void AboutBox::initStrings() { } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/aboutbox.h b/src/ui/dialog/aboutbox.h index 7b3308672..015e344a1 100644 --- a/src/ui/dialog/aboutbox.h +++ b/src/ui/dialog/aboutbox.h @@ -55,13 +55,13 @@ private: #endif // INKSCAPE_UI_DIALOG_ABOUTBOX_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 9f37626ed..dcea91741 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -545,9 +545,9 @@ private: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/button.cpp b/src/ui/widget/button.cpp index bac866920..6c2d419cf 100644 --- a/src/ui/widget/button.cpp +++ b/src/ui/widget/button.cpp @@ -51,13 +51,13 @@ RadioButton::RadioButton(Glib::ustring const &label, Glib::ustring const &toolti } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/button.h b/src/ui/widget/button.h index a214dd881..471b7d8a2 100644 --- a/src/ui/widget/button.h +++ b/src/ui/widget/button.h @@ -67,13 +67,13 @@ public: #endif // INKSCAPE_UI_WIDGET_BUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/entity-entry.cpp b/src/ui/widget/entity-entry.cpp index 0f526f77a..c7d5efe29 100644 --- a/src/ui/widget/entity-entry.cpp +++ b/src/ui/widget/entity-entry.cpp @@ -206,9 +206,9 @@ EntityMultiLineEntry::on_changed() Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/entity-entry.h b/src/ui/widget/entity-entry.h index 09289496d..35f6ecfb4 100644 --- a/src/ui/widget/entity-entry.h +++ b/src/ui/widget/entity-entry.h @@ -76,9 +76,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/licensor.cpp b/src/ui/widget/licensor.cpp index 42f352e3c..7429bb07e 100644 --- a/src/ui/widget/licensor.cpp +++ b/src/ui/widget/licensor.cpp @@ -160,9 +160,9 @@ void Licensor::update (SPDocument *doc) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/licensor.h b/src/ui/widget/licensor.h index 0ac3e5ab8..c75c5fe9e 100644 --- a/src/ui/widget/licensor.h +++ b/src/ui/widget/licensor.h @@ -56,9 +56,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/notebook-page.cpp b/src/ui/widget/notebook-page.cpp index 6653499b8..2f03ed23b 100644 --- a/src/ui/widget/notebook-page.cpp +++ b/src/ui/widget/notebook-page.cpp @@ -44,13 +44,13 @@ NotebookPage::NotebookPage(int n_rows, int n_columns, bool expand, bool fill, gu } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/notebook-page.h b/src/ui/widget/notebook-page.h index 38ae9e054..4f7915423 100644 --- a/src/ui/widget/notebook-page.h +++ b/src/ui/widget/notebook-page.h @@ -67,13 +67,13 @@ protected: #endif // INKSCAPE_UI_WIDGET_NOTEBOOK_PAGE_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index eae0d4a95..89b0b8f7e 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -728,9 +728,9 @@ PageSizer::on_units_changed() Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h index dc8e34d82..f4bcae4b6 100644 --- a/src/ui/widget/page-sizer.h +++ b/src/ui/widget/page-sizer.h @@ -277,9 +277,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h index cb4ce17d1..5d9816e74 100644 --- a/src/ui/widget/preferences-widget.h +++ b/src/ui/widget/preferences-widget.h @@ -306,9 +306,9 @@ public: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 8a81b1c02..44d8dcbf3 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -788,9 +788,9 @@ RegisteredRandom::on_value_changed() Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index d8c0e6602..1f505a3cd 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -419,9 +419,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registry.cpp b/src/ui/widget/registry.cpp index 725e52791..ea8198422 100644 --- a/src/ui/widget/registry.cpp +++ b/src/ui/widget/registry.cpp @@ -48,9 +48,9 @@ Registry::setUpdating (bool upd) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/registry.h b/src/ui/widget/registry.h index 2da29735c..a236b96ad 100644 --- a/src/ui/widget/registry.h +++ b/src/ui/widget/registry.h @@ -39,9 +39,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/rotateable.cpp b/src/ui/widget/rotateable.cpp index 72ec69362..2d7597d7c 100644 --- a/src/ui/widget/rotateable.cpp +++ b/src/ui/widget/rotateable.cpp @@ -173,13 +173,13 @@ Rotateable::~Rotateable() { } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/rotateable.h b/src/ui/widget/rotateable.h index 52fb5306c..6404c3550 100644 --- a/src/ui/widget/rotateable.h +++ b/src/ui/widget/rotateable.h @@ -62,9 +62,9 @@ private: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 85538c8c7..a0a163286 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -1571,9 +1571,9 @@ Dialog::FillAndStroke *get_fill_and_stroke_panel(SPDesktop *desktop) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index df0f41507..0b6a14762 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -301,13 +301,13 @@ protected: #endif // INKSCAPE_UI_WIDGET_BUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-scale.cpp b/src/ui/widget/spin-scale.cpp index ade3d1e60..bb08d67df 100644 --- a/src/ui/widget/spin-scale.cpp +++ b/src/ui/widget/spin-scale.cpp @@ -235,13 +235,13 @@ void DualSpinScale::update_linked() } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-scale.h b/src/ui/widget/spin-scale.h index 5fec8b1d8..d0447e4a6 100644 --- a/src/ui/widget/spin-scale.h +++ b/src/ui/widget/spin-scale.h @@ -113,13 +113,13 @@ private: #endif // INKSCAPE_UI_WIDGET_SPIN_SCALE_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-slider.cpp b/src/ui/widget/spin-slider.cpp index 1cb59a7b3..9b361ae78 100644 --- a/src/ui/widget/spin-slider.cpp +++ b/src/ui/widget/spin-slider.cpp @@ -262,13 +262,13 @@ void DualSpinSlider::update_linked() } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spin-slider.h b/src/ui/widget/spin-slider.h index 5f86fd15a..74982ea58 100644 --- a/src/ui/widget/spin-slider.h +++ b/src/ui/widget/spin-slider.h @@ -111,13 +111,13 @@ private: #endif // INKSCAPE_UI_WIDGET_SPIN_SLIDER_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp index 7709a837b..d7669d4e5 100644 --- a/src/ui/widget/spinbutton.cpp +++ b/src/ui/widget/spinbutton.cpp @@ -100,13 +100,13 @@ void SpinButton::undo() } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/spinbutton.h b/src/ui/widget/spinbutton.h index 812b5f515..cbe33e8ea 100644 --- a/src/ui/widget/spinbutton.h +++ b/src/ui/widget/spinbutton.h @@ -111,13 +111,13 @@ private: #endif // INKSCAPE_UI_WIDGET_SPINBUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index 98f4e47cd..157fd2ad9 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -386,9 +386,9 @@ void StyleSwatch::setStyle(SPStyle *query) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index 557ca82e2..582d2ebb3 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -108,13 +108,13 @@ friend class ToolObserver; #endif // INKSCAPE_UI_WIDGET_BUTTON_H -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp index 5fc588fdc..aac7451f4 100644 --- a/src/ui/widget/tolerance-slider.cpp +++ b/src/ui/widget/tolerance-slider.cpp @@ -216,9 +216,9 @@ void ToleranceSlider::update (double val) Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/tolerance-slider.h b/src/ui/widget/tolerance-slider.h index 2184cd52b..7ae8e4712 100644 --- a/src/ui/widget/tolerance-slider.h +++ b/src/ui/widget/tolerance-slider.h @@ -88,9 +88,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/unit-menu.cpp b/src/ui/widget/unit-menu.cpp index 7416a2f02..423313a1f 100644 --- a/src/ui/widget/unit-menu.cpp +++ b/src/ui/widget/unit-menu.cpp @@ -140,13 +140,13 @@ bool UnitMenu::isRadial() const } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/widget/unit-menu.h b/src/ui/widget/unit-menu.h index 114c536c9..2fd25a6a9 100644 --- a/src/ui/widget/unit-menu.h +++ b/src/ui/widget/unit-menu.h @@ -141,9 +141,9 @@ protected: Local Variables: mode:c++ c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)) + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ -// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 977857ef75a45ed1ec79cfdcf0f25dd66d4a7e86 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 30 Aug 2014 14:00:28 +0100 Subject: Reduce header bloat (bzr r13341.1.184) --- src/axis-manip.h | 2 +- src/desktop-events.h | 8 +++++--- src/display/sp-canvas-item.h | 4 ++-- src/display/sp-canvas.h | 1 - src/ege-adjustment-action.h | 2 -- src/ege-output-action.h | 2 -- src/ege-select-one-action.h | 2 -- src/extension/input.h | 5 ++--- src/extension/internal/emf-inout.cpp | 2 +- src/extension/internal/wmf-inout.cpp | 1 + src/extension/output.h | 1 - src/helper/action.h | 6 +----- src/icon-size.h | 2 -- src/ink-action.h | 2 -- src/ink-comboboxentry-action.h | 4 ---- src/knot.cpp | 1 + src/knot.h | 4 +--- src/proj_pt.h | 2 +- src/sp-pattern.h | 6 +----- src/ui/dialog/clonetiler.h | 1 - src/ui/dialog/export.h | 9 --------- src/ui/dialog/filedialogimpl-gtkmm.cpp | 1 + src/ui/tools/flood-tool.h | 4 +--- src/ui/tools/select-tool.h | 1 - src/ui/tools/spiral-tool.h | 8 +++----- src/ui/tools/text-tool.h | 7 +++---- src/ui/widget/unit-tracker.h | 7 +++++-- src/widgets/button.cpp | 1 + src/widgets/button.h | 12 ++++++++++-- src/widgets/eek-preview.h | 1 - src/widgets/gradient-image.h | 1 - src/widgets/gradient-selector.cpp | 4 +++- src/widgets/gradient-selector.h | 20 ++++++++------------ src/widgets/gradient-vector.h | 8 -------- src/widgets/paint-selector.h | 1 - src/widgets/sp-color-icc-selector.h | 2 -- src/widgets/sp-color-notebook.h | 1 - src/widgets/sp-color-scales.h | 2 -- src/widgets/sp-color-selector.h | 4 +--- src/widgets/sp-color-slider.h | 2 -- src/widgets/sp-color-wheel-selector.h | 1 - src/widgets/sp-widget.h | 1 - src/widgets/sp-xmlview-content.h | 2 -- src/widgets/spinbutton-events.h | 4 +++- src/widgets/toolbox.h | 6 +++--- 45 files changed, 59 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/src/axis-manip.h b/src/axis-manip.h index 9392e2ddd..7842b4135 100644 --- a/src/axis-manip.h +++ b/src/axis-manip.h @@ -13,7 +13,7 @@ #define SEEN_AXIS_MANIP_H #include -#include +#include namespace Proj { diff --git a/src/desktop-events.h b/src/desktop-events.h index 7123ce91b..dc85e563b 100644 --- a/src/desktop-events.h +++ b/src/desktop-events.h @@ -13,13 +13,15 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include - class SPDesktop; struct SPDesktopWidget; struct SPCanvasItem; +typedef union _GdkEvent GdkEvent; +typedef struct _GdkEventCrossing GdkEventCrossing; +typedef struct _GdkEventMotion GdkEventMotion; +typedef struct _GtkWidget GtkWidget; + /* Item handlers */ int sp_desktop_root_handler (SPCanvasItem *item, GdkEvent *event, SPDesktop *desktop); diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h index 6781be59c..a388ffa91 100644 --- a/src/display/sp-canvas-item.h +++ b/src/display/sp-canvas-item.h @@ -24,8 +24,6 @@ #endif #include -#include -#include #include <2geom/rect.h> #include "ui/control-types.h" @@ -36,6 +34,8 @@ struct SPCanvasBuf; struct SPCanvasGroup; typedef struct _SPCanvasItemClass SPCanvasItemClass; +typedef union _GdkEvent GdkEvent; +typedef struct _GdkCursor GdkCursor; #define SP_TYPE_CANVAS_ITEM (sp_canvas_item_get_type()) #define SP_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_CANVAS_ITEM, SPCanvasItem)) diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 72ae4b6bc..adae30f35 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -30,7 +30,6 @@ # endif #endif -#include #include #include #include diff --git a/src/ege-adjustment-action.h b/src/ege-adjustment-action.h index 590035eb3..8cfaa3e52 100644 --- a/src/ege-adjustment-action.h +++ b/src/ege-adjustment-action.h @@ -45,9 +45,7 @@ /* Note: this file should be kept compilable as both .cpp and .c */ -#include #include -#include G_BEGIN_DECLS diff --git a/src/ege-output-action.h b/src/ege-output-action.h index fc21c2f27..0f4e21805 100644 --- a/src/ege-output-action.h +++ b/src/ege-output-action.h @@ -45,9 +45,7 @@ /* Note: this file should be kept compilable as both .cpp and .c */ -#include #include -#include G_BEGIN_DECLS diff --git a/src/ege-select-one-action.h b/src/ege-select-one-action.h index d605f4a67..0c5cecaa3 100644 --- a/src/ege-select-one-action.h +++ b/src/ege-select-one-action.h @@ -48,9 +48,7 @@ /* Note: this file should be kept compilable as both .cpp and .c */ -#include #include -#include G_BEGIN_DECLS diff --git a/src/extension/input.h b/src/extension/input.h index b01ffeb86..2a0a177a0 100644 --- a/src/extension/input.h +++ b/src/extension/input.h @@ -14,9 +14,8 @@ #include #include #include "extension.h" -#include "xml/repr.h" -#include "document.h" -#include + +class SPDocument; namespace Inkscape { namespace Extension { diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp index 084fbcd58..9a5a78a34 100644 --- a/src/extension/internal/emf-inout.cpp +++ b/src/extension/internal/emf-inout.cpp @@ -27,12 +27,12 @@ # include "config.h" #endif -//#include //This must precede text_reassemble.h or it blows up in pngconf.h when compiling #include #include #include #include +#include "document.h" #include "sp-root.h" // even though it is included indirectly by wmf-inout.h #include "sp-path.h" #include "print.h" diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp index 5ccad678a..c03e7efe0 100644 --- a/src/extension/internal/wmf-inout.cpp +++ b/src/extension/internal/wmf-inout.cpp @@ -33,6 +33,7 @@ #include #include +#include "document.h" #include "sp-root.h" // even though it is included indirectly by wmf-inout.h #include "sp-path.h" #include "print.h" diff --git a/src/extension/output.h b/src/extension/output.h index c5b1beb45..44a731ca0 100644 --- a/src/extension/output.h +++ b/src/extension/output.h @@ -13,7 +13,6 @@ #ifndef INKSCAPE_EXTENSION_OUTPUT_H__ #define INKSCAPE_EXTENSION_OUTPUT_H__ -#include #include "extension.h" class SPDocument; diff --git a/src/helper/action.h b/src/helper/action.h index 1f2de87b4..4b81ee7f9 100644 --- a/src/helper/action.h +++ b/src/helper/action.h @@ -13,12 +13,8 @@ #define SEEN_INKSCAPE_SP_ACTION_H #include "helper/action-context.h" -#include +#include #include -#include - -struct SPAction; -struct SPActionClass; #define SP_TYPE_ACTION (sp_action_get_type()) #define SP_ACTION(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_ACTION, SPAction)) diff --git a/src/icon-size.h b/src/icon-size.h index 4bb4f1df6..d7a9c9b0b 100644 --- a/src/icon-size.h +++ b/src/icon-size.h @@ -12,8 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include namespace Inkscape { diff --git a/src/ink-action.h b/src/ink-action.h index 1d4106681..ac5cb9873 100644 --- a/src/ink-action.h +++ b/src/ink-action.h @@ -2,9 +2,7 @@ #define SEEN_INK_ACTION -#include #include -#include #include "icon-size.h" #include "attributes.h" diff --git a/src/ink-comboboxentry-action.h b/src/ink-comboboxentry-action.h index a66f0790e..04b66e8fe 100644 --- a/src/ink-comboboxentry-action.h +++ b/src/ink-comboboxentry-action.h @@ -19,12 +19,8 @@ #ifndef SEEN_INK_COMBOBOXENTRY_ACTION #define SEEN_INK_COMBOBOXENTRY_ACTION -#include -#include - #include - #define INK_COMBOBOXENTRY_TYPE_ACTION (ink_comboboxentry_action_get_type()) #define INK_COMBOBOXENTRY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INK_COMBOBOXENTRY_TYPE_ACTION, Ink_ComboBoxEntry_Action)) #define INK_COMBOBOXENTRY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INK_COMBOBOXENTRY_TYPE_ACTION, Ink_ComboBoxEntry_ActionClass)) diff --git a/src/knot.cpp b/src/knot.cpp index 6205af26a..49b4dbb54 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -28,6 +28,7 @@ #include "message-stack.h" #include "message-context.h" #include "ui/tools/tool-base.h" +#include using Inkscape::DocumentUndo; diff --git a/src/knot.h b/src/knot.h index b18f89566..b79614bcb 100644 --- a/src/knot.h +++ b/src/knot.h @@ -17,14 +17,12 @@ #include #include <2geom/point.h> #include "knot-enums.h" -#include #include #include "enums.h" -#include -#include "sp-item.h" class SPDesktop; struct SPCanvasItem; +class SPItem; #define SP_KNOT(obj) (dynamic_cast(static_cast(obj))) #define SP_IS_KNOT(obj) (dynamic_cast(static_cast(obj)) != NULL) diff --git a/src/proj_pt.h b/src/proj_pt.h index 226c182cc..28ec0aca3 100644 --- a/src/proj_pt.h +++ b/src/proj_pt.h @@ -13,7 +13,7 @@ #define SEEN_PROJ_PT_H #include <2geom/point.h> -#include +#include namespace Proj { diff --git a/src/sp-pattern.h b/src/sp-pattern.h index eb34b6714..8f7dbbadd 100644 --- a/src/sp-pattern.h +++ b/src/sp-pattern.h @@ -13,21 +13,17 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - -#include "sp-item.h" - #define SP_PATTERN(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_PATTERN(obj) (dynamic_cast((SPObject*)obj) != NULL) class SPPatternReference; +class SPItem; #include "svg/svg-length.h" #include "sp-paint-server.h" #include "uri-references.h" #include "viewbox.h" -#include #include diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h index 9bacc701d..70da86338 100644 --- a/src/ui/dialog/clonetiler.h +++ b/src/ui/dialog/clonetiler.h @@ -11,7 +11,6 @@ #define __SP_CLONE_TILER_H__ #include "ui/widget/panel.h" -#include #include "ui/dialog/desktop-tracker.h" #include "ui/widget/color-picker.h" diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 6f3c0dfac..23af0109b 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -12,20 +12,11 @@ #ifndef SP_EXPORT_H #define SP_EXPORT_H -#include -#include - -#include -#include -#include #include -#include -#include "desktop.h" #include "ui/dialog/desktop-tracker.h" #include "ui/widget/panel.h" #include "ui/widget/button.h" -#include "ui/widget/entry.h" namespace Gtk { class Dialog; diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 8ba3ad684..575519848 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -40,6 +40,7 @@ #include #include +#include "document.h" #include "extension/input.h" #include "extension/output.h" #include "extension/db.h" diff --git a/src/ui/tools/flood-tool.h b/src/ui/tools/flood-tool.h index 3ed670e8b..5104a42e9 100644 --- a/src/ui/tools/flood-tool.h +++ b/src/ui/tools/flood-tool.h @@ -11,9 +11,7 @@ * Released under GNU GPL */ -#include -#include -#include +#include #include "ui/tools/tool-base.h" #define SP_FLOOD_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) diff --git a/src/ui/tools/select-tool.h b/src/ui/tools/select-tool.h index edc4069a2..5af99a56a 100644 --- a/src/ui/tools/select-tool.h +++ b/src/ui/tools/select-tool.h @@ -13,7 +13,6 @@ */ #include "ui/tools/tool-base.h" -#include #define SP_SELECT_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_SELECT_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) diff --git a/src/ui/tools/spiral-tool.h b/src/ui/tools/spiral-tool.h index 416aeb7e4..add92342d 100644 --- a/src/ui/tools/spiral-tool.h +++ b/src/ui/tools/spiral-tool.h @@ -15,17 +15,15 @@ * Released under GNU GPL */ -#include -#include -#include +#include #include <2geom/point.h> #include "ui/tools/tool-base.h" -#include "sp-spiral.h" - #define SP_SPIRAL_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_SPIRAL_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) +class SPSpiral; + namespace Inkscape { namespace UI { namespace Tools { diff --git a/src/ui/tools/text-tool.h b/src/ui/tools/text-tool.h index ca2b3d19a..289ee180d 100644 --- a/src/ui/tools/text-tool.h +++ b/src/ui/tools/text-tool.h @@ -14,10 +14,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -/* #include */ -#include -#include -#include +#include #include "ui/tools/tool-base.h" #include <2geom/point.h> @@ -26,6 +23,8 @@ #define SP_TEXT_CONTEXT(obj) (dynamic_cast((Inkscape::UI::Tools::ToolBase*)obj)) #define SP_IS_TEXT_CONTEXT(obj) (dynamic_cast((const Inkscape::UI::Tools::ToolBase*)obj) != NULL) +typedef struct _GtkIMContext GtkIMContext; + struct SPCtrlLine; namespace Inkscape { diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h index 61bb556ef..06245930e 100644 --- a/src/ui/widget/unit-tracker.h +++ b/src/ui/widget/unit-tracker.h @@ -16,13 +16,16 @@ #define INKSCAPE_UI_WIDGET_UNIT_TRACKER_H #include -#include - #include "util/units.h" using Inkscape::Util::Unit; using Inkscape::Util::UnitType; +typedef struct _GObject GObject; +typedef struct _GtkAction GtkAction; +typedef struct _GtkAdjustment GtkAdjustment; +typedef struct _GtkListStore GtkListStore; + namespace Inkscape { namespace UI { namespace Widget { diff --git a/src/widgets/button.cpp b/src/widgets/button.cpp index f97bba072..cda97654e 100644 --- a/src/widgets/button.cpp +++ b/src/widgets/button.cpp @@ -18,6 +18,7 @@ #include "helper/action-context.h" #include "interface.h" #include "shortcuts.h" +#include "helper/action.h" #include diff --git a/src/widgets/button.h b/src/widgets/button.h index d5e29da1a..2bceb5e97 100644 --- a/src/widgets/button.h +++ b/src/widgets/button.h @@ -17,10 +17,18 @@ #define SP_IS_BUTTON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_BUTTON)) #include -#include -#include "helper/action.h" +#include #include "icon-size.h" +struct SPAction; + +namespace Inkscape { +namespace UI { +namespace View { +class View; +} +} +} typedef enum { SP_BUTTON_TYPE_NORMAL, diff --git a/src/widgets/eek-preview.h b/src/widgets/eek-preview.h index e4c724cc5..883ce713e 100644 --- a/src/widgets/eek-preview.h +++ b/src/widgets/eek-preview.h @@ -37,7 +37,6 @@ #ifndef SEEN_EEK_PREVIEW_H #define SEEN_EEK_PREVIEW_H -#include #include /** diff --git a/src/widgets/gradient-image.h b/src/widgets/gradient-image.h index 6a9c89acf..0d3833441 100644 --- a/src/widgets/gradient-image.h +++ b/src/widgets/gradient-image.h @@ -17,7 +17,6 @@ class SPGradient; -#include #include #define SP_TYPE_GRADIENT_IMAGE (sp_gradient_image_get_type ()) diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index e85c115a8..a5e16aed2 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -16,8 +16,10 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif + +#include + #include "gradient-vector.h" -#include #include "document.h" #include "document-undo.h" diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h index 1a6468ad4..e090d7cbd 100644 --- a/src/widgets/gradient-selector.h +++ b/src/widgets/gradient-selector.h @@ -19,27 +19,23 @@ # include #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - -#include -#include - -#include -#include -#include #include -#include #include #include -#include "sp-gradient.h" #include "sp-gradient-spread.h" #include "sp-gradient-units.h" +class SPDocument; class SPGradient; +namespace Gtk { +class CellRendererPixbuf; +class CellRendererText; +class ScrolledWindow; +class TreeView; +} + #define SP_TYPE_GRADIENT_SELECTOR (sp_gradient_selector_get_type ()) #define SP_GRADIENT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_GRADIENT_SELECTOR, SPGradientSelector)) #define SP_GRADIENT_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_GRADIENT_SELECTOR, SPGradientSelectorClass)) diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index fc85b0d9c..5ae90b28f 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -19,16 +19,8 @@ # include "config.h" #endif -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include - -#include #include - -#include #include "gradient-selector.h" #define SP_TYPE_GRADIENT_VECTOR_SELECTOR (sp_gradient_vector_selector_get_type ()) diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index 1e8ad6d2e..788aa673e 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -12,7 +12,6 @@ * */ -#include #include #include "color.h" diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h index f63ab0853..6cdaff639 100644 --- a/src/widgets/sp-color-icc-selector.h +++ b/src/widgets/sp-color-icc-selector.h @@ -2,8 +2,6 @@ #define SEEN_SP_COLOR_ICC_SELECTOR_H #include -#include - #include "sp-color-selector.h" namespace Inkscape { diff --git a/src/widgets/sp-color-notebook.h b/src/widgets/sp-color-notebook.h index 50c2bb2e7..469bb56e8 100644 --- a/src/widgets/sp-color-notebook.h +++ b/src/widgets/sp-color-notebook.h @@ -12,7 +12,6 @@ * This code is in public domain */ -#include #include "sp-color-selector.h" #include diff --git a/src/widgets/sp-color-scales.h b/src/widgets/sp-color-scales.h index de6544d11..72cbafa2f 100644 --- a/src/widgets/sp-color-scales.h +++ b/src/widgets/sp-color-scales.h @@ -2,9 +2,7 @@ #define SEEN_SP_COLOR_SCALES_H #include -#include -#include #include struct SPColorScales; diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h index 9d71a4a56..30061774a 100644 --- a/src/widgets/sp-color-selector.h +++ b/src/widgets/sp-color-selector.h @@ -2,9 +2,7 @@ #define SEEN_SP_COLOR_SELECTOR_H #include -#include "../color.h" - -#include +#include "color.h" struct SPColorSelector; diff --git a/src/widgets/sp-color-slider.h b/src/widgets/sp-color-slider.h index 85db01081..b81d62e41 100644 --- a/src/widgets/sp-color-slider.h +++ b/src/widgets/sp-color-slider.h @@ -14,8 +14,6 @@ #include -#include - #define SP_TYPE_COLOR_SLIDER (sp_color_slider_get_type ()) #define SP_COLOR_SLIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_SLIDER, SPColorSlider)) #define SP_COLOR_SLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_SLIDER, SPColorSliderClass)) diff --git a/src/widgets/sp-color-wheel-selector.h b/src/widgets/sp-color-wheel-selector.h index 23ac0050d..12b060dbe 100644 --- a/src/widgets/sp-color-wheel-selector.h +++ b/src/widgets/sp-color-wheel-selector.h @@ -1,7 +1,6 @@ #ifndef SEEN_SP_COLOR_WHEEL_SELECTOR_H #define SEEN_SP_COLOR_WHEEL_SELECTOR_H -#include #include #include "sp-color-selector.h" diff --git a/src/widgets/sp-widget.h b/src/widgets/sp-widget.h index b3cce32a6..6227c3a72 100644 --- a/src/widgets/sp-widget.h +++ b/src/widgets/sp-widget.h @@ -15,7 +15,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include #define SP_TYPE_WIDGET (sp_widget_get_type()) diff --git a/src/widgets/sp-xmlview-content.h b/src/widgets/sp-xmlview-content.h index a09d2d92d..140eacf46 100644 --- a/src/widgets/sp-xmlview-content.h +++ b/src/widgets/sp-xmlview-content.h @@ -14,8 +14,6 @@ #include #include -#include - #define SP_TYPE_XMLVIEW_CONTENT (sp_xmlview_content_get_type ()) #define SP_XMLVIEW_CONTENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_XMLVIEW_CONTENT, SPXMLViewContent)) diff --git a/src/widgets/spinbutton-events.h b/src/widgets/spinbutton-events.h index c1df88c8a..9bf50d87c 100644 --- a/src/widgets/spinbutton-events.h +++ b/src/widgets/spinbutton-events.h @@ -10,7 +10,9 @@ */ #include -#include /* GtkWidget */ + +typedef struct _GdkEventKey GdkEventKey; +typedef struct _GtkWidget GtkWidget; gboolean spinbutton_focus_in (GtkWidget *w, GdkEventKey *event, gpointer data); void spinbutton_undo (GtkWidget *w); diff --git a/src/widgets/toolbox.h b/src/widgets/toolbox.h index fb749bfb5..db9130034 100644 --- a/src/widgets/toolbox.h +++ b/src/widgets/toolbox.h @@ -13,15 +13,15 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include #include "icon-size.h" -#include "../ege-adjustment-action.h" -#include "../preferences.h" +#include "preferences.h" #define TOOLBAR_SLIDER_HINT "full" +typedef struct _EgeAdjustmentAction EgeAdjustmentAction; + class SPDesktop; namespace Inkscape { -- cgit v1.2.3 From bb1fa6bf07ac6a00eaced3f60400a86cbcb6be0d Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 30 Aug 2014 11:31:41 -0400 Subject: Fix SP_ACTIVE_DOCUMENT usage (document can be determined from context) (bzr r13341.1.185) --- src/live_effects/lpe-perspective_path.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index a2372131c..9e21f5d25 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -18,6 +18,7 @@ #include "document.h" #include "document-private.h" #include "live_effects/lpe-perspective_path.h" +#include "live_effects/lpeobject.h" #include "sp-item-group.h" #include "knot-holder-entity.h" #include "knotholder.h" @@ -62,7 +63,7 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : concatenate_before_pwd2 = true; // don't split the path into its subpaths _provides_knotholder_entities = true; unapply = false; - Persp3D *persp = persp3d_document_first_persp(inkscape_active_document()); + Persp3D *persp = persp3d_document_first_persp(lpeobject->document); if(persp == 0 ){ char *msg = _("You need a BOX 3D object"); Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, @@ -72,7 +73,7 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : return; } Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; - pmat = pmat * inkscape_active_desktop()->doc2dt(); + pmat = pmat * SP_ACTIVE_DESKTOP->doc2dt(); pmat.copy_tmat(tmat); } @@ -95,7 +96,7 @@ void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { perspectiveID = perspective->get_text(); Persp3D *first = 0; Persp3D *persp = 0; - for ( SPObject *child = inkscape_active_document()->getDefs()->firstChild(); child && !persp; child = child->getNext() ) { + for ( SPObject *child = this->lpeobj->document->getDefs()->firstChild(); child && !persp; child = child->getNext() ) { if (SP_IS_PERSP3D(child) && first == 0) { first = SP_PERSP3D(child); } @@ -125,7 +126,7 @@ void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { dialog.run(); } Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; - pmat = pmat * inkscape_active_desktop()->doc2dt(); + pmat = pmat * SP_ACTIVE_DESKTOP->doc2dt(); pmat.copy_tmat(tmat); }; @@ -144,7 +145,7 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > cons Piecewise preimage[4]; //Geom::Point orig = Geom::Point(bounds_X.min(), bounds_Y.middle()); - //orig = Geom::Point(orig[X], sp_document_height(inkscape_active_document()) - orig[Y]); + //orig = Geom::Point(orig[X], sp_document_height(this->lpeobj->document) - orig[Y]); //double offset = uses_plane_xy ? boundingbox_X.extent() : 0.0; -- cgit v1.2.3 From 60c9a93dd37ecc1a4875dde3f827e9f6c3e0c642 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 30 Aug 2014 11:42:57 -0400 Subject: Fix gtk3 build (bzr r13341.1.186) --- src/widgets/gradient-vector.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 68f40f80c..53ce8ceac 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -23,6 +23,7 @@ # include "config.h" #endif +#include #include "gradient-vector.h" #include "ui/widget/color-preview.h" #include "verbs.h" @@ -30,17 +31,17 @@ #include "macros.h" #include #include -#include "../widgets/gradient-image.h" -#include "../inkscape.h" -#include "../document-private.h" -#include "../gradient-chemistry.h" -#include "../helper/window.h" +#include "widgets/gradient-image.h" +#include "inkscape.h" +#include "document-private.h" +#include "gradient-chemistry.h" +#include "helper/window.h" #include "io/resource.h" #include "xml/repr.h" -#include "../dialogs/dialog-events.h" -#include "../preferences.h" +#include "dialogs/dialog-events.h" +#include "preferences.h" #include "svg/css-ostringstream.h" #include "sp-stop.h" #include "selection-chemistry.h" @@ -50,8 +51,7 @@ #include "desktop.h" #include "layer-manager.h" -#include -#include +#include #include "document-undo.h" using Inkscape::DocumentUndo; @@ -468,10 +468,10 @@ void SPGradientVectorSelector::setSwatched() ### Vector Editing Widget ##################################################################*/ -#include "../widgets/sp-color-notebook.h" -#include "../widgets/widget-sizes.h" -#include "../xml/node-event-vector.h" -#include "../svg/svg-color.h" +#include "widgets/sp-color-notebook.h" +#include "widgets/widget-sizes.h" +#include "xml/node-event-vector.h" +#include "svg/svg-color.h" #define PAD 4 -- cgit v1.2.3 From 7290c6aa6cbaf9bbf8418eb463a0f7570f645e9a Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 30 Aug 2014 11:44:33 -0400 Subject: Remove old stub from inkview (bzr r13341.1.187) --- src/inkview.cpp | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'src') diff --git a/src/inkview.cpp b/src/inkview.cpp index 4188c832f..2969bb140 100644 --- a/src/inkview.cpp +++ b/src/inkview.cpp @@ -570,16 +570,6 @@ static void usage() exit(1); } -#ifdef XXX -/* TODO !!! make this temporary stub unnecessary */ -InkscapeApplication *inkscape_get_instance() { return NULL; } -void inkscape_ref (void) {} -void inkscape_unref (void) {} -void inkscape_add_document (SPDocument *document) {} -void inkscape_remove_document (SPDocument *document) {} -#endif - - /* Local Variables: mode:c++ -- cgit v1.2.3 From 77edfe45996574c82f66c2156ce6e8037520c8ff Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sat, 30 Aug 2014 13:23:17 -0400 Subject: Minor pass of header cleanup (bzr r13341.1.189) --- src/attribute-rel-util.h | 2 +- src/axis-manip.cpp | 9 ++++ src/axis-manip.h | 30 +++++------ src/cms-color-types.h | 5 +- src/cms-system.h | 8 ++- src/color-profile.h | 21 ++++---- src/color-rgba.h | 5 +- src/color.cpp | 8 +-- src/color.h | 6 +-- src/conn-avoid-ref.h | 2 +- src/display/cairo-utils.h | 6 +-- src/display/canvas-bpath.cpp | 3 -- src/display/canvas-text.cpp | 4 -- src/display/drawing.h | 7 ++- src/extension/internal/cairo-render-context.h | 3 ++ src/satisfied-guide-cns.h | 2 +- src/sp-gradient.cpp | 21 ++++---- src/sp-gradient.h | 27 +++++----- src/sp-guide.cpp | 2 +- src/sp-guide.h | 7 ++- src/sp-mesh-array.cpp | 2 + src/sp-mesh-gradient.cpp | 2 + src/sp-object.h | 73 ++++++++++++++------------- 23 files changed, 126 insertions(+), 129 deletions(-) (limited to 'src') diff --git a/src/attribute-rel-util.h b/src/attribute-rel-util.h index 3a6661965..604987779 100644 --- a/src/attribute-rel-util.h +++ b/src/attribute-rel-util.h @@ -8,7 +8,7 @@ * Author: tavmjong */ -#include "glibmm/ustring.h" +#include #include "xml/sp-css-attr.h" using Inkscape::XML::Node; diff --git a/src/axis-manip.cpp b/src/axis-manip.cpp index 1240d99e6..8955202c8 100644 --- a/src/axis-manip.cpp +++ b/src/axis-manip.cpp @@ -9,6 +9,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include "axis-manip.h" namespace Proj { @@ -31,6 +32,14 @@ get_remaining_axes (Axis axis) { return std::make_pair (extract_first_axis_direction (plane), extract_second_axis_direction (plane)); } +char * string_from_axes (Box3D::Axis axis) { + GString *pstring = g_string_new(""); + if (axis & Box3D::X) g_string_append_printf (pstring, "X"); + if (axis & Box3D::Y) g_string_append_printf (pstring, "Y"); + if (axis & Box3D::Z) g_string_append_printf (pstring, "Z"); + return pstring->str; +} + } // namespace Box3D /* diff --git a/src/axis-manip.h b/src/axis-manip.h index 7842b4135..619b9089c 100644 --- a/src/axis-manip.h +++ b/src/axis-manip.h @@ -12,8 +12,9 @@ #ifndef SEEN_AXIS_MANIP_H #define SEEN_AXIS_MANIP_H +#include +#include #include -#include namespace Proj { @@ -34,7 +35,7 @@ enum Axis { extern Axis axes[4]; -inline gchar const * +inline char const* string_from_axis(Proj::Axis axis) { switch (axis) { case X: return "X"; break; @@ -88,7 +89,7 @@ inline int axis_to_int(Box3D::Axis axis) { return -1; break; default: - g_assert_not_reached(); + assert(false); } } @@ -103,7 +104,7 @@ inline Proj::Axis toProj(Box3D::Axis axis) { case Box3D::NONE: return Proj::NONE; default: - g_assert_not_reached(); + assert(false); } } @@ -126,7 +127,7 @@ inline Box3D::Axis toAffine(Proj::Axis axis) { case Proj::NONE: return Box3D::NONE; default: - g_assert_not_reached(); + assert(false); } } @@ -144,7 +145,7 @@ namespace Box3D { // (which is normally used to index an array). Return -1 if the bit sequence // does not specify a face. A face can either be given by its plane (e.g, XY) // or by the axis that is orthogonal to it (e.g., Z). -inline gint face_to_int (guint face_id) { +inline int face_to_int (unsigned int face_id) { switch (face_id) { case 1: return 0; case 2: return 1; @@ -164,7 +165,7 @@ inline gint face_to_int (guint face_id) { } } -inline gint int_to_face (guint id) { +inline int int_to_face (unsigned id) { switch (id) { case 0: return Box3D::YZ ^ Box3D::FRONT; case 1: return Box3D::XZ ^ Box3D::FRONT; @@ -176,7 +177,7 @@ inline gint int_to_face (guint id) { return Box3D::NONE; // should not be reached } -inline bool is_face_id (guint face_id) { +inline bool is_face_id (unsigned int face_id) { return !((face_id & 0x7) == 0x7); } @@ -186,8 +187,8 @@ inline gint opposite_face (guint face_id) { } **/ -inline guint number_of_axis_directions (Box3D::Axis axis) { - guint num = 0; +inline unsigned int number_of_axis_directions (Box3D::Axis axis) { + unsigned int num = 0; if (axis & Box3D::X) num++; if (axis & Box3D::Y) num++; if (axis & Box3D::Z) num++; @@ -238,14 +239,7 @@ inline Box3D::Axis get_perpendicular_axis_direction (Box3D::Axis dirs) { return Box3D::NONE; } -inline gchar * string_from_axes (Box3D::Axis axis) { - GString *pstring = g_string_new(""); - if (axis & Box3D::X) g_string_append_printf (pstring, "X"); - if (axis & Box3D::Y) g_string_append_printf (pstring, "Y"); - if (axis & Box3D::Z) g_string_append_printf (pstring, "Z"); - return pstring->str; -} - +char * string_from_axes (Box3D::Axis axis); std::pair get_remaining_axes (Axis axis); } // namespace Box3D diff --git a/src/cms-color-types.h b/src/cms-color-types.h index 47157c243..b94c96029 100644 --- a/src/cms-color-types.h +++ b/src/cms-color-types.h @@ -10,15 +10,14 @@ # include "config.h" #endif // HAVE_CONFIG_H -#include - #if HAVE_LIBLCMS1 # include #endif #if HAVE_STDINT_H -# include +# include // uint8_t, etc #endif +typedef unsigned int guint32; typedef void * cmsHPROFILE; typedef void * cmsHTRANSFORM; diff --git a/src/cms-system.h b/src/cms-system.h index c528deb94..73d1a89c4 100644 --- a/src/cms-system.h +++ b/src/cms-system.h @@ -5,8 +5,6 @@ * Macros and fn declarations related to linear gradients. */ -#include -#include #include #include #include "cms-color-types.h" @@ -19,13 +17,13 @@ class ColorProfile; class CMSSystem { public: - static cmsHPROFILE getHandle( SPDocument* document, guint* intent, gchar const* name ); + static cmsHPROFILE getHandle( SPDocument* document, unsigned int* intent, char const* name ); static cmsHTRANSFORM getDisplayTransform(); static Glib::ustring getDisplayId( int screen, int monitor ); - static Glib::ustring setDisplayPer( gpointer buf, guint bufLen, int screen, int monitor ); + static Glib::ustring setDisplayPer( void* buf, unsigned int bufLen, int screen, int monitor ); static cmsHTRANSFORM getDisplayPer( Glib::ustring const& id ); @@ -39,7 +37,7 @@ public: static bool isPrintColorSpace(ColorProfile const *profile); - static gint getChannelCount(ColorProfile const *profile); + static int getChannelCount(ColorProfile const *profile); }; diff --git a/src/color-profile.h b/src/color-profile.h index 2da757b91..cb6b25945 100644 --- a/src/color-profile.h +++ b/src/color-profile.h @@ -2,7 +2,6 @@ #define SEEN_COLOR_PROFILE_H #include -#include #include #include #include "cms-color-types.h" @@ -31,7 +30,7 @@ public: ColorProfile(); virtual ~ColorProfile(); - friend cmsHPROFILE colorprofile_get_handle( SPDocument*, guint*, gchar const* ); + friend cmsHPROFILE colorprofile_get_handle( SPDocument*, unsigned int*, char const* ); friend class CMSSystem; static std::vector getBaseProfileDirs(); @@ -49,21 +48,21 @@ public: #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - gchar* href; - gchar* local; - gchar* name; - gchar* intentStr; - guint rendering_intent; + char* href; + char* local; + char* name; + char* intentStr; + unsigned int rendering_intent; // FIXME: type the enum and hold that instead protected: ColorProfileImpl *impl; - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void release(); + virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); + virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; } // namespace Inkscape diff --git a/src/color-rgba.h b/src/color-rgba.h index ef7d9aee1..55cf68877 100644 --- a/src/color-rgba.h +++ b/src/color-rgba.h @@ -9,8 +9,9 @@ #ifndef SEEN_COLOR_RGBA_H #define SEEN_COLOR_RGBA_H -#include // g_assert() +#include #include "decimal-round.h" +typedef unsigned int guint32; /** * A class to contain a floating point RGBA color as one unit. @@ -96,7 +97,7 @@ public: * @return The requested value. */ float operator[](unsigned int const i) const { - g_assert( unsigned(i) < 4 ); + assert( unsigned(i) < 4 ); return _c[i]; } diff --git a/src/color.cpp b/src/color.cpp index dccd603b0..da4406748 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -160,7 +160,7 @@ void SPColor::set( guint32 value ) * Convert SPColor with integer alpha value to 32bit RGBA value. * \pre alpha < 256 */ -guint32 SPColor::toRGBA32( gint alpha ) const +guint32 SPColor::toRGBA32( int alpha ) const { g_return_val_if_fail (alpha <= 0xff, 0x0); @@ -175,12 +175,12 @@ guint32 SPColor::toRGBA32( gint alpha ) const * Convert SPColor with float alpha value to 32bit RGBA value. * \pre color != NULL && 0 <= alpha <= 1 */ -guint32 SPColor::toRGBA32( gdouble alpha ) const +guint32 SPColor::toRGBA32( double alpha ) const { g_return_val_if_fail(alpha >= 0.0, 0x0); g_return_val_if_fail(alpha <= 1.0, 0x0); - return toRGBA32( static_cast(SP_COLOR_F_TO_U(alpha)) ); + return toRGBA32( static_cast(SP_COLOR_F_TO_U(alpha)) ); } std::string SPColor::toString() const @@ -284,7 +284,7 @@ sp_color_rgb_to_hsv_floatv (float *hsv, float r, float g, float b) void sp_color_hsv_to_rgb_floatv (float *rgb, float h, float s, float v) { - gdouble f, w, q, t, d; + double f, w, q, t, d; d = h * 5.99999999; f = d - floor (d); diff --git a/src/color.h b/src/color.h index 604dff0e3..887daf66b 100644 --- a/src/color.h +++ b/src/color.h @@ -13,8 +13,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include +typedef unsigned int guint32; // uint is guaranteed to hold up to 2^32 − 1 /* Useful composition macros */ @@ -52,8 +52,8 @@ struct SPColor { void set( float r, float g, float b ); void set( guint32 value ); - guint32 toRGBA32( gint alpha ) const; - guint32 toRGBA32( gdouble alpha ) const; + guint32 toRGBA32( int alpha ) const; + guint32 toRGBA32( double alpha ) const; std::string toString() const; diff --git a/src/conn-avoid-ref.h b/src/conn-avoid-ref.h index ce364abf1..e9e12118f 100644 --- a/src/conn-avoid-ref.h +++ b/src/conn-avoid-ref.h @@ -14,13 +14,13 @@ */ #include <2geom/point.h> -#include #include #include class SPDesktop; class SPObject; class SPItem; +typedef struct _GSList GSList; namespace Avoid { class ShapeRef; } class SPAvoidRef { diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index f252c4a44..9c46ef359 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -12,15 +12,13 @@ #ifndef SEEN_INKSCAPE_DISPLAY_CAIRO_UTILS_H #define SEEN_INKSCAPE_DISPLAY_CAIRO_UTILS_H +#include <2geom/forward.h> #include -//#include // workaround -//#include #include -//#include -#include <2geom/forward.h> #include "style.h" struct SPColor; +typedef struct _GdkPixbuf GdkPixbuf; namespace Inkscape { diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index 328409e12..46b59d25a 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -11,9 +11,6 @@ * */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif #include #include #include "desktop.h" diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index 88812af0a..5ad87b4ef 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include #include diff --git a/src/display/drawing.h b/src/display/drawing.h index cc74833ba..88e35b03b 100644 --- a/src/display/drawing.h +++ b/src/display/drawing.h @@ -13,7 +13,6 @@ #define SEEN_INKSCAPE_DISPLAY_DRAWING_H #include -#include #include #include #include @@ -23,7 +22,7 @@ #include "nr-filter-colormatrix.h" typedef struct _SPCanvasArena SPCanvasArena; - +typedef unsigned int guint32; namespace Inkscape { @@ -65,7 +64,7 @@ public: OutlineColors const &colors() const { return _colors; } - void setGrayscaleMatrix(gdouble value_matrix[20]); + void setGrayscaleMatrix(double value_matrix[20]); void update(Geom::IntRect const &area = Geom::IntRect::infinite(), UpdateContext const &ctx = UpdateContext(), unsigned flags = DrawingItem::STATE_ALL, unsigned reset = 0); void render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags = 0); @@ -100,7 +99,7 @@ private: OutlineColors _colors; Filters::FilterColorMatrix::ColorMatrixMatrix _grayscale_colormatrix; - SPCanvasArena *_canvasarena; // may be NULL is this arena is not the screen + SPCanvasArena *_canvasarena; // may be NULL if this arena is not the screen // but used for export etc. friend class DrawingItem; diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 8d3e63775..8071cae36 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -31,6 +31,9 @@ class SPClipPath; class SPMask; +typedef struct _PangoFont PangoFont; +typedef struct _PangoLayout PangoLayout; + namespace Inkscape { class Pixbuf; diff --git a/src/satisfied-guide-cns.h b/src/satisfied-guide-cns.h index 73e1e7e7f..25e5919d0 100644 --- a/src/satisfied-guide-cns.h +++ b/src/satisfied-guide-cns.h @@ -3,7 +3,7 @@ #include <2geom/forward.h> #include -#include +#include "sp-item.h" class SPDesktop; class SPGuideConstraint; diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 70c54451a..b3e885560 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -54,9 +54,6 @@ #include "style.h" #include "display/grayscale.h" -#define SP_MACROS_SILENT -#include "macros.h" - /// Has to be power of 2 Seems to be unused. //#define NCOLORS NR_GRADIENT_VECTOR_LENGTH @@ -107,11 +104,11 @@ void SPGradient::setSwatch( bool swatch ) * Equivalent meaning they have the same stop count, same stop colors and same stop opacity * @param that - A gradient to compare this to */ -gboolean SPGradient::isEquivalent(SPGradient *that) +bool SPGradient::isEquivalent(SPGradient *that) { //TODO Make this work for mesh gradients - bool status = FALSE; + bool status = false; while(1){ // not really a loop, used to avoid deep nesting or multiple exit points from function if (this->getStopCount() != that->getStopCount()) { break; } @@ -132,11 +129,11 @@ gboolean SPGradient::isEquivalent(SPGradient *that) SPStop *as = this->getVector()->getFirstStop(); SPStop *bs = that->getVector()->getFirstStop(); - bool effective = TRUE; + bool effective = true; while (effective && (as && bs)) { if (!as->getEffectiveColor().isClose(bs->getEffectiveColor(), 0.001) || as->offset != bs->offset) { - effective = FALSE; + effective = false; break; } else { @@ -144,9 +141,9 @@ gboolean SPGradient::isEquivalent(SPGradient *that) bs = bs->getNextStop(); } } - if(!effective)break; + if (!effective) break; - status = TRUE; + status = true; break; } return status; @@ -157,9 +154,9 @@ gboolean SPGradient::isEquivalent(SPGradient *that) * Aligned means that they have exactly the same coordinates and transform. * @param that - A gradient to compare this to */ -gboolean SPGradient::isAligned(SPGradient *that) +bool SPGradient::isAligned(SPGradient *that) { - bool status = FALSE; + bool status = false; /* Some gradients have coordinates/other values specified, some don't. yes/yes check the coordinates/other values @@ -223,7 +220,7 @@ gboolean SPGradient::isAligned(SPGradient *that) } else { break; } - status = TRUE; + status = true; break; } return status; diff --git a/src/sp-gradient.h b/src/sp-gradient.h index 1dfff22ee..a14dcc09e 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -15,7 +15,6 @@ */ #include -#include #include #include <2geom/affine.h> #include "sp-paint-server.h" @@ -109,30 +108,30 @@ public: private: /** gradientUnits attribute */ SPGradientUnits units; - guint units_set : 1; + unsigned int units_set : 1; public: /** gradientTransform attribute */ Geom::Affine gradientTransform; - guint gradientTransform_set : 1; + unsigned int gradientTransform_set : 1; private: /** spreadMethod attribute */ SPGradientSpread spread; - guint spread_set : 1; + unsigned int spread_set : 1; /** Gradient stops */ - guint has_stops : 1; + unsigned int has_stops : 1; /** Gradient patches */ - guint has_patches : 1; + unsigned int has_patches : 1; public: /** Reference (href) */ SPGradientReference *ref; /** State in Inkscape gradient system */ - guint state; + unsigned int state; /** Linear and Radial Gradients */ @@ -146,8 +145,8 @@ public: SPStop* getFirstStop(); int getStopCount() const; - gboolean isEquivalent(SPGradient *b); - gboolean isAligned(SPGradient *b); + bool isEquivalent(SPGradient *b); + bool isAligned(SPGradient *b); /** Mesh Gradients **************/ @@ -175,7 +174,7 @@ public: */ SPGradient *getVector(bool force_private = false); - static GType getType(); + //static GType getType(); /** Forces vector to be built, if not present (i.e. changed) */ void ensureVector(); @@ -196,7 +195,7 @@ public: void setSwatch(bool swatch = true); - static void gradientRefModified(SPObject *href, guint flags, SPGradient *gradient); + static void gradientRefModified(SPObject *href, unsigned int flags, SPGradient *gradient); static void gradientRefChanged(SPObject *old_ref, SPObject *ref, SPGradient *gr); private: @@ -208,13 +207,13 @@ private: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void modified(guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void modified(unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual void child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref); virtual void remove_child(Inkscape::XML::Node *child); - virtual void set(unsigned key, gchar const *value); + virtual void set(unsigned key, char const *value); }; void diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 60f15a79d..0e83c2acf 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -341,7 +341,7 @@ void SPGuide::hideSPGuide(SPCanvas *canvas) g_assert_not_reached(); } -void SPGuide::sensitize(SPCanvas *canvas, gboolean sensitive) +void SPGuide::sensitize(SPCanvas *canvas, bool sensitive) { g_assert(canvas != NULL); g_assert(SP_IS_CANVAS(canvas)); diff --git a/src/sp-guide.h b/src/sp-guide.h index fa4f0033b..9f5d7ba03 100644 --- a/src/sp-guide.h +++ b/src/sp-guide.h @@ -19,6 +19,9 @@ #include "sp-object.h" #include "sp-guide-attachment.h" +typedef unsigned int guint32; +typedef void (*GCallback) (void); + struct SPCanvas; struct SPCanvasGroup; class SPDesktop; @@ -52,14 +55,14 @@ public: static SPGuide *createSPGuide(SPDocument *doc, Geom::Point const &pt1, Geom::Point const &pt2); void showSPGuide(SPCanvasGroup *group, GCallback handler); void hideSPGuide(SPCanvas *canvas); - void sensitize(SPCanvas *canvas, gboolean sensitive); + void sensitize(SPCanvas *canvas, bool sensitive); Geom::Point getPositionFrom(Geom::Point const &pt) const; double getDistanceFrom(Geom::Point const &pt) const; protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); }; void sp_guide_pt_pairs_to_guides(SPDocument *doc, std::list > &pts); diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 300f2ad19..8bfe23656 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -37,6 +37,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include + // For color picking #include "display/drawing.h" #include "display/drawing-context.h" diff --git a/src/sp-mesh-gradient.cpp b/src/sp-mesh-gradient.cpp index 1b04a6f8e..bf28164a9 100644 --- a/src/sp-mesh-gradient.cpp +++ b/src/sp-mesh-gradient.cpp @@ -1,3 +1,5 @@ +#include + #include "attributes.h" #include "display/cairo-utils.h" #include "xml/repr.h" diff --git a/src/sp-object.h b/src/sp-object.h index e58f161d6..21926ad90 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -46,7 +46,7 @@ class SPObject; #define SP_OBJECT_WRITE_EXT (1 << 1) #define SP_OBJECT_WRITE_ALL (1 << 2) -#include +#include #include #include #include @@ -57,6 +57,7 @@ class SPObject; class SPCSSAttr; class SPStyle; +typedef struct _GSList GSList; namespace Inkscape { namespace XML { @@ -109,8 +110,8 @@ class SPDocument; class SPIXmlSpace { public: SPIXmlSpace(): set(0), value(SP_XML_SPACE_DEFAULT) {}; - guint set : 1; - guint value : 1; + unsigned int set : 1; + unsigned int value : 1; }; /* @@ -183,7 +184,7 @@ SPObject *sp_object_hunref(SPObject *object, gpointer owner); * provides document level functionality such as the undo stack, * dictionary and so on. Source: doc/architecture.txt */ -class SPObject { // : public GObject { +class SPObject { public: enum CollectionPolicy { COLLECT_WITH_PARENT, @@ -209,7 +210,7 @@ private: SPObject(const SPObject&); SPObject& operator=(const SPObject&); - gchar *id; /* Our very own unique id */ + char *id; /* Our very own unique id */ Inkscape::XML::Node *repr; /* Our xml representation */ public: int refCount; @@ -217,7 +218,7 @@ public: /** * Returns the objects current ID string. */ - gchar const* getId() const; + char const* getId() const; /** * Returns the XML representation of tree @@ -281,7 +282,7 @@ public: typedef Inkscape::Util::ForwardPointerIterator ConstSiblingIterator; bool isSiblingOf(SPObject const *object) const { - g_return_val_if_fail(object != NULL, false); + if (object == NULL) return false; return this->parent && this->parent == object->parent; } @@ -332,26 +333,26 @@ public: * Gets the author-visible label property for the object or a default if * no label is defined. */ - gchar const *label() const; + char const *label() const; /** * Returns a default label property for this object. */ - gchar const *defaultLabel() const; + char const *defaultLabel() const; /** * Sets the author-visible label for this object. * * @param label the new label. */ - void setLabel(gchar const *label); + void setLabel(char const *label); /** * Returns the title of this object, or NULL if there is none. * The caller must free the returned string using g_free() - see comment * for getTitleOrDesc() below. */ - gchar *title() const; + char *title() const; /** * Sets the title of this object. @@ -359,14 +360,14 @@ public: * (if any) should be deleted. * The second argument is optional - @see setTitleOrDesc() below for details. */ - bool setTitle(gchar const *title, bool verbatim = false); + bool setTitle(char const *title, bool verbatim = false); /** * Returns the description of this object, or NULL if there is none. * The caller must free the returned string using g_free() - see comment * for getTitleOrDesc() below. */ - gchar *desc() const; + char *desc() const; /** * Sets the description of this object. @@ -374,7 +375,7 @@ public: * description (if any) should be deleted. * The second argument is optional - @see setTitleOrDesc() below for details. */ - bool setDesc(gchar const *desc, bool verbatim=false); + bool setDesc(char const *desc, bool verbatim=false); /** * Set the policy under which this object will be orphan-collected. @@ -501,9 +502,9 @@ public: * Indicates that another object supercedes this one. */ void setSuccessor(SPObject *successor) { - g_assert(successor != NULL); - g_assert(_successor == NULL); - g_assert(successor->_successor == NULL); + assert(successor != NULL); + assert(_successor == NULL); + assert(successor->_successor == NULL); sp_object_ref(successor, NULL); _successor = successor; } @@ -655,8 +656,8 @@ public: sigc::signal _modified_signal; SPObject *_successor; CollectionPolicy _collection_policy; - gchar *_label; - mutable gchar *_default_label; + char *_label; + mutable char *_default_label; // WARNING: // Methods below should not be used outside of the SP tree, @@ -690,7 +691,7 @@ public: unsigned getPosition(); - gchar const * getAttribute(gchar const *name,SPException *ex=NULL) const; + char const * getAttribute(char const *name,SPException *ex=NULL) const; void appendChild(Inkscape::XML::Node *child); @@ -699,18 +700,18 @@ public: /** * Call virtual set() function of object. */ - void setKeyValue(unsigned int key, gchar const *value); + void setKeyValue(unsigned int key, char const *value); - void setAttribute(gchar const *key, gchar const *value, SPException *ex=NULL); + void setAttribute(char const *key, char const *value, SPException *ex=NULL); /** * Read value of key attribute from XML node into object. */ - void readAttr(gchar const *key); + void readAttr(char const *key); - gchar const *getTagName(SPException *ex) const; + char const *getTagName(SPException *ex) const; - void removeAttribute(gchar const *key, SPException *ex=NULL); + void removeAttribute(char const *key, SPException *ex=NULL); /** * Returns an object style property. @@ -740,13 +741,13 @@ public: * element instead), we should probably make the caller * responsible for ascending the repr tree as necessary. */ - gchar const *getStyleProperty(gchar const *key, gchar const *def) const; + char const *getStyleProperty(char const *key, char const *def) const; - void setCSS(SPCSSAttr *css, gchar const *attr); + void setCSS(SPCSSAttr *css, char const *attr); - void changeCSS(SPCSSAttr *css, gchar const *attr); + void changeCSS(SPCSSAttr *css, char const *attr); - bool storeAsDouble( gchar const *key, double *val ) const; + bool storeAsDouble( char const *key, double *val ) const; private: // Private member functions used in the definitions of setTitle(), @@ -769,7 +770,7 @@ private: * The return value is true if a change was made to the title/description, * and usually false otherwise. */ - bool setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool verbatim); + bool setTitleOrDesc(char const *value, char const *svg_tagname, bool verbatim); /** * Returns the title or description of this object, or NULL if there is none. @@ -781,13 +782,13 @@ private: * Consequently, the return value is a newly allocated string (or NULL), and * must be freed (using g_free()) by the caller. */ - gchar * getTitleOrDesc(gchar const *svg_tagname) const; + char * getTitleOrDesc(char const *svg_tagname) const; /** * Find the first child of this object with a given tag name, * and return it. Returns NULL if there is no matching child. */ - SPObject * findFirstChild(gchar const *tagname) const; + SPObject * findFirstChild(char const *tagname) const; /** * Return the full textual content of an element (typically all the @@ -802,12 +803,12 @@ public: /** * Callback for attr_changed node event. */ - static void repr_attr_changed(Inkscape::XML::Node *repr, gchar const *key, gchar const *oldval, gchar const *newval, bool is_interactive, gpointer data); + static void repr_attr_changed(Inkscape::XML::Node *repr, char const *key, char const *oldval, char const *newval, bool is_interactive, gpointer data); /** * Callback for content_changed node event. */ - static void repr_content_changed(Inkscape::XML::Node *repr, gchar const *oldcontent, gchar const *newcontent, gpointer data); + static void repr_content_changed(Inkscape::XML::Node *repr, char const *oldcontent, char const *newcontent, gpointer data); /** * Callback for child_added node event. @@ -838,12 +839,12 @@ protected: virtual void order_changed(Inkscape::XML::Node* child, Inkscape::XML::Node* old_repr, Inkscape::XML::Node* new_repr); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); public: virtual void read_content(); -- cgit v1.2.3 From 1f2d8bc4ce99e970cead4ca96c1859c383a9c043 Mon Sep 17 00:00:00 2001 From: "Liam P. White" Date: Sun, 31 Aug 2014 14:17:26 -0400 Subject: Header cleanup: stop using Glib types where they aren't truly needed. Eases GThread deprecation errors. (bzr r13341.1.190) --- src/CMakeLists.txt | 1 - src/Makefile_insert | 1 - src/box3d-side.h | 8 +- src/box3d.h | 20 ++--- src/context-fns.cpp | 13 ++- src/context-fns.h | 15 ++-- src/desktop-style.h | 3 +- src/dir-util.h | 5 +- src/document-private.h | 1 + src/document-undo.cpp | 13 --- src/document.cpp | 2 +- src/document.h | 56 ++++++------ src/draw-anchor.cpp | 4 +- src/draw-anchor.h | 9 +- src/event-log.h | 8 -- src/extension/internal/gdkpixbuf-input.cpp | 13 ++- src/extension/internal/gdkpixbuf-input.h | 2 +- src/extract-uri.h | 4 +- src/factory.h | 2 +- src/file.h | 8 +- src/filter-chemistry.h | 9 +- src/filter-enums.h | 2 - src/gc-anchored.h | 1 - src/gc-core.h | 1 - src/gradient-chemistry.h | 21 ++--- src/graphlayout.h | 13 ++- src/helper-fns.h | 30 +------ src/inkscape-version.h | 2 +- src/interface.cpp | 2 +- src/interface.h | 18 ++-- src/isinf.h | 2 +- src/isnormal.h | 19 ---- src/knot-holder-entity.h | 30 +++---- src/knot.h | 62 +++++++------ src/knotholder.h | 9 +- src/layer-manager.h | 11 +-- src/layer-model.h | 6 +- src/line-geometry.h | 5 +- src/line-snapper.cpp | 5 +- src/line-snapper.h | 5 +- src/live_effects/lpe-copy_rotate.cpp | 1 + src/live_effects/lpe-knot.cpp | 1 + src/live_effects/lpeobject-reference.h | 6 +- src/live_effects/lpeobject.h | 4 +- src/main-cmdlineact.h | 6 +- src/marker.h | 10 +-- src/message-context.h | 15 ++-- src/message-stack.h | 31 +++---- src/number-opt-number.h | 30 +++---- src/object-edit.cpp | 140 ++++++++++++++--------------- src/object-hierarchy.cpp | 23 ++--- src/object-hierarchy.h | 3 +- src/path-chemistry.h | 5 +- src/path-prefix.h | 16 ++-- src/persp3d-reference.h | 7 +- src/persp3d.h | 15 ++-- src/perspective-line.h | 1 - src/preferences-skeleton.h | 3 +- src/preferences.h | 6 +- src/print.h | 6 +- src/profile-manager.h | 5 +- src/proj_pt.h | 16 ++-- src/rdf.h | 39 ++++---- src/removeoverlap.h | 2 +- src/rubberband.h | 10 +-- src/selcue.h | 8 +- src/selection-chemistry.h | 30 +++---- src/selection-describer.h | 6 +- src/selection.h | 21 ++--- src/seltrans-handles.h | 14 +-- src/seltrans.h | 67 +++++++------- src/shape-editor.h | 8 +- src/shortcuts.h | 11 +-- src/snap-candidate.h | 5 +- src/snap-preferences.h | 18 ++-- src/snap.h | 1 + src/snapped-curve.h | 6 +- src/snapped-point.h | 7 +- src/snapper.h | 13 ++- src/sp-anchor.h | 14 +-- src/sp-clippath.h | 21 +++-- src/sp-conn-end-pair.h | 18 ++-- src/sp-conn-end.h | 13 ++- src/sp-cursor.cpp | 9 +- src/sp-cursor.h | 9 +- src/sp-defs.h | 2 +- src/sp-desc.h | 6 +- src/sp-ellipse.h | 8 +- src/sp-filter-primitive.h | 12 +-- src/sp-filter.h | 17 ++-- src/sp-flowdiv.h | 26 +++--- src/sp-flowregion.h | 8 +- src/sp-flowtext.h | 10 +-- src/sp-font-face.h | 12 +-- src/sp-font.h | 8 +- src/sp-glyph-kerning.h | 10 +-- src/sp-glyph.h | 4 +- src/sp-gradient-vector.h | 5 +- src/sp-gradient.h | 21 ++--- src/sp-guide.h | 2 +- src/sp-image.h | 13 ++- src/sp-item-group.h | 17 ++-- src/sp-item-notify-moveto.cpp | 9 +- src/sp-item-transform.cpp | 2 + src/sp-item-transform.h | 9 +- src/sp-item.cpp | 2 +- src/sp-item.h | 25 +++--- src/sp-line.h | 6 +- src/sp-linear-gradient.cpp | 2 + src/sp-linear-gradient.h | 4 +- src/sp-lpe-item.h | 10 +-- src/sp-mask.h | 16 ++-- src/sp-mesh-array.h | 64 +++++++------ src/sp-mesh-gradient.h | 4 +- src/sp-mesh-patch.h | 6 +- src/sp-mesh-row.h | 5 +- src/sp-metadata.h | 9 +- src/sp-missing-glyph.h | 12 +-- src/sp-namedview.cpp | 2 +- src/sp-namedview.h | 29 +++--- src/sp-object-group.h | 2 +- src/sp-object.cpp | 16 ++-- src/sp-object.h | 14 +-- src/sp-offset.h | 18 ++-- src/sp-paint-server-reference.h | 3 +- src/sp-paint-server.h | 4 +- src/sp-path.h | 10 +-- src/sp-pattern.h | 31 +++---- src/sp-polygon.h | 13 ++- src/sp-polyline.h | 6 +- src/sp-radial-gradient.cpp | 2 + src/sp-radial-gradient.h | 8 +- src/sp-rect.h | 32 +++---- src/sp-root.h | 8 +- src/sp-script.h | 10 +-- src/sp-shape.h | 16 ++-- src/sp-solid-color.cpp | 2 + src/sp-solid-color.h | 8 +- src/sp-spiral.h | 16 ++-- src/sp-star.h | 18 ++-- src/sp-stop.h | 13 +-- src/sp-string.h | 4 +- src/sp-style-elem.h | 4 +- src/sp-switch.h | 10 ++- src/sp-symbol.h | 18 ++-- src/sp-text.h | 18 ++-- src/sp-textpath.h | 7 +- src/sp-title.h | 6 +- src/sp-tref-reference.h | 8 +- src/sp-tref.h | 6 +- src/sp-tspan.h | 7 +- src/sp-use-reference.h | 8 +- src/sp-use.h | 15 ++-- src/splivarot.h | 7 +- src/streq.h | 1 - src/style-enums.h | 6 +- src/style.h | 35 ++++---- src/svg-view-widget.h | 2 +- src/svg-view.h | 13 ++- src/text-chemistry.h | 2 + src/text-editing.h | 19 ++-- src/transf_mat_3x4.h | 4 +- src/unclump.cpp | 1 + src/unclump.h | 2 +- src/unicoderange.h | 14 +-- src/uri-references.h | 6 +- src/uri.h | 35 ++++---- src/vanishing-point.h | 12 ++- src/verbs.h | 49 +++++----- src/version.cpp | 22 ++--- src/version.h | 12 ++- 171 files changed, 1028 insertions(+), 1113 deletions(-) delete mode 100644 src/isnormal.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ab697d126..34f06ed99 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -351,7 +351,6 @@ set(inkscape_SRC inkscape.h interface.h isinf.h - isnormal.h knot-enums.h knot-holder-entity.h knot.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 8e45cb4e0..e1b95c1d6 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -74,7 +74,6 @@ ink_common_sources += \ inkscape.cpp inkscape.h inkscape-private.h \ interface.cpp interface.h \ isinf.h \ - isnormal.h \ knot.cpp knot.h \ knot-enums.h \ knotholder.cpp knotholder.h \ diff --git a/src/box3d-side.h b/src/box3d-side.h index 04bd196c2..89b3b0399 100644 --- a/src/box3d-side.h +++ b/src/box3d-side.h @@ -36,16 +36,16 @@ public: static Box3DSide * createBox3DSide(SPBox3D *box); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void set(unsigned int key, gchar const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual void update(SPCtx *ctx, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); + virtual void update(SPCtx *ctx, unsigned int flags); virtual void set_shape(); }; void box3d_side_position_set (Box3DSide *side); // FIXME: Replace this by box3d_side_set_shape?? -gchar *box3d_side_axes_string(Box3DSide *side); +char *box3d_side_axes_string(Box3DSide *side); Persp3D *box3d_side_perspective(Box3DSide *side); diff --git a/src/box3d.h b/src/box3d.h index 4107d2452..60b966187 100644 --- a/src/box3d.h +++ b/src/box3d.h @@ -32,9 +32,9 @@ public: SPBox3D(); virtual ~SPBox3D(); - gint z_orders[6]; // z_orders[i] holds the ID of the face at position #i in the group (from top to bottom) + int z_orders[6]; // z_orders[i] holds the ID of the face at position #i in the group (from top to bottom) - gchar *persp_href; + char *persp_href; Persp3DReference *persp_ref; Proj::Pt3 orig_corner0; @@ -45,7 +45,7 @@ public: Box3D::Axis swapped; // to indicate which coordinates are swapped during dragging - gint my_counter; // for debugging only + int my_counter; // for debugging only /** * Create a SPBox3D and append it to the parent. @@ -54,24 +54,24 @@ public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void set(unsigned int key, gchar const* value); - virtual void update(SPCtx *ctx, guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual void update(SPCtx *ctx, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char* display_name(); virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides() const; virtual const char* displayName() const; - virtual gchar *description() const; + virtual char *description() const; }; void box3d_position_set (SPBox3D *box); -Proj::Pt3 box3d_get_proj_corner (SPBox3D const *box, guint id); -Geom::Point box3d_get_corner_screen (SPBox3D const *box, guint id, bool item_coords = true); +Proj::Pt3 box3d_get_proj_corner (SPBox3D const *box, unsigned int id); +Geom::Point box3d_get_corner_screen (SPBox3D const *box, unsigned int id, bool item_coords = true); Proj::Pt3 box3d_get_proj_center (SPBox3D *box); Geom::Point box3d_get_center_screen (SPBox3D *box); -void box3d_set_corner (SPBox3D *box, guint id, Geom::Point const &new_pos, Box3D::Axis movement, bool constrained); +void box3d_set_corner (SPBox3D *box, unsigned int id, Geom::Point const &new_pos, Box3D::Axis movement, bool constrained); void box3d_set_center (SPBox3D *box, Geom::Point const &new_pos, Geom::Point const &old_pos, Box3D::Axis movement, bool constrained); void box3d_corners_for_PLs (const SPBox3D * box, Proj::Axis axis, Geom::Point &corner1, Geom::Point &corner2, Geom::Point &corner3, Geom::Point &corner4); bool box3d_recompute_z_orders (SPBox3D *box); diff --git a/src/context-fns.cpp b/src/context-fns.cpp index 1e30e51de..e1df53d98 100644 --- a/src/context-fns.cpp +++ b/src/context-fns.cpp @@ -1,17 +1,14 @@ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include -#include "sp-item.h" + +#include "context-fns.h" #include "desktop.h" +#include "display/snap-indicator.h" #include "message-context.h" #include "message-stack.h" -#include "context-fns.h" #include "snap.h" -#include "ui/tools/tool-base.h" +#include "sp-item.h" #include "sp-namedview.h" -#include "display/snap-indicator.h" +#include "ui/tools/tool-base.h" static const double midpt_1_goldenratio = (1 + goldenratio) / 2; static const double midpt_goldenratio_2 = (goldenratio + 2) / 2; diff --git a/src/context-fns.h b/src/context-fns.h index bd48e5fb8..82554a6c9 100644 --- a/src/context-fns.h +++ b/src/context-fns.h @@ -2,7 +2,6 @@ #define SEEN_CONTEXT_FNS_H /* - * * * Authors: * @@ -11,11 +10,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include <2geom/forward.h> -class SPDesktop; -class SPItem; +class SPDesktop; +class SPItem; +typedef union _GdkEvent GdkEvent; + +const double goldenratio = 1.61803398874989484820; // golden ratio namespace Inkscape { namespace UI { @@ -25,12 +26,6 @@ class ToolBase; } } -} - -const double goldenratio = 1.61803398874989484820; // golden ratio - -namespace Inkscape -{ class MessageContext; class MessageStack; diff --git a/src/desktop-style.h b/src/desktop-style.h index fc20e97b9..40ca27e9e 100644 --- a/src/desktop-style.h +++ b/src/desktop-style.h @@ -13,13 +13,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - class ColorRGBA; class SPCSSAttr; class SPDesktop; class SPObject; class SPStyle; +typedef struct _GSList GSList; namespace Inkscape { namespace XML { class Node; diff --git a/src/dir-util.h b/src/dir-util.h index 17261af41..4865158bd 100644 --- a/src/dir-util.h +++ b/src/dir-util.h @@ -9,8 +9,7 @@ * */ -#include -#include +#include /** * Returns a form of \a path relative to \a base if that is easy to construct (eg if \a path @@ -49,7 +48,7 @@ char *inkscape_rel2abs(char const *path, char const *base, char *result, size_t char *inkscape_abs2rel(char const *path, char const *base, char *result, size_t const size); -gchar *prepend_current_dir_if_relative(gchar const *filename); +gchar *prepend_current_dir_if_relative(char const *filename); #endif // !SEEN_DIR_UTIL_H diff --git a/src/document-private.h b/src/document-private.h index 4560aa28f..8e28b288b 100644 --- a/src/document-private.h +++ b/src/document-private.h @@ -34,6 +34,7 @@ class Event; } } +typedef struct _GHashTable GHashTable; struct SPDocumentPrivate { typedef std::map IDChangedSignalMap; diff --git a/src/document-undo.cpp b/src/document-undo.cpp index 478266b7b..0519b6874 100644 --- a/src/document-undo.cpp +++ b/src/document-undo.cpp @@ -44,19 +44,6 @@ * (Lauris Kaplinski) */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - - -#if HAVE_STRING_H -#endif - - -#if HAVE_STDLIB_H -#endif - #include #include #include "xml/repr.h" diff --git a/src/document.cpp b/src/document.cpp index f79a00178..bb1954916 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1370,7 +1370,7 @@ GSList *SPDocument::getItemsAtPoints(unsigned const key, std::vectorpriv != NULL, NULL); diff --git a/src/document.h b/src/document.h index ee903449d..4ace249ae 100644 --- a/src/document.h +++ b/src/document.h @@ -75,8 +75,8 @@ class SPDocument : public Inkscape::GC::Managed<>, public: typedef sigc::signal IDChangedSignal; typedef sigc::signal ResourcesChangedSignal; - typedef sigc::signal ModifiedSignal; - typedef sigc::signal URISetSignal; + typedef sigc::signal ModifiedSignal; + typedef sigc::signal URISetSignal; typedef sigc::signal ResizedSignal; typedef sigc::signal ReconstructionStart; typedef sigc::signal ReconstructionFinish; @@ -100,9 +100,9 @@ public: CRCascade *style_cascade; protected: - gchar *uri; ///< A filename (not a URI yet), or NULL - gchar *base; ///< To be used for resolving relative hrefs. - gchar *name; ///< basename(uri) or other human-readable label for the document. + char *uri; ///< A filename (not a URI yet), or NULL + char *base; ///< To be used for resolving relative hrefs. + char *name; ///< basename(uri) or other human-readable label for the document. public: @@ -112,10 +112,10 @@ public: Glib::ustring actionkey; /// Handler ID - guint modified_id; + unsigned modified_id; /// Connector rerouting handler ID - guint rerouting_handler_id; + unsigned rerouting_handler_id; Inkscape::ProfileManager* profileManager; @@ -137,15 +137,15 @@ public: Inkscape::XML::Document const *getReprDoc() const { return rdoc; } /** A filename (not a URI yet), or NULL */ - gchar const *getURI() const { return uri; } - void setUri(gchar const *uri); + char const *getURI() const { return uri; } + void setUri(char const *uri); /** To be used for resolving relative hrefs. */ - gchar const *getBase() const { return base; }; - void setBase( gchar const* base ); + char const *getBase() const { return base; }; + void setBase( char const* base ); /** basename(uri) or other human-readable label for the document. */ - gchar const* getName() const { return name; } + char const* getName() const { return name; } /** Return the main defs object for the document. */ SPDefs *getDefs(); @@ -173,10 +173,10 @@ public: sigc::connection connectResized(ResizedSignal::slot_type slot); sigc::connection connectCommit(CommitSignal::slot_type slot); - void bindObjectToId(gchar const *id, SPObject *object); + void bindObjectToId(char const *id, SPObject *object); SPObject *getObjectById(Glib::ustring const &id) const; - SPObject *getObjectById(gchar const *id) const; - sigc::connection connectIdChanged(const gchar *id, IDChangedSignal::slot_type slot); + SPObject *getObjectById(char const *id) const; + sigc::connection connectIdChanged(const char *id, IDChangedSignal::slot_type slot); void bindObjectToRepr(Inkscape::XML::Node *repr, SPObject *object); SPObject *getObjectByRepr(Inkscape::XML::Node *repr) const; @@ -222,12 +222,12 @@ public: sigc::connection _selection_changed_connection; sigc::connection _desktop_activated_connection; - sigc::connection connectResourcesChanged(const gchar *key, SPDocument::ResourcesChangedSignal::slot_type slot); + sigc::connection connectResourcesChanged(char const *key, SPDocument::ResourcesChangedSignal::slot_type slot); void fitToRect(Geom::Rect const &rect, bool with_margins = false); - static SPDocument *createNewDoc(const gchar *uri, unsigned int keepalive, + static SPDocument *createNewDoc(char const*uri, unsigned int keepalive, bool make_new = false, SPDocument *parent=NULL ); - static SPDocument *createNewDocFromMem(const gchar *buffer, gint length, unsigned int keepalive); + static SPDocument *createNewDocFromMem(char const*buffer, int length, unsigned int keepalive); SPDocument *createChildDoc(std::string const &uri); /** @@ -235,8 +235,8 @@ public: */ static SPItem *getItemFromListAtPointBottom(unsigned int dkey, SPGroup *group, const GSList *list, Geom::Point const &p, bool take_insensitive = false); - static SPDocument *createDoc(Inkscape::XML::Document *rdoc, gchar const *uri, - gchar const *base, gchar const *name, unsigned int keepalive, + static SPDocument *createDoc(Inkscape::XML::Document *rdoc, char const *uri, + char const *base, char const *name, unsigned int keepalive, SPDocument *parent); SPDocument *doRef(); @@ -250,25 +250,25 @@ public: void setHeight(const Inkscape::Util::Quantity &height); void setViewBox(const Geom::Rect &viewBox); void requestModified(); - gint ensureUpToDate(); - bool addResource(const gchar *key, SPObject *object); - bool removeResource(const gchar *key, SPObject *object); - const GSList *getResourceList(const gchar *key) const; + int ensureUpToDate(); + bool addResource(char const *key, SPObject *object); + bool removeResource(char const *key, SPObject *object); + const GSList *getResourceList(char const *key) const; GSList *getItemsInBox(unsigned int dkey, Geom::Rect const &box) const; GSList *getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box) const; - SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, gboolean into_groups, SPItem *upto = NULL) const; + SPItem *getItemAtPoint(unsigned int key, Geom::Point const &p, bool into_groups, SPItem *upto = NULL) const; GSList *getItemsAtPoints(unsigned const key, std::vector points) const; SPItem *getGroupAtPoint(unsigned int key, Geom::Point const &p) const; - void changeUriAndHrefs(gchar const *uri); - void emitResizedSignal(gdouble width, gdouble height); + void changeUriAndHrefs(char const *uri); + void emitResizedSignal(double width, double height); unsigned int vacuumDocument(); void importDefs(SPDocument *source); private: - void do_change_uri(gchar const *const filename, bool const rebase); + void do_change_uri(char const *const filename, bool const rebase); void setupViewport(SPItemCtx *ctx); }; diff --git a/src/draw-anchor.cpp b/src/draw-anchor.cpp index 00db936e1..6b02bb607 100644 --- a/src/draw-anchor.cpp +++ b/src/draw-anchor.cpp @@ -30,7 +30,7 @@ using Inkscape::ControlManager; /** * Creates an anchor object and initializes it. */ -SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, gboolean start, Geom::Point delta) +SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, Geom::Point delta) { if (SP_IS_LPETOOL_CONTEXT(dc)) { // suppress all kinds of anchors in LPEToolContext @@ -73,7 +73,7 @@ SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor) * Test if point is near anchor, if so fill anchor on canvas and return * pointer to it or NULL. */ -SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, gboolean activate) +SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate) { SPCtrl *ctrl = SP_CTRL(anchor->ctrl); diff --git a/src/draw-anchor.h b/src/draw-anchor.h index e7b252186..1f7b55920 100644 --- a/src/draw-anchor.h +++ b/src/draw-anchor.h @@ -5,7 +5,6 @@ * Drawing anchors. */ -#include #include <2geom/point.h> namespace Inkscape { @@ -26,17 +25,17 @@ struct SPCanvasItem; struct SPDrawAnchor { Inkscape::UI::Tools::FreehandBase *dc; SPCurve *curve; - guint start : 1; - guint active : 1; + unsigned int start : 1; + unsigned int active : 1; Geom::Point dp; SPCanvasItem *ctrl; }; -SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, gboolean start, +SPDrawAnchor *sp_draw_anchor_new(Inkscape::UI::Tools::FreehandBase *dc, SPCurve *curve, bool start, Geom::Point delta); SPDrawAnchor *sp_draw_anchor_destroy(SPDrawAnchor *anchor); -SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, gboolean activate); +SPDrawAnchor *sp_draw_anchor_test(SPDrawAnchor *anchor, Geom::Point w, bool activate); #endif /* !SEEN_DRAW_ANCHOR_H */ diff --git a/src/event-log.h b/src/event-log.h index 7e3ba6817..6d4112a5a 100644 --- a/src/event-log.h +++ b/src/event-log.h @@ -11,14 +11,6 @@ #ifndef INKSCAPE_EVENT_LOG_H #define INKSCAPE_EVENT_LOG_H -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif - #include #include #include diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp index da179bee0..28e44c461 100644 --- a/src/extension/internal/gdkpixbuf-input.cpp +++ b/src/extension/internal/gdkpixbuf-input.cpp @@ -1,21 +1,20 @@ -#ifdef HAVE_CONFIG_H -# include -#endif +#include + #include #include #include +#include "dir-util.h" +#include "display/cairo-utils.h" #include "document-private.h" -#include +#include "document-undo.h" #include "extension/input.h" #include "extension/system.h" +#include "image-resolution.h" #include "gdkpixbuf-input.h" #include "preferences.h" #include "selection-chemistry.h" #include "sp-image.h" -#include "document-undo.h" #include "util/units.h" -#include "image-resolution.h" -#include "display/cairo-utils.h" #include namespace Inkscape { diff --git a/src/extension/internal/gdkpixbuf-input.h b/src/extension/internal/gdkpixbuf-input.h index 597e7246b..2e03a96db 100644 --- a/src/extension/internal/gdkpixbuf-input.h +++ b/src/extension/internal/gdkpixbuf-input.h @@ -10,7 +10,7 @@ namespace Internal { class GdkpixbufInput : Inkscape::Extension::Implementation::Implementation { public: SPDocument *open(Inkscape::Extension::Input *mod, - gchar const *uri); + char const *uri); static void init(); }; diff --git a/src/extract-uri.h b/src/extract-uri.h index a6707f1a1..e9ee0b1d8 100644 --- a/src/extract-uri.h +++ b/src/extract-uri.h @@ -1,9 +1,7 @@ #ifndef SEEN_EXTRACT_URI_H #define SEEN_EXTRACT_URI_H -#include - -gchar *extract_uri(gchar const *s, gchar const** endptr = 0); +char *extract_uri(char const *s, char const** endptr = 0); #endif /* !SEEN_EXTRACT_URI_H */ diff --git a/src/factory.h b/src/factory.h index c76501cfd..c1288b460 100644 --- a/src/factory.h +++ b/src/factory.h @@ -91,7 +91,7 @@ struct NodeTraits { break; case Inkscape::XML::ELEMENT_NODE: { - gchar const *const sptype = node.attribute("sodipodi:type"); + char const *const sptype = node.attribute("sodipodi:type"); if (sptype) { name = sptype; diff --git a/src/file.h b/src/file.h index 7f80f3645..4ffbc8ec0 100644 --- a/src/file.h +++ b/src/file.h @@ -75,7 +75,7 @@ bool sp_file_open( * Displays a file open dialog. Calls sp_file_open on * an OK. */ -void sp_file_open_dialog (Gtk::Window &parentWindow, gpointer object, gpointer data); +void sp_file_open_dialog (Gtk::Window &parentWindow, void* object, void* data); /** * Reverts file to disk-copy on "YES" @@ -96,19 +96,19 @@ bool file_save_remote(SPDocument *doc, const Glib::ustring &uri, /** * */ -bool sp_file_save (Gtk::Window &parentWindow, gpointer object, gpointer data); +bool sp_file_save (Gtk::Window &parentWindow, void* object, void* data); /** * Saves the given document. Displays a file select dialog * to choose the new name. */ -bool sp_file_save_as (Gtk::Window &parentWindow, gpointer object, gpointer data); +bool sp_file_save_as (Gtk::Window &parentWindow, void* object, void* data); /** * Saves a copy of the given document. Displays a file select dialog * to choose a name for the copy. */ -bool sp_file_save_a_copy (Gtk::Window &parentWindow, gpointer object, gpointer data); +bool sp_file_save_a_copy (Gtk::Window &parentWindow, void* object, void* data); /** diff --git a/src/filter-chemistry.h b/src/filter-chemistry.h index 2ac3ebe8f..104016845 100644 --- a/src/filter-chemistry.h +++ b/src/filter-chemistry.h @@ -14,8 +14,6 @@ #ifndef SEEN_SP_FILTER_CHEMISTRY_H #define SEEN_SP_FILTER_CHEMISTRY_H -#include - #include "display/nr-filter-types.h" class SPDocument; @@ -24,12 +22,11 @@ class SPFilterPrimitive; class SPItem; class SPObject; - SPFilterPrimitive *filter_add_primitive(SPFilter *filter, Inkscape::Filters::FilterPrimitiveType); SPFilter *new_filter (SPDocument *document); -SPFilter *new_filter_gaussian_blur (SPDocument *document, gdouble stdDeviation, double expansion, double expansionX, double expansionY, double width, double height); -SPFilter *new_filter_simple_from_item (SPDocument *document, SPItem *item, const char *mode, gdouble stdDeviation); -SPFilter *modify_filter_gaussian_blur_from_item (SPDocument *document, SPItem *item, gdouble stdDeviation); +SPFilter *new_filter_gaussian_blur (SPDocument *document, double stdDeviation, double expansion, double expansionX, double expansionY, double width, double height); +SPFilter *new_filter_simple_from_item (SPDocument *document, SPItem *item, const char *mode, double stdDeviation); +SPFilter *modify_filter_gaussian_blur_from_item (SPDocument *document, SPItem *item, double stdDeviation); void remove_filter (SPObject *item, bool recursive); void remove_filter_gaussian_blur (SPObject *item); bool filter_is_single_gaussian_blur(SPFilter *filter); diff --git a/src/filter-enums.h b/src/filter-enums.h index e6d656f8a..3ced5ab94 100644 --- a/src/filter-enums.h +++ b/src/filter-enums.h @@ -12,8 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - #include "display/nr-filter-blend.h" #include "display/nr-filter-colormatrix.h" #include "display/nr-filter-component-transfer.h" diff --git a/src/gc-anchored.h b/src/gc-anchored.h index a20904dce..99b78c784 100644 --- a/src/gc-anchored.h +++ b/src/gc-anchored.h @@ -9,7 +9,6 @@ #ifndef SEEN_INKSCAPE_GC_ANCHORED_H #define SEEN_INKSCAPE_GC_ANCHORED_H -#include #include "gc-managed.h" namespace Inkscape { diff --git a/src/gc-core.h b/src/gc-core.h index 3957bda1a..d9d0bf4ff 100644 --- a/src/gc-core.h +++ b/src/gc-core.h @@ -24,7 +24,6 @@ #else # include #endif -#include namespace Inkscape { namespace GC { diff --git a/src/gradient-chemistry.h b/src/gradient-chemistry.h index 728874f88..792ccc72e 100644 --- a/src/gradient-chemistry.h +++ b/src/gradient-chemistry.h @@ -22,6 +22,7 @@ class SPCSSAttr; class SPItem; +typedef unsigned int guint32; /** * Either normalizes given gradient to vector, or returns fresh normalized @@ -53,7 +54,7 @@ SPGradient *sp_gradient_vector_for_object( SPDocument *doc, SPDesktop *desktop, void sp_object_ensure_fill_gradient_normalized (SPObject *object); void sp_object_ensure_stroke_gradient_normalized (SPObject *object); -SPGradient *sp_gradient_convert_to_userspace (SPGradient *gr, SPItem *item, const gchar *property); +SPGradient *sp_gradient_convert_to_userspace (SPGradient *gr, SPItem *item, const char *property); SPGradient *sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item); SPGradient *sp_gradient_fork_vector_if_necessary (SPGradient *gr); @@ -61,11 +62,11 @@ SPGradient *sp_gradient_get_forked_vector_if_necessary(SPGradient *gradient, boo SPStop* sp_last_stop(SPGradient *gradient); -SPStop* sp_get_stop_i(SPGradient *gradient, guint i); -guint sp_number_of_stops(SPGradient const *gradient); -guint sp_number_of_stops_before_stop(SPGradient const *gradient, SPStop *target); +SPStop* sp_get_stop_i(SPGradient *gradient, unsigned int i); +unsigned int sp_number_of_stops(SPGradient const *gradient); +unsigned int sp_number_of_stops_before_stop(SPGradient const *gradient, SPStop *target); -guint32 average_color(guint32 c1, guint32 c2, gdouble p = 0.5); +guint32 average_color(guint32 c1, guint32 c2, double p = 0.5); SPStop *sp_vector_add_stop(SPGradient *vector, SPStop* prev_stop, SPStop* next_stop, gfloat offset); @@ -86,20 +87,20 @@ void sp_gradient_unset_swatch(SPDesktop *desktop, std::string id); SPGradient *getGradient(SPItem *item, Inkscape::PaintTarget fill_or_stroke); -void sp_item_gradient_set_coords(SPItem *item, GrPointType point_type, guint point_i, Geom::Point p_desk, Inkscape::PaintTarget fill_or_stroke, bool write_repr, bool scale); +void sp_item_gradient_set_coords(SPItem *item, GrPointType point_type, unsigned int point_i, Geom::Point p_desk, Inkscape::PaintTarget fill_or_stroke, bool write_repr, bool scale); /** * Returns the position of point point_type of the gradient applied to item (either fill_or_stroke), * in desktop coordinates. */ -Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke); +Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, unsigned int point_i, Inkscape::PaintTarget fill_or_stroke); SPGradient *sp_item_gradient_get_vector(SPItem *item, Inkscape::PaintTarget fill_or_stroke); SPGradientSpread sp_item_gradient_get_spread(SPItem *item, Inkscape::PaintTarget fill_or_stroke); -void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke, SPCSSAttr *stop); -guint32 sp_item_gradient_stop_query_style(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke); -void sp_item_gradient_edit_stop(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke); +void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, unsigned int point_i, Inkscape::PaintTarget fill_or_stroke, SPCSSAttr *stop); +guint32 sp_item_gradient_stop_query_style(SPItem *item, GrPointType point_type, unsigned int point_i, Inkscape::PaintTarget fill_or_stroke); +void sp_item_gradient_edit_stop(SPItem *item, GrPointType point_type, unsigned int point_i, Inkscape::PaintTarget fill_or_stroke); void sp_item_gradient_reverse_vector(SPItem *item, Inkscape::PaintTarget fill_or_stroke); void sp_item_gradient_invert_vector_color(SPItem *item, Inkscape::PaintTarget fill_or_stroke); diff --git a/src/graphlayout.h b/src/graphlayout.h index 6083ad77f..0ffb645b6 100644 --- a/src/graphlayout.h +++ b/src/graphlayout.h @@ -14,10 +14,15 @@ #ifndef SEEN_GRAPHLAYOUT_H #define SEEN_GRAPHLAYOUT_H -struct _GSList; -void graphlayout(_GSList const *const items); +#include + +typedef struct _GSList GSList; class SPItem; + +void graphlayout(GSList const *const items); + bool isConnector(SPItem const *const item); -#include -void filterConnectors(_GSList const *const items, std::list &filtered); + +void filterConnectors(GSList const *const items, std::list &filtered); + #endif // SEEN_GRAPHLAYOUT_H diff --git a/src/helper-fns.h b/src/helper-fns.h index 699fbbe11..2f1829c37 100644 --- a/src/helper-fns.h +++ b/src/helper-fns.h @@ -10,7 +10,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include +#include #include #include @@ -59,34 +59,6 @@ inline bool helperfns_read_bool(gchar const *value, bool default_value){ return default_value; } -/* convert ascii representation to double - * the function can only be used to convert numbers as given by gui elements that use localized representation - * numbers are delimeted by space - * @param value ascii representation of the number - * @param size number of elements in string - * @return the vector of the converted numbers - */ -/* -inline std::vector helperfns_read_vector(const gchar* value, int size){ - std::vector v(size, (gdouble) 0); - std::istringstream is(value); - for(int i = 0; i < size; i++){ - std::string str; - is >> str; - char *end; - - double ret = g_ascii_strtod(str.c_str(), &end); - if (*end) { - g_warning("helper-fns::helperfns_read_vector() Unable to convert \"%s\" to number", str.c_str()); - // We could leave this out, too. If strtod can't convert - // anything, it will return zero. - ret = 0; - } - v[i] = ret; - }; - return v; -} -*/ /* convert ascii representation to double * the function can only be used to convert numbers as given by gui elements that use localized representation * numbers are delimeted by space diff --git a/src/inkscape-version.h b/src/inkscape-version.h index 791351184..ff219047e 100644 --- a/src/inkscape-version.h +++ b/src/inkscape-version.h @@ -16,7 +16,7 @@ namespace Inkscape { -extern gchar const *version_string; ///< Full version string +extern char const *version_string; ///< Full version string } // namespace Inkscape diff --git a/src/interface.cpp b/src/interface.cpp index 1cbeb44a3..3b5958a33 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -149,7 +149,7 @@ static void injectRenamedIcons(); static const int MIN_ONSCREEN_DISTANCE = 50; void -sp_create_window(SPViewWidget *vw, gboolean editable) +sp_create_window(SPViewWidget *vw, bool editable) { g_return_if_fail(vw != NULL); g_return_if_fail(SP_IS_VIEW_WIDGET(vw)); diff --git a/src/interface.h b/src/interface.h index 215a3bfc9..2418223ae 100644 --- a/src/interface.h +++ b/src/interface.h @@ -17,13 +17,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include -#endif - -#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H -#include -#endif +//#ifdef HAVE_CONFIG_H +//# include +//#endif #include @@ -50,7 +46,7 @@ class View; /** * Create a new document window. */ -void sp_create_window (SPViewWidget *vw, gboolean editable); +void sp_create_window (SPViewWidget *vw, bool editable); /** * \param widget unused @@ -87,15 +83,15 @@ unsigned int sp_ui_close_all (void); GtkWidget *sp_ui_main_menubar (Inkscape::UI::View::View *view); void sp_menu_append_recent_documents (GtkWidget *menu); -void sp_ui_dialog_title_string (Inkscape::Verb * verb, gchar* c); +void sp_ui_dialog_title_string (Inkscape::Verb * verb, char* c); Glib::ustring getLayoutPrefPath( Inkscape::UI::View::View *view ); /** * */ -void sp_ui_error_dialog (const gchar * message); -bool sp_ui_overwrite_file (const gchar * filename); +void sp_ui_error_dialog (char const* message); +bool sp_ui_overwrite_file (char const* filename); /** diff --git a/src/isinf.h b/src/isinf.h index b4c56f79d..8d590b972 100644 --- a/src/isinf.h +++ b/src/isinf.h @@ -2,7 +2,7 @@ #define __ISINF_H__ /* - * Fix for missing std::isnormal with SOLARIS8/GCC3.2 + * Fix for missing std::isinf with SOLARIS8/GCC3.2 */ #if defined (SOLARIS) diff --git a/src/isnormal.h b/src/isnormal.h deleted file mode 100644 index d53105926..000000000 --- a/src/isnormal.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __ISNORMAL_H__ -#define __ISNORMAL_H__ - -/* - * Fix for missing std::isnormal with SOLARIS8/GCC3.2 - */ - -#if defined (SOLARIS) - - #include - #define isnormal(x) (fpclass(x) >= FP_NZERO) - -#else - - using std::isnormal; - -#endif - -#endif /* __ISNORMAL_H__ */ diff --git a/src/knot-holder-entity.h b/src/knot-holder-entity.h index dde60f515..43ab25e5c 100644 --- a/src/knot-holder-entity.h +++ b/src/knot-holder-entity.h @@ -14,11 +14,11 @@ * Released under GNU GPL */ -#include -#include "knot.h" #include <2geom/forward.h> -#include "snapper.h" + #include "display/sp-canvas-item.h" +#include "knot.h" +#include "snapper.h" class SPItem; class SPKnot; @@ -31,7 +31,7 @@ namespace LivePathEffect { } // namespace LivePathEffect } // namespace Inkscape -typedef void (* SPKnotHolderSetFunc) (SPItem *item, Geom::Point const &p, Geom::Point const &origin, guint state); +typedef void (* SPKnotHolderSetFunc) (SPItem *item, Geom::Point const &p, Geom::Point const &origin, unsigned int state); typedef Geom::Point (* SPKnotHolderGetFunc) (SPItem *item); /** @@ -50,22 +50,22 @@ public: virtual void create(SPDesktop *desktop, SPItem *item, KnotHolder *parent, Inkscape::ControlType type = Inkscape::CTRL_TYPE_UNKNOWN, - const gchar *tip = "", + char const*tip = "", SPKnotShapeType shape = SP_KNOT_SHAPE_DIAMOND, SPKnotModeType mode = SP_KNOT_MODE_XOR, guint32 color = 0xffffff00); /* the get/set/click handlers are virtual functions; each handler class for a knot should be derived from KnotHolderEntity and override these functions */ - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) = 0; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) = 0; virtual Geom::Point knot_get() const = 0; - virtual void knot_click(guint /*state*/) {} + virtual void knot_click(unsigned int /*state*/) {} void update_knot(); //private: - Geom::Point snap_knot_position(Geom::Point const &p, guint state); - Geom::Point snap_knot_position_constrained(Geom::Point const &p, Inkscape::Snapper::SnapConstraint const &constraint, guint state); + Geom::Point snap_knot_position(Geom::Point const &p, unsigned int state); + Geom::Point snap_knot_position_constrained(Geom::Point const &p, Inkscape::Snapper::SnapConstraint const &constraint, unsigned int state); SPKnot *knot; SPItem *item; @@ -77,11 +77,11 @@ public: static int counter; /** Connection to \a knot's "moved" signal. */ - guint handler_id; + unsigned int handler_id; /** Connection to \a knot's "clicked" signal. */ - guint _click_handler_id; + unsigned int _click_handler_id; /** Connection to \a knot's "ungrabbed" signal. */ - guint _ungrab_handler_id; + unsigned int _ungrab_handler_id; private: sigc::connection _moved_connection; @@ -103,7 +103,7 @@ class PatternKnotHolderEntityXY : public KnotHolderEntity { public: PatternKnotHolderEntityXY(bool fill) : KnotHolderEntity(), _fill(fill) {} virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); private: // true if the entity tracks fill, false for stroke bool _fill; @@ -113,7 +113,7 @@ class PatternKnotHolderEntityAngle : public KnotHolderEntity { public: PatternKnotHolderEntityAngle(bool fill) : KnotHolderEntity(), _fill(fill) {} virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); private: bool _fill; }; @@ -122,7 +122,7 @@ class PatternKnotHolderEntityScale : public KnotHolderEntity { public: PatternKnotHolderEntityScale(bool fill) : KnotHolderEntity(), _fill(fill) {} virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); private: bool _fill; }; diff --git a/src/knot.h b/src/knot.h index b79614bcb..e3ad98e66 100644 --- a/src/knot.h +++ b/src/knot.h @@ -14,15 +14,19 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include <2geom/point.h> -#include "knot-enums.h" #include + +#include "knot-enums.h" #include "enums.h" class SPDesktop; -struct SPCanvasItem; class SPItem; +struct SPCanvasItem; + +typedef struct _GdkCursor GdkCursor; +typedef union _GdkEvent GdkEvent; +typedef unsigned int guint32; #define SP_KNOT(obj) (dynamic_cast(static_cast(obj))) #define SP_IS_KNOT(obj) (dynamic_cast(static_cast(obj)) != NULL) @@ -36,19 +40,17 @@ class SPItem; */ class SPKnot { public: - SPKnot(SPDesktop *desktop, gchar const *tip); + SPKnot(SPDesktop *desktop, char const *tip); virtual ~SPKnot(); - - int ref_count; - + int ref_count; // FIXME encapsulation SPDesktop *desktop; /**< Desktop we are on. */ SPCanvasItem *item; /**< Our CanvasItem. */ SPItem *owner; /**< Optional Owner Item */ - guint flags; + unsigned int flags; - guint size; /**< Always square. */ + unsigned int size; /**< Always square. */ Geom::Point pos; /**< Our desktop coordinates. */ Geom::Point grabbed_rel_pos; /**< Grabbed relative position. */ Geom::Point drag_origin; /**< Origin of drag. */ @@ -59,39 +61,41 @@ public: guint32 fill[SP_KNOT_VISIBLE_STATES]; guint32 stroke[SP_KNOT_VISIBLE_STATES]; - guchar *image[SP_KNOT_VISIBLE_STATES]; + unsigned char *image[SP_KNOT_VISIBLE_STATES]; GdkCursor *cursor[SP_KNOT_VISIBLE_STATES]; GdkCursor *saved_cursor; - gpointer pixbuf; + void* pixbuf; - gchar *tip; + char *tip; - gulong _event_handler_id; + unsigned long _event_handler_id; double pressure; /**< The tablet pen pressure when the knot is being dragged. */ - sigc::signal click_signal; - sigc::signal doubleclicked_signal; - sigc::signal grabbed_signal; - sigc::signal ungrabbed_signal; - sigc::signal moved_signal; + // FIXME: signals should NOT need to emit the object they came from, the callee should + // be able to figure that out + sigc::signal click_signal; + sigc::signal doubleclicked_signal; + sigc::signal grabbed_signal; + sigc::signal ungrabbed_signal; + sigc::signal moved_signal; sigc::signal event_signal; - sigc::signal request_signal; + sigc::signal request_signal; //TODO: all the members above should eventualle become private, accessible via setters/getters - void setSize(guint i); - void setShape(guint i); - void setAnchor(guint i); - void setMode(guint i); - void setPixbuf(gpointer p); + void setSize(unsigned int i); + void setShape(unsigned int i); + void setAnchor(unsigned int i); + void setMode(unsigned int i); + void setPixbuf(void* p); void setFill(guint32 normal, guint32 mouseover, guint32 dragging); void setStroke(guint32 normal, guint32 mouseover, guint32 dragging); - void setImage(guchar* normal, guchar* mouseover, guchar* dragging); + void setImage(unsigned char* normal, unsigned char* mouseover, unsigned char* dragging); void setCursor(GdkCursor* normal, GdkCursor* mouseover, GdkCursor* dragging); @@ -108,7 +112,7 @@ public: /** * Set flag in knot, with side effects. */ - void setFlag(guint flag, bool set); + void setFlag(unsigned int flag, bool set); /** * Update knot's pixbuf and set its control state. @@ -118,17 +122,17 @@ public: /** * Request or set new position for knot. */ - void requestPosition(Geom::Point const &pos, guint state); + void requestPosition(Geom::Point const &pos, unsigned int state); /** * Update knot for dragging and tell canvas an item was grabbed. */ - void startDragging(Geom::Point const &p, gint x, gint y, guint32 etime); + void startDragging(Geom::Point const &p, int x, int y, guint32 etime); /** * Move knot to new position and emits "moved" signal. */ - void setPosition(Geom::Point const &p, guint state); + void setPosition(Geom::Point const &p, unsigned int state); /** * Move knot to new position, without emitting a MOVED signal. diff --git a/src/knotholder.h b/src/knotholder.h index dc2300105..d33adb610 100644 --- a/src/knotholder.h +++ b/src/knotholder.h @@ -17,7 +17,6 @@ * */ -#include #include <2geom/forward.h> #include #include @@ -47,9 +46,9 @@ public: void update_knots(); - void knot_moved_handler(SPKnot *knot, Geom::Point const &p, guint state); - void knot_clicked_handler(SPKnot *knot, guint state); - void knot_ungrabbed_handler(SPKnot *knot, guint); + void knot_moved_handler(SPKnot *knot, Geom::Point const &p, unsigned int state); + void knot_clicked_handler(SPKnot *knot, unsigned int state); + void knot_ungrabbed_handler(SPKnot *knot, unsigned int); void add(KnotHolderEntity *e); @@ -76,7 +75,7 @@ protected: SPKnotHolderReleasedFunc released; - gboolean local_change; ///< if true, no need to recreate knotholder if repr was changed. + bool local_change; ///< if true, no need to recreate knotholder if repr was changed. bool dragging; diff --git a/src/layer-manager.h b/src/layer-manager.h index 1b69324d5..9eea68004 100644 --- a/src/layer-manager.h +++ b/src/layer-manager.h @@ -10,11 +10,12 @@ #ifndef SEEN_INKSCAPE_LAYER_MANAGER_H #define SEEN_INKSCAPE_LAYER_MANAGER_H +#include +#include + #include "document-subset.h" #include "gc-finalized.h" #include "gc-soft-ptr.h" -#include -#include class SPDesktop; class SPDocument; @@ -29,8 +30,8 @@ public: virtual ~LayerManager(); void setCurrentLayer( SPObject* obj ); - void renameLayer( SPObject* obj, gchar const *label, bool uniquify ); - Glib::ustring getNextLayerName( SPObject* obj, gchar const *label); + void renameLayer( SPObject* obj, char const *label, bool uniquify ); + Glib::ustring getNextLayerName( SPObject* obj, char const *label); sigc::connection connectCurrentLayerChanged(const sigc::slot & slot) { return _layer_changed_signal.connect(slot); @@ -44,7 +45,7 @@ private: friend class LayerWatcher; class LayerWatcher; - void _objectModified( SPObject* obj, guint flags ); + void _objectModified( SPObject* obj, unsigned int flags ); void _setDocument(SPDocument *document); void _rebuild(); void _selectedLayerChanged(SPObject *layer); diff --git a/src/layer-model.h b/src/layer-model.h index 79b7fbe44..86aba63ef 100644 --- a/src/layer-model.h +++ b/src/layer-model.h @@ -22,12 +22,8 @@ * */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include #include +#include class SPDocument; class SPObject; diff --git a/src/line-geometry.h b/src/line-geometry.h index d7be9570c..a77d6e1f3 100644 --- a/src/line-geometry.h +++ b/src/line-geometry.h @@ -12,13 +12,14 @@ #ifndef SEEN_LINE_GEOMETRY_H #define SEEN_LINE_GEOMETRY_H +#include <2geom/point.h> #include -#include "glib.h" + #include "axis-manip.h" // FIXME: This is only for Box3D::epsilon; move that to a better location -#include "2geom/point.h" #include "persp3d.h" class SPDesktop; +typedef unsigned int guint32; namespace Box3D { diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp index 930b7fca9..6122b133a 100644 --- a/src/line-snapper.cpp +++ b/src/line-snapper.cpp @@ -11,9 +11,10 @@ */ #include <2geom/line.h> +#include + #include "line-snapper.h" #include "snapped-line.h" -//#include #include "snap.h" Inkscape::LineSnapper::LineSnapper(SnapManager *sm, Geom::Coord const d) : Snapper(sm, d) @@ -37,7 +38,7 @@ void Inkscape::LineSnapper::freeSnap(IntermSnapResults &isr, Geom::Point const p1 = i->second; // point at guide/grid line Geom::Point const p2 = p1 + Geom::rot90(i->first); // 2nd point at guide/grid line // std::cout << " line through " << i->second << " with normal " << i->first; - g_assert(i->first != Geom::Point(0,0)); // we cannot project on an linesegment of zero length + assert(i->first != Geom::Point(0,0)); // we cannot project on an linesegment of zero length Geom::Point const p_proj = Geom::projection(p.getPoint(), Geom::Line(p1, p2)); Geom::Coord const dist = Geom::L2(p_proj - p.getPoint()); diff --git a/src/line-snapper.h b/src/line-snapper.h index 4b165e0a5..b2fc3d389 100644 --- a/src/line-snapper.h +++ b/src/line-snapper.h @@ -12,10 +12,9 @@ #include "snapper.h" -namespace Inkscape -{ -class SnapCandidatePoint; +namespace Inkscape { +class SnapCandidatePoint; /** * Superclass for snappers to horizontal and vertical lines. diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 65bbcdad1..e466093d3 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -12,6 +12,7 @@ */ #include +#include #include "live_effects/lpe-copy_rotate.h" #include "sp-shape.h" diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index cac3a9347..938287c22 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -22,6 +22,7 @@ #include "knotholder.h" #include +#include #include <2geom/sbasis-to-bezier.h> #include <2geom/sbasis.h> diff --git a/src/live_effects/lpeobject-reference.h b/src/live_effects/lpeobject-reference.h index b1ba1ee4e..374e715ec 100644 --- a/src/live_effects/lpeobject-reference.h +++ b/src/live_effects/lpeobject-reference.h @@ -9,10 +9,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information. */ -#include -#include #include +#include "uri-references.h" + namespace Inkscape { namespace XML { class Node; @@ -33,7 +33,7 @@ public: SPObject *owner; // concerning the LPEObject that is refered to: - gchar *lpeobject_href; + char *lpeobject_href; Inkscape::XML::Node *lpeobject_repr; LivePathEffectObject *lpeobject; diff --git a/src/live_effects/lpeobject.h b/src/live_effects/lpeobject.h index 9700024fe..2e62707e3 100644 --- a/src/live_effects/lpeobject.h +++ b/src/live_effects/lpeobject.h @@ -47,9 +47,9 @@ protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; #endif diff --git a/src/main-cmdlineact.h b/src/main-cmdlineact.h index fe11357fa..c8ef64f10 100644 --- a/src/main-cmdlineact.h +++ b/src/main-cmdlineact.h @@ -15,20 +15,18 @@ * Released under GNU GPL v2.x, read the file 'COPYING' for more information */ -#include - namespace Inkscape { class ActionContext; class CmdLineAction { bool _isVerb; - gchar * _arg; + char * _arg; static std::list _list; public: - CmdLineAction (bool isVerb, gchar const * arg); + CmdLineAction (bool isVerb, char const * arg); virtual ~CmdLineAction (); void doIt (ActionContext const & context); diff --git a/src/marker.h b/src/marker.h index 9eefcdf16..b58523251 100644 --- a/src/marker.h +++ b/src/marker.h @@ -1,5 +1,5 @@ -#ifndef __SP_MARKER_H__ -#define __SP_MARKER_H__ +#ifndef SEEN_SP_MARKER_H +#define SEEN_SP_MARKER_H /* * SVG implementation @@ -12,7 +12,6 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - /* * This is quite similar in logic to * Maybe we should merge them somehow (Lauris) @@ -26,8 +25,9 @@ struct SPMarkerView; #include <2geom/rect.h> #include <2geom/affine.h> -#include "svg/svg-length.h" + #include "enums.h" +#include "svg/svg-length.h" #include "sp-item-group.h" #include "uri-references.h" #include "viewbox.h" @@ -93,7 +93,7 @@ Inkscape::DrawingItem *sp_marker_show_instance (SPMarker *marker, Inkscape::Draw unsigned int key, unsigned int pos, Geom::Affine const &base, float linewidth); void sp_marker_hide (SPMarker *marker, unsigned int key); -const gchar *generate_marker (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Point center, Geom::Affine move); +const char *generate_marker (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Point center, Geom::Affine move); SPObject *sp_marker_fork_if_necessary(SPObject *marker); #endif diff --git a/src/message-context.h b/src/message-context.h index a92874d68..ea86c4ec0 100644 --- a/src/message-context.h +++ b/src/message-context.h @@ -14,8 +14,9 @@ #ifndef SEEN_INKSCAPE_MESSAGE_CONTEXT_H #define SEEN_INKSCAPE_MESSAGE_CONTEXT_H -#include +#include #include + #include "message.h" namespace Inkscape { @@ -48,7 +49,7 @@ public: * @param type the message type * @param message the message text */ - void set(MessageType type, gchar const *message); + void set(MessageType type, char const *message); /** @brief pushes a message on the stack using prinf-style formatting, * and replacing our old message @@ -56,7 +57,7 @@ public: * @param type the message type * @param format a printf-style formatting string */ - void setF(MessageType type, gchar const *format, ...) G_GNUC_PRINTF(3,4); + void setF(MessageType type, char const *format, ...) G_GNUC_PRINTF(3,4); /** @brief pushes a message on the stack using printf-style formatting, * and a stdarg argument list @@ -65,7 +66,7 @@ public: * @param format a printf-style formatting string * @param args printf-style arguments */ - void setVF(MessageType type, gchar const *format, va_list args); + void setVF(MessageType type, char const *format, va_list args); /** @brief pushes a message onto the stack for a brief period of time * without disturbing our "current" message @@ -73,7 +74,7 @@ public: * @param type the message type * @param message the message text */ - void flash(MessageType type, gchar const *message); + void flash(MessageType type, char const *message); /** @brief pushes a message onto the stack for a brief period of time * using printf-style formatting, without disturbing our current @@ -82,7 +83,7 @@ public: * @param type the message type * @param format a printf-style formatting string */ - void flashF(MessageType type, gchar const *format, ...) G_GNUC_PRINTF(3,4); + void flashF(MessageType type, char const *format, ...) G_GNUC_PRINTF(3,4); /** @brief pushes a message onto the stack for a brief period of time * using printf-style formatting and a stdarg argument list; @@ -92,7 +93,7 @@ public: * @param format a printf-style formatting string * @param args printf-style arguments */ - void flashVF(MessageType type, gchar const *format, va_list args); + void flashVF(MessageType type, char const *format, va_list args); /** @brief removes our current message from the stack */ void clear(); diff --git a/src/message-stack.h b/src/message-stack.h index 3b8307761..42bf4e8a7 100644 --- a/src/message-stack.h +++ b/src/message-stack.h @@ -16,11 +16,12 @@ #ifndef SEEN_INKSCAPE_MESSAGE_STACK_H #define SEEN_INKSCAPE_MESSAGE_STACK_H -#include -#include -#include -#include +#include +#include +#include // G_GNUC_PRINTF is the only thing worth having from here #include +#include + #include "gc-managed.h" #include "gc-finalized.h" #include "gc-anchored.h" @@ -61,14 +62,14 @@ public: /** @brief returns the text of the message currently at the top of * the stack */ - gchar const *currentMessage() { + char const *currentMessage() { return _messages ? _messages->message : NULL; } /** @brief connects to the "changed" signal which is emitted whenever * the topmost message on the stack changes. */ - sigc::connection connectChanged(sigc::slot slot) + sigc::connection connectChanged(sigc::slot slot) { return _changed_signal.connect(slot); } @@ -80,7 +81,7 @@ public: * * @return the id of the pushed message */ - MessageId push(MessageType type, gchar const *message); + MessageId push(MessageType type, char const *message); /** @brief pushes a message onto the stack using printf-like formatting * @@ -89,7 +90,7 @@ public: * * @return the id of the pushed message */ - MessageId pushF(MessageType type, gchar const *format, ...) G_GNUC_PRINTF(3,4); + MessageId pushF(MessageType type, char const *format, ...) G_GNUC_PRINTF(3,4); /** @brief pushes a message onto the stack using printf-like formatting, * using a stdarg argument list @@ -100,7 +101,7 @@ public: * * @return the id of the pushed message */ - MessageId pushVF(MessageType type, gchar const *format, va_list args); + MessageId pushVF(MessageType type, char const *format, va_list args); /** @brief removes a message from the stack, given its id * @@ -119,7 +120,7 @@ public: * * @return the id of the pushed message */ - MessageId flash(MessageType type, gchar const *message); + MessageId flash(MessageType type, char const *message); /** * Temporarily pushes a message onto the stack. @@ -140,7 +141,7 @@ public: * * @return the id of the pushed message */ - MessageId flashF(MessageType type, gchar const *format, ...) G_GNUC_PRINTF(3,4); + MessageId flashF(MessageType type, char const *format, ...) G_GNUC_PRINTF(3,4); /** @brief temporarily pushes a message onto the stack using * printf-like formatting, using a stdarg argument list @@ -151,7 +152,7 @@ public: * * @return the id of the pushed message */ - MessageId flashVF(MessageType type, gchar const *format, va_list args); + MessageId flashVF(MessageType type, char const *format, va_list args); private: struct Message { @@ -167,13 +168,13 @@ private: void operator=(MessageStack const &); // no assign /// pushes a message onto the stack with an optional timeout - MessageId _push(MessageType type, guint lifetime, gchar const *message); + MessageId _push(MessageType type, unsigned int lifetime, char const *message); Message *_discard(Message *m); ///< frees a message struct and returns the next such struct in the list void _emitChanged(); ///< emits the "changed" signal - static gboolean _timeout(gpointer data); ///< callback to expire flashed messages + static int _timeout(void* data); ///< callback to expire flashed messages - sigc::signal _changed_signal; + sigc::signal _changed_signal; Message *_messages; ///< the stack of messages as a linked list MessageId _next_id; ///< the next message id to assign }; diff --git a/src/number-opt-number.h b/src/number-opt-number.h index d9ab56102..f6fe584f9 100644 --- a/src/number-opt-number.h +++ b/src/number-opt-number.h @@ -13,27 +13,23 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include #include -//todo: use glib instead of stdlib -#include +#include + #include "svg/stringstream.h" class NumberOptNumber { public: - gfloat number; + float number; - gfloat optNumber; + float optNumber; - guint _set : 1; + unsigned int _set : 1; - guint optNumber_set : 1; + unsigned int optNumber_set : 1; NumberOptNumber() { @@ -44,27 +40,27 @@ public: optNumber_set = FALSE; } - gfloat getNumber() + float getNumber() { if(_set) return number; return -1; } - gfloat getOptNumber() + float getOptNumber() { if(optNumber_set) return optNumber; return -1; } - void setOptNumber(gfloat num) + void setOptNumber(float num) { optNumber_set = true; optNumber = num; } - void setNumber(gfloat num) + void setNumber(float num) { _set = true; number = num; @@ -78,7 +74,7 @@ public: return _set; } - gchar *getValueString() + char *getValueString() { Inkscape::SVGOStringStream os; @@ -96,12 +92,12 @@ public: return g_strdup(os.str().c_str()); } - void set(gchar const *str) + void set(char const *str) { if(!str) return; - gchar **values = g_strsplit(str, " ", 2); + char **values = g_strsplit(str, " ", 2); if( values[0] != NULL ) { diff --git a/src/object-edit.cpp b/src/object-edit.cpp index fe22f6c1c..14a5bd3d5 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -96,33 +96,33 @@ KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop) class RectKnotHolderEntityRX : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; /* handle for vertical rounding radius */ class RectKnotHolderEntityRY : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; /* handle for width/height adjustment */ class RectKnotHolderEntityWH : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); protected: - void set_internal(Geom::Point const &p, Geom::Point const &origin, guint state); + void set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; /* handle for x/y adjustment */ class RectKnotHolderEntityXY : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; Geom::Point @@ -134,7 +134,7 @@ RectKnotHolderEntityRX::knot_get() const } void -RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { SPRect *rect = SP_RECT(item); @@ -159,7 +159,7 @@ RectKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*orig } void -RectKnotHolderEntityRX::knot_click(guint state) +RectKnotHolderEntityRX::knot_click(unsigned int state) { SPRect *rect = SP_RECT(item); @@ -183,7 +183,7 @@ RectKnotHolderEntityRY::knot_get() const } void -RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { SPRect *rect = SP_RECT(item); @@ -217,7 +217,7 @@ RectKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*orig } void -RectKnotHolderEntityRY::knot_click(guint state) +RectKnotHolderEntityRY::knot_click(unsigned int state) { SPRect *rect = SP_RECT(item); @@ -255,7 +255,7 @@ RectKnotHolderEntityWH::knot_get() const } void -RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &origin, guint state) +RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &origin, unsigned int state) { SPRect *rect = SP_RECT(item); @@ -327,7 +327,7 @@ RectKnotHolderEntityWH::set_internal(Geom::Point const &p, Geom::Point const &or } void -RectKnotHolderEntityWH::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) +RectKnotHolderEntityWH::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) { set_internal(p, origin, state); update_knot(); @@ -342,7 +342,7 @@ RectKnotHolderEntityXY::knot_get() const } void -RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) +RectKnotHolderEntityXY::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) { SPRect *rect = SP_RECT(item); @@ -468,10 +468,10 @@ RectKnotHolder::RectKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderRel class Box3DKnotHolderEntity : public KnotHolderEntity { public: virtual Geom::Point knot_get() const = 0; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) = 0; + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) = 0; Geom::Point knot_get_generic(SPItem *item, unsigned int knot_id) const; - void knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &p, guint state); + void knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &p, unsigned int state); }; Geom::Point @@ -481,7 +481,7 @@ Box3DKnotHolderEntity::knot_get_generic(SPItem *item, unsigned int knot_id) cons } void -Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &new_pos, guint state) +Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom::Point const &new_pos, unsigned int state) { Geom::Point const s = snap_knot_position(new_pos, state); @@ -504,55 +504,55 @@ Box3DKnotHolderEntity::knot_set_generic(SPItem *item, unsigned int knot_id, Geom class Box3DKnotHolderEntity0 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntity1 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntity2 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntity3 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntity4 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntity5 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntity6 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntity7 : public Box3DKnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; class Box3DKnotHolderEntityCenter : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; Geom::Point @@ -610,55 +610,55 @@ Box3DKnotHolderEntityCenter::knot_get() const } void -Box3DKnotHolderEntity0::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity0::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 0, new_pos, state); } void -Box3DKnotHolderEntity1::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity1::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 1, new_pos, state); } void -Box3DKnotHolderEntity2::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity2::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 2, new_pos, state); } void -Box3DKnotHolderEntity3::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity3::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 3, new_pos, state); } void -Box3DKnotHolderEntity4::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity4::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 4, new_pos, state); } void -Box3DKnotHolderEntity5::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity5::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 5, new_pos, state); } void -Box3DKnotHolderEntity6::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity6::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 6, new_pos, state); } void -Box3DKnotHolderEntity7::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, guint state) +Box3DKnotHolderEntity7::knot_set(Geom::Point const &new_pos, Geom::Point const &/*origin*/, unsigned int state) { knot_set_generic(item, 7, new_pos, state); } void -Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point const &origin, guint state) +Box3DKnotHolderEntityCenter::knot_set(Geom::Point const &new_pos, Geom::Point const &origin, unsigned int state) { Geom::Point const s = snap_knot_position(new_pos, state); @@ -739,29 +739,29 @@ Box3DKnotHolder::Box3DKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderR class ArcKnotHolderEntityStart : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; class ArcKnotHolderEntityEnd : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; class ArcKnotHolderEntityRX : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; class ArcKnotHolderEntityRY : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; /* @@ -783,7 +783,7 @@ sp_genericellipse_side(SPGenericEllipse *ellipse, Geom::Point const &p) } void -ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +ArcKnotHolderEntityStart::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); @@ -813,7 +813,7 @@ ArcKnotHolderEntityStart::knot_get() const } void -ArcKnotHolderEntityStart::knot_click(guint state) +ArcKnotHolderEntityStart::knot_click(unsigned int state) { SPGenericEllipse *ge = SP_GENERICELLIPSE(item); @@ -824,7 +824,7 @@ ArcKnotHolderEntityStart::knot_click(guint state) } void -ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +ArcKnotHolderEntityEnd::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { int snaps = Inkscape::Preferences::get()->getInt("/options/rotationsnapsperpi/value", 12); @@ -855,7 +855,7 @@ ArcKnotHolderEntityEnd::knot_get() const void -ArcKnotHolderEntityEnd::knot_click(guint state) +ArcKnotHolderEntityEnd::knot_click(unsigned int state) { SPGenericEllipse *ge = SP_GENERICELLIPSE(item); @@ -867,7 +867,7 @@ ArcKnotHolderEntityEnd::knot_click(guint state) void -ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +ArcKnotHolderEntityRX::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { SPGenericEllipse *ge = SP_GENERICELLIPSE(item); @@ -891,7 +891,7 @@ ArcKnotHolderEntityRX::knot_get() const } void -ArcKnotHolderEntityRX::knot_click(guint state) +ArcKnotHolderEntityRX::knot_click(unsigned int state) { SPGenericEllipse *ge = SP_GENERICELLIPSE(item); @@ -902,7 +902,7 @@ ArcKnotHolderEntityRX::knot_click(guint state) } void -ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +ArcKnotHolderEntityRY::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { SPGenericEllipse *ge = SP_GENERICELLIPSE(item); @@ -926,7 +926,7 @@ ArcKnotHolderEntityRY::knot_get() const } void -ArcKnotHolderEntityRY::knot_click(guint state) +ArcKnotHolderEntityRY::knot_click(unsigned int state) { SPGenericEllipse *ge = SP_GENERICELLIPSE(item); @@ -975,19 +975,19 @@ ArcKnotHolder::ArcKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderRelea class StarKnotHolderEntity1 : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; class StarKnotHolderEntity2 : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; void -StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { SPStar *star = SP_STAR(item); @@ -1013,7 +1013,7 @@ StarKnotHolderEntity1::knot_set(Geom::Point const &p, Geom::Point const &/*origi } void -StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +StarKnotHolderEntity2::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { SPStar *star = SP_STAR(item); @@ -1063,7 +1063,7 @@ StarKnotHolderEntity2::knot_get() const } static void -sp_star_knot_click(SPItem *item, guint state) +sp_star_knot_click(SPItem *item, unsigned int state) { SPStar *star = SP_STAR(item); @@ -1080,13 +1080,13 @@ sp_star_knot_click(SPItem *item, guint state) } void -StarKnotHolderEntity1::knot_click(guint state) +StarKnotHolderEntity1::knot_click(unsigned int state) { sp_star_knot_click(item, state); } void -StarKnotHolderEntity2::knot_click(guint state) +StarKnotHolderEntity2::knot_click(unsigned int state) { sp_star_knot_click(item, state); } @@ -1119,14 +1119,14 @@ StarKnotHolder::StarKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderRel class SpiralKnotHolderEntityInner : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual void knot_click(guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); + virtual void knot_click(unsigned int state); }; class SpiralKnotHolderEntityOuter : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; @@ -1137,7 +1137,7 @@ public: * [control] constrain inner arg to round per PI/4 */ void -SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) +SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); @@ -1186,7 +1186,7 @@ SpiralKnotHolderEntityInner::knot_set(Geom::Point const &p, Geom::Point const &o * [control] constrain inner arg to round per PI/4 */ void -SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint state) +SpiralKnotHolderEntityOuter::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int state) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); @@ -1276,7 +1276,7 @@ SpiralKnotHolderEntityOuter::knot_get() const } void -SpiralKnotHolderEntityInner::knot_click(guint state) +SpiralKnotHolderEntityInner::knot_click(unsigned int state) { SPSpiral *spiral = SP_SPIRAL(item); @@ -1314,11 +1314,11 @@ SpiralKnotHolder::SpiralKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolde class OffsetKnotHolderEntity : public KnotHolderEntity { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; void -OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, guint /*state*/) +OffsetKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &/*origin*/, unsigned int /*state*/) { SPOffset *offset = SP_OFFSET(item); @@ -1357,7 +1357,7 @@ OffsetKnotHolder::OffsetKnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolde class FlowtextKnotHolderEntity : public RectKnotHolderEntityWH { public: virtual Geom::Point knot_get() const; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state); }; Geom::Point @@ -1369,7 +1369,7 @@ FlowtextKnotHolderEntity::knot_get() const } void -FlowtextKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) +FlowtextKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &origin, unsigned int state) { set_internal(p, origin, state); } diff --git a/src/object-hierarchy.cpp b/src/object-hierarchy.cpp index f2bf177dc..f241da83d 100644 --- a/src/object-hierarchy.cpp +++ b/src/object-hierarchy.cpp @@ -9,6 +9,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include +#include + #include "sp-object.h" #include "object-hierarchy.h" @@ -32,7 +35,7 @@ void ObjectHierarchy::clear() { } void ObjectHierarchy::setTop(SPObject *object) { - g_return_if_fail(object != NULL); + if (object == NULL) { printf("Assertion object != NULL failed\n"); return; } if ( top() == object ) { return; @@ -53,8 +56,8 @@ void ObjectHierarchy::setTop(SPObject *object) { } void ObjectHierarchy::_addTop(SPObject *senior, SPObject *junior) { - g_assert(junior != NULL); - g_assert(senior != NULL); + assert(junior != NULL); + assert(senior != NULL); SPObject *object = junior->parent; do { @@ -64,7 +67,7 @@ void ObjectHierarchy::_addTop(SPObject *senior, SPObject *junior) { } void ObjectHierarchy::_addTop(SPObject *object) { - g_assert(object != NULL); + assert(object != NULL); _hierarchy.push_back(_attach(object)); _added_signal.emit(object); } @@ -82,7 +85,7 @@ void ObjectHierarchy::_trimAbove(SPObject *limit) { } void ObjectHierarchy::setBottom(SPObject *object) { - g_return_if_fail(object != NULL); + if (object == NULL) { printf("assertion object != NULL failed\n"); return; } if ( bottom() == object ) { return; @@ -125,8 +128,8 @@ void ObjectHierarchy::_trimBelow(SPObject *limit) { } void ObjectHierarchy::_addBottom(SPObject *senior, SPObject *junior) { - g_assert(junior != NULL); - g_assert(senior != NULL); + assert(junior != NULL); + assert(senior != NULL); if ( junior != senior ) { _addBottom(senior, junior->parent); @@ -135,15 +138,15 @@ void ObjectHierarchy::_addBottom(SPObject *senior, SPObject *junior) { } void ObjectHierarchy::_addBottom(SPObject *object) { - g_assert(object != NULL); + assert(object != NULL); _hierarchy.push_front(_attach(object)); _added_signal.emit(object); } void ObjectHierarchy::_trim_for_release(SPObject *object) { this->_trimBelow(object); - g_assert(!this->_hierarchy.empty()); - g_assert(this->_hierarchy.front().object == object); + assert(!this->_hierarchy.empty()); + assert(this->_hierarchy.front().object == object); sp_object_ref(object, NULL); this->_detach(this->_hierarchy.front()); diff --git a/src/object-hierarchy.h b/src/object-hierarchy.h index 0343d850e..16004c81a 100644 --- a/src/object-hierarchy.h +++ b/src/object-hierarchy.h @@ -10,12 +10,11 @@ #ifndef SEEN_INKSCAPE_OBJECT_HIERARCHY_H #define SEEN_INKSCAPE_OBJECT_HIERARCHY_H +#include #include #include -#include #include #include -#include class SPObject; diff --git a/src/path-chemistry.h b/src/path-chemistry.h index efc687b44..a2150440c 100644 --- a/src/path-chemistry.h +++ b/src/path-chemistry.h @@ -13,8 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include - class SPDesktop; class SPItem; @@ -25,6 +23,9 @@ class Node; } // namespace XML } // namespace Inkscape +typedef unsigned int guint32; +typedef struct _GSList GSList; + void sp_selected_path_combine (SPDesktop *desktop); void sp_selected_path_break_apart (SPDesktop *desktop); // interactive=true only has an effect if desktop != NULL, i.e. if a GUI is available diff --git a/src/path-prefix.h b/src/path-prefix.h index be57ae354..6ef0ccbe9 100644 --- a/src/path-prefix.h +++ b/src/path-prefix.h @@ -10,15 +10,15 @@ * define'd directories, and instead should use only the paths defined here. * */ -#ifndef _PATH_PREFIX_H_ -#define _PATH_PREFIX_H_ +#ifndef SEEN_PATH_PREFIX_H +#define SEEN_PATH_PREFIX_H #include "require-config.h" // INKSCAPE_DATADIR #include "prefix.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +//#ifdef __cplusplus +//extern "C" { +//#endif /* __cplusplus */ #ifdef ENABLE_BINRELOC # define INKSCAPE_APPICONDIR BR_DATADIR( "/pixmaps" ) @@ -112,8 +112,8 @@ extern "C" { # endif #endif -#ifdef __cplusplus -} -#endif /* __cplusplus */ +//#ifdef __cplusplus +//} +//#endif /* __cplusplus */ #endif /* _PATH_PREFIX_H_ */ diff --git a/src/persp3d-reference.h b/src/persp3d-reference.h index fa9eca5c9..cce497d94 100644 --- a/src/persp3d-reference.h +++ b/src/persp3d-reference.h @@ -10,9 +10,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information. */ -#include "uri-references.h" -#include +#include #include + +#include "uri-references.h" #include "persp3d.h" class SPObject; @@ -35,7 +36,7 @@ public: SPObject *owner; // concerning the Persp3D (we only use SPBox3D) that is refered to: - gchar *persp_href; + char *persp_href; Inkscape::XML::Node *persp_repr; Persp3D *persp; diff --git a/src/persp3d.h b/src/persp3d.h index bd3777a19..be5680bcb 100644 --- a/src/persp3d.h +++ b/src/persp3d.h @@ -1,5 +1,5 @@ -#ifndef __PERSP3D_H__ -#define __PERSP3D_H__ +#ifndef SEEN_PERSP3D_H +#define SEEN_PERSP3D_H /* * Implementation of 3D perspectives as SPObjects @@ -16,8 +16,9 @@ #define SP_IS_PERSP3D(obj) (dynamic_cast((SPObject*)obj) != NULL) #include -#include #include +#include + #include "transf_mat_3x4.h" #include "document.h" #include "inkscape.h" // for SP_ACTIVE_DOCUMENT @@ -64,11 +65,11 @@ protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; @@ -100,7 +101,7 @@ void persp3d_update_z_orders (Persp3D *persp); inline unsigned int persp3d_num_boxes (Persp3D *persp) { return persp->perspective_impl->boxes.size(); } std::list persp3d_list_of_boxes(Persp3D *persp); -bool persp3d_perspectives_coincide(const Persp3D *lhs, const Persp3D *rhs); +bool persp3d_perspectives_coincide(Persp3D const *lhs, Persp3D const *rhs); void persp3d_absorb(Persp3D *persp1, Persp3D *persp2); Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup = NULL); @@ -112,7 +113,7 @@ void persp3d_print_debugging_info (Persp3D *persp); void persp3d_print_debugging_info_all(SPDocument *doc); void persp3d_print_all_selected(); -void print_current_persp3d(gchar *func_name, Persp3D *persp); +void print_current_persp3d(char *func_name, Persp3D *persp); #endif /* __PERSP3D_H__ */ diff --git a/src/perspective-line.h b/src/perspective-line.h index 57abaae9c..64f7d03bd 100644 --- a/src/perspective-line.h +++ b/src/perspective-line.h @@ -13,7 +13,6 @@ #define SEEN_PERSPECTIVE_LINE_H #include "line-geometry.h" -#include class SPDesktop; diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 734e8a582..66a3e47d4 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -1,8 +1,9 @@ #ifndef SEEN_PREFERENCES_SKELETON_H #define SEEN_PREFERENCES_SKELETON_H -#include +#include "inkscape-version.h" +// FIXME why is this here? #ifdef N_ #undef N_ #endif diff --git a/src/preferences.h b/src/preferences.h index d5429815e..d5ae40e56 100644 --- a/src/preferences.h +++ b/src/preferences.h @@ -13,14 +13,16 @@ #ifndef INKSCAPE_PREFSTORE_H #define INKSCAPE_PREFSTORE_H -#include -#include #include #include #include +#include +#include + #include "xml/repr.h" class SPCSSAttr; +typedef unsigned int guint32; namespace Inkscape { diff --git a/src/print.h b/src/print.h index bbf95b833..ab2bcc0a7 100644 --- a/src/print.h +++ b/src/print.h @@ -41,18 +41,18 @@ unsigned int sp_print_stroke(SPPrintContext *ctx, Geom::PathVector const &pathv, Geom::OptRect const &pbox, Geom::OptRect const &dbox, Geom::OptRect const &bbox); unsigned int sp_print_image_R8G8B8A8_N(SPPrintContext *ctx, - guchar *px, unsigned int w, unsigned int h, unsigned int rs, + unsigned char *px, unsigned int w, unsigned int h, unsigned int rs, Geom::Affine const &transform, SPStyle const *style); unsigned int sp_print_text(SPPrintContext *ctx, char const *text, Geom::Point p, SPStyle const *style); -void sp_print_get_param(SPPrintContext *ctx, gchar *name, bool *value); +void sp_print_get_param(SPPrintContext *ctx, char *name, bool *value); /* UI */ void sp_print_document(Gtk::Window& parentWindow, SPDocument *doc); -void sp_print_document_to_file(SPDocument *doc, gchar const *filename); +void sp_print_document_to_file(SPDocument *doc, char const *filename); #endif /* !PRINT_H_INKSCAPE */ diff --git a/src/profile-manager.h b/src/profile-manager.h index be9446c17..54cd4a1da 100644 --- a/src/profile-manager.h +++ b/src/profile-manager.h @@ -9,9 +9,10 @@ #ifndef SEEN_INKSCAPE_PROFILE_MANAGER_H #define SEEN_INKSCAPE_PROFILE_MANAGER_H +#include + #include "document-subset.h" #include "gc-finalized.h" -#include class SPDocument; @@ -26,7 +27,7 @@ public: ProfileManager(SPDocument *document); ~ProfileManager(); - ColorProfile* find(gchar const* name); + ColorProfile* find(char const* name); private: ProfileManager(ProfileManager const &); // no copy diff --git a/src/proj_pt.h b/src/proj_pt.h index 28ec0aca3..1ee4b7f14 100644 --- a/src/proj_pt.h +++ b/src/proj_pt.h @@ -13,7 +13,7 @@ #define SEEN_PROJ_PT_H #include <2geom/point.h> -#include +#include namespace Proj { @@ -25,7 +25,7 @@ public: Pt2 () { pt[0] = 0; pt[1] = 0; pt[2] = 1.0; } // we default to (0 : 0 : 1) Pt2 (double x, double y, double w) { pt[0] = x; pt[1] = y; pt[2] = w; } Pt2 (Geom::Point const &point) { pt[0] = point[Geom::X]; pt[1] = point[Geom::Y]; pt[2] = 1; } - Pt2 (const gchar *coord_str); + Pt2 (const char *coord_str); inline double operator[] (unsigned int index) const { if (index > 2) { return Geom::infinity(); } @@ -81,8 +81,8 @@ public: void normalize(); Geom::Point affine(); inline bool is_finite() { return pt[2] != 0; } // FIXME: Should we allow for some tolerance? - gchar *coord_string(); - inline void print(gchar const *s) const { g_print ("%s(%8.2f : %8.2f : %8.2f)\n", s, pt[0], pt[1], pt[2]); } + char *coord_string(); + inline void print(char const *s) const { printf ("%s(%8.2f : %8.2f : %8.2f)\n", s, pt[0], pt[1], pt[2]); } private: double pt[3]; @@ -93,7 +93,7 @@ class Pt3 { public: Pt3 () { pt[0] = 0; pt[1] = 0; pt[2] = 0; pt[3] = 1.0; } // we default to (0 : 0 : 0 : 1) Pt3 (double x, double y, double z, double w) { pt[0] = x; pt[1] = y; pt[2] = z; pt[3] = w; } - Pt3 (const gchar *coord_str); + Pt3 (const char *coord_str); inline bool operator== (Pt3 &rhs) { normalize(); @@ -146,9 +146,9 @@ public: } void normalize(); inline bool is_finite() { return pt[3] != 0; } // FIXME: Should we allow for some tolerance? - gchar *coord_string(); - inline void print(gchar const *s) const { - g_print ("%s(%8.2f : %8.2f : %8.2f : %8.2f)\n", s, pt[0], pt[1], pt[2], pt[3]); + char *coord_string(); + inline void print(char const *s) const { + printf ("%s(%8.2f : %8.2f : %8.2f : %8.2f)\n", s, pt[0], pt[1], pt[2], pt[3]); } private: diff --git a/src/rdf.h b/src/rdf.h index 3dde1cb48..c3ced1583 100644 --- a/src/rdf.h +++ b/src/rdf.h @@ -11,7 +11,6 @@ #ifndef SEEN_RDF_H #define SEEN_RDF_H -#include #include #include "document.h" @@ -22,18 +21,18 @@ * \brief Holds license name/resource doubles for rdf_license_t entries */ struct rdf_double_t { - gchar const *name; - gchar const *resource; + char const *name; + char const *resource; }; /** * \brief Holds license name and RDF information */ struct rdf_license_t { - gchar const *name; /* localized name of this license */ - gchar const *uri; /* URL for the RDF/Work/license element */ + char const *name; /* localized name of this license */ + char const *uri; /* URL for the RDF/Work/license element */ struct rdf_double_t *details; /* the license details */ -// gchar const *fragment; /* XML contents for the RDF/License tag */ +// char const *fragment; /* XML contents for the RDF/License tag */ }; extern rdf_license_t rdf_licenses []; @@ -69,10 +68,10 @@ enum RDF_Editable { */ struct rdf_work_entity_t { char const *name; /* unique name of this entity for internal reference */ - gchar const *title; /* localized title of this entity for data entry */ - gchar const *tag; /* namespace tag for the RDF/Work element */ + char const *title; /* localized title of this entity for data entry */ + char const *tag; /* namespace tag for the RDF/Work element */ RDFType datatype; /* how to extract/inject the RDF information */ - gchar const *tip; /* tool tip to explain the meaning of the entity */ + char const *tip; /* tool tip to explain the meaning of the entity */ RDF_Format format; /* in what format is this data edited? */ RDF_Editable editable;/* in what way is the data editable? */ }; @@ -83,19 +82,19 @@ extern rdf_work_entity_t rdf_work_entities []; * \brief Generic collection of RDF information for the RDF debug function */ struct rdf_t { - gchar* work_title; - gchar* work_date; - gchar* work_creator; - gchar* work_owner; - gchar* work_publisher; - gchar* work_type; - gchar* work_source; - gchar* work_subject; - gchar* work_description; + char* work_title; + char* work_date; + char* work_creator; + char* work_owner; + char* work_publisher; + char* work_type; + char* work_source; + char* work_subject; + char* work_description; struct rdf_license_t* license; }; -struct rdf_work_entity_t * rdf_find_entity(gchar const * name); +struct rdf_work_entity_t * rdf_find_entity(char const * name); /** * \brief Retrieves a known RDF/Work entity's contents from the document XML by name @@ -114,7 +113,7 @@ const gchar * rdf_get_work_entity(SPDocument const * doc, */ unsigned int rdf_set_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity, - const gchar * text); + const char * text); /** * \brief Attempts to match and retrieve a known RDF/License from the document XML diff --git a/src/removeoverlap.h b/src/removeoverlap.h index 1ba41572a..7109c9513 100644 --- a/src/removeoverlap.h +++ b/src/removeoverlap.h @@ -13,7 +13,7 @@ #ifndef SEEN_REMOVEOVERLAP_H #define SEEN_REMOVEOVERLAP_H -#include +typedef struct _GSList GSList; void removeoverlap(GSList const *items, double xGap, double yGap); diff --git a/src/rubberband.h b/src/rubberband.h index fbebe2b08..a7bc57145 100644 --- a/src/rubberband.h +++ b/src/rubberband.h @@ -10,17 +10,17 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include #include <2geom/point.h> #include <2geom/rect.h> +#include +#include /* fixme: do multidocument safe */ -class CtrlRect; +class CtrlRect; +class SPCurve; +class SPDesktop; struct SPCanvasItem; -class SPCurve; -class SPDesktop; enum { RUBBERBAND_MODE_RECT, diff --git a/src/selcue.h b/src/selcue.h index bcac7315f..d9b16b0f5 100644 --- a/src/selcue.h +++ b/src/selcue.h @@ -1,5 +1,5 @@ -#ifndef __SP_SELCUE_H__ -#define __SP_SELCUE_H__ +#ifndef SEEN_SP_SELCUE_H +#define SEEN_SP_SELCUE_H /* * Helper object for showing selected items @@ -13,8 +13,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include #include -#include #include class SPDesktop; @@ -52,7 +52,7 @@ private: void _updateItemBboxes(); void _updateItemBboxes(Inkscape::Preferences *prefs); - void _updateItemBboxes(gint mode, int prefs_bbox); + void _updateItemBboxes(int mode, int prefs_bbox); void _newItemBboxes(); void _newTextBaselines(); void _boundingBoxPrefsChanged(int prefs_bbox); diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index 01c35d65a..016a54b5c 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -17,21 +17,21 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include <2geom/forward.h> #include "sp-item.h" -#include "2geom/forward.h" -namespace Inkscape { class Selection; } +class SPCSSAttr; +class SPDesktop; +typedef struct _GSList GSList; namespace Inkscape { + +class Selection; + namespace LivePathEffect { class PathParam; } -} -class SPCSSAttr; -class SPDesktop; - -namespace Inkscape { class SelectionHelper { public: static void selectAll(SPDesktop *desktop); @@ -108,21 +108,21 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons void sp_selection_remove_transform (SPDesktop *desktop); void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1); void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale); -void sp_selection_rotate_relative (Inkscape::Selection *selection, Geom::Point const ¢er, gdouble angle); +void sp_selection_rotate_relative (Inkscape::Selection *selection, Geom::Point const ¢er, double angle); void sp_selection_skew_relative (Inkscape::Selection *selection, Geom::Point const &align, double dx, double dy); void sp_selection_move_relative (Inkscape::Selection *selection, Geom::Point const &move, bool compensate = true); void sp_selection_move_relative (Inkscape::Selection *selection, double dx, double dy); void sp_selection_rotate_90 (SPDesktop *desktop, bool ccw); -void sp_selection_rotate (Inkscape::Selection *selection, gdouble angle); -void sp_selection_rotate_screen (Inkscape::Selection *selection, gdouble angle); +void sp_selection_rotate (Inkscape::Selection *selection, double angle); +void sp_selection_rotate_screen (Inkscape::Selection *selection, double angle); -void sp_selection_scale (Inkscape::Selection *selection, gdouble grow); -void sp_selection_scale_screen (Inkscape::Selection *selection, gdouble grow_pixels); -void sp_selection_scale_times (Inkscape::Selection *selection, gdouble times); +void sp_selection_scale (Inkscape::Selection *selection, double grow); +void sp_selection_scale_screen (Inkscape::Selection *selection, double grow_pixels); +void sp_selection_scale_times (Inkscape::Selection *selection, double times); -void sp_selection_move (Inkscape::Selection *selection, gdouble dx, gdouble dy); -void sp_selection_move_screen (Inkscape::Selection *selection, gdouble dx, gdouble dy); +void sp_selection_move (Inkscape::Selection *selection, double dx, double dy); +void sp_selection_move_screen (Inkscape::Selection *selection, double dx, double dy); void sp_selection_item_next (SPDesktop *desktop); void sp_selection_item_prev (SPDesktop *desktop); diff --git a/src/selection-describer.h b/src/selection-describer.h index b4174edd8..5514ce4b1 100644 --- a/src/selection-describer.h +++ b/src/selection-describer.h @@ -16,11 +16,10 @@ #include #include "message-context.h" -namespace Inkscape { class Selection; } - namespace Inkscape { class MessageStack; +class Selection; class SelectionDescriber : public sigc::trackable { public: @@ -29,7 +28,7 @@ public: private: void _updateMessageFromSelection(Inkscape::Selection *selection); - void _selectionModified(Inkscape::Selection *selection, guint /*flags*/); + void _selectionModified(Inkscape::Selection *selection, unsigned int /*flags*/); sigc::connection *_selection_changed_connection; sigc::connection *_selection_modified_connection; @@ -43,6 +42,7 @@ private: } #endif + /* Local Variables: mode:c++ diff --git a/src/selection.h b/src/selection.h index ba38bec08..5964b20e8 100644 --- a/src/selection.h +++ b/src/selection.h @@ -30,6 +30,7 @@ class SPDesktop; class SPItem; class SPBox3D; class Persp3D; +typedef struct _GSList GSList; namespace Inkscape { class LayerModel; @@ -256,10 +257,10 @@ public: std::list const box3DList(Persp3D *persp = NULL); /** Returns the number of layers in which there are selected objects. */ - guint numberOfLayers(); + unsigned int numberOfLayers(); /** Returns the number of parents to which the selected objects belong. */ - guint numberOfParents(); + unsigned int numberOfParents(); /** Returns the bounding rectangle of the selection. */ Geom::OptRect bounds(SPItem::BBoxType type) const; @@ -317,11 +318,11 @@ public: * @return the resulting connection * */ - sigc::connection connectModified(sigc::slot const &slot) + sigc::connection connectModified(sigc::slot const &slot) { return _modified_signal.connect(slot); } - sigc::connection connectModifiedFirst(sigc::slot const &slot) + sigc::connection connectModifiedFirst(sigc::slot const &slot) { return _modified_signal.slots().insert(_modified_signal.slots().begin(), slot); } @@ -333,12 +334,12 @@ private: void operator=(Selection const &); /** Issues modification notification signals. */ - static gboolean _emit_modified(Selection *selection); + static int _emit_modified(Selection *selection); /** Schedules an item modification signal to be sent. */ - void _schedule_modified(SPObject *obj, guint flags); + void _schedule_modified(SPObject *obj, unsigned int flags); /** Issues modified selection signal. */ - void _emitModified(guint flags); + void _emitModified(unsigned int flags); /** Issues changed selection signal. */ void _emitChanged(bool persist_selection_context = false); @@ -374,15 +375,15 @@ private: LayerModel *_layers; GC::soft_ptr _desktop; SPObject* _selection_context; - guint _flags; - guint _idle; + unsigned int _flags; + unsigned int _idle; std::map _modified_connections; std::map _release_connections; sigc::connection _context_release_connection; sigc::signal _changed_signal; - sigc::signal _modified_signal; + sigc::signal _modified_signal; }; } diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h index 740729a6e..ebd5758c8 100644 --- a/src/seltrans-handles.h +++ b/src/seltrans-handles.h @@ -14,11 +14,13 @@ #include <2geom/forward.h> #include + #include "enums.h" -namespace Inkscape -{ - class SelTrans; +typedef unsigned int guint32; + +namespace Inkscape { + class SelTrans; } guint32 const DEF_COLOR[] = { 0xff, 0xff6600, 0xff6600, 0xff, 0xff, 0xff }; @@ -34,7 +36,7 @@ enum SPSelTransType { struct SPSelTransTypeInfo { guint32 const *color; - gchar const *tip; + char const *tip; }; // One per handle type in order extern SPSelTransTypeInfo const handtypes[5]; @@ -45,7 +47,7 @@ struct SPSelTransHandle { SPSelTransType type; SPAnchorType anchor; GdkCursorType cursor; - guint control; + unsigned int control; gdouble x, y; }; // These are 4 * each handle type + 1 for center @@ -64,5 +66,3 @@ extern SPSelTransHandle const hands[17]; End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : - - diff --git a/src/seltrans.h b/src/seltrans.h index 44268ed69..d5db1542d 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -15,32 +15,33 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include #include <2geom/point.h> #include <2geom/affine.h> #include <2geom/rect.h> +#include +#include +#include + #include "knot.h" -#include "selcue.h" #include "message-context.h" -#include -#include "sp-item.h" #include "seltrans-handles.h" +#include "selcue.h" +#include "sp-item.h" + class SPKnot; class SPDesktop; struct SPCanvasItem; struct SPCtrlLine; struct SPSelTransHandle; +typedef struct _GSList GSList; -namespace Inkscape -{ +namespace Inkscape { Geom::Scale calcScaleFactors(Geom::Point const &initial_point, Geom::Point const &new_point, Geom::Point const &origin, bool const skew = false); -namespace XML -{ - class Node; +namespace XML { + class Node; } class SelTrans @@ -56,26 +57,26 @@ public: void increaseState(); void resetState(); void setCenter(Geom::Point const &p); - void grab(Geom::Point const &p, gdouble x, gdouble y, bool show_handles, bool translating); + void grab(Geom::Point const &p, double x, double y, bool show_handles, bool translating); void transform(Geom::Affine const &rel_affine, Geom::Point const &norm); void ungrab(); void stamp(); - void moveTo(Geom::Point const &xy, guint state); - void stretch(SPSelTransHandle const &handle, Geom::Point &pt, guint state); - void scale(Geom::Point &pt, guint state); - void skew(SPSelTransHandle const &handle, Geom::Point &pt, guint state); - void rotate(Geom::Point &pt, guint state); - gboolean request(SPSelTransHandle const &handle, Geom::Point &pt, guint state); - gboolean scaleRequest(Geom::Point &pt, guint state); - gboolean stretchRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); - gboolean skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, guint state); - gboolean rotateRequest(Geom::Point &pt, guint state); - gboolean centerRequest(Geom::Point &pt, guint state); - - gboolean handleRequest(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle); - void handleGrab(SPKnot *knot, guint state, SPSelTransHandle const &handle); - void handleClick(SPKnot *knot, guint state, SPSelTransHandle const &handle); - void handleNewEvent(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const &handle); + void moveTo(Geom::Point const &xy, unsigned int state); + void stretch(SPSelTransHandle const &handle, Geom::Point &pt, unsigned int state); + void scale(Geom::Point &pt, unsigned int state); + void skew(SPSelTransHandle const &handle, Geom::Point &pt, unsigned int state); + void rotate(Geom::Point &pt, unsigned int state); + int request(SPSelTransHandle const &handle, Geom::Point &pt, unsigned int state); + int scaleRequest(Geom::Point &pt, unsigned int state); + int stretchRequest(SPSelTransHandle const &handle, Geom::Point &pt, unsigned int state); + int skewRequest(SPSelTransHandle const &handle, Geom::Point &pt, unsigned int state); + int rotateRequest(Geom::Point &pt, unsigned int state); + int centerRequest(Geom::Point &pt, unsigned int state); + + int handleRequest(SPKnot *knot, Geom::Point *position, unsigned int state, SPSelTransHandle const &handle); + void handleGrab(SPKnot *knot, unsigned int state, SPSelTransHandle const &handle); + void handleClick(SPKnot *knot, unsigned int state, SPSelTransHandle const &handle); + void handleNewEvent(SPKnot *knot, Geom::Point *position, unsigned int state, SPSelTransHandle const &handle); enum Show { @@ -115,7 +116,7 @@ private: void _updateHandles(); void _updateVolatileState(); void _selChanged(Inkscape::Selection *selection); - void _selModified(Inkscape::Selection *selection, guint flags); + void _selModified(Inkscape::Selection *selection, unsigned int flags); void _boundingBoxPrefsChanged(int prefs_bbox); void _makeHandles(); void _showHandles(SPSelTransType type); @@ -156,7 +157,7 @@ private: Geom::OptRect _bbox; Geom::OptRect _visual_bbox; Geom::OptRect _geometric_bbox; - gdouble _strokewidth; + double _strokewidth; Geom::Affine _current_relative_affine; Geom::Affine _absolute_affine; @@ -173,8 +174,8 @@ private: Geom::Point _origin_for_specpoints; Geom::Point _origin_for_bboxpoints; - gdouble _handle_x; - gdouble _handle_y; + double _handle_x; + double _handle_y; boost::optional _center; bool _center_is_set; ///< we've already set _center, no need to reread it from items @@ -184,8 +185,8 @@ private: SPCanvasItem *_norm; SPCanvasItem *_grip; SPCtrlLine *_l[4]; - guint _sel_changed_id; - guint _sel_modified_id; + unsigned int _sel_changed_id; + unsigned int _sel_modified_id; GSList *_stamp_cache; Geom::Point _origin; ///< position of origin for transforms diff --git a/src/shape-editor.h b/src/shape-editor.h index df0dbfa3a..d2611b111 100644 --- a/src/shape-editor.h +++ b/src/shape-editor.h @@ -12,8 +12,6 @@ * */ -#include - namespace Inkscape { namespace XML { class Node; } } class KnotHolder; @@ -37,10 +35,10 @@ public: bool knot_mouseover() const; - static void blockSetItem(bool b) { _blockSetItem = b; } // kludge? + static void blockSetItem(bool b) { _blockSetItem = b; } // kludge - static void event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar const *name, gchar const * /*old_value*/, - gchar const * /*new_value*/, bool /*is_interactive*/, void *data); + static void event_attr_changed(Inkscape::XML::Node * /*repr*/, char const *name, char const * /*old_value*/, + char const * /*new_value*/, bool /*is_interactive*/, void *data); private: bool has_knotholder(); void reset_item (bool keep_knotholder = true); diff --git a/src/shortcuts.h b/src/shortcuts.h index 406768f97..f24a82603 100644 --- a/src/shortcuts.h +++ b/src/shortcuts.h @@ -1,5 +1,5 @@ -#ifndef __SP_SHORTCUTS_H__ -#define __SP_SHORTCUTS_H__ +#ifndef SEEN_SP_SHORTCUTS_H +#define SEEN_SP_SHORTCUTS_H /* * Keyboard shortcut processing @@ -16,9 +16,6 @@ typedef struct _GtkAccelGroup GtkAccelGroup; typedef struct _GtkWidget GtkWidget; -struct _GtkAccelGroup; -struct _GtkWidget; - namespace Inkscape { class Verb; namespace UI { @@ -42,14 +39,14 @@ bool sp_shortcut_invoke (unsigned int shortcut, Inkscape::UI::View::View *view); void sp_shortcut_init(); Inkscape::Verb * sp_shortcut_get_verb (unsigned int shortcut); unsigned int sp_shortcut_get_primary (Inkscape::Verb * verb); // Returns GDK_VoidSymbol if no shortcut is found. -gchar* sp_shortcut_get_label (unsigned int shortcut); // Returns the human readable form of the shortcut (or NULL), for example Shift+Ctrl+F. Free the returned string with g_free. +char* sp_shortcut_get_label (unsigned int shortcut); // Returns the human readable form of the shortcut (or NULL), for example Shift+Ctrl+F. Free the returned string with g_free. void sp_shortcut_set(unsigned int const shortcut, Inkscape::Verb *const verb, bool const is_primary, bool const is_user_set=false); void sp_shortcut_unset(unsigned int const shortcut); void sp_shortcut_add_to_file(char const *action, unsigned int const shortcut); void sp_shortcut_delete_from_file(char const *action, unsigned int const shortcut); void sp_shortcuts_delete_all_from_file(); Glib::ustring sp_shortcut_to_label(unsigned int const shortcut); -unsigned int sp_gdkmodifier_to_shortcut(guint accel_key, Gdk::ModifierType gdkmodifier, guint hardware_keycode); +unsigned int sp_gdkmodifier_to_shortcut(unsigned int accel_key, Gdk::ModifierType gdkmodifier, unsigned int hardware_keycode); void sp_shortcut_get_file_names(std::vector *names, std::vector *paths); bool sp_shortcut_is_user_set(Inkscape::Verb *verb); void sp_shortcut_file_export(); diff --git a/src/snap-candidate.h b/src/snap-candidate.h index 8bb7cb52f..54e33e1a8 100644 --- a/src/snap-candidate.h +++ b/src/snap-candidate.h @@ -14,7 +14,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -//#include "snapped-point.h" +#include <2geom/point.h> +#include <2geom/rect.h> +#include + #include "snap-enums.h" class SPItem; // forward declaration diff --git a/src/snap-preferences.h b/src/snap-preferences.h index a7a2e2926..7bdeea52e 100644 --- a/src/snap-preferences.h +++ b/src/snap-preferences.h @@ -49,13 +49,13 @@ public: void setSnapPerp(bool enabled) {_snap_perp = enabled;} void setSnapTang(bool enabled) {_snap_tang = enabled;} - gdouble getGridTolerance() const {return _grid_tolerance;} - gdouble getGuideTolerance() const {return _guide_tolerance;} - gdouble getObjectTolerance() const {return _object_tolerance;} + double getGridTolerance() const {return _grid_tolerance;} + double getGuideTolerance() const {return _guide_tolerance;} + double getObjectTolerance() const {return _object_tolerance;} - void setGridTolerance(gdouble val) {_grid_tolerance = val;} - void setGuideTolerance(gdouble val) {_guide_tolerance = val;} - void setObjectTolerance(gdouble val) {_object_tolerance = val;} + void setGridTolerance(double val) {_grid_tolerance = val;} + void setGuideTolerance(double val) {_guide_tolerance = val;} + void setObjectTolerance(double val) {_object_tolerance = val;} private: @@ -91,9 +91,9 @@ private: bool _snap_perp; bool _snap_tang; - gdouble _grid_tolerance; - gdouble _guide_tolerance; - gdouble _object_tolerance; + double _grid_tolerance; + double _guide_tolerance; + double _object_tolerance; }; } diff --git a/src/snap.h b/src/snap.h index 67af20063..20b2b246f 100644 --- a/src/snap.h +++ b/src/snap.h @@ -32,6 +32,7 @@ enum SPGuideDragType { // used both here and in desktop-events.cpp class SPGuide; class SPNamedView; +typedef struct _GSList GSList; /** * Class to coordinate snapping operations. diff --git a/src/snapped-curve.h b/src/snapped-curve.h index 6bb8bfeca..0e3a1c747 100644 --- a/src/snapped-curve.h +++ b/src/snapped-curve.h @@ -11,14 +11,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information. */ +#include <2geom/forward.h> #include #include + #include "snapped-point.h" #include "snapped-line.h" -#include <2geom/forward.h> -namespace Inkscape -{ +namespace Inkscape { /// Class describing the result of an attempt to snap to a curve. class SnappedCurve : public SnappedPoint diff --git a/src/snapped-point.h b/src/snapped-point.h index bf440c450..9d77ab162 100644 --- a/src/snapped-point.h +++ b/src/snapped-point.h @@ -12,10 +12,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information. */ -#include -#include #include <2geom/geom.h> -#include +#include +#include + +#include "snap-candidate.h" namespace Inkscape { diff --git a/src/snapper.h b/src/snapper.h index c609239cf..9616d0954 100644 --- a/src/snapper.h +++ b/src/snapper.h @@ -12,15 +12,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information. */ -#include -#include #include -#include // for g_assert +#include +#include +#include "snap-candidate.h" #include "snapped-point.h" #include "snapped-line.h" #include "snapped-curve.h" -#include "snap-candidate.h" struct IntermSnapResults { std::list points; @@ -86,7 +85,7 @@ public: bool hasPoint() const {return _type != DIRECTION && _type != UNDEFINED;} Geom::Point getPoint() const { - g_assert(_type != DIRECTION && _type != UNDEFINED); + assert(_type != DIRECTION && _type != UNDEFINED); return _point; } @@ -95,7 +94,7 @@ public: } Geom::Coord getRadius() const { - g_assert(_type == CIRCLE); + assert(_type == CIRCLE); return _radius; } @@ -121,7 +120,7 @@ public: Geom::Point const p2_on_cl = p1_on_cl + _direction; return Geom::projection(p, Geom::Line(p1_on_cl, p2_on_cl)); } else { - g_warning("Bug: trying to find the projection onto an undefined constraint"); + printf("WARNING: Bug: trying to find the projection onto an undefined constraint"); return Geom::Point(); } } diff --git a/src/sp-anchor.h b/src/sp-anchor.h index 778640032..d17718344 100644 --- a/src/sp-anchor.h +++ b/src/sp-anchor.h @@ -1,5 +1,5 @@ -#ifndef __SP_ANCHOR_H__ -#define __SP_ANCHOR_H__ +#ifndef SEEN_SP_ANCHOR_H +#define SEEN_SP_ANCHOR_H /* * SVG element implementation @@ -23,16 +23,16 @@ public: SPAnchor(); virtual ~SPAnchor(); - gchar *href; + char *href; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void set(unsigned int key, gchar const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char* displayName() const; - virtual gchar* description() const; - virtual gint event(SPEvent *event); + virtual char* description() const; + virtual int event(SPEvent *event); }; #endif diff --git a/src/sp-clippath.h b/src/sp-clippath.h index ba7a90a57..eb8b14174 100644 --- a/src/sp-clippath.h +++ b/src/sp-clippath.h @@ -19,6 +19,9 @@ #define SP_IS_CLIPPATH(obj) (dynamic_cast((SPObject*)obj) != NULL) struct SPClipPathView; +typedef struct _GSList GSList; + +#include #include "sp-object-group.h" #include "uri-references.h" @@ -42,8 +45,8 @@ public: unsigned int clipPathUnits : 1; SPClipPathView *display; - static const gchar *create(GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform); - static GType sp_clippath_get_type(void); + static char const *create(GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform); + //static GType sp_clippath_get_type(void); Inkscape::DrawingItem *show(Inkscape::Drawing &drawing, unsigned int key); void hide(unsigned int key); @@ -57,12 +60,12 @@ protected: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; @@ -90,10 +93,10 @@ protected: Inkscape::XML::Node * const owner_repr = owner->getRepr(); //XML Tree being used directly here while it shouldn't be... Inkscape::XML::Node * const obj_repr = obj->getRepr(); - gchar const * owner_name = NULL; - gchar const * owner_clippath = NULL; - gchar const * obj_name = NULL; - gchar const * obj_id = NULL; + char const * owner_name = NULL; + char const * owner_clippath = NULL; + char const * obj_name = NULL; + char const * obj_id = NULL; if (owner_repr != NULL) { owner_name = owner_repr->name(); owner_clippath = owner_repr->attribute("clippath"); @@ -102,7 +105,7 @@ protected: obj_name = obj_repr->name(); obj_id = obj_repr->attribute("id"); } - g_warning("Ignoring recursive clippath reference " + printf("WARNING: Ignoring recursive clippath reference " "<%s clippath=\"%s\"> in <%s id=\"%s\">", owner_name, owner_clippath, obj_name, obj_id); diff --git a/src/sp-conn-end-pair.h b/src/sp-conn-end-pair.h index 9f7f5a5d2..93f54378c 100644 --- a/src/sp-conn-end-pair.h +++ b/src/sp-conn-end-pair.h @@ -11,12 +11,10 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include -#include -#include -#include +#include +#include + #include "libavoid/connector.h" @@ -33,21 +31,21 @@ class Node; } } -extern void recreateCurve(SPCurve *curve, Avoid::ConnRef *connRef, gdouble curvature); +extern void recreateCurve(SPCurve *curve, Avoid::ConnRef *connRef, double curvature); class SPConnEndPair { public: SPConnEndPair(SPPath *); ~SPConnEndPair(); void release(); - void setAttr(unsigned const key, gchar const *const value); + void setAttr(unsigned const key, char const *const value); void writeRepr(Inkscape::XML::Node *const repr) const; void getAttachedItems(SPItem *[2]) const; void getEndpoints(Geom::Point endPts[]) const; - gdouble getCurvature(void) const; + double getCurvature(void) const; SPConnEnd** getConnEnds(void); bool isOrthogonal(void) const; - friend void recreateCurve(SPCurve *curve, Avoid::ConnRef *connRef, gdouble curvature); + friend void recreateCurve(SPCurve *curve, Avoid::ConnRef *connRef, double curvature); void tellLibavoidNewEndpoints(const bool processTransaction = false); bool reroutePathFromLibavoid(void); void makePathInvalid(void); @@ -64,7 +62,7 @@ private: Avoid::ConnRef *_connRef; int _connType; - gdouble _connCurvature; + double _connCurvature; // A sigc connection for transformed signal. sigc::connection _transformed_connection; diff --git a/src/sp-conn-end.h b/src/sp-conn-end.h index a0b1ba5df..2b89a159d 100644 --- a/src/sp-conn-end.h +++ b/src/sp-conn-end.h @@ -1,8 +1,7 @@ #ifndef SEEN_SP_CONN_END #define SEEN_SP_CONN_END -#include -#include +#include #include #include "sp-use-reference.h" @@ -15,7 +14,7 @@ public: SPConnEnd(SPObject *owner); SPUseReference ref; - gchar *href; + char *href; /** Change of href string (not a modification of the attributes of the referrent). */ sigc::connection _changed_connection; @@ -29,13 +28,13 @@ public: /** A sigc connection for owning group transformed, used to do move compensation. */ sigc::connection _group_connection; - void setAttacherHref(gchar const *, SPPath *); - void setAttacherEndpoint(gchar const *, SPPath *); + void setAttacherHref(char const * value, SPPath * unused); + //void setAttacherEndpoint(char const *, SPPath *); // not defined private: - SPConnEnd(SPConnEnd const &); - SPConnEnd &operator=(SPConnEnd const &); + SPConnEnd(SPConnEnd const &); // no copy + SPConnEnd &operator=(SPConnEnd const &); // no assign }; void sp_conn_end_href_changed(SPObject *old_ref, SPObject *ref, diff --git a/src/sp-cursor.cpp b/src/sp-cursor.cpp index ea73da00c..16659d1cf 100644 --- a/src/sp-cursor.cpp +++ b/src/sp-cursor.cpp @@ -17,13 +17,14 @@ */ #include +#include #include #include #include "color.h" #include "sp-cursor.h" -static void free_cursor_data(guchar *pixels, gpointer /*data*/) { +static void free_cursor_data(unsigned char *pixels, void* /*data*/) { delete [] reinterpret_cast(pixels); } @@ -53,7 +54,7 @@ struct RGBA { } }; -GdkPixbuf *sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke) +GdkPixbuf *sp_cursor_pixbuf_from_xpm(char const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke) { int height = 0; int width = 0; @@ -72,7 +73,7 @@ GdkPixbuf *sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& bl char const *p = xpm[1 + i]; g_assert(*p >=0); - guchar const ccode = (guchar) *p; + unsigned char const ccode = (guchar) *p; p++; while (isspace(*p)) { @@ -110,7 +111,7 @@ GdkPixbuf *sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& bl return gdk_pixbuf_new_from_data(reinterpret_cast(pixmap_buffer), GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * sizeof(guint32), free_cursor_data, NULL); } -GdkCursor *sp_cursor_new_from_xpm(gchar const *const *xpm, gint hot_x, gint hot_y) +GdkCursor *sp_cursor_new_from_xpm(char const *const *xpm, int hot_x, int hot_y) { GdkCursor *cursor = 0; GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)xpm); diff --git a/src/sp-cursor.h b/src/sp-cursor.h index f445127ad..c0b8b46a3 100644 --- a/src/sp-cursor.h +++ b/src/sp-cursor.h @@ -1,10 +1,13 @@ #ifndef SP_CURSOR_H #define SP_CURSOR_H -#include +typedef unsigned int guint32; +typedef struct _GdkPixbuf GdkPixbuf; +typedef struct _GdkCursor GdkCursor; +typedef struct _GdkColor GdkColor; -GdkPixbuf* sp_cursor_pixbuf_from_xpm(gchar const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke); -GdkCursor *sp_cursor_new_from_xpm(gchar const *const *xpm, gint hot_x, gint hot_y); +GdkPixbuf* sp_cursor_pixbuf_from_xpm(char const *const *xpm, GdkColor const& black, GdkColor const& white, guint32 fill, guint32 stroke); +GdkCursor *sp_cursor_new_from_xpm(char const *const *xpm, int hot_x, int hot_y); #endif diff --git a/src/sp-defs.h b/src/sp-defs.h index 6efdea1f3..c122cb2a9 100644 --- a/src/sp-defs.h +++ b/src/sp-defs.h @@ -27,7 +27,7 @@ protected: virtual void release(); virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; #endif // !SEEN_SP_DEFS_H diff --git a/src/sp-desc.h b/src/sp-desc.h index 2bb42b333..40888bee4 100644 --- a/src/sp-desc.h +++ b/src/sp-desc.h @@ -1,5 +1,5 @@ -#ifndef __SP_DESC_H__ -#define __SP_DESC_H__ +#ifndef SEEN_SP_DESC_H +#define SEEN_SP_DESC_H /* * SVG implementation @@ -23,7 +23,7 @@ public: virtual ~SPDesc(); protected: - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; #endif diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h index e575b8761..09768fd6d 100644 --- a/src/sp-ellipse.h +++ b/src/sp-ellipse.h @@ -24,7 +24,7 @@ #define SP_IS_GENERICELLIPSE(obj) (dynamic_cast((obj)) != NULL) enum GenericEllipseType { - SP_GENERIC_ELLIPSE_UNDEFINED, + SP_GENERIC_ELLIPSE_UNDEFINED, // FIXME shouldn't exist SP_GENERIC_ELLIPSE_ARC, SP_GENERIC_ELLIPSE_CIRCLE, SP_GENERIC_ELLIPSE_ELLIPSE @@ -53,10 +53,10 @@ public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void set(unsigned int key, gchar const *value); + virtual void set(unsigned int key, char const *value); virtual void update(SPCtx *ctx, unsigned int flags); - virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node *write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char *displayName() const; virtual void set_shape(); @@ -76,7 +76,7 @@ public: Geom::Point getPointAtAngle(double arg) const; bool set_elliptical_path_attribute(Inkscape::XML::Node *repr); - void position_set(gdouble x, gdouble y, gdouble rx, gdouble ry); + void position_set(double x, double y, double rx, double ry); protected: /** diff --git a/src/sp-filter-primitive.h b/src/sp-filter-primitive.h index 040e2f31f..d81adbd10 100644 --- a/src/sp-filter-primitive.h +++ b/src/sp-filter-primitive.h @@ -1,5 +1,5 @@ -#ifndef __SP_FILTER_PRIMITIVE_H__ -#define __SP_FILTER_PRIMITIVE_H__ +#ifndef SEEN_SP_FILTER_PRIMITIVE_H +#define SEEN_SP_FILTER_PRIMITIVE_H /** \file * Document level base class for all SVG filter primitives. @@ -40,11 +40,11 @@ protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); public: virtual void build_renderer(Inkscape::Filters::Filter* filter) = 0; @@ -54,8 +54,8 @@ public: void sp_filter_primitive_renderer_common(SPFilterPrimitive *sp_prim, Inkscape::Filters::FilterPrimitive *nr_prim); int sp_filter_primitive_name_previous_out(SPFilterPrimitive *prim); -int sp_filter_primitive_read_in(SPFilterPrimitive *prim, gchar const *name); -int sp_filter_primitive_read_result(SPFilterPrimitive *prim, gchar const *name); +int sp_filter_primitive_read_in(SPFilterPrimitive *prim, char const *name); +int sp_filter_primitive_read_result(SPFilterPrimitive *prim, char const *name); #endif /* diff --git a/src/sp-filter.h b/src/sp-filter.h index 0d087c5bf..e6318c569 100644 --- a/src/sp-filter.h +++ b/src/sp-filter.h @@ -12,6 +12,7 @@ #ifndef SP_FILTER_H_SEEN #define SP_FILTER_H_SEEN +#include #include #include "number-opt-number.h" @@ -19,8 +20,6 @@ #include "sp-filter-units.h" #include "svg/svg-length.h" -#include - #define SP_FILTER(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_FILTER(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -45,9 +44,9 @@ public: virtual ~SPFilter(); SPFilterUnits filterUnits; - guint filterUnits_set : 1; + unsigned int filterUnits_set : 1; SPFilterUnits primitiveUnits; - guint primitiveUnits_set : 1; + unsigned int primitiveUnits_set : 1; SVGLength x; SVGLength y; SVGLength width; @@ -68,11 +67,11 @@ protected: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); virtual void remove_child(Inkscape::XML::Node* child); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; void sp_filter_set_filter_units(SPFilter *filter, SPFilterUnits filterUnits); @@ -88,14 +87,14 @@ void sp_filter_build_renderer(SPFilter *sp_filter, Inkscape::Filters::Filter *nr int sp_filter_primitive_count(SPFilter *filter); /// Returns a slot number for given image name, or -1 for unknown name. -int sp_filter_get_image_name(SPFilter *filter, gchar const *name); +int sp_filter_get_image_name(SPFilter *filter, char const *name); /// Returns slot number for given image name, even if it's unknown. -int sp_filter_set_image_name(SPFilter *filter, gchar const *name); +int sp_filter_set_image_name(SPFilter *filter, char const *name); /** Finds image name based on it's slot number. Returns 0 for unknown slot * numbers. */ -gchar const *sp_filter_name_for_image(SPFilter const *filter, int const image); +char const *sp_filter_name_for_image(SPFilter const *filter, int const image); /// Returns a result image name that is not in use inside this filter. Glib::ustring sp_filter_get_new_result_name(SPFilter *filter); diff --git a/src/sp-flowdiv.h b/src/sp-flowdiv.h index d00cfc51b..4a3690726 100644 --- a/src/sp-flowdiv.h +++ b/src/sp-flowdiv.h @@ -1,5 +1,5 @@ -#ifndef __SP_ITEM_FLOWDIV_H__ -#define __SP_ITEM_FLOWDIV_H__ +#ifndef SEEN_SP_ITEM_FLOWDIV_H +#define SEEN_SP_ITEM_FLOWDIV_H /* */ @@ -31,11 +31,11 @@ public: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void update(SPCtx* ctx, guint flags); + virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual void set(unsigned int key, gchar const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; class SPFlowtspan : public SPItem { @@ -46,11 +46,11 @@ public: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void update(SPCtx* ctx, guint flags); + virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual void set(unsigned int key, gchar const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; class SPFlowpara : public SPItem { @@ -61,11 +61,11 @@ public: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void update(SPCtx* ctx, guint flags); + virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual void set(unsigned int key, gchar const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; // these do not need any style @@ -78,7 +78,7 @@ protected: virtual void release(); virtual void modified(unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; class SPFlowregionbreak : public SPObject { @@ -90,7 +90,7 @@ protected: virtual void release(); virtual void modified(unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; #endif diff --git a/src/sp-flowregion.h b/src/sp-flowregion.h index 721eb0432..024a298b8 100644 --- a/src/sp-flowregion.h +++ b/src/sp-flowregion.h @@ -1,5 +1,5 @@ -#ifndef __SP_ITEM_FLOWREGION_H__ -#define __SP_ITEM_FLOWREGION_H__ +#ifndef SEEN_SP_ITEM_FLOWREGION_H +#define SEEN_SP_ITEM_FLOWREGION_H /* */ @@ -30,7 +30,7 @@ public: virtual void remove_child(Inkscape::XML::Node *child); virtual void update(SPCtx *ctx, unsigned int flags); virtual void modified(guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char* displayName() const; }; @@ -47,7 +47,7 @@ public: virtual void remove_child(Inkscape::XML::Node *child); virtual void update(SPCtx *ctx, unsigned int flags); virtual void modified(guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char* displayName() const; }; diff --git a/src/sp-flowtext.h b/src/sp-flowtext.h index a5b7db22e..743d55030 100644 --- a/src/sp-flowtext.h +++ b/src/sp-flowtext.h @@ -4,10 +4,10 @@ /* */ -#include "sp-item.h" - #include <2geom/forward.h> + #include "libnrtype/Layout-TNG.h" +#include "sp-item.h" #define SP_FLOWTEXT(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_FLOWTEXT(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -63,18 +63,18 @@ public: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); virtual void remove_child(Inkscape::XML::Node* child); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); virtual Geom::Affine set_transform(Geom::Affine const& xform); virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type) const; virtual void print(SPPrintContext *ctx); virtual const char* displayName() const; - virtual gchar* description() const; + virtual char* description() const; virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void hide(unsigned int key); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; diff --git a/src/sp-font-face.h b/src/sp-font-face.h index 531dd5843..669b93197 100644 --- a/src/sp-font-face.h +++ b/src/sp-font-face.h @@ -1,9 +1,5 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef __SP_FONTFACE_H__ -#define __SP_FONTFACE_H__ +#ifndef SEEN_SP_FONTFACE_H +#define SEEN_SP_FONTFACE_H #include @@ -117,11 +113,11 @@ protected: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); virtual void remove_child(Inkscape::XML::Node* child); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; #endif //#ifndef __SP_FONTFACE_H__ diff --git a/src/sp-font.h b/src/sp-font.h index 6e6f4eec2..6e26a02b2 100644 --- a/src/sp-font.h +++ b/src/sp-font.h @@ -1,7 +1,3 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - #ifndef SP_FONT_H_SEEN #define SP_FONT_H_SEEN @@ -40,11 +36,11 @@ protected: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); virtual void remove_child(Inkscape::XML::Node* child); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; #endif //#ifndef SP_FONT_H_SEEN diff --git a/src/sp-glyph-kerning.h b/src/sp-glyph-kerning.h index 52413f8a7..c96c0b6e4 100644 --- a/src/sp-glyph-kerning.h +++ b/src/sp-glyph-kerning.h @@ -25,11 +25,11 @@ class GlyphNames { public: - GlyphNames(const gchar* value); + GlyphNames(char const* value); ~GlyphNames(); - bool contains(const char* name); + bool contains(char const* name); private: - gchar* names; + char* names; }; class SPGlyphKerning : public SPObject { @@ -47,9 +47,9 @@ public: protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; class SPHkern : public SPGlyphKerning { diff --git a/src/sp-glyph.h b/src/sp-glyph.h index e92357c94..297ac930e 100644 --- a/src/sp-glyph.h +++ b/src/sp-glyph.h @@ -52,9 +52,9 @@ public: protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; diff --git a/src/sp-gradient-vector.h b/src/sp-gradient-vector.h index 8e860c169..e57820b56 100644 --- a/src/sp-gradient-vector.h +++ b/src/sp-gradient-vector.h @@ -1,7 +1,6 @@ #ifndef SEEN_SP_GRADIENT_VECTOR_H #define SEEN_SP_GRADIENT_VECTOR_H -#include #include #include "color.h" @@ -14,9 +13,9 @@ * copying from SPStop to SPGradientStop. */ struct SPGradientStop { - gdouble offset; + double offset; SPColor color; - gfloat opacity; + float opacity; }; /** diff --git a/src/sp-gradient.h b/src/sp-gradient.h index a14dcc09e..fbb48df62 100644 --- a/src/sp-gradient.h +++ b/src/sp-gradient.h @@ -14,29 +14,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include -#include #include <2geom/affine.h> +#include +#include +#include +#include + #include "sp-paint-server.h" #include "sp-gradient-spread.h" #include "sp-gradient-units.h" #include "sp-gradient-vector.h" #include "sp-mesh-array.h" -#include -#include - - - -//#include -//#include -//#include <2geom/forward.h> -//#include "sp-gradient-spread.h" -//#include "sp-gradient-units.h" -// -//class SPGradient; -//struct SPMeshGradient; - class SPGradientReference; class SPStop; diff --git a/src/sp-guide.h b/src/sp-guide.h index 9f5d7ba03..cd67df222 100644 --- a/src/sp-guide.h +++ b/src/sp-guide.h @@ -13,9 +13,9 @@ * */ +#include <2geom/point.h> #include -#include <2geom/point.h> #include "sp-object.h" #include "sp-guide-attachment.h" diff --git a/src/sp-image.h b/src/sp-image.h index 17262d74f..9fa33b5de 100644 --- a/src/sp-image.h +++ b/src/sp-image.h @@ -14,7 +14,6 @@ #ifndef SEEN_INKSCAPE_SP_IMAGE_H #define SEEN_INKSCAPE_SP_IMAGE_H -#include #include #include "svg/svg-length.h" #include "display/curve.h" @@ -43,24 +42,24 @@ public: SPCurve *curve; // This curve is at the image's boundary for snapping - gchar *href; + char *href; #if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - gchar *color_profile; + char *color_profile; #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) Inkscape::Pixbuf *pixbuf; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void set(unsigned int key, gchar const* value); - virtual void update(SPCtx *ctx, guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual void update(SPCtx *ctx, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual void modified(unsigned int flags); virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type) const; virtual void print(SPPrintContext *ctx); virtual const char* displayName() const; - virtual gchar* description() const; + virtual char* description() const; virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual Geom::Affine set_transform(Geom::Affine const &transform); diff --git a/src/sp-item-group.h b/src/sp-item-group.h index 2004a72b8..4e15ee5df 100644 --- a/src/sp-item-group.h +++ b/src/sp-item-group.h @@ -1,5 +1,5 @@ -#ifndef __SP_ITEM_GROUP_H__ -#define __SP_ITEM_GROUP_H__ +#ifndef SEEN_SP_ITEM_GROUP_H +#define SEEN_SP_ITEM_GROUP_H /* * SVG implementation @@ -25,6 +25,7 @@ namespace Inkscape { class Drawing; class DrawingItem; +typedef struct _GSList GSList; } // namespace Inkscape @@ -54,7 +55,7 @@ public: void translateChildItems(Geom::Translate const &tr); void scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p); - gint getItemCount() const; + int getItemCount() const; virtual void _showChildren (Inkscape::Drawing &drawing, Inkscape::DrawingItem *ai, unsigned int key, unsigned int flags); private: @@ -69,15 +70,15 @@ public: virtual void order_changed(Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref); virtual void update(SPCtx *ctx, unsigned int flags); - virtual void modified(guint flags); - virtual void set(unsigned int key, gchar const* value); + virtual void modified(unsigned int flags); + virtual void set(unsigned int key, char const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType bboxtype) const; virtual void print(SPPrintContext *ctx); virtual const char* displayName() const; - virtual gchar *description() const; + virtual char *description() const; virtual Inkscape::DrawingItem *show (Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void hide (unsigned int key); @@ -90,7 +91,7 @@ void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = tr GSList *sp_item_group_item_list (SPGroup *group); -SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name); +SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const char *name); #endif diff --git a/src/sp-item-notify-moveto.cpp b/src/sp-item-notify-moveto.cpp index 0f5117289..90fd676ee 100644 --- a/src/sp-item-notify-moveto.cpp +++ b/src/sp-item-notify-moveto.cpp @@ -9,6 +9,7 @@ #include using std::vector; +#define return_if_fail(test) if (!(test)) { printf("WARNING: assertion '%s' failed", #test); return; } /** * Called by sp_guide_moveto to indicate that the guide line corresponding to g has been moved, and @@ -19,15 +20,15 @@ using std::vector; void sp_item_notify_moveto(SPItem &item, SPGuide const &mv_g, int const snappoint_ix, double const position, bool const commit) { - g_return_if_fail(SP_IS_ITEM(&item)); - g_return_if_fail( unsigned(snappoint_ix) < 8 ); + return_if_fail(SP_IS_ITEM(&item)); + return_if_fail( unsigned(snappoint_ix) < 8 ); Geom::Point const dir( mv_g.normal_to_line ); double const dir_lensq(dot(dir, dir)); - g_return_if_fail( dir_lensq != 0 ); + return_if_fail( dir_lensq != 0 ); std::vector snappoints; item.getSnappoints(snappoints, NULL); - g_return_if_fail( snappoint_ix < int(snappoints.size()) ); + return_if_fail( snappoint_ix < int(snappoints.size()) ); double const pos0 = dot(dir, snappoints[snappoint_ix].getPoint()); /// \todo effic: skip if mv_g is already satisfied. diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp index 086da56ff..86beee907 100644 --- a/src/sp-item-transform.cpp +++ b/src/sp-item-transform.cpp @@ -18,6 +18,8 @@ #include "sp-item.h" #include "sp-item-transform.h" +#include + void sp_item_rotate_rel(SPItem *item, Geom::Rotate const &rotation) { Geom::Point center = item->getCenter(); diff --git a/src/sp-item-transform.h b/src/sp-item-transform.h index 230d5a3dd..d563c9768 100644 --- a/src/sp-item-transform.h +++ b/src/sp-item-transform.h @@ -1,9 +1,8 @@ #ifndef SEEN_SP_ITEM_TRANSFORM_H #define SEEN_SP_ITEM_TRANSFORM_H -#include - #include <2geom/forward.h> + class SPItem; void sp_item_rotate_rel(SPItem *item, Geom::Rotate const &rotation); @@ -11,9 +10,9 @@ void sp_item_scale_rel (SPItem *item, Geom::Scale const &scale); void sp_item_skew_rel (SPItem *item, double skewX, double skewY); void sp_item_move_rel(SPItem *item, Geom::Translate const &tr); -Geom::Affine get_scale_transform_for_uniform_stroke (Geom::Rect const &bbox_visual, gdouble stroke_x, gdouble stroke_y, bool transform_stroke, bool preserve, gdouble x0, gdouble y0, gdouble x1, gdouble y1); -Geom::Affine get_scale_transform_for_variable_stroke (Geom::Rect const &bbox_visual, Geom::Rect const &bbox_geom, bool transform_stroke, bool preserve, gdouble x0, gdouble y0, gdouble x1, gdouble y1); -Geom::Rect get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Affine const &abs_affine, gdouble const initial_strokewidth, bool const transform_stroke); +Geom::Affine get_scale_transform_for_uniform_stroke (Geom::Rect const &bbox_visual, double stroke_x, double stroke_y, bool transform_stroke, bool preserve, double x0, double y0, double x1, double y1); +Geom::Affine get_scale_transform_for_variable_stroke (Geom::Rect const &bbox_visual, Geom::Rect const &bbox_geom, bool transform_stroke, bool preserve, double x0, double y0, double x1, double y1); +Geom::Rect get_visual_bbox (Geom::OptRect const &initial_geom_bbox, Geom::Affine const &abs_affine, double const initial_strokewidth, bool const transform_stroke); #endif // SEEN_SP_ITEM_TRANSFORM_H diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 428f9555e..c79508199 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -360,7 +360,7 @@ void SPItem::lowerToBottom() { * \param target - the SPItem to move into or after * \param intoafter - move to after the target (false), move inside (sublayer) of the target (true) */ -void SPItem::moveTo(SPItem *target, gboolean intoafter) { +void SPItem::moveTo(SPItem *target, bool intoafter) { Inkscape::XML::Node *target_ref = ( target ? target->getRepr() : NULL ); Inkscape::XML::Node *our_ref = getRepr(); diff --git a/src/sp-item.h b/src/sp-item.h index 15784d041..197d33263 100644 --- a/src/sp-item.h +++ b/src/sp-item.h @@ -18,10 +18,11 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ -#include + #include <2geom/forward.h> #include <2geom/affine.h> #include <2geom/rect.h> +#include #include "sp-object.h" #include "snap-preferences.h" @@ -72,7 +73,7 @@ enum PatternTransform { class SPEvent { public: unsigned int type; - gpointer data; + void* data; }; /// SPItemView @@ -179,7 +180,7 @@ public: void lowerOne(); void raiseToTop(); void lowerToBottom(); - void moveTo(SPItem *target, gboolean intoafter); + void moveTo(SPItem *target, bool intoafter); sigc::connection connectTransformed(sigc::slot slot) { return _transformed_signal.connect(slot); @@ -198,7 +199,7 @@ public: unsigned int pos_in_parent() const; - gchar *detailedDescription() const; + char *detailedDescription() const; bool isFiltered() const; @@ -209,14 +210,14 @@ public: void getSnappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs=0) const; void adjust_pattern(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false, PatternTransform = TRANSFORM_BOTH); void adjust_gradient(/* Geom::Affine const &premul, */ Geom::Affine const &postmul, bool set = false); - void adjust_stroke(gdouble ex); - void adjust_stroke_width_recursive(gdouble ex); + void adjust_stroke(double ex); + void adjust_stroke_width_recursive(double ex); void freeze_stroke_width_recursive(bool freeze); void adjust_paint_recursive(Geom::Affine advertized_transform, Geom::Affine t_ancestors, bool is_pattern); void adjust_livepatheffect(Geom::Affine const &postmul, bool set = false); void doWriteTransform(Inkscape::XML::Node *repr, Geom::Affine const &transform, Geom::Affine const *adv = NULL, bool compensate = true); void set_item_transform(Geom::Affine const &transform_matrix); - gint emitEvent (SPEvent &event); + int emitEvent (SPEvent &event); Inkscape::DrawingItem *get_arenaitem(unsigned int key); Geom::Affine i2doc_affine() const; @@ -240,14 +241,14 @@ private: public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void set(unsigned int key, gchar const* value); - virtual void update(SPCtx *ctx, guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual void update(SPCtx *ctx, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual Geom::OptRect bbox(Geom::Affine const &transform, SPItem::BBoxType type) const; virtual void print(SPPrintContext *ctx); virtual const char* displayName() const; - virtual gchar* description() const; + virtual char* description() const; virtual Inkscape::DrawingItem* show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags); virtual void hide(unsigned int key); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; @@ -255,7 +256,7 @@ public: virtual void convert_to_guides() const; - virtual gint event(SPEvent *event); + virtual int event(SPEvent *event); }; diff --git a/src/sp-line.h b/src/sp-line.h index c1932d3ee..d6a075659 100644 --- a/src/sp-line.h +++ b/src/sp-line.h @@ -31,13 +31,13 @@ public: SVGLength y2; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual void set(unsigned int key, gchar const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); + virtual void set(unsigned int key, char const* value); virtual const char* displayName() const; virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides() const; - virtual void update(SPCtx* ctx, guint flags); + virtual void update(SPCtx* ctx, unsigned int flags); virtual void set_shape(); }; diff --git a/src/sp-linear-gradient.cpp b/src/sp-linear-gradient.cpp index 959e8d733..6e9f5e6dd 100644 --- a/src/sp-linear-gradient.cpp +++ b/src/sp-linear-gradient.cpp @@ -1,3 +1,5 @@ +#include + #include "sp-linear-gradient.h" #include "attributes.h" diff --git a/src/sp-linear-gradient.h b/src/sp-linear-gradient.h index ac3fdb04a..a152e7fe2 100644 --- a/src/sp-linear-gradient.h +++ b/src/sp-linear-gradient.h @@ -26,8 +26,8 @@ public: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void set(unsigned key, gchar const *value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned key, char const *value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; #endif /* !SP_LINEAR_GRADIENT_H */ diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 3e858748d..fbac467fd 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -14,14 +14,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "sp-item.h" - #include +#include "sp-item.h" #define SP_LPE_ITEM(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_LPE_ITEM(obj) (dynamic_cast((SPObject*)obj) != NULL) -class CLPEItem; class LivePathEffectObject; class SPCurve; class SPDesktop; @@ -58,7 +56,7 @@ public: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, gchar const* value); + virtual void set(unsigned int key, char const* value); virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); @@ -66,7 +64,7 @@ public: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); virtual void remove_child(Inkscape::XML::Node* child); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual void update_patheffect(bool write); @@ -90,7 +88,7 @@ public: bool setCurrentPathEffect(Inkscape::LivePathEffect::LPEObjectReference* lperef); void removeCurrentPathEffect(bool keep_paths); void removeAllPathEffects(bool keep_paths); - void addPathEffect(gchar *value, bool reset); + void addPathEffect(char *value, bool reset); void addPathEffect(LivePathEffectObject * new_lpeobj); bool forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users = 1); diff --git a/src/sp-mask.h b/src/sp-mask.h index e08d1e81e..e991fedb6 100644 --- a/src/sp-mask.h +++ b/src/sp-mask.h @@ -55,12 +55,12 @@ protected: virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); virtual void update(SPCtx* ctx, unsigned int flags); virtual void modified(unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; class SPMaskReference : public Inkscape::URIReference { @@ -86,10 +86,10 @@ protected: Inkscape::XML::Node * const owner_repr = owner->getRepr(); //XML Tree being used directly here while it shouldn't be... Inkscape::XML::Node * const obj_repr = obj->getRepr(); - gchar const * owner_name = NULL; - gchar const * owner_mask = NULL; - gchar const * obj_name = NULL; - gchar const * obj_id = NULL; + char const * owner_name = NULL; + char const * owner_mask = NULL; + char const * obj_name = NULL; + char const * obj_id = NULL; if (owner_repr != NULL) { owner_name = owner_repr->name(); owner_mask = owner_repr->attribute("mask"); @@ -98,7 +98,7 @@ protected: obj_name = obj_repr->name(); obj_id = obj_repr->attribute("id"); } - g_warning("Ignoring recursive mask reference " + printf("WARNING: Ignoring recursive mask reference " "<%s mask=\"%s\"> in <%s id=\"%s\">", owner_name, owner_mask, obj_name, obj_id); @@ -108,6 +108,6 @@ protected: } }; -const gchar *sp_mask_create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform); +const char *sp_mask_create (GSList *reprs, SPDocument *document, Geom::Affine const* applyTransform); #endif // SEEN_SP_MASK_H diff --git a/src/sp-mesh-array.h b/src/sp-mesh-array.h index b10974e7e..330f6d87b 100644 --- a/src/sp-mesh-array.h +++ b/src/sp-mesh-array.h @@ -39,8 +39,6 @@ an array which simplifies things like inserting new rows or columns. */ -#include -#include #include <2geom/point.h> #include "color.h" @@ -89,13 +87,13 @@ public: opacity = 0.0; } NodeType node_type; - guint node_edge; + unsigned int node_edge; bool set; Geom::Point p; - guint draggable; // index of on-screen node - gchar path_type; + unsigned int draggable; // index of on-screen node + char path_type; SPColor color; - gdouble opacity; + double opacity; }; @@ -110,21 +108,21 @@ private: public: SPMeshPatchI( std::vector > *n, int r, int c ); - Geom::Point getPoint( guint side, guint point ); - std::vector< Geom::Point > getPointsForSide( guint i ); - void setPoint( guint side, guint point, Geom::Point p, bool set = true ); - gchar getPathType( guint i ); - void setPathType( guint, gchar t ); - Geom::Point getTensorPoint( guint i ); - void setTensorPoint( guint i, Geom::Point p ); + Geom::Point getPoint( unsigned int side, unsigned int point ); + std::vector< Geom::Point > getPointsForSide( unsigned int i ); + void setPoint( unsigned int side, unsigned int point, Geom::Point p, bool set = true ); + char getPathType( unsigned int i ); + void setPathType( unsigned int, char t ); + Geom::Point getTensorPoint( unsigned int i ); + void setTensorPoint( unsigned int i, Geom::Point p ); bool tensorIsSet(); - bool tensorIsSet( guint i ); - Geom::Point coonsTensorPoint( guint i ); + bool tensorIsSet( unsigned int i ); + Geom::Point coonsTensorPoint( unsigned int i ); void updateNodes(); - SPColor getColor( guint i ); - void setColor( guint i, SPColor c ); - gdouble getOpacity( guint i ); - void setOpacity( guint i, gdouble o ); + SPColor getColor( unsigned int i ); + void setColor( unsigned int i, SPColor c ); + double getOpacity( unsigned int i ); + void setOpacity( unsigned int i, double o ); }; class SPMeshGradient; @@ -160,26 +158,26 @@ public: void print(); // Get size of patch - guint patch_rows(); - guint patch_columns(); + unsigned int patch_rows(); + unsigned int patch_columns(); - SPMeshNode * node( guint i, guint j ) { return nodes[i][j]; } + SPMeshNode * node( unsigned int i, unsigned int j ) { return nodes[i][j]; } // Operations on corners - bool adjacent_corners( guint i, guint j, SPMeshNode* n[4] ); - guint side_toggle( std::vector< guint > ); - guint side_arc( std::vector< guint > ); - guint tensor_toggle( std::vector< guint > ); - guint color_smooth( std::vector< guint > ); - guint color_pick( std::vector< guint >, SPItem* ); + bool adjacent_corners( unsigned int i, unsigned int j, SPMeshNode* n[4] ); + unsigned int side_toggle( std::vector< unsigned int > ); + unsigned int side_arc( std::vector< unsigned int > ); + unsigned int tensor_toggle( std::vector< unsigned int > ); + unsigned int color_smooth( std::vector< unsigned int > ); + unsigned int color_pick( std::vector< unsigned int >, SPItem* ); // Update other nodes in response to a node move. - void update_handles( guint corner, std::vector< guint > selected_corners, Geom::Point old_p, MeshNodeOperation op ); + void update_handles( unsigned int corner, std::vector< unsigned int > selected_corners, Geom::Point old_p, MeshNodeOperation op ); - void split_row( guint i, guint n ); - void split_column( guint j, guint n ); - void split_row( guint i, double coord ); - void split_column( guint j, double coord ); + void split_row( unsigned int i, unsigned int n ); + void split_column( unsigned int j, unsigned int n ); + void split_row( unsigned int i, double coord ); + void split_column( unsigned int j, double coord ); }; #endif /* !SEEN_SP_MESH_ARRAY_H */ diff --git a/src/sp-mesh-gradient.h b/src/sp-mesh-gradient.h index 0b570c4dd..4df753f62 100644 --- a/src/sp-mesh-gradient.h +++ b/src/sp-mesh-gradient.h @@ -24,8 +24,8 @@ public: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void set(unsigned key, gchar const *value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned key, char const *value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; #endif /* !SP_MESH_GRADIENT_H */ diff --git a/src/sp-mesh-patch.h b/src/sp-mesh-patch.h index ddade6503..e57ad1699 100644 --- a/src/sp-mesh-patch.h +++ b/src/sp-mesh-patch.h @@ -12,9 +12,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include -//#include "svg/svg-length.h" #include "sp-object.h" #define SP_MESHPATCH(obj) (dynamic_cast((SPObject*)obj)) @@ -34,8 +32,8 @@ public: protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void set(unsigned int key, const gchar* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual void set(unsigned int key, const char* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; #endif /* !SEEN_SP_MESHPATCH_H */ diff --git a/src/sp-mesh-row.h b/src/sp-mesh-row.h index e39bdc631..793b5a645 100644 --- a/src/sp-mesh-row.h +++ b/src/sp-mesh-row.h @@ -11,7 +11,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include "sp-object.h" #define SP_MESHROW(obj) (dynamic_cast((SPObject*)obj)) @@ -28,8 +27,8 @@ public: protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void set(unsigned int key, const gchar* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual void set(unsigned int key, const char* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; #endif /* !SEEN_SP_MESHROW_H */ diff --git a/src/sp-metadata.h b/src/sp-metadata.h index 2a9d58e11..a89020390 100644 --- a/src/sp-metadata.h +++ b/src/sp-metadata.h @@ -1,5 +1,5 @@ -#ifndef __SP_METADATA_H__ -#define __SP_METADATA_H__ +#ifndef SEEN_SP_METADATA_H +#define SEEN_SP_METADATA_H /* * SVG implementation @@ -14,7 +14,6 @@ #include "sp-object.h" - /* Metadata base class */ #define SP_METADATA(obj) (dynamic_cast((SPObject*)obj)) @@ -29,9 +28,9 @@ protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, const char* value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; SPMetadata * sp_document_metadata (SPDocument *document); diff --git a/src/sp-missing-glyph.h b/src/sp-missing-glyph.h index a72ed0e99..06bc92231 100644 --- a/src/sp-missing-glyph.h +++ b/src/sp-missing-glyph.h @@ -1,9 +1,5 @@ -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef __SP_MISSING_GLYPH_H__ -#define __SP_MISSING_GLYPH_H__ +#ifndef SEEN_SP_MISSING_GLYPH_H +#define SEEN_SP_MISSING_GLYPH_H /* * SVG element implementation @@ -31,8 +27,8 @@ public: protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); private: double horiz_adv_x; diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index a01ba891e..1d9fa06a3 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -935,7 +935,7 @@ void SPNamedView::hide(SPDesktop const *desktop) views = g_slist_remove(views, desktop); } -void SPNamedView::activateGuides(gpointer desktop, gboolean active) +void SPNamedView::activateGuides(void* desktop, bool active) { g_assert(desktop != NULL); g_assert(g_slist_find(views, desktop)); diff --git a/src/sp-namedview.h b/src/sp-namedview.h index 05cbcc398..37310dc76 100644 --- a/src/sp-namedview.h +++ b/src/sp-namedview.h @@ -29,6 +29,9 @@ namespace Inkscape { } } +typedef unsigned int guint32; +typedef guint32 GQuark; + enum { SP_BORDER_LAYER_BOTTOM, SP_BORDER_LAYER_TOP @@ -48,11 +51,11 @@ public: double zoom; double cx; double cy; - gint window_width; - gint window_height; - gint window_x; - gint window_y; - gint window_maximized; + int window_width; + int window_height; + int window_x; + int window_y; + int window_maximized; SnapManager snap_manager; GSList * grids; @@ -74,13 +77,13 @@ public: GSList *guides; GSList *views; - gint viewcount; + int viewcount; void show(SPDesktop *desktop); void hide(SPDesktop const *desktop); - void activateGuides(gpointer desktop, gboolean active); - gchar const *getName() const; - guint getViewCount(); + void activateGuides(void* desktop, bool active); + char const *getName() const; + unsigned int getViewCount(); GSList const *getViewList() const; Inkscape::Util::Unit const * getDefaultUnit() const; @@ -100,17 +103,17 @@ private: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void set(unsigned int key, gchar const* value); + virtual void set(unsigned int key, char const* value); virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); virtual void remove_child(Inkscape::XML::Node* child); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; -SPNamedView *sp_document_namedview(SPDocument *document, gchar const *name); -SPNamedView const *sp_document_namedview(SPDocument const *document, gchar const *name); +SPNamedView *sp_document_namedview(SPDocument *document, char const *name); +SPNamedView const *sp_document_namedview(SPDocument const *document, char const *name); void sp_namedview_window_from_document(SPDesktop *desktop); void sp_namedview_document_from_window(SPDesktop *desktop); diff --git a/src/sp-object-group.h b/src/sp-object-group.h index 4df346228..dcaa8a1d0 100644 --- a/src/sp-object-group.h +++ b/src/sp-object-group.h @@ -30,7 +30,7 @@ protected: virtual void order_changed(Inkscape::XML::Node* child, Inkscape::XML::Node* old, Inkscape::XML::Node* new_repr); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; #endif // SEEN_SP_OBJECTGROUP_H diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 65228ec0a..fcff43aa5 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -1406,12 +1406,12 @@ bool SPObject::setDesc(gchar const *desc, bool verbatim) return setTitleOrDesc(desc, "svg:desc", verbatim); } -gchar * SPObject::getTitleOrDesc(gchar const *svg_tagname) const +char * SPObject::getTitleOrDesc(gchar const *svg_tagname) const { - gchar *result = 0; + char *result = NULL; SPObject *elem = findFirstChild(svg_tagname); if ( elem ) { - result = g_string_free(elem->textualContent(), FALSE); + result = elem->textualContent(); } return result; } @@ -1493,7 +1493,7 @@ SPObject * SPObject::findFirstChild(gchar const *tagname) const return NULL; } -GString * SPObject::textualContent() const +char* SPObject::textualContent() const { GString* text = g_string_new(""); @@ -1502,15 +1502,15 @@ GString * SPObject::textualContent() const Inkscape::XML::NodeType child_type = child->repr->type(); if (child_type == Inkscape::XML::ELEMENT_NODE) { - GString * new_text = child->textualContent(); - g_string_append(text, new_text->str); - g_string_free(new_text, TRUE); + char* new_string = child->textualContent(); + g_string_append(text, new_string); + g_free(new_string); } else if (child_type == Inkscape::XML::TEXT_NODE) { g_string_append(text, child->repr->content()); } } - return text; + return g_string_free(text, FALSE); } /* diff --git a/src/sp-object.h b/src/sp-object.h index 21926ad90..423f6ba37 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -153,7 +153,7 @@ SPObject *sp_object_unref(SPObject *object, SPObject *owner=NULL); * \pre object points to real object * @todo need to move this to be a member of SPObject. */ -SPObject *sp_object_href(SPObject *object, gpointer owner); +SPObject *sp_object_href(SPObject *object, void* owner); /** * Decrease weak refcount. @@ -165,7 +165,7 @@ SPObject *sp_object_href(SPObject *object, gpointer owner); * \pre object points to real object and hrefcount>0 * @todo need to move this to be a member of SPObject. */ -SPObject *sp_object_hunref(SPObject *object, gpointer owner); +SPObject *sp_object_hunref(SPObject *object, void* owner); /** * SPObject is an abstract base class of all of the document nodes at the @@ -795,7 +795,7 @@ private: * content except the tags). * Must not be used on anything except elements. */ - GString * textualContent() const; + char * textualContent() const; /* Real handlers of repr signals */ @@ -803,17 +803,17 @@ public: /** * Callback for attr_changed node event. */ - static void repr_attr_changed(Inkscape::XML::Node *repr, char const *key, char const *oldval, char const *newval, bool is_interactive, gpointer data); + static void repr_attr_changed(Inkscape::XML::Node *repr, char const *key, char const *oldval, char const *newval, bool is_interactive, void* data); /** * Callback for content_changed node event. */ - static void repr_content_changed(Inkscape::XML::Node *repr, char const *oldcontent, char const *newcontent, gpointer data); + static void repr_content_changed(Inkscape::XML::Node *repr, char const *oldcontent, char const *newcontent, void* data); /** * Callback for child_added node event. */ - static void repr_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data); + static void repr_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void* data); /** * Callback for remove_child node event. @@ -825,7 +825,7 @@ public: * * \todo fixme: */ - static void repr_order_changed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *newer, gpointer data); + static void repr_order_changed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *newer, void* data); friend class SPObjectImpl; diff --git a/src/sp-offset.h b/src/sp-offset.h index 259a69b78..eb3fe227c 100644 --- a/src/sp-offset.h +++ b/src/sp-offset.h @@ -11,11 +11,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "sp-shape.h" - -#include +#include #include +#include "sp-shape.h" + #define SP_OFFSET(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_OFFSET(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -54,7 +54,7 @@ public: SPOffset(); virtual ~SPOffset(); - void *originalPath; ///< will be a livarot Path, just don't declare it here to please the gcc linker + void *originalPath; ///< will be a livarot Path, just don't declare it here to please the gcc linker FIXME what? char *original; ///< SVG description of the source path float rad; ///< offset radius @@ -65,7 +65,7 @@ public: bool sourceDirty; bool isUpdating; - gchar *sourceHref; + char *sourceHref; SPUseReference *sourceRef; Inkscape::XML::Node *sourceRepr; ///< the repr associated with that id SPObject *sourceObject; @@ -76,14 +76,14 @@ public: sigc::connection _transformed_connection; virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void set(unsigned int key, gchar const* value); - virtual void update(SPCtx *ctx, guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual void update(SPCtx *ctx, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned flags); virtual void release(); virtual void snappoints(std::vector &p, Inkscape::SnapPreferences const *snapprefs) const; virtual const char* displayName() const; - virtual gchar* description() const; + virtual char* description() const; virtual void set_shape(); }; diff --git a/src/sp-paint-server-reference.h b/src/sp-paint-server-reference.h index e08694c2f..bbd9c25fa 100644 --- a/src/sp-paint-server-reference.h +++ b/src/sp-paint-server-reference.h @@ -15,9 +15,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "sp-object.h" #include "uri-references.h" +class SPDocument; +class SPObject; class SPPaintServer; class SPPaintServerReference : public Inkscape::URIReference { diff --git a/src/sp-paint-server.h b/src/sp-paint-server.h index c1c8d651e..beac72af5 100644 --- a/src/sp-paint-server.h +++ b/src/sp-paint-server.h @@ -15,10 +15,12 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include #include <2geom/rect.h> #include "sp-object.h" +typedef struct _cairo cairo_t; +typedef struct _cairo_pattern cairo_pattern_t; + #define SP_PAINT_SERVER(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_PAINT_SERVER(obj) (dynamic_cast((SPObject*)obj) != NULL) diff --git a/src/sp-path.h b/src/sp-path.h index 5f8a91d98..572fd648d 100644 --- a/src/sp-path.h +++ b/src/sp-path.h @@ -32,7 +32,7 @@ public: SPPath(); virtual ~SPPath(); - gint nodesInPath() const; + int nodesInPath() const; // still in lowercase because the names should be clearer on whether curve, curve->copy or curve-ref is returned. void set_original_curve (SPCurve *curve, unsigned int owner, bool write); @@ -49,13 +49,13 @@ public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void update(SPCtx* ctx, guint flags); + virtual void update(SPCtx* ctx, unsigned int flags); - virtual void set(unsigned int key, gchar const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char* displayName() const; - virtual gchar* description() const; + virtual char* description() const; virtual Geom::Affine set_transform(Geom::Affine const &transform); virtual void convert_to_guides() const; diff --git a/src/sp-pattern.h b/src/sp-pattern.h index 8f7dbbadd..f021101e2 100644 --- a/src/sp-pattern.h +++ b/src/sp-pattern.h @@ -18,6 +18,7 @@ class SPPatternReference; class SPItem; +typedef struct _GSList GSList; #include "svg/svg-length.h" #include "sp-paint-server.h" @@ -33,17 +34,17 @@ public: virtual ~SPPattern(); /* Reference (href) */ - gchar *href; + char *href; SPPatternReference *ref; /* patternUnits and patternContentUnits attribute */ - guint patternUnits : 1; - guint patternUnits_set : 1; - guint patternContentUnits : 1; - guint patternContentUnits_set : 1; + unsigned int patternUnits : 1; + unsigned int patternUnits_set : 1; + unsigned int patternContentUnits : 1; + unsigned int patternContentUnits_set : 1; /* patternTransform attribute */ Geom::Affine patternTransform; - guint patternTransform_set : 1; + unsigned int patternTransform_set : 1; /* Tile rectangle */ SVGLength x; SVGLength y; @@ -83,22 +84,22 @@ enum { SP_PATTERN_UNITS_OBJECTBOUNDINGBOX }; -guint pattern_users (SPPattern *pattern); +unsigned int pattern_users (SPPattern *pattern); SPPattern *pattern_chain (SPPattern *pattern); -SPPattern *sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property); +SPPattern *sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const char *property); void sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set); -const gchar *pattern_tile (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move); +const char *pattern_tile (GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move); SPPattern *pattern_getroot (SPPattern *pat); -guint pattern_patternUnits (SPPattern const *pat); -guint pattern_patternContentUnits (SPPattern const *pat); +unsigned int pattern_patternUnits (SPPattern const *pat); +unsigned int pattern_patternContentUnits (SPPattern const *pat); Geom::Affine const &pattern_patternTransform(SPPattern const *pat); -gdouble pattern_x (SPPattern const *pat); -gdouble pattern_y (SPPattern const *pat); -gdouble pattern_width (SPPattern const *pat); -gdouble pattern_height (SPPattern const *pat); +double pattern_x (SPPattern const *pat); +double pattern_y (SPPattern const *pat); +double pattern_width (SPPattern const *pat); +double pattern_height (SPPattern const *pat); Geom::OptRect pattern_viewBox (SPPattern const *pat); #endif // SEEN_SP_PATTERN_H diff --git a/src/sp-polygon.h b/src/sp-polygon.h index 41ab245bd..438fdf794 100644 --- a/src/sp-polygon.h +++ b/src/sp-polygon.h @@ -1,5 +1,5 @@ -#ifndef __SP_POLYGON_H__ -#define __SP_POLYGON_H__ +#ifndef SEEN_SP_POLYGON_H +#define SEEN_SP_POLYGON_H /* * SVG implementation @@ -15,7 +15,6 @@ #include "sp-shape.h" - #define SP_POLYGON(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_POLYGON(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -25,12 +24,12 @@ public: virtual ~SPPolygon(); virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); - virtual void set(unsigned int key, gchar const* value); - virtual gchar* description() const; + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); + virtual void set(unsigned int key, char const* value); + virtual char* description() const; }; // made 'public' so that SPCurve can set it as friend: -void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value); +void sp_polygon_set(SPObject *object, unsigned int key, char const*value); #endif diff --git a/src/sp-polyline.h b/src/sp-polyline.h index e24ea95c7..1ca102a9e 100644 --- a/src/sp-polyline.h +++ b/src/sp-polyline.h @@ -12,10 +12,10 @@ public: virtual ~SPPolyLine(); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void set(unsigned int key, gchar const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); - virtual gchar* description() const; + virtual char* description() const; }; #endif // SEEN_SP_POLYLINE_H diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp index 7c481fead..2c2b17b7d 100644 --- a/src/sp-radial-gradient.cpp +++ b/src/sp-radial-gradient.cpp @@ -1,3 +1,5 @@ +#include + #include "sp-radial-gradient.h" #include "attributes.h" diff --git a/src/sp-radial-gradient.h b/src/sp-radial-gradient.h index 42ff109aa..f753623b7 100644 --- a/src/sp-radial-gradient.h +++ b/src/sp-radial-gradient.h @@ -5,10 +5,12 @@ * SPRadialGradient: SVG implementtion. */ -#include #include "sp-gradient.h" #include "svg/svg-length.h" +typedef struct _cairo cairo_t; +typedef struct _cairo_pattern cairo_pattern_t; + #define SP_RADIALGRADIENT(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_RADIALGRADIENT(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -28,8 +30,8 @@ public: protected: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); - virtual void set(unsigned key, gchar const *value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned key, char const *value); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); }; #endif /* !SP_RADIAL_GRADIENT_H */ diff --git a/src/sp-rect.h b/src/sp-rect.h index aa3f88e42..757229724 100644 --- a/src/sp-rect.h +++ b/src/sp-rect.h @@ -14,10 +14,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "svg/svg-length.h" -#include "sp-shape.h" #include <2geom/forward.h> +#include "svg/svg-length.h" +#include "sp-shape.h" #define SP_RECT(obj) (dynamic_cast((SPObject*)obj)) #define SP_IS_RECT(obj) (dynamic_cast((SPObject*)obj) != NULL) @@ -27,34 +27,34 @@ public: SPRect(); virtual ~SPRect(); - void setPosition(gdouble x, gdouble y, gdouble width, gdouble height); + void setPosition(double x, double y, double width, double height); /* If SET if FALSE, VALUE is just ignored */ - void setRx(bool set, gdouble value); - void setRy(bool set, gdouble value); + void setRx(bool set, double value); + void setRy(bool set, double value); - gdouble getVisibleRx() const; - void setVisibleRx(gdouble rx); + double getVisibleRx() const; + void setVisibleRx(double rx); - gdouble getVisibleRy() const; - void setVisibleRy(gdouble ry); + double getVisibleRy() const; + void setVisibleRy(double ry); Geom::Rect getRect() const; - gdouble getVisibleWidth() const; - void setVisibleWidth(gdouble rx); + double getVisibleWidth() const; + void setVisibleWidth(double rx); - gdouble getVisibleHeight() const; - void setVisibleHeight(gdouble ry); + double getVisibleHeight() const; + void setVisibleHeight(double ry); void compensateRxRy(Geom::Affine xform); virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void set(unsigned key, gchar const *value); + virtual void set(unsigned key, char const *value); virtual void update(SPCtx* ctx, unsigned int flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual const char* displayName() const; virtual void set_shape(); @@ -71,7 +71,7 @@ public: SVGLength ry; private: - static gdouble vectorStretch(Geom::Point p0, Geom::Point p1, Geom::Affine xform); + static double vectorStretch(Geom::Point p0, Geom::Point p1, Geom::Affine xform); }; #endif // SEEN_SP_RECT_H diff --git a/src/sp-root.h b/src/sp-root.h index a25e8030c..2776ae887 100644 --- a/src/sp-root.h +++ b/src/sp-root.h @@ -40,7 +40,7 @@ public: SVGLength width; SVGLength height; - gchar *onload; + char *onload; /** * Primary \ element where we put new defs (patterns, gradients etc.). @@ -52,9 +52,9 @@ public: virtual void build(SPDocument *document, Inkscape::XML::Node *repr); virtual void release(); - virtual void set(unsigned int key, gchar const* value); - virtual void update(SPCtx *ctx, guint flags); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); + virtual void set(unsigned int key, char const* value); + virtual void update(SPCtx *ctx, unsigned int flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags); virtual void modified(unsigned int flags); virtual void child_added(Inkscape::XML::Node* child, Inkscape::XML::Node* ref); diff --git a/src/sp-script.h b/src/sp-script.h index 36072a0ca..b71f86720 100644 --- a/src/sp-script.h +++ b/src/sp-script.h @@ -1,5 +1,5 @@ -#ifndef __SP_SCRIPT_H__ -#define __SP_SCRIPT_H__ +#ifndef SEEN_SP_SCRIPT_H +#define SEEN_SP_SCRIPT_H /* * SVG