diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-11-23 23:36:49 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-11-23 23:36:49 +0000 |
| commit | 0969085ddf607a7a98cf7fd6d9b10da5fbebe62d (patch) | |
| tree | 59b2bc9ed3412ab2de4c703ef30342dfe2401704 /src/ui/tools/freehand-base.cpp | |
| parent | refactor from lastApplied (diff) | |
| parent | Fixed a bug pointed by suv running from comand line, also removed another des... (diff) | |
| download | inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.tar.gz inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.zip | |
fixing to trunk
(bzr r12588.1.34)
Diffstat (limited to 'src/ui/tools/freehand-base.cpp')
| -rw-r--r-- | src/ui/tools/freehand-base.cpp | 232 |
1 files changed, 146 insertions, 86 deletions
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 4f2ec6c48..68b57dc90 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -31,7 +31,7 @@ #include "desktop-handles.h" #include "desktop-style.h" #include "document.h" -#include "draw-anchor.h" +#include "ui/draw-anchor.h" #include "macros.h" #include "message-stack.h" #include "ui/tools/pen-tool.h" @@ -45,6 +45,7 @@ #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" @@ -80,6 +81,7 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape, gint hot_x, gint ho , red_color(0xff00007f) , blue_color(0x0000ff7f) , green_color(0x00ff007f) + , highlight_color(0x0000007f) , red_bpath(NULL) , red_curve(NULL) , blue_bpath(NULL) @@ -91,6 +93,7 @@ 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) , ea(NULL) , waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE) @@ -146,6 +149,9 @@ void FreehandBase::setup() { this->green_anchor = NULL; this->green_closed = FALSE; + // Create start anchor alternative curve + this->overwriteCurve = new SPCurve(); + this->attach = TRUE; spdc_attach_selection(this, this->selection); } @@ -227,6 +233,32 @@ static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); static_cast<LPEPowerStroke*>(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); + } + + std::ostringstream s; + s.imbue(std::locale::classic()); + s << "0," << stroke_width / 2.; + // write powerstroke parameters: lpe->getRepr()->setAttribute("start_linecap_type", "zerowidth"); lpe->getRepr()->setAttribute("end_linecap_type", "zerowidth"); @@ -234,6 +266,7 @@ static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & 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", s.str().c_str()); } @@ -241,7 +274,9 @@ static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *i { using namespace Inkscape::LivePathEffect; - Effect::createAndApply(BEND_PATH, dc->desktop->doc(), item); + if(!SP_LPE_ITEM(item)->hasPathEffectOfType(BEND_PATH)){ + Effect::createAndApply(BEND_PATH, dc->desktop->doc(), item); + } Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); // write bend parameters: @@ -261,37 +296,41 @@ 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 + if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { + Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); + } + + //Store the clipboard path to apply in the future without the use of clipboard - //Store the clipboard path to apply in the future without the use of clipboard static Geom::PathVector previous_shape_pathv; - //Last shape applied type "-1" means "no previous shape" - int shape = prefs->getInt(tool_name(dc) + "/shape", 0); + enum shapeType { NONE, TRIANGLE_IN, TRIANGLE_OUT, ELLIPSE, CLIPBOARD, BEND_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"); - static SPItem *itemEnd; + static SPItem *bendItem; #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 - if(shape == 6){ + + if(shape == LAST_APPLIED){ + shape = previous_shape_type; - if(shape == 4){ - shape = 6; - } - if(shape == 5){ - shape = 7; - } - if(previous_shape_type == -1){ - shape = 0; + if(shape == CLIPBOARD || shape == BEND_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<Geom::Point> points(1); @@ -301,7 +340,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(); @@ -312,7 +351,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(); @@ -329,7 +368,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, 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); @@ -342,74 +381,56 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, shape_applied = true; break; } - case 5: + case BEND_CLIPBOARD: { - // take shape from clipboard; TODO: catch the case where clipboard is empty Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,false) == true){ gchar const *svgd = item->getRepr()->attribute("d"); - item->deleteObject(); - if(itemEnd != NULL && itemEnd->getRepr() != NULL) - itemEnd->deleteObject(); - Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); - sp_selection_group(selection, dc->desktop); - GSList *items = const_cast<GSList *>(selection->itemList()); - SPObject *obj = reinterpret_cast<SPObject *>(g_slist_nth_data(items,0)); - if(SP_IS_OBJECT(obj)){ - itemEnd = SP_ITEM(obj); - sp_selection_duplicate(dc->desktop); - itemEnd->setExplicitlyHidden(true); - items = const_cast<GSList *>(selection->itemList()); - obj = reinterpret_cast<SPObject *>(g_slist_nth_data(items,0)); - if(SP_IS_OBJECT(obj)){ - spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); - SP_ITEM(obj)->setExplicitlyHidden(false); - selection->set(SP_ITEM(obj),true); - } - } - } - break; - } - case 6: - { - 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; + item->getRepr()->setAttribute("d", ""); + bendItem = dc->selection->singleItem(); + item->setSuccessor(bendItem); + item = bendItem; + g_assert(item != NULL); + spdc_apply_bend_shape(svgd, dc, item); + dc->selection->set(item,true); } - - shape = previous_shape_type; break; } - case 7: + case LAST_APPLIED: { - // take shape from clipboard; TODO: catch the case where clipboard is empty - if(itemEnd != NULL && itemEnd->getRepr() != NULL){ - gchar const *svgd = item->getRepr()->attribute("d"); - item->deleteObject(); - Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); - selection->add(SP_OBJECT(itemEnd)); - sp_selection_duplicate(dc->desktop); - selection->remove(SP_OBJECT(itemEnd)); - GSList *items = const_cast<GSList *>(selection->itemList()); - SPObject *obj = reinterpret_cast<SPObject *>(g_slist_nth_data(items,0)); - if(SP_IS_OBJECT(obj)){ - SP_ITEM(obj)->getRepr()->setAttribute("inkscape:path-effect", NULL); - spdc_apply_bend_shape(svgd, dc, SP_ITEM(obj)); - SP_ITEM(obj)->setExplicitlyHidden(false); - selection->set(SP_ITEM(obj),true); + if(previous_shape_type == CLIPBOARD){ + 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; + } + } else { + if(bendItem != NULL && bendItem->getRepr() != NULL){ + gchar const *svgd = item->getRepr()->attribute("d"); + item->getRepr()->setAttribute("d", ""); + Inkscape::Selection *selection = sp_desktop_selection(dc->desktop); + selection->add(SP_OBJECT(bendItem)); + sp_selection_duplicate(dc->desktop); + selection->remove(SP_OBJECT(bendItem)); + bendItem = dc->selection->singleItem(); + item->setSuccessor(bendItem); + item = bendItem; + g_assert(item != NULL); + spdc_apply_bend_shape(svgd, dc, item); + dc->selection->set(item,true); } } - shape = previous_shape_type; break; } default: break; } - previous_shape_type = shape; + if(shape != LAST_APPLIED){ + 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(); @@ -424,8 +445,9 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, sp_repr_css_attr_unref(css); return; } - if(previous_shape_type == 5)return; - + if(previous_shape_type == 5 || previous_shape_type == 6 || previous_shape_type == 7){ + return; + } if (dc->waiting_LPE_type != INVALID_LPE) { Effect::createAndApply(dc->waiting_LPE_type, dc->desktop->doc(), item); dc->waiting_LPE_type = INVALID_LPE; @@ -564,7 +586,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) { @@ -611,9 +633,20 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) 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(); + if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 || + prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){ + dc->overwriteCurve->append_continuous(c, 0.0625); + c->unref(); + 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->overwriteCurve); + } + }else{ + dc->sa->curve->append_continuous(c, 0.0625); + c->unref(); + dc->sa->curve->closepath_current(); + } spdc_flush_white(dc, NULL); return; } @@ -622,6 +655,10 @@ 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); } @@ -634,6 +671,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<Geom::CubicBezier const*>(&*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(); } @@ -647,7 +703,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed) static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) { SPCurve *c; - if (dc->white_curves) { g_assert(dc->white_item); c = SPCurve::concat(dc->white_curves); @@ -677,6 +732,7 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) bool has_lpe = false; Inkscape::XML::Node *repr; + if (dc->white_item) { repr = dc->white_item->getRepr(); has_lpe = SP_LPE_ITEM(dc->white_item)->hasPathEffectRecursive(); @@ -700,12 +756,17 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc) // we finished the path; now apply any waiting LPEs or freehand shapes spdc_check_for_and_apply_waiting_LPE(dc, item, c); - - if(previous_shape_type != 5) dc->selection->set(repr); + if(previous_shape_type == -1 || previous_shape_type == 5 || previous_shape_type == 6){ + return; + } + if(previous_shape_type != 7){ + dc->selection->set(repr); + } + Inkscape::GC::release(repr); - if(previous_shape_type != 5) item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - if(previous_shape_type != 5) item->doWriteTransform(item->getRepr(), item->transform, NULL, true); - if(previous_shape_type != 5) item->updateRepr(); + item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + item->updateRepr(); + item->doWriteTransform(item->getRepr(), item->transform, NULL, true); } DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, @@ -740,7 +801,6 @@ SPDrawAnchor *spdc_test_inside(FreehandBase *dc, Geom::Point p) active = na; } } - return active; } |
