diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2015-08-24 19:48:18 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2015-08-24 19:48:18 +0000 |
| commit | 0094efd3c64b8a7ab96135c697a0ac265069a78f (patch) | |
| tree | 564dc028eff4f5a7758ad762203e85f34f8e830d /src/ui | |
| parent | update to trunk (diff) | |
| parent | Revert custom gdl patch (focus indicator of docked dialogs) for Quartz backen... (diff) | |
| download | inkscape-0094efd3c64b8a7ab96135c697a0ac265069a78f.tar.gz inkscape-0094efd3c64b8a7ab96135c697a0ac265069a78f.zip | |
update to trunk
(bzr r13879.1.22)
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/clipboard.cpp | 43 | ||||
| -rw-r--r-- | src/ui/dialog/filedialogimpl-gtkmm.cpp | 68 | ||||
| -rw-r--r-- | src/ui/dialog/inkscape-preferences.cpp | 64 | ||||
| -rw-r--r-- | src/ui/tool/multi-path-manipulator.cpp | 9 | ||||
| -rw-r--r-- | src/ui/tool/node.cpp | 107 | ||||
| -rw-r--r-- | src/ui/tool/path-manipulator.cpp | 27 | ||||
| -rw-r--r-- | src/ui/tool/path-manipulator.h | 4 | ||||
| -rw-r--r-- | src/ui/tools/freehand-base.cpp | 71 | ||||
| -rw-r--r-- | src/ui/tools/pen-tool.cpp | 262 | ||||
| -rw-r--r-- | src/ui/tools/pen-tool.h | 104 |
10 files changed, 282 insertions, 477 deletions
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index d6cf1f980..816daf2e5 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -154,6 +154,7 @@ private: Inkscape::XML::Node *_root; ///< Reference to the clipboard's root node Inkscape::XML::Node *_clipnode; ///< The node that holds extra information Inkscape::XML::Document *_doc; ///< Reference to the clipboard's Inkscape::XML::Document + std::set<SPItem*> cloned_elements; // we need a way to copy plain text AND remember its style; // the standard _clipnode is only available in an SVG tree, hence this special storage @@ -239,7 +240,7 @@ void ClipboardManagerImpl::copy(SPDesktop *desktop) // Special case for when the color picker ("dropper") is active - copies color under cursor if (tools_isactive(desktop, TOOLS_DROPPER)) { //_setClipboardColor(sp_dropper_context_get_color(desktop->event_context)); - _setClipboardColor(SP_DROPPER_CONTEXT(desktop->event_context)->get_color()); + _setClipboardColor(SP_DROPPER_CONTEXT(desktop->event_context)->get_color()); _discardInternalClipboard(); return; } @@ -523,7 +524,7 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a // resize each object in the selection if (separately) { - std::vector<SPItem*> itemlist=selection->itemList(); + std::vector<SPItem*> itemlist=selection->itemList(); for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ SPItem *item = *i; if (item) { @@ -630,7 +631,7 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) // at the first object to be <svg:path> or <svg:text>. // 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.")); @@ -662,7 +663,8 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) { // copy the defs used by all items - std::vector<SPItem*> itemlist=selection->itemList(); + std::vector<SPItem*> itemlist=selection->itemList(); + cloned_elements.clear(); for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ SPItem *item = *i; if (item) { @@ -673,14 +675,33 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) } // copy the representation of the items - std::vector<SPItem*> sorted_items(itemlist); + std::vector<SPObject*> sorted_items; + for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++) + sorted_items.push_back(*i); sort(sorted_items.begin(),sorted_items.end(),sp_object_compare_position_bool); - for(std::vector<SPItem*>::const_iterator i=sorted_items.begin();i!=sorted_items.end();i++){ - SPItem *item = *i; + //remove already copied elements from cloned_elements + std::vector<SPItem*>tr; + for(std::set<SPItem*>::iterator it = cloned_elements.begin();it!=cloned_elements.end();it++){ + if(std::find(sorted_items.begin(),sorted_items.end(),*it)!=sorted_items.end()) + tr.push_back(*it); + } + for(std::vector<SPItem*>::iterator it = tr.begin();it!=tr.end();it++){ + cloned_elements.erase(*it); + } + + sorted_items.insert(sorted_items.end(),cloned_elements.begin(),cloned_elements.end()); + + for(std::vector<SPObject*>::const_iterator i=sorted_items.begin();i!=sorted_items.end();i++){ + SPItem *item = dynamic_cast<SPItem*>(*i); if (item) { Inkscape::XML::Node *obj = item->getRepr(); - Inkscape::XML::Node *obj_copy = _copyNode(obj, _doc, _root); + Inkscape::XML::Node *obj_copy; + if(cloned_elements.find(item)==cloned_elements.end()) + obj_copy = _copyNode(obj, _doc, _root); + else + obj_copy = _copyNode(obj, _doc, _clipnode); + // copy complete inherited style SPCSSAttr *css = sp_repr_css_attr_inherited(obj, "style"); @@ -737,6 +758,12 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) */ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) { + SPUse *use=dynamic_cast<SPUse *>(item); + if(use){ + if(cloned_elements.insert(use->get_original()).second) + _copyUsedDefs(use->get_original()); + } + // copy fill and stroke styles (patterns and gradients) SPStyle *style = item->style; diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 17cf835cd..042637d22 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -199,37 +199,9 @@ void SVGPreview::showImage(Glib::ustring &theFileName) // files so we assume they are well formed. // std::cout << "SVGPreview::showImage: " << theFileName << std::endl; - std::ifstream input(theFileName.c_str()); - std::string width; std::string height; - if( !input ) { - std::cerr << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; - } else { - - std::string token; - - Glib::MatchInfo match_info; - Glib::RefPtr<Glib::Regex> regex1 = Glib::Regex::create("width=\"(.*)\""); - Glib::RefPtr<Glib::Regex> regex2 = Glib::Regex::create("height=\"(.*)\""); - - while( !input.eof() && (height.empty() || width.empty()) ) { - - input >> token; - // std::cout << "|" << token << "|" << std::endl; - - if (regex1->match(token, match_info)) { - width = match_info.fetch(1).raw(); - } - - if (regex2->match(token, match_info)) { - height = match_info.fetch(1).raw(); - } - - } - } - /*##################################### # LET'S HAVE SOME FUN WITH SVG! # Instead of just loading an image, why @@ -265,6 +237,46 @@ void SVGPreview::showImage(Glib::ustring &theFileName) gint imgWidth = img->get_width(); gint imgHeight = img->get_height(); + + Glib::ustring svg = ".svg"; + if (hasSuffix(fileName, svg)) { + std::ifstream input(theFileName.c_str()); + if( !input ) { + std::cerr << "SVGPreview::showImage: Failed to open file: " << theFileName << std::endl; + } else { + + std::string token; + + Glib::MatchInfo match_info; + Glib::RefPtr<Glib::Regex> regex1 = Glib::Regex::create("width=\"(.*)\""); + Glib::RefPtr<Glib::Regex> regex2 = Glib::Regex::create("height=\"(.*)\""); + + while( !input.eof() && (height.empty() || width.empty()) ) { + + input >> token; + // std::cout << "|" << token << "|" << std::endl; + + if (regex1->match(token, match_info)) { + width = match_info.fetch(1).raw(); + } + + if (regex2->match(token, match_info)) { + height = match_info.fetch(1).raw(); + } + + } + } + } + + // TODO: replace int to string conversion with std::to_string when fully C++11 compliant + if (height.empty() || width.empty()) { + std::ostringstream s_width; + std::ostringstream s_height; + s_width << imgWidth; + s_height << imgHeight; + width = s_width.str(); + height = s_height.str(); + } // Find the minimum scale to fit the image inside the preview area double scaleFactorX = (0.9 * (double)previewWidth) / ((double)imgWidth); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 98695e080..49864ccbb 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -522,22 +522,54 @@ void InkscapePreferences::initPageUI() Gtk::TreeModel::iterator iter_ui = this->AddPage(_page_ui, _("Interface"), PREFS_PAGE_UI); _path_ui = _page_list.get_model()->get_path(iter_ui); - Glib::ustring languages[] = {_("System default"), _("Albanian (sq)"), _("Amharic (am)"), _("Arabic (ar)"), _("Armenian (hy)"),_("Azerbaijani (az)"), _("Basque (eu)"), _("Belarusian (be)"), - _("Bulgarian (bg)"), _("Bengali (bn)"), _("Bengali/Bangladesh (bn_BD)"), _("Breton (br)"), _("Catalan (ca)"), _("Valencian Catalan (ca@valencia)"), _("Chinese/China (zh_CN)"), - _("Chinese/Taiwan (zh_TW)"), _("Croatian (hr)"), _("Czech (cs)"), - _("Danish (da)"), _("Dutch (nl)"), _("Dzongkha (dz)"), _("German (de)"), _("Greek (el)"), _("English (en)"), _("English/Australia (en_AU)"), - _("English/Canada (en_CA)"), _("English/Great Britain (en_GB)"), _("Pig Latin (en_US@piglatin)"), - _("Esperanto (eo)"), _("Estonian (et)"), _("Farsi (fa)"), _("Finnish (fi)"), - _("French (fr)"), _("Irish (ga)"), _("Galician (gl)"), _("Hebrew (he)"), _("Hungarian (hu)"), - _("Indonesian (id)"), _("Icelandic (is)"), _("Italian (it)"), _("Japanese (ja)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Korean (ko)"), _("Lithuanian (lt)"), _("Latvian (lv)"), _("Macedonian (mk)"), - _("Mongolian (mn)"), _("Nepali (ne)"), _("Norwegian Bokmål (nb)"), _("Norwegian Nynorsk (nn)"), _("Panjabi (pa)"), - _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), _("Romanian (ro)"), _("Russian (ru)"), - _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), - _("Swedish (sv)"),_("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), _("Ukrainian (uk)"), _("Vietnamese (vi)")}; - Glib::ustring langValues[] = {"", "sq", "am", "ar", "hy", "az", "eu", "be", "bg", "bn", "bn_BD", "br", "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", "da", "nl", - "dz", "de", "el", "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", "fa", "fi", "fr", "ga", - "gl", "he", "hu", "id", "is", "it", "ja", "km", "rw", "ko", "lt", "lv", "mk", "mn", "ne", "nb", "nn", "pa", - "pl", "pt", "pt_BR", "ro", "ru", "sr", "sr@latin", "sk", "sl", "es", "es_MX", "sv", "te", "th", "tr", "uk", "vi" }; + Glib::ustring languages[] = {_("System default"), + _("Albanian (sq)"), _("Amharic (am)"), _("Arabic (ar)"), _("Armenian (hy)"), _("Assamese (as)"), _("Azerbaijani (az)"), + _("Basque (eu)"), _("Belarusian (be)"), _("Bulgarian (bg)"), _("Bengali (bn)"), _("Bengali/Bangladesh (bn_BD)"), _("Bodo (brx)"), _("Breton (br)"), + _("Catalan (ca)"), _("Valencian Catalan (ca@valencia)"), _("Chinese/China (zh_CN)"), _("Chinese/Taiwan (zh_TW)"), _("Croatian (hr)"), _("Czech (cs)"), + _("Danish (da)"), _("Dogri (doi)"), _("Dutch (nl)"), _("Dzongkha (dz)"), + _("German (de)"), _("Greek (el)"), + _("English (en)"), _("English/Australia (en_AU)"), _("English/Canada (en_CA)"), _("English/Great Britain (en_GB)"), _("Pig Latin (en_US@piglatin)"), _("Esperanto (eo)"), _("Estonian (et)"), + _("Farsi (fa)"), _("Finnish (fi)"), _("French (fr)"), + _("Galician (gl)"), _("Gujarati (gu)"), + _("Hebrew (he)"), _("Hindi (hi)"), _("Hungarian (hu)"), + _("Icelandic (is)"), _("Indonesian (id)"), _("Irish (ga)"), _("Italian (it)"), + _("Japanese (ja)"), + _("Kannada (kn)"), _("Kashmiri in Peso-Arabic script (ks@aran)"), _("Kashmiri in Devanagari script (ks@deva)"), _("Khmer (km)"), _("Kinyarwanda (rw)"), _("Konkani (kok)"), _("Konkani in Latin script (kok@latin)"), _("Korean (ko)"), + _("Latvian (lv)"), _("Lithuanian (lt)"), + _("Macedonian (mk)"), _("Maithili (mai)"), _("Malayalam (ml)"), _("Manipuri (mni)"), _("Manipuri in Bengali script (mni@beng)"), _("Marathi (mr)"), _("Mongolian (mn)"), + _("Nepali (ne)"), _("Norwegian Bokmål (nb)"), _("Norwegian Nynorsk (nn)"), + _("Odia (or)"), + _("Panjabi (pa)"), _("Polish (pl)"), _("Portuguese (pt)"), _("Portuguese/Brazil (pt_BR)"), + _("Romanian (ro)"), _("Russian (ru)"), + _("Sanskrit (sa)"), _("Santali (sat)"), _("Santali in Devanagari script (sat@deva)"), _("Serbian (sr)"), _("Serbian in Latin script (sr@latin)"), + _("Sindhi (sd)"), _("Sindhi in Devanagari script (sd@deva)"), _("Slovak (sk)"), _("Slovenian (sl)"), _("Spanish (es)"), _("Spanish/Mexico (es_MX)"), _("Swedish (sv)"), + _("Tamil (ta)"), _("Telugu (te)"), _("Thai (th)"), _("Turkish (tr)"), + _("Ukrainian (uk)"), _("Urdu (ur)"), + _("Vietnamese (vi)")}; + Glib::ustring langValues[] = {"", + "sq", "am", "ar", "hy", "as", "az", + "eu", "be", "bg", "bn", "bn_BD", "brx", "br", + "ca", "ca@valencia", "zh_CN", "zh_TW", "hr", "cs", + "da", "doi", "nl", "dz", + "de", "el", + "en", "en_AU", "en_CA", "en_GB", "en_US@piglatin", "eo", "et", + "fa", "fi", "fr", + "gl", "gu", + "he", "hi", "hu", + "is", "id", "ga", "it", + "ja", + "kn", "ks@aran", "ks@deva", "km", "rw", "kok", "kok@latin", "ko", + "lv", "lt", + "mk", "mai", "ml", "mni", "mni@beng", "mr", "mn", + "ne", "nb", "nn", + "or", + "pa", "pl", "pt", "pt_BR", + "ro", "ru", + "sa", "sat", "sat@deva", "sr", "sr@latin", + "sd", "sd@deva", "sk", "sl", "es", "es_MX", "sv", + "ta", "te", "th", "tr", + "uk", "ur", + "vi" }; { // sorting languages according to translated name diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index 46c6246a1..9ec6f733f 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -683,13 +683,14 @@ bool MultiPathManipulator::event(Inkscape::UI::Tools::ToolBase *event_context, G //if the trace is bspline ( mode 2) if(mode==2){ // is this correct ? - if(del_preserves_shape ^ held_control(event->key)) + if(del_preserves_shape ^ held_control(event->key)){ deleteNodes(false); - else + } else { deleteNodes(true); - } - else + } + } else { deleteNodes(del_preserves_shape ^ held_control(event->key)); + } // Delete any selected gradient nodes as well event_context->deleteSelectedDrag(held_control(event->key)); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index ca6f5abb1..55d801c46 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -60,10 +60,8 @@ Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) namespace Inkscape { namespace UI { -/*const double handleCubicGap = 0.01;*/ -const double noPower = 0.0; -const double defaultStartPower = 0.3334; -/*const double defaultEndPower = 0.6667;*/ +const double NO_POWER = 0.0; +const double DEFAULT_START_POWER = 0.3334; ControlPoint::ColorSet Node::node_colors = { {0xbfbfbf00, 0x000000ff}, // normal fill, stroke @@ -142,6 +140,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; + double bspline_weight = 0.0; if (Geom::are_near(new_pos, _parent->position())) { // The handle becomes degenerate. @@ -176,8 +175,9 @@ 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)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),this)); + setPosition(_pm()._bsplineHandleReposition(this, false)); + bspline_weight = _pm()._bsplineHandlePosition(this, false); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), bspline_weight)); } return; } @@ -193,8 +193,9 @@ 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)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),this)); + setPosition(_pm()._bsplineHandleReposition(this, false)); + bspline_weight = _pm()._bsplineHandlePosition(this, false); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), bspline_weight)); } return; @@ -219,8 +220,9 @@ 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)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),this)); + setPosition(_pm()._bsplineHandleReposition(this, false)); + bspline_weight = _pm()._bsplineHandlePosition(this, false); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), bspline_weight)); } } @@ -299,7 +301,7 @@ bool Handle::_eventHandler(Inkscape::UI::Tools::ToolBase *event_context, GdkEven default: break; } break; - // new double click event to set the handlers of a node to the default proportion, defaultStartPower% + // new double click event to set the handlers of a node to the default proportion, DEFAULT_START_POWER% case GDK_2BUTTON_PRESS: handle_2button_press(); break; @@ -310,11 +312,11 @@ 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 defaultStartPower +//this function moves the handler and its oposite to the default proportion of DEFAULT_START_POWER void Handle::handle_2button_press(){ if(_pm()._isBSpline()){ - setPosition(_pm()._bsplineHandleReposition(this,defaultStartPower)); - this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(),defaultStartPower)); + setPosition(_pm()._bsplineHandleReposition(this, DEFAULT_START_POWER)); + this->other()->setPosition(_pm()._bsplineHandleReposition(this->other(), DEFAULT_START_POWER)); _pm().update(); } } @@ -375,7 +377,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,this)*steps)/steps); + new_pos=_pm()._bsplineHandleReposition(this,ceilf(_pm()._bsplineHandlePosition(this, false)*steps)/steps); } } @@ -549,7 +551,7 @@ Glib::ustring Handle::_getTip(unsigned state) const "<b>Auto node handle</b>: drag to convert to smooth node (%s)"), more); }else{ return format_tip(C_("Path handle tip", - "<b>BSpline node handle</b>: Shift to drag, double click to reset (%s). %g power"),more,_pm()._bsplineHandlePosition(h,NULL)); + "<b>BSpline node handle</b>: Shift to drag, double click to reset (%s). %g power"),more,_pm()._bsplineHandlePosition(h)); } } } @@ -627,22 +629,18 @@ void Node::move(Geom::Point const &new_pos) Geom::Point delta = new_pos - position(); // save the previous nodes strength to apply it again once the node is moved - double nodeWeight = noPower; - double nextNodeWeight = noPower; - double prevNodeWeight = noPower; + double nodeWeight = NO_POWER; + double nextNodeWeight = NO_POWER; + double prevNodeWeight = NO_POWER; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); - nodeWeight = fmax(_pm()._bsplineHandlePosition(n->front()),_pm()._bsplineHandlePosition(n->back())); + nodeWeight = fmax(_pm()._bsplineHandlePosition(n->front(), false),_pm()._bsplineHandlePosition(n->back(), false)); if(prevNode){ - if(prevNode->isEndNode()){ - prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(),prevNode->front()); - } + prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front()); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(),nextNode->back()); - } + nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back()); } setPosition(new_pos); @@ -659,18 +657,10 @@ 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->isEndNode()){ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNodeWeight)); - }else{ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNode->back())); - } + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNodeWeight)); - }else{ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNode->front())); - } + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); } } } @@ -681,22 +671,18 @@ void Node::transform(Geom::Affine const &m) Geom::Point old_pos = position(); // save the previous nodes strength to apply it again once the node is moved - double nodeWeight = noPower; - double nextNodeWeight = noPower; - double prevNodeWeight = noPower; + double nodeWeight = NO_POWER; + double nextNodeWeight = NO_POWER; + double prevNodeWeight = NO_POWER; Node *n = this; Node * nextNode = n->nodeToward(n->front()); Node * prevNode = n->nodeToward(n->back()); nodeWeight = _pm()._bsplineHandlePosition(n->front()); if(prevNode){ - if(prevNode->isEndNode()){ - prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front(),prevNode->front()); - } + prevNodeWeight = _pm()._bsplineHandlePosition(prevNode->front()); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back(),nextNode->back()); - } + nextNodeWeight = _pm()._bsplineHandlePosition(nextNode->back()); } setPosition(position() * m); @@ -709,21 +695,13 @@ void Node::transform(Geom::Affine const &m) // move the involved handlers, first the node ones, later the adjoining ones if(_pm()._isBSpline()){ - _front.setPosition(_pm()._bsplineHandleReposition(this->front(),nodeWeight)); - _back.setPosition(_pm()._bsplineHandleReposition(this->back(),nodeWeight)); + _front.setPosition(_pm()._bsplineHandleReposition(this->front(), nodeWeight)); + _back.setPosition(_pm()._bsplineHandleReposition(this->back(), nodeWeight)); if(prevNode){ - if(prevNode->isEndNode()){ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNodeWeight)); - }else{ - prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(),prevNode->back())); - } + prevNode->front()->setPosition(_pm()._bsplineHandleReposition(prevNode->front(), prevNodeWeight)); } if(nextNode){ - if(nextNode->isEndNode()){ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNodeWeight)); - }else{ - nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(),nextNode->front())); - } + nextNode->back()->setPosition(_pm()._bsplineHandleReposition(nextNode->back(), nextNodeWeight)); } } } @@ -913,15 +891,15 @@ void Node::setType(NodeType type, bool update_handles) break; default: break; } - /* in node type changes, about bspline traces, we can mantain them with noPower power in border mode, + /* in node type changes, about bspline traces, we can mantain them with NO_POWER power in border mode, or we give them the default power in curve mode */ if(_pm()._isBSpline()){ - double weight = noPower; - if(_pm()._bsplineHandlePosition(this->front()) != noPower ){ - weight = defaultStartPower; + double weight = NO_POWER; + if(_pm()._bsplineHandlePosition(this->front()) != NO_POWER ){ + weight = DEFAULT_START_POWER; } - _front.setPosition(_pm()._bsplineHandleReposition(this->front(),weight)); - _back.setPosition(_pm()._bsplineHandleReposition(this->back(),weight)); + _front.setPosition(_pm()._bsplineHandleReposition(this->front(), weight)); + _back.setPosition(_pm()._bsplineHandleReposition(this->back(), weight)); } } _type = type; @@ -1435,7 +1413,6 @@ Glib::ustring Node::_getTip(unsigned state) const { bool isBSpline = _pm()._isBSpline(); Handle *h = const_cast<Handle *>(&_front); - Handle *h2 = const_cast<Handle *>(&_back); if (state_held_shift(state)) { bool can_drag_out = (_next() && _front.isDegenerate()) || (_prev() && _back.isDegenerate()); if (can_drag_out) { @@ -1464,7 +1441,7 @@ Glib::ustring Node::_getTip(unsigned state) const // No modifiers: assemble tip from node type char const *nodetype = node_type_to_localized_string(_type); - double power = _pm()._bsplineHandlePosition(h,h2); + double power = _pm()._bsplineHandlePosition(h); if (_selection.transformHandlesEnabled() && selected()) { if (_selection.size() == 1 && !isBSpline) { return format_tip(C_("Path node tip", diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 848b10373..7b7bc98ee 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -56,9 +56,9 @@ enum PathChange { }; } // anonymous namespace -const double HANDLE_CUBIC_GAP = 0.01; +const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; -const double defaultStartPower = 0.3334; +const double DEFAULT_START_POWER = 0.3334; /** @@ -695,10 +695,12 @@ 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(),start.prev()->back())); + double bspline_weight = _bsplineHandlePosition(start.prev()->back(), false); + start.prev()->front()->setPosition(_bsplineHandleReposition(start.prev()->front(), bspline_weight)); } if(end){ - end->back()->setPosition(_bsplineHandleReposition(end->back(),end->front())); + double bspline_weight = _bsplineHandlePosition(end->front(), false); + end->back()->setPosition(_bsplineHandleReposition(end->back(),bspline_weight)); } } @@ -1033,7 +1035,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d line_inside_nodes->moveto(n->position()); line_inside_nodes->lineto(second->position()); sbasis_inside_nodes = line_inside_nodes->first_segment()->toSBasis(); - Geom::Point next = sbasis_inside_nodes.valueAt(defaultStartPower); + Geom::Point next = sbasis_inside_nodes.valueAt(DEFAULT_START_POWER); next = Geom::Point(next[Geom::X] + HANDLE_CUBIC_GAP,next[Geom::Y] + HANDLE_CUBIC_GAP); line_inside_nodes->reset(); n->front()->setPosition(next); @@ -1044,7 +1046,7 @@ NodeList::iterator PathManipulator::subdivideSegment(NodeList::iterator first, d line_inside_nodes->moveto(n->position()); line_inside_nodes->lineto(first->position()); sbasis_inside_nodes = line_inside_nodes->first_segment()->toSBasis(); - Geom::Point previous = sbasis_inside_nodes.valueAt(defaultStartPower); + Geom::Point previous = sbasis_inside_nodes.valueAt(DEFAULT_START_POWER); previous = Geom::Point(previous[Geom::X] + HANDLE_CUBIC_GAP,previous[Geom::Y] + HANDLE_CUBIC_GAP); n->back()->setPosition(previous); }else{ @@ -1277,13 +1279,10 @@ bool PathManipulator::_isBSpline() const { } // returns the corresponding strength to the position of the handlers -double PathManipulator::_bsplineHandlePosition(Handle *h, Handle *h2) +double PathManipulator::_bsplineHandlePosition(Handle *h, bool check_other) { using Geom::X; using Geom::Y; - if(h2){ - h = h2; - } double pos = NO_POWER; Node *n = h->parent(); Node * next_node = NULL; @@ -1296,16 +1295,16 @@ double PathManipulator::_bsplineHandlePosition(Handle *h, Handle *h2) pos = Geom::nearest_time(Geom::Point(h->position()[X] - HANDLE_CUBIC_GAP, h->position()[Y] - HANDLE_CUBIC_GAP), *line_inside_nodes->first_segment()); } } - if (pos == NO_POWER && !h2){ - return _bsplineHandlePosition(h, h->other()); + if (pos == NO_POWER && check_other){ + return _bsplineHandlePosition(h->other(), false); } return pos; } // give the location for the handler in the corresponding position -Geom::Point PathManipulator::_bsplineHandleReposition(Handle *h, Handle *h2) +Geom::Point PathManipulator::_bsplineHandleReposition(Handle *h, bool check_other) { - double pos = this->_bsplineHandlePosition(h, h2); + double pos = this->_bsplineHandlePosition(h, check_other); return _bsplineHandleReposition(h,pos); } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 4c6f74ba4..283cb610a 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -111,8 +111,8 @@ private: void _recalculateIsBSpline(); bool _isBSpline() const; - double _bsplineHandlePosition(Handle *h, Handle *h2 = NULL); - Geom::Point _bsplineHandleReposition(Handle *h, Handle *h2 = NULL); + double _bsplineHandlePosition(Handle *h, bool check_other = true); + Geom::Point _bsplineHandleReposition(Handle *h, bool check_other = true); Geom::Point _bsplineHandleReposition(Handle *h, double pos); void _createGeometryFromControlPoints(bool alert_LPE = false); unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape); diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index bdce1cd46..a889a12e6 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -215,7 +215,7 @@ static Glib::ustring const tool_name(FreehandBase *dc) : "/tools/freehand/pencil" ); } -static void spdc_paste_curve_as_freehand_shape(const SPCurve *c, FreehandBase *dc, SPItem *item) +static void spdc_paste_curve_as_freehand_shape(Geom::PathVector const &newpath, FreehandBase *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; @@ -223,8 +223,7 @@ static void spdc_paste_curve_as_freehand_shape(const SPCurve *c, FreehandBase *d Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - gchar *svgd = sp_svg_write_path(c->get_pathvector()); - static_cast<LPEPatternAlongPath*>(lpe)->pattern.paste_param_path(svgd); + static_cast<LPEPatternAlongPath*>(lpe)->pattern.set_new_value(newpath,true); } static void spdc_apply_powerstroke_shape(const std::vector<Geom::Point> & points, FreehandBase *dc, SPItem *item) @@ -278,10 +277,10 @@ static void spdc_apply_bend_shape(gchar const *svgd, FreehandBase *dc, SPItem *i Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); // write bend parameters: - lpe->getRepr()->setAttribute("bendpath", svgd); lpe->getRepr()->setAttribute("prop_scale", "1"); lpe->getRepr()->setAttribute("scale_y_rel", "false"); lpe->getRepr()->setAttribute("vertical", "false"); + static_cast<LPEBendPath*>(lpe)->bend_path.paste_param_path(svgd); } static void spdc_apply_simplify(std::string threshold, FreehandBase *dc, SPItem *item) @@ -386,7 +385,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, c->curveto(SHAPE_LENGTH, (1 + C1) * SHAPE_HEIGHT/2, (1 + C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, SHAPE_LENGTH/2, SHAPE_HEIGHT); c->curveto((1 - C1) * SHAPE_LENGTH/2, SHAPE_HEIGHT, 0, (1 + C1) * SHAPE_HEIGHT/2, 0, SHAPE_HEIGHT/2); c->closepath(); - spdc_paste_curve_as_freehand_shape(c, dc, item); + spdc_paste_curve_as_freehand_shape(c->get_pathvector(), dc, item); c->unref(); shape_applied = true; @@ -396,19 +395,27 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { // take shape from clipboard; Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - Glib::ustring svgd = cm->getPathParameter(SP_ACTIVE_DESKTOP); - if(svgd != ""){ - previous_shape_pathv = sp_svg_read_pathv(svgd.data()); - Inkscape::XML::Node *nv_repr = SP_ACTIVE_DESKTOP->getNamedView()->getRepr(); - if (nv_repr->attribute("inkscape:document-units")){ - double scale_units = Inkscape::Util::Quantity::convert(1, "px", nv_repr->attribute("inkscape:document-units")); - if (!Geom::are_near(scale_units, 1.0, Geom::EPSILON)) { - previous_shape_pathv *= Geom::Scale(scale_units); + if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ + SPItem * pasted_clipboard = dc->selection->singleItem(); + if(pasted_clipboard){ + Inkscape::XML::Node *pasted_clipboard_root = pasted_clipboard->getRepr(); + Inkscape::XML::Node *path = sp_repr_lookup_name(pasted_clipboard_root, "svg:path", -1); // unlimited search depth + if ( path != NULL ) { + gchar const *svgd = path->attribute("d"); + dc->selection->remove(SP_OBJECT(pasted_clipboard)); + previous_shape_pathv = sp_svg_read_pathv(svgd); + previous_shape_pathv *= pasted_clipboard->transform; + spdc_paste_curve_as_freehand_shape(previous_shape_pathv, dc, item); + + shape = CLIPBOARD; + shape_applied = true; + pasted_clipboard->deleteObject(); + } else { + shape = NONE; } + } else { + shape = NONE; } - SPCurve const *c = new SPCurve(previous_shape_pathv); - spdc_paste_curve_as_freehand_shape(c, dc, item); - shape_applied = true; } else { shape = NONE; } @@ -419,15 +426,14 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); if(cm->paste(SP_ACTIVE_DESKTOP,true) == true){ gchar const *svgd = item->getRepr()->attribute("d"); - Geom::PathVector path = sp_svg_read_pathv(svgd); - path *= item->i2doc_affine().inverse(); - svgd = sp_svg_write_path( path ); bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); + bend_item->transform.setTranslation(Geom::Point()); spdc_apply_bend_shape(svgd, dc, bend_item); - bend_item->transform = Geom::Affine(1,0,0,1,0,0); dc->selection->add(SP_OBJECT(bend_item)); + + shape = BEND_CLIPBOARD; } else { shape = NONE; } @@ -440,32 +446,37 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, { 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(); + spdc_paste_curve_as_freehand_shape(previous_shape_pathv, dc, item); shape_applied = true; + shape = CLIPBOARD; + } else{ + shape = NONE; } - shape = CLIPBOARD; } else { if(bend_item != NULL && bend_item->getRepr() != NULL){ gchar const *svgd = item->getRepr()->attribute("d"); - Geom::PathVector path = sp_svg_read_pathv(svgd); - path *= item->i2doc_affine().inverse(); - svgd = sp_svg_write_path( path ); dc->selection->add(SP_OBJECT(bend_item)); sp_selection_duplicate(dc->desktop); dc->selection->remove(SP_OBJECT(bend_item)); bend_item = dc->selection->singleItem(); if(bend_item){ bend_item->moveTo(item,false); - spdc_apply_bend_shape(svgd, dc, bend_item); + Geom::Coord expansion_X = bend_item->transform.expansionX(); + Geom::Coord expansion_Y = bend_item->transform.expansionY(); bend_item->transform = Geom::Affine(1,0,0,1,0,0); + bend_item->transform.setExpansionX(expansion_X); + bend_item->transform.setExpansionY(expansion_Y); + spdc_apply_bend_shape(svgd, dc, bend_item); dc->selection->add(SP_OBJECT(bend_item)); + + shape = BEND_CLIPBOARD; + } else { + shape = NONE; } + } else { + shape = NONE; } - shape = BEND_CLIPBOARD; } break; } diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index d924d8773..2ed366a7d 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 HANDLE_CUBIC_GAP = 0.01; +const double HANDLE_CUBIC_GAP = 0.001; const std::string& PenTool::getPrefsPath() { return PenTool::prefsPath; @@ -382,11 +382,12 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { 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); - _finish( false); + _finish(true); return true; } return false; } + bool ret = false; if (bevent.button == 1 && !this->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) @@ -860,7 +861,7 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) { bool PenTool::_handle2ButtonPress(GdkEventButton const &bevent) { bool ret = false; // only end on LMB double click. Otherwise horizontal scrolling causes ending of the path - if (this->npoints != 0 && bevent.button == 1) { + if (this->npoints != 0 && bevent.button == 1 && this->state != PenTool::CLOSE) { this->_finish(false); ret = true; } @@ -1717,9 +1718,9 @@ void PenTool::_bsplineSpiroBuild() //Effect *spr = static_cast<Effect*> ( new LPEbspline(lpeobj) ); //spr->doEffect(curve); if(this->bspline){ - this->_bsplineDoEffect(curve); + LivePathEffect::sp_bspline_do_effect(curve, 0); }else{ - this->_spiroDoEffect(curve); + LivePathEffect::sp_spiro_do_effect(curve); } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); @@ -1743,257 +1744,6 @@ void PenTool::_bsplineSpiroBuild() } } -//from LPE BSPLINE: -void PenTool::_bsplineDoEffect(SPCurve * curve) -{ - //const double NO_POWER = 0.0; - const double DEFAULT_START_POWER = 0.3334; - const double DEFAULT_END_POWER = 0.6667; - 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(); - - for (Geom::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(); - SPCurve *curve_n = new SPCurve(); - Geom::Point previousNode(0, 0); - Geom::Point node(0, 0); - Geom::Point point_at1(0, 0); - Geom::Point point_at2(0, 0); - Geom::Point next_point_at1(0, 0); - Geom::D2<Geom::SBasis> sbasis_in; - Geom::D2<Geom::SBasis> sbasis_out; - Geom::D2<Geom::SBasis> sbasis_helper; - 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(); - } - } - curve_n->moveto(curve_it1->initialPoint()); - while (curve_it1 != curve_endit) { - SPCurve *in = new SPCurve(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); - if (cubic) { - sbasis_in = in->first_segment()->toSBasis(); - if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { - point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER); - } else { - point_at1 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[1], *in->first_segment())); - } - if(are_near((*cubic)[2],(*cubic)[3]) && !are_near((*cubic)[1],(*cubic)[0])) { - point_at2 = sbasis_in.valueAt(DEFAULT_END_POWER); - } else { - point_at2 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[2], *in->first_segment())); - } - } else { - point_at1 = in->first_segment()->initialPoint(); - point_at2 = in->first_segment()->finalPoint(); - } - in->reset(); - delete in; - if ( curve_it2 != curve_endit ) { - SPCurve *out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it2); - if (cubic) { - sbasis_out = out->first_segment()->toSBasis(); - if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { - next_point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER); - } else { - next_point_at1 = sbasis_out.valueAt(Geom::nearest_time((*cubic)[1], *out->first_segment())); - } - } else { - next_point_at1 = out->first_segment()->initialPoint(); - } - out->reset(); - delete out; - } - if (path_it->closed() && curve_it2 == curve_endit) { - SPCurve *start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - Geom::D2<Geom::SBasis> sbasis_start = start->first_segment()->toSBasis(); - SPCurve *line_helper = new SPCurve(); - cubic = dynamic_cast<Geom::CubicBezier const *>(&*path_it->begin()); - if (cubic) { - line_helper->moveto(sbasis_start.valueAt( - Geom::nearest_time((*cubic)[1], *start->first_segment()))); - } else { - line_helper->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<Geom::SBasis> sbasis_end = end->first_segment()->toSBasis(); - cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); - if (cubic) { - line_helper->lineto(sbasis_end.valueAt( - Geom::nearest_time((*cubic)[2], *end->first_segment()))); - } else { - line_helper->lineto(end->first_segment()->finalPoint()); - } - end->reset(); - delete end; - sbasis_helper = line_helper->first_segment()->toSBasis(); - line_helper->reset(); - delete line_helper; - node = sbasis_helper.valueAt(0.5); - curve_n->curveto(point_at1, point_at2, node); - curve_n->move_endpoints(node, node); - } else if ( curve_it2 == curve_endit) { - curve_n->curveto(point_at1, point_at2, curve_it1->finalPoint()); - curve_n->move_endpoints(path_it->begin()->initialPoint(), curve_it1->finalPoint()); - } else { - SPCurve *line_helper = new SPCurve(); - line_helper->moveto(point_at2); - line_helper->lineto(next_point_at1); - sbasis_helper = line_helper->first_segment()->toSBasis(); - line_helper->reset(); - delete line_helper; - previousNode = node; - node = sbasis_helper.valueAt(0.5); - Geom::CubicBezier const *cubic2 = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); - if((cubic && are_near((*cubic)[0],(*cubic)[1])) || (cubic2 && are_near((*cubic2)[2],(*cubic2)[3]))) { - node = curve_it1->finalPoint(); - } - curve_n->curveto(point_at1, point_at2, node); - } - ++curve_it1; - ++curve_it2; - } - //y cerramos la curva - if (path_it->closed()) { - curve_n->closepath_current(); - } - curve->append(curve_n, false); - curve_n->reset(); - delete curve_n; - } -} - -//Spiro function cloned from lpe-spiro.cpp -// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp -void PenTool::_spiroDoEffect(SPCurve * curve) -{ - using Geom::X; - using Geom::Y; - - 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; - - { - Geom::Point p = path_it->front().pointAt(0); - path[ip].x = p[X]; - path[ip].y = p[Y]; - path[ip].ty = '{' ; - ip++; - } - - 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(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } - - while ( curve_it2 != curve_endit ) - { - Geom::Point p = curve_it1->finalPoint(); - path[ip].x = p[X]; - path[ip].y = p[Y]; - - 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++; - } - - Geom::Point p = curve_it1->finalPoint(); - path[ip].x = p[X]; - path[ip].y = p[Y]; - if (path_it->closed()) { - Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front()); - switch (nodetype) { - case Geom::NODE_NONE: - 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 { - path[ip].ty = '}'; - ip++; - } - - int sp_len = ip; - Spiro::spiro_run(path, sp_len, *curve); - ip = 0; - } - - g_free (path); -} - void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint status) { g_assert( this->npoints != 0 ); diff --git a/src/ui/tools/pen-tool.h b/src/ui/tools/pen-tool.h index 0ae16caf0..5a21e3bac 100644 --- a/src/ui/tools/pen-tool.h +++ b/src/ui/tools/pen-tool.h @@ -22,21 +22,21 @@ namespace Tools { */ class PenTool : public FreehandBase { public: - PenTool(); - PenTool(gchar const *const *cursor_shape, gint hot_x, gint hot_y); - virtual ~PenTool(); - - enum Mode { - MODE_CLICK, - MODE_DRAG - }; - - enum State { - POINT, - CONTROL, - CLOSE, - STOP - }; + PenTool(); + PenTool(gchar const *const *cursor_shape, gint hot_x, gint hot_y); + virtual ~PenTool(); + + enum Mode { + MODE_CLICK, + MODE_DRAG + }; + + enum State { + POINT, + CONTROL, + CLOSE, + STOP + }; Geom::Point p[5]; @@ -66,28 +66,28 @@ public: bool events_disabled; - static const std::string prefsPath; + static const std::string prefsPath; - virtual const std::string& getPrefsPath(); + virtual const std::string& getPrefsPath(); - int nextParaxialDirection(Geom::Point const &pt, Geom::Point const &origin, guint state) const; - void setPolylineMode(); - bool hasWaitingLPE(); + int nextParaxialDirection(Geom::Point const &pt, Geom::Point const &origin, guint state) const; + void setPolylineMode(); + bool hasWaitingLPE(); void waitForLPEMouseClicks(Inkscape::LivePathEffect::EffectType effect_type, unsigned int num_clicks, bool use_polylines = true); protected: - virtual void setup(); - virtual void finish(); - virtual void set(const Inkscape::Preferences::Entry& val); - virtual bool root_handler(GdkEvent* event); - virtual bool item_handler(SPItem* item, GdkEvent* event); + virtual void setup(); + virtual void finish(); + virtual void set(const Inkscape::Preferences::Entry& val); + virtual bool root_handler(GdkEvent* event); + virtual bool item_handler(SPItem* item, GdkEvent* event); private: - bool _handleButtonPress(GdkEventButton const &bevent); - bool _handleMotionNotify(GdkEventMotion const &mevent); - bool _handleButtonRelease(GdkEventButton const &revent); - bool _handle2ButtonPress(GdkEventButton const &bevent); - bool _handleKeyPress(GdkEvent *event); + bool _handleButtonPress(GdkEventButton const &bevent); + bool _handleMotionNotify(GdkEventMotion const &mevent); + bool _handleButtonRelease(GdkEventButton const &revent); + bool _handle2ButtonPress(GdkEventButton const &bevent); + bool _handleKeyPress(GdkEvent *event); //adds spiro & bspline modes void _penContextSetMode(guint mode); //this function changes the colors red, green and blue making them transparent or not depending on if the function uses spiro @@ -110,40 +110,36 @@ private: void _bsplineSpiroEndAnchorOn(); //closes the curve with the last node in CUSP mode void _bsplineSpiroEndAnchorOff(); - //CHECK: join all the curves "in game" and we call doEffect function + //apply the effect void _bsplineSpiroBuild(); - //function bspline cloned from lpe-bspline.cpp - void _bsplineDoEffect(SPCurve * curve); - //function spiro cloned from lpe-spiro.cpp - void _spiroDoEffect(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); - void _finishSegment(Geom::Point p, guint state); + + 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); + void _finishSegment(Geom::Point p, guint state); bool _undoLastPoint(); - void _finish(gboolean closed); + void _finish(gboolean closed); - void _resetColors(); + void _resetColors(); - void _disableEvents(); - void _enableEvents(); + void _disableEvents(); + void _enableEvents(); - void _setToNearestHorizVert(Geom::Point &pt, guint const state, bool snap) const; + void _setToNearestHorizVert(Geom::Point &pt, guint const state, bool snap) const; - void _setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_to_compare, gchar const *message); + void _setAngleDistanceStatusMessage(Geom::Point const p, int pc_point_to_compare, gchar const *message); - void _lastpointToLine(); - void _lastpointToCurve(); - void _lastpointMoveScreen(gdouble x, gdouble y); - void _lastpointMove(gdouble x, gdouble y); - void _redrawAll(); + void _lastpointToLine(); + void _lastpointToCurve(); + void _lastpointMoveScreen(gdouble x, gdouble y); + void _lastpointMove(gdouble x, gdouble y); + void _redrawAll(); - void _endpointSnapHandle(Geom::Point &p, guint const state) const; - void _endpointSnap(Geom::Point &p, guint const state) const; + void _endpointSnapHandle(Geom::Point &p, guint const state) const; + void _endpointSnap(Geom::Point &p, guint const state) const; - void _cancel(); + void _cancel(); }; } |
