diff options
| author | Denis Declara <declara91@gmail.com> | 2012-05-05 13:32:42 +0000 |
|---|---|---|
| committer | Denis Declara <declara91@gmail.com> | 2012-05-05 13:32:42 +0000 |
| commit | aeb9c1bde66de096910757abb17dedb94ad74207 (patch) | |
| tree | c0adf97685b0fa8af1553b14d20601f280492762 /src/draw-context.cpp | |
| parent | Fixed some math, so that the objects now line up correctly (diff) | |
| parent | Adding checks to prevent null pointer dereferences (diff) | |
| download | inkscape-aeb9c1bde66de096910757abb17dedb94ad74207.tar.gz inkscape-aeb9c1bde66de096910757abb17dedb94ad74207.zip | |
Trunk merge
(bzr r11073.1.29)
Diffstat (limited to 'src/draw-context.cpp')
| -rw-r--r-- | src/draw-context.cpp | 267 |
1 files changed, 84 insertions, 183 deletions
diff --git a/src/draw-context.cpp b/src/draw-context.cpp index d8ce2729d..cf47fed29 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -4,6 +4,7 @@ * Author: * Lauris Kaplinski <lauris@kaplinski.com> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2000 Lauris Kaplinski * Copyright (C) 2000-2001 Ximian, Inc. @@ -42,77 +43,12 @@ #include "sp-namedview.h" #include "live_effects/lpe-powerstroke.h" #include "style.h" +#include "ui/control-manager.h" #include <gdk/gdkkeysyms.h> #if !GTK_CHECK_VERSION(2,22,0) -#define GDK_KEY_Up 0xff52 -#define GDK_KEY_KP_Up 0xff97 -#define GDK_KEY_Down 0xff54 -#define GDK_KEY_KP_Down 0xff99 -#define GDK_KEY_Left 0xff51 -#define GDK_KEY_KP_Left 0xff96 -#define GDK_KEY_Right 0xff53 -#define GDK_KEY_KP_Right 0xff98 -#define GDK_KEY_Page_Up 0xff55 -#define GDK_KEY_KP_Page_Up 0xff9a -#define GDK_KEY_Page_Down 0xff56 -#define GDK_KEY_KP_Page_Down 0xff9b -#define GDK_KEY_Home 0xff50 -#define GDK_KEY_KP_Home 0xff95 -#define GDK_KEY_End 0xff57 -#define GDK_KEY_KP_End 0xff9c -#define GDK_KEY_a 0x061 -#define GDK_KEY_A 0x041 -#define GDK_KEY_g 0x067 -#define GDK_KEY_G 0x047 -#define GDK_KEY_l 0x06c -#define GDK_KEY_L 0x04c -#define GDK_KEY_r 0x072 -#define GDK_KEY_R 0x052 -#define GDK_KEY_s 0x073 -#define GDK_KEY_S 0x053 -#define GDK_KEY_u 0x075 -#define GDK_KEY_U 0x055 -#define GDK_KEY_x 0x078 -#define GDK_KEY_X 0x058 -#define GDK_KEY_z 0x07a -#define GDK_KEY_Z 0x05a -#define GDK_KEY_Escape 0xff1b -#define GDK_KEY_Control_L 0xffe3 -#define GDK_KEY_Control_R 0xffe4 -#define GDK_KEY_Alt_L 0xffe9 -#define GDK_KEY_Alt_R 0xffea -#define GDK_KEY_Shift_L 0xffe1 -#define GDK_KEY_Shift_R 0xffe2 -#define GDK_KEY_Meta_L 0xffe7 -#define GDK_KEY_Meta_R 0xffe8 -#define GDK_KEY_KP_0 0xffb0 -#define GDK_KEY_KP_1 0xffb1 -#define GDK_KEY_KP_2 0xffb2 -#define GDK_KEY_KP_3 0xffb3 -#define GDK_KEY_KP_4 0xffb4 -#define GDK_KEY_KP_5 0xffb5 -#define GDK_KEY_KP_6 0xffb6 -#define GDK_KEY_KP_7 0xffb7 -#define GDK_KEY_KP_8 0xffb8 -#define GDK_KEY_KP_9 0xffb9 -#define GDK_KEY_Insert 0xff63 -#define GDK_KEY_KP_Insert 0xff9e -#define GDK_KEY_Delete 0xffff -#define GDK_KEY_KP_Delete 0xff9f -#define GDK_KEY_BackSpace 0xff08 -#define GDK_KEY_Return 0xff0d -#define GDK_KEY_KP_Enter 0xff8d -#define GDK_KEY_space 0x020 -#define GDK_KEY_Tab 0xff09 -#define GDK_KEY_ISO_Left_Tab 0xfe20 -#define GDK_KEY_bracketleft 0x05b -#define GDK_KEY_bracketright 0x05d -#define GDK_KEY_less 0x03c -#define GDK_KEY_greater 0x03e -#define GDK_KEY_comma 0x02c -#define GDK_KEY_period 0x02e +#include "compat-key-syms.h" #endif using Inkscape::DocumentUndo; @@ -132,6 +68,12 @@ static void spdc_selection_modified(Inkscape::Selection *sel, guint flags, SPDra static void spdc_attach_selection(SPDrawContext *dc, Inkscape::Selection *sel); +/** + * Flushes white curve(s) and additional curve into object. + * + * No cleaning of colored curves - this has to be done by caller + * No rereading of white data, so if you cannot rely on ::modified, do it in caller + */ static void spdc_flush_white(SPDrawContext *dc, SPCurve *gc); static void spdc_reset_white(SPDrawContext *dc); @@ -140,9 +82,7 @@ static void spdc_free_colors(SPDrawContext *dc); static SPEventContextClass *draw_parent_class; - -GType -sp_draw_context_get_type(void) +GType sp_draw_context_get_type(void) { static GType type = 0; if (!type) { @@ -154,15 +94,14 @@ sp_draw_context_get_type(void) sizeof(SPDrawContext), 4, (GInstanceInitFunc) sp_draw_context_init, - NULL, /* value_table */ + NULL, // value_table }; type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPDrawContext", &info, (GTypeFlags)0); } return type; } -static void -sp_draw_context_class_init(SPDrawContextClass *klass) +static void sp_draw_context_class_init(SPDrawContextClass *klass) { GObjectClass *object_class; SPEventContextClass *ec_class; @@ -180,8 +119,7 @@ sp_draw_context_class_init(SPDrawContextClass *klass) ec_class->root_handler = sp_draw_context_root_handler; } -static void -sp_draw_context_init(SPDrawContext *dc) +static void sp_draw_context_init(SPDrawContext *dc) { dc->attach = FALSE; @@ -214,8 +152,7 @@ sp_draw_context_init(SPDrawContext *dc) new (&dc->sel_modified_connection) sigc::connection(); } -static void -sp_draw_context_dispose(GObject *object) +static void sp_draw_context_dispose(GObject *object) { SPDrawContext *dc = SP_DRAW_CONTEXT(object); @@ -236,8 +173,7 @@ sp_draw_context_dispose(GObject *object) G_OBJECT_CLASS(draw_parent_class)->dispose(object); } -static void -sp_draw_context_setup(SPEventContext *ec) +static void sp_draw_context_setup(SPEventContext *ec) { SPDrawContext *dc = SP_DRAW_CONTEXT(ec); SPDesktop *dt = ec->desktop; @@ -248,7 +184,7 @@ sp_draw_context_setup(SPEventContext *ec) dc->selection = sp_desktop_selection(dt); - /* Connect signals to track selection changes */ + // Connect signals to track selection changes dc->sel_changed_connection = dc->selection->connectChanged( sigc::bind(sigc::ptr_fun(&spdc_selection_changed), dc) ); @@ -256,21 +192,24 @@ sp_draw_context_setup(SPEventContext *ec) sigc::bind(sigc::ptr_fun(&spdc_selection_modified), dc) ); - /* Create red bpath */ + // Create red bpath dc->red_bpath = sp_canvas_bpath_new(sp_desktop_sketch(ec->desktop), NULL); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->red_bpath), dc->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - /* Create red curve */ + + // Create red curve dc->red_curve = new SPCurve(); - /* Create blue bpath */ + // Create blue bpath 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 blue curve */ + + // Create blue curve dc->blue_curve = new SPCurve(); - /* Create green curve */ + // Create green curve dc->green_curve = new SPCurve(); - /* No green anchor by default */ + + // No green anchor by default dc->green_anchor = NULL; dc->green_closed = FALSE; @@ -278,8 +217,7 @@ sp_draw_context_setup(SPEventContext *ec) spdc_attach_selection(dc, dc->selection); } -static void -sp_draw_context_finish(SPEventContext *ec) +static void sp_draw_context_finish(SPEventContext *ec) { SPDrawContext *dc = SP_DRAW_CONTEXT(ec); @@ -297,13 +235,11 @@ sp_draw_context_finish(SPEventContext *ec) spdc_free_colors(dc); } -static void -sp_draw_context_set(SPEventContext */*ec*/, Inkscape::Preferences::Entry */*val*/) +static void sp_draw_context_set(SPEventContext */*ec*/, Inkscape::Preferences::Entry */*val*/) { } -gint -sp_draw_context_root_handler(SPEventContext *ec, GdkEvent *event) +gint sp_draw_context_root_handler(SPEventContext *ec, GdkEvent *event) { gint ret = FALSE; @@ -336,16 +272,14 @@ sp_draw_context_root_handler(SPEventContext *ec, GdkEvent *event) return ret; } -static Glib::ustring const -tool_name(SPDrawContext *dc) +static Glib::ustring const tool_name(SPDrawContext *dc) { return ( SP_IS_PEN_CONTEXT(dc) ? "/tools/freehand/pen" : "/tools/freehand/pencil" ); } -static void -spdc_paste_curve_as_freehand_shape(const SPCurve *c, SPDrawContext *dc, SPItem *item) +static void spdc_paste_curve_as_freehand_shape(const SPCurve *c, SPDrawContext *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; @@ -357,8 +291,7 @@ spdc_paste_curve_as_freehand_shape(const SPCurve *c, SPDrawContext *dc, SPItem * static_cast<LPEPatternAlongPath*>(lpe)->pattern.paste_param_path(svgd); } -static void -spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points, SPDrawContext *dc, SPItem *item) +static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points, SPDrawContext *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; @@ -375,12 +308,7 @@ spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points, SPDrawCont lpe->getRepr()->setAttribute("interpolator_beta", "0.2"); } -/* - * If we have an item and a waiting LPE, apply the effect to the item - * (spiro spline mode is treated separately) - */ -void -spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item, SPCurve *curve) +void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item, SPCurve *curve) { using namespace Inkscape::LivePathEffect; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -486,8 +414,7 @@ spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item, SPCurve *c * Selection handlers */ -static void -spdc_selection_changed(Inkscape::Selection *sel, SPDrawContext *dc) +static void spdc_selection_changed(Inkscape::Selection *sel, SPDrawContext *dc) { if (dc->attach) { spdc_attach_selection(dc, sel); @@ -496,18 +423,16 @@ spdc_selection_changed(Inkscape::Selection *sel, SPDrawContext *dc) /* fixme: We have to ensure this is not delayed (Lauris) */ -static void -spdc_selection_modified(Inkscape::Selection *sel, guint /*flags*/, SPDrawContext *dc) +static void spdc_selection_modified(Inkscape::Selection *sel, guint /*flags*/, SPDrawContext *dc) { if (dc->attach) { spdc_attach_selection(dc, sel); } } -static void -spdc_attach_selection(SPDrawContext *dc, Inkscape::Selection */*sel*/) +static void spdc_attach_selection(SPDrawContext *dc, Inkscape::Selection */*sel*/) { - /* We reset white and forget white/start/end anchors */ + // We reset white and forget white/start/end anchors spdc_reset_white(dc); dc->sa = NULL; dc->ea = NULL; @@ -515,17 +440,19 @@ spdc_attach_selection(SPDrawContext *dc, Inkscape::Selection */*sel*/) SPItem *item = dc->selection ? dc->selection->singleItem() : NULL; if ( item && SP_IS_PATH(item) ) { - /* Create new white data */ - /* Item */ + // Create new white data + // Item dc->white_item = item; - /* Curve list */ - /* We keep it in desktop coordinates to eliminate calculation errors */ + + // Curve list + // We keep it in desktop coordinates to eliminate calculation errors SPCurve *norm = SP_PATH(item)->get_curve_for_edit(); norm->transform((dc->white_item)->i2dt_affine()); g_return_if_fail( norm != NULL ); dc->white_curves = g_slist_reverse(norm->split()); norm->unref(); - /* Anchor list */ + + // Anchor list for (GSList *l = dc->white_curves; l != NULL; l = l->next) { SPCurve *c; c = static_cast<SPCurve*>(l->data); @@ -540,20 +467,11 @@ spdc_attach_selection(SPDrawContext *dc, Inkscape::Selection */*sel*/) dc->white_anchors = g_slist_prepend(dc->white_anchors, a); } } - /* fixme: recalculate active anchor? */ + // fixme: recalculate active anchor? } } -/** - * Snaps node or handle to PI/rotationsnapsperpi degree increments. - * - * \param dc draw context - * \param p cursor point (to be changed by snapping) - * \param o origin point - * \param state keyboard state to check if ctrl or shift was pressed -*/ - void spdc_endpoint_snap_rotation(SPEventContext const *const ec, Geom::Point &p, Geom::Point const &o, guint state) { @@ -604,36 +522,31 @@ void spdc_endpoint_snap_free(SPEventContext const * const ec, Geom::Point& p, bo m.unSetup(); } -static SPCurve * -reverse_then_unref(SPCurve *orig) +static SPCurve *reverse_then_unref(SPCurve *orig) { SPCurve *ret = orig->create_reverse(); orig->unref(); return ret; } -/** - * Concats red, blue and green. - * If any anchors are defined, process these, optionally removing curves from white list - * Invoke _flush_white to write result back to object. - */ -void -spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) +void spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) { - /* Concat RBG */ + // Concat RBG SPCurve *c = dc->green_curve; - /* Green */ + // Green dc->green_curve = new SPCurve(); while (dc->green_bpaths) { gtk_object_destroy(GTK_OBJECT(dc->green_bpaths->data)); dc->green_bpaths = g_slist_remove(dc->green_bpaths, dc->green_bpaths->data); } - /* Blue */ + + // Blue c->append_continuous(dc->blue_curve, 0.0625); dc->blue_curve->reset(); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(dc->blue_bpath), NULL); - /* Red */ + + // Red if (dc->red_curve_is_valid) { c->append_continuous(dc->red_curve, 0.0625); } @@ -645,18 +558,18 @@ spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) return; } - /* Step A - test, whether we ended on green anchor */ + // Step A - test, whether we ended on green anchor if ( forceclosed || ( dc->green_anchor && dc->green_anchor->active ) ) { // We hit green anchor, closing Green-Blue-Red SP_EVENT_CONTEXT_DESKTOP(dc)->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed.")); c->closepath_current(); - /* Closed path, just flush */ + // Closed path, just flush spdc_flush_white(dc, c); c->unref(); return; } - /* Step B - both start and end anchored to same curve */ + // Step B - both start and end anchored to same curve if ( dc->sa && dc->ea && ( dc->sa->curve == dc->ea->curve ) && ( ( dc->sa != dc->ea ) @@ -674,7 +587,7 @@ spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) return; } - /* Step C - test start */ + // Step C - test start if (dc->sa) { SPCurve *s = dc->sa->curve; dc->white_curves = g_slist_remove(dc->white_curves, s); @@ -700,16 +613,7 @@ spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed) c->unref(); } -/* - * Flushes white curve(s) and additional curve into object - * - * No cleaning of colored curves - this has to be done by caller - * No rereading of white data, so if you cannot rely on ::modified, do it in caller - * - */ - -static void -spdc_flush_white(SPDrawContext *dc, SPCurve *gc) +static void spdc_flush_white(SPDrawContext *dc, SPCurve *gc) { SPCurve *c; @@ -728,7 +632,7 @@ spdc_flush_white(SPDrawContext *dc, SPCurve *gc) return; } - /* Now we have to go back to item coordinates at last */ + // Now we have to go back to item coordinates at last c->transform( dc->white_item ? (dc->white_item)->dt2i_affine() : SP_EVENT_CONTEXT_DESKTOP(dc)->dt2doc() ); @@ -738,7 +642,7 @@ spdc_flush_white(SPDrawContext *dc, SPCurve *gc) Inkscape::XML::Document *xml_doc = doc->getReprDoc(); if ( c && !c->is_empty() ) { - /* We actually have something to write */ + // We actually have something to write bool has_lpe = false; Inkscape::XML::Node *repr; @@ -747,7 +651,7 @@ spdc_flush_white(SPDrawContext *dc, SPCurve *gc) has_lpe = sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(dc->white_item)); } else { repr = xml_doc->createElement("svg:path"); - /* Set style */ + // Set style sp_desktop_apply_style_tool(desktop, repr, tool_name(dc).data(), false); } @@ -760,7 +664,7 @@ spdc_flush_white(SPDrawContext *dc, SPCurve *gc) g_free(str); if (!dc->white_item) { - /* Attach repr */ + // Attach repr SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); // we finished the path; now apply any waiting LPEs or freehand shapes @@ -785,19 +689,15 @@ spdc_flush_white(SPDrawContext *dc, SPCurve *gc) c->unref(); - /* Flush pending updates */ + // Flush pending updates doc->ensureUpToDate(); } -/** - * Returns FIRST active anchor (the activated one). - */ -SPDrawAnchor * -spdc_test_inside(SPDrawContext *dc, Geom::Point p) +SPDrawAnchor *spdc_test_inside(SPDrawContext *dc, Geom::Point p) { SPDrawAnchor *active = NULL; - /* Test green anchor */ + // Test green anchor if (dc->green_anchor) { active = sp_draw_anchor_test(dc->green_anchor, p, TRUE); } @@ -812,11 +712,10 @@ spdc_test_inside(SPDrawContext *dc, Geom::Point p) return active; } -static void -spdc_reset_white(SPDrawContext *dc) +static void spdc_reset_white(SPDrawContext *dc) { if (dc->white_item) { - /* We do not hold refcount */ + // We do not hold refcount dc->white_item = NULL; } while (dc->white_curves) { @@ -829,10 +728,9 @@ spdc_reset_white(SPDrawContext *dc) } } -static void -spdc_free_colors(SPDrawContext *dc) +static void spdc_free_colors(SPDrawContext *dc) { - /* Red */ + // Red if (dc->red_bpath) { gtk_object_destroy(GTK_OBJECT(dc->red_bpath)); dc->red_bpath = NULL; @@ -840,7 +738,8 @@ spdc_free_colors(SPDrawContext *dc) if (dc->red_curve) { dc->red_curve = dc->red_curve->unref(); } - /* Blue */ + + // Blue if (dc->blue_bpath) { gtk_object_destroy(GTK_OBJECT(dc->blue_bpath)); dc->blue_bpath = NULL; @@ -848,7 +747,8 @@ spdc_free_colors(SPDrawContext *dc) if (dc->blue_curve) { dc->blue_curve = dc->blue_curve->unref(); } - /* Green */ + + // Green while (dc->green_bpaths) { gtk_object_destroy(GTK_OBJECT(dc->green_bpaths->data)); dc->green_bpaths = g_slist_remove(dc->green_bpaths, dc->green_bpaths->data); @@ -859,9 +759,10 @@ spdc_free_colors(SPDrawContext *dc) if (dc->green_anchor) { dc->green_anchor = sp_draw_anchor_destroy(dc->green_anchor); } - /* White */ + + // White if (dc->white_item) { - /* We do not hold refcount */ + // We do not hold refcount dc->white_item = NULL; } while (dc->white_curves) { @@ -874,7 +775,6 @@ spdc_free_colors(SPDrawContext *dc) } } -/* Create a single dot represented by a circle */ void spdc_create_single_dot(SPEventContext *ec, Geom::Point const &pt, char const *tool, guint event_state) { g_return_if_fail(!strcmp(tool, "/tools/freehand/pen") || !strcmp(tool, "/tools/freehand/pencil")); Glib::ustring tool_path = tool; @@ -886,10 +786,10 @@ void spdc_create_single_dot(SPEventContext *ec, Geom::Point const &pt, char cons SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); Inkscape::GC::release(repr); - /* apply the tool's current style */ + // apply the tool's current style sp_desktop_apply_style_tool(desktop, repr, tool, false); - /* find out stroke width (TODO: is there an easier way??) */ + // find out stroke width (TODO: is there an easier way??) double stroke_width = 3.0; gchar const *style_str = NULL; style_str = repr->attribute("style"); @@ -900,23 +800,24 @@ void spdc_create_single_dot(SPEventContext *ec, Geom::Point const &pt, char cons style->stroke_width.computed = 0; sp_style_unref(style); } - /* unset stroke and set fill color to former stroke color */ + + // unset stroke and set fill color to former stroke color gchar * str; str = g_strdup_printf("fill:#%06x;stroke:none;", sp_desktop_get_color_tool(desktop, tool, false) >> 8); repr->setAttribute("style", str); g_free(str); - /* put the circle where the mouse click occurred and set the diameter to the - current stroke width, multiplied by the amount specified in the preferences */ + // put the circle where the mouse click occurred and set the diameter to the + // current stroke width, multiplied by the amount specified in the preferences Inkscape::Preferences *prefs = Inkscape::Preferences::get(); Geom::Affine const i2d (item->i2dt_affine ()); Geom::Point pp = pt; double rad = 0.5 * prefs->getDouble(tool_path + "/dot-size", 3.0); if (event_state & GDK_MOD1_MASK) { - /* TODO: We vary the dot size between 0.5*rad and 1.5*rad, where rad is the dot size - as specified in prefs. Very simple, but it might be sufficient in practice. If not, - we need to devise something more sophisticated. */ + // TODO: We vary the dot size between 0.5*rad and 1.5*rad, where rad is the dot size + // as specified in prefs. Very simple, but it might be sufficient in practice. If not, + // we need to devise something more sophisticated. double s = g_random_double_range(-0.5, 0.5); rad *= (1 + s); } |
