X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdyna-draw-context.cpp;h=91079aaa4dd278a287fc7034a6b1a2d32a3a94c3;hb=b53b8aff0aa55c2349ea10992daac23a929ae19f;hp=7585232458ec7a1cead320dcd82a5d7744007f41;hpb=c3a00a461062af1b65c3392677378c284ade5880;p=inkscape.git diff --git a/src/dyna-draw-context.cpp b/src/dyna-draw-context.cpp index 758523245..91079aaa4 100644 --- a/src/dyna-draw-context.cpp +++ b/src/dyna-draw-context.cpp @@ -27,6 +27,7 @@ #include #include +#include #include "svg/svg.h" #include "display/canvas-bpath.h" @@ -43,7 +44,6 @@ #include "desktop-style.h" #include "message-context.h" #include "pixmaps/cursor-calligraphy.xpm" -#include "pixmaps/cursor-calligraphy.pixbuf" #include "dyna-draw-context.h" #include "libnr/n-art-bpath.h" #include "libnr/nr-path.h" @@ -76,7 +76,7 @@ static gint sp_dyna_draw_context_root_handler(SPEventContext *ec, GdkEvent *even static void clear_current(SPDynaDrawContext *dc); static void set_to_accumulated(SPDynaDrawContext *dc); -static void add_cap(SPCurve *curve, NR::Point const &from, NR::Point const &to, double rounding); +static void add_cap(SPCurve *curve, NR::Point const &pre, NR::Point const &from, NR::Point const &to, NR::Point const &post, double rounding); static void accumulate_calligraphic(SPDynaDrawContext *dc); static void fit_and_split(SPDynaDrawContext *ddc, gboolean release); @@ -130,11 +130,6 @@ sp_dyna_draw_context_init(SPDynaDrawContext *ddc) SPEventContext *event_context = SP_EVENT_CONTEXT(ddc); event_context->cursor_shape = cursor_calligraphy_xpm; - event_context->cursor_pixbuf = gdk_pixbuf_new_from_inline( - -1, - cursor_calligraphy_pixbuf, - FALSE, - NULL); event_context->hot_x = 4; event_context->hot_y = 4; @@ -222,7 +217,7 @@ sp_dyna_draw_context_setup(SPEventContext *ec) g_signal_connect(G_OBJECT(ddc->currentshape), "event", G_CALLBACK(sp_desktop_root_handler), ec->desktop); sp_event_context_read(ec, "mass"); - sp_event_context_read(ec, "drag"); + sp_event_context_read(ec, "wiggle"); sp_event_context_read(ec, "angle"); sp_event_context_read(ec, "width"); sp_event_context_read(ec, "thinning"); @@ -247,9 +242,9 @@ sp_dyna_draw_context_set(SPEventContext *ec, gchar const *key, gchar const *val) if (!strcmp(key, "mass")) { double const dval = ( val ? g_ascii_strtod (val, NULL) : 0.2 ); ddc->mass = CLAMP(dval, -1000.0, 1000.0); - } else if (!strcmp(key, "drag")) { - double const dval = ( val ? g_ascii_strtod (val, NULL) : DRAG_DEFAULT ); - ddc->drag = CLAMP(dval, DRAG_MIN, DRAG_MAX); + } else if (!strcmp(key, "wiggle")) { + double const dval = ( val ? g_ascii_strtod (val, NULL) : (1 - DRAG_DEFAULT)); + ddc->drag = CLAMP((1 - dval), DRAG_MIN, DRAG_MAX); // drag is inverse to wiggle } else if (!strcmp(key, "angle")) { double const dval = ( val ? g_ascii_strtod (val, NULL) : 0.0); ddc->angle = CLAMP (dval, -90, 90); @@ -547,9 +542,14 @@ sp_dyna_draw_context_root_handler(SPEventContext *event_context, case GDK_BUTTON_RELEASE: sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); dc->is_drawing = false; + if ( dc->dragging && event->button.button == 1 ) { dc->dragging = FALSE; + NR::Point const motion_w(event->button.x, event->button.y); + NR::Point const motion_dt(desktop->w2d(motion_w)); + sp_dyna_draw_apply(dc, motion_dt); + /* Remove all temporary line segments */ while (dc->segments) { gtk_object_destroy(GTK_OBJECT(dc->segments->data)); @@ -693,17 +693,36 @@ set_to_accumulated(SPDynaDrawContext *dc) } sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_CALLIGRAPHIC, - /* TODO: annotate */ "dyna-draw-context.cpp:689"); + _("Create calligraphic stroke")); } static void -add_cap(SPCurve *curve, NR::Point const &from, NR::Point const &to, +add_cap(SPCurve *curve, + NR::Point const &pre, NR::Point const &from, + NR::Point const &to, NR::Point const &post, double rounding) { - NR::Point vec = rounding * NR::rot90( ( to - from ) / sqrt(2.0) ); + NR::Point vel = rounding * NR::rot90( to - from ) / sqrt(2.0); + double mag = NR::L2(vel); + + NR::Point v_in = from - pre; + double mag_in = NR::L2(v_in); + if ( mag_in > DYNA_EPSILON ) { + v_in = mag * v_in / mag_in; + } else { + v_in = NR::Point(0, 0); + } - if ( NR::L2(vec) > DYNA_EPSILON ) { - sp_curve_curveto(curve, from + vec, to + vec, to); + NR::Point v_out = to - post; + double mag_out = NR::L2(v_out); + if ( mag_out > DYNA_EPSILON ) { + v_out = mag * v_out / mag_out; + } else { + v_out = NR::Point(0, 0); + } + + if ( NR::L2(v_in) > DYNA_EPSILON || NR::L2(v_out) > DYNA_EPSILON ) { + sp_curve_curveto(curve, from + v_in, to + v_out, to); } } @@ -713,10 +732,24 @@ accumulate_calligraphic(SPDynaDrawContext *dc) if ( !sp_curve_empty(dc->cal1) && !sp_curve_empty(dc->cal2) ) { sp_curve_reset(dc->accumulated); /* Is this required ?? */ SPCurve *rev_cal2 = sp_curve_reverse(dc->cal2); + + g_assert(dc->cal1->end > 1); + g_assert(rev_cal2->end > 1); + g_assert(SP_CURVE_SEGMENT(dc->cal1, 0)->code == NR_MOVETO_OPEN); + g_assert(SP_CURVE_SEGMENT(rev_cal2, 0)->code == NR_MOVETO_OPEN); + g_assert(SP_CURVE_SEGMENT(dc->cal1, 1)->code == NR_CURVETO); + g_assert(SP_CURVE_SEGMENT(rev_cal2, 1)->code == NR_CURVETO); + g_assert(SP_CURVE_SEGMENT(dc->cal1, dc->cal1->end-1)->code == NR_CURVETO); + g_assert(SP_CURVE_SEGMENT(rev_cal2, rev_cal2->end-1)->code == NR_CURVETO); + sp_curve_append(dc->accumulated, dc->cal1, FALSE); - add_cap(dc->accumulated, sp_curve_last_point(dc->cal1), sp_curve_first_point(rev_cal2), dc->cap_rounding); + + add_cap(dc->accumulated, SP_CURVE_SEGMENT(dc->cal1, dc->cal1->end-1)->c(2), SP_CURVE_SEGMENT(dc->cal1, dc->cal1->end-1)->c(3), SP_CURVE_SEGMENT(rev_cal2, 0)->c(3), SP_CURVE_SEGMENT(rev_cal2, 1)->c(1), dc->cap_rounding); + sp_curve_append(dc->accumulated, rev_cal2, TRUE); - add_cap(dc->accumulated, sp_curve_last_point(rev_cal2), sp_curve_first_point(dc->cal1), dc->cap_rounding); + + add_cap(dc->accumulated, SP_CURVE_SEGMENT(rev_cal2, rev_cal2->end-1)->c(2), SP_CURVE_SEGMENT(rev_cal2, rev_cal2->end-1)->c(3), SP_CURVE_SEGMENT(dc->cal1, 0)->c(3), SP_CURVE_SEGMENT(dc->cal1, 1)->c(1), dc->cap_rounding); + sp_curve_closepath(dc->accumulated); sp_curve_unref(rev_cal2); @@ -792,8 +825,9 @@ fit_and_split(SPDynaDrawContext *dc, gboolean release) for (NR::Point *bp2 = b2 + BEZIER_SIZE * ( nb2 - 1 ); bp2 >= b2; bp2 -= BEZIER_SIZE) { sp_curve_curveto(dc->currentcurve, bp2[2], bp2[1], bp2[0]); } - if (!dc->segments) { - add_cap(dc->currentcurve, b2[0], b1[0], dc->cap_rounding); + // FIXME: dc->segments is always NULL at this point?? + if (!dc->segments) { // first segment + add_cap(dc->currentcurve, b2[1], b2[0], b1[0], b1[1], dc->cap_rounding); } sp_curve_closepath(dc->currentcurve); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->currentshape), dc->currentcurve); @@ -869,7 +903,7 @@ draw_temporary_box(SPDynaDrawContext *dc) for (gint i = dc->npoints-1; i >= 0; i--) { sp_curve_lineto(dc->currentcurve, dc->point2[i]); } - add_cap(dc->currentcurve, dc->point2[0], dc->point1[0], dc->cap_rounding); + add_cap(dc->currentcurve, dc->point2[1], dc->point2[0], dc->point1[0], dc->point1[1], dc->cap_rounding); sp_curve_closepath(dc->currentcurve); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->currentshape), dc->currentcurve); }