summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-08-24 19:48:18 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-08-24 19:48:18 +0000
commit0094efd3c64b8a7ab96135c697a0ac265069a78f (patch)
tree564dc028eff4f5a7758ad762203e85f34f8e830d /src
parentupdate to trunk (diff)
parentRevert custom gdl patch (focus indicator of docked dialogs) for Quartz backen... (diff)
downloadinkscape-0094efd3c64b8a7ab96135c697a0ac265069a78f.tar.gz
inkscape-0094efd3c64b8a7ab96135c697a0ac265069a78f.zip
update to trunk
(bzr r13879.1.22)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/d2-sbasis.cpp20
-rw-r--r--src/2geom/numeric/fitting-model.h1
-rw-r--r--src/2geom/sbasis-geometric.cpp2
-rw-r--r--src/2geom/sbasis-roots.cpp6
-rw-r--r--src/2geom/sbasis-to-bezier.cpp4
-rw-r--r--src/2geom/sbasis.h73
-rw-r--r--src/CMakeLists.txt55
-rw-r--r--src/Makefile.am1
-rw-r--r--src/display/drawing-image.cpp2
-rw-r--r--src/extension/internal/gdkpixbuf-input.cpp4
-rw-r--r--src/file.cpp26
-rw-r--r--src/libgdl/gdl-dock-item-grip.c3
-rw-r--r--src/libgdl/gdl-dock-item.c3
-rw-r--r--src/libnrtype/Layout-TNG-OutIter.cpp2
-rw-r--r--src/live_effects/lpe-bendpath.h3
-rw-r--r--src/live_effects/lpe-bspline.cpp324
-rw-r--r--src/live_effects/lpe-bspline.h13
-rw-r--r--src/live_effects/lpe-spiro.cpp16
-rw-r--r--src/live_effects/lpe-spiro.h2
-rw-r--r--src/live_effects/spiro-converters.cpp32
-rw-r--r--src/live_effects/spiro-converters.h24
-rw-r--r--src/live_effects/spiro.cpp15
-rw-r--r--src/sp-factory.cpp2
-rw-r--r--src/sp-item-group.cpp10
-rw-r--r--src/sp-lpe-item.h36
-rw-r--r--src/svg/CMakeLists.txt2
-rw-r--r--src/ui/clipboard.cpp43
-rw-r--r--src/ui/dialog/filedialogimpl-gtkmm.cpp68
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp64
-rw-r--r--src/ui/tool/multi-path-manipulator.cpp9
-rw-r--r--src/ui/tool/node.cpp107
-rw-r--r--src/ui/tool/path-manipulator.cpp27
-rw-r--r--src/ui/tool/path-manipulator.h4
-rw-r--r--src/ui/tools/freehand-base.cpp71
-rw-r--r--src/ui/tools/pen-tool.cpp262
-rw-r--r--src/ui/tools/pen-tool.h104
-rw-r--r--src/xml/repr-util.cpp1
37 files changed, 605 insertions, 836 deletions
diff --git a/src/2geom/d2-sbasis.cpp b/src/2geom/d2-sbasis.cpp
index ebec16fdd..4f00ff6a5 100644
--- a/src/2geom/d2-sbasis.cpp
+++ b/src/2geom/d2-sbasis.cpp
@@ -147,12 +147,12 @@ Piecewise<D2<SBasis> > force_continuity(Piecewise<D2<SBasis> > const &f, double
SBasis &prev_sb=result.segs[prev][dim];
SBasis &cur_sb =result.segs[cur][dim];
Coord const c=pt0[dim];
- if (prev_sb.empty()) {
+ if (prev_sb.isZero(0)) {
prev_sb = SBasis(Linear(0.0, c));
} else {
prev_sb[0][1] = c;
}
- if (cur_sb.empty()) {
+ if (cur_sb.isZero(0)) {
cur_sb = SBasis(Linear(c, 0.0));
} else {
cur_sb[0][0] = c;
@@ -198,30 +198,22 @@ Point unitTangentAt(D2<SBasis> const & a, Coord t, unsigned n)
return Point (0,0);
}
-static void set_first_point(Piecewise<D2<SBasis> > &f, Point a){
+static void set_first_point(Piecewise<D2<SBasis> > &f, Point const &a){
if ( f.empty() ){
f.concat(Piecewise<D2<SBasis> >(D2<SBasis>(SBasis(Linear(a[X])), SBasis(Linear(a[Y])))));
return;
}
for (unsigned dim=0; dim<2; dim++){
- if (f.segs.front()[dim].size() == 0){
- f.segs.front()[dim] = SBasis(Linear(a[dim],0));
- }else{
- f.segs.front()[dim][0][0] = a[dim];
- }
+ f.segs.front()[dim][0][0] = a[dim];
}
}
-static void set_last_point(Piecewise<D2<SBasis> > &f, Point a){
+static void set_last_point(Piecewise<D2<SBasis> > &f, Point const &a){
if ( f.empty() ){
f.concat(Piecewise<D2<SBasis> >(D2<SBasis>(SBasis(Linear(a[X])), SBasis(Linear(a[Y])))));
return;
}
for (unsigned dim=0; dim<2; dim++){
- if (f.segs.back()[dim].size() == 0){
- f.segs.back()[dim] = SBasis(Linear(0,a[dim]));
- }else{
- f.segs.back()[dim][0][1] = a[dim];
- }
+ f.segs.back()[dim][0][1] = a[dim];
}
}
diff --git a/src/2geom/numeric/fitting-model.h b/src/2geom/numeric/fitting-model.h
index fb96d1d2a..b2ca92ad8 100644
--- a/src/2geom/numeric/fitting-model.h
+++ b/src/2geom/numeric/fitting-model.h
@@ -372,7 +372,6 @@ class LFMSBasis
void instance(SBasis & sb, ConstVectorView const& raw_data) const
{
- sb.clear();
sb.resize(m_order+1);
for (unsigned int i = 0, k = 0; i < raw_data.size(); i+=2, ++k)
{
diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp
index 4c474f7f0..8aaa15144 100644
--- a/src/2geom/sbasis-geometric.cpp
+++ b/src/2geom/sbasis-geometric.cpp
@@ -228,7 +228,7 @@ Geom::unitVector(D2<SBasis> const &V_in, double tol, unsigned order){
// -This done, unitVector will have jumps at zeros: fill the gaps with arcs of circles.
D2<SBasis> V = RescaleForNonVanishingEnds(V_in);
- if (V[0].empty() && V[1].empty())
+ if (V[0].isZero(0) && V[1].isZero(0))
return Piecewise<D2<SBasis> >(D2<SBasis>(Linear(1),SBasis()));
SBasis x = V[0], y = V[1];
SBasis r_eqn1, r_eqn2;
diff --git a/src/2geom/sbasis-roots.cpp b/src/2geom/sbasis-roots.cpp
index 57bef4c0f..e3e5e4441 100644
--- a/src/2geom/sbasis-roots.cpp
+++ b/src/2geom/sbasis-roots.cpp
@@ -222,7 +222,7 @@ static void multi_roots_internal(SBasis const &f,
double b,
double fb){
- if (f.size()==0){
+ if (f.isZero(0)){
int idx;
idx=upper_level(levels,0,vtol);
if (idx<(int)levels.size()&&fabs(levels.at(idx))<=vtol){
@@ -414,7 +414,7 @@ static void level_sets_internal(SBasis const &f,
double fb,
double tol=1e-5){
- if (f.size()==0){
+ if (f.isZero(0)){
unsigned idx;
idx=upper_level( levels, 0. );
if (idx<levels.size() && levels[idx].contains(0.)){
@@ -614,6 +614,7 @@ std::vector<double> roots1(SBasis const & s, Interval const ivl) {
std::vector<double> roots(SBasis const & s) {
switch(s.size()) {
case 0:
+ assert(false);
return std::vector<double>();
case 1:
return roots1(s);
@@ -628,6 +629,7 @@ std::vector<double> roots(SBasis const & s) {
std::vector<double> roots(SBasis const & s, Interval const ivl) {
switch(s.size()) {
case 0:
+ assert(false);
return std::vector<double>();
case 1:
return roots1(s, ivl);
diff --git a/src/2geom/sbasis-to-bezier.cpp b/src/2geom/sbasis-to-bezier.cpp
index 09fbb03ef..d9a90aace 100644
--- a/src/2geom/sbasis-to-bezier.cpp
+++ b/src/2geom/sbasis-to-bezier.cpp
@@ -100,9 +100,7 @@ int sgn(unsigned int j, unsigned int k)
*/
void sbasis_to_bezier (Bezier & bz, SBasis const& sb, size_t sz)
{
- if (sb.size() == 0) {
- THROW_RANGEERROR("size of sb is too small");
- }
+ assert(sb.size() > 0);
size_t q, n;
bool even;
diff --git a/src/2geom/sbasis.h b/src/2geom/sbasis.h
index 787e8b722..6923017be 100644
--- a/src/2geom/sbasis.h
+++ b/src/2geom/sbasis.h
@@ -83,49 +83,52 @@ public:
const_iterator end() const { return d.end();}
iterator begin() { return d.begin();}
iterator end() { return d.end();}
- bool empty() const {return d.empty();}
+ bool empty() const { return d.size() == 1 && d[0][0] == 0 && d[0][1] == 0; }
Linear &back() {return d.back();}
Linear const &back() const {return d.back();}
- void pop_back() { d.pop_back();}
- void resize(unsigned n) { d.resize(n);}
- void resize(unsigned n, Linear const& l) { d.resize(n, l);}
+ void pop_back() {
+ if (d.size() > 1) {
+ d.pop_back();
+ } else {
+ d[0][0] = 0;
+ d[0][1] = 0;
+ }
+ }
+ void resize(unsigned n) { d.resize(std::max<unsigned>(n, 1));}
+ void resize(unsigned n, Linear const& l) { d.resize(std::max<unsigned>(n, 1), l);}
void reserve(unsigned n) { d.reserve(n);}
- void clear() {d.clear();}
+ void clear() {
+ d.resize(1);
+ d[0][0] = 0;
+ d[0][1] = 0;
+ }
void insert(iterator before, const_iterator src_begin, const_iterator src_end) { d.insert(before, src_begin, src_end);}
Linear& at(unsigned i) { return d.at(i);}
//void insert(Linear* before, int& n, Linear const &l) { d.insert(std::vector<Linear>::iterator(before), n, l);}
bool operator==(SBasis const&B) const { return d == B.d;}
bool operator!=(SBasis const&B) const { return d != B.d;}
- operator std::vector<Linear>() { return d;}
-
- SBasis() {}
+ SBasis()
+ : d(1, Linear(0, 0))
+ {}
explicit SBasis(double a)
- : d(1)
- {
- d[0][0] = a;
- d[0][1] = a;
- }
+ : d(1, Linear(a, a))
+ {}
explicit SBasis(double a, double b)
- : d(1)
- {
- d[0][0] = a;
- d[0][1] = b;
- }
- SBasis(SBasis const & a) :
- d(a.d)
+ : d(1, Linear(a, b))
{}
- SBasis(std::vector<Linear> const & ls) :
- d(ls)
+ SBasis(SBasis const &a)
+ : d(a.d)
+ {}
+ SBasis(std::vector<Linear> const &ls)
+ : d(ls)
+ {}
+ SBasis(Linear const &bo)
+ : d(1, bo)
+ {}
+ SBasis(Linear* bo)
+ : d(1, bo ? *bo : Linear(0, 0))
{}
- SBasis(Linear const & bo) {
- push_back(bo);
- }
- SBasis(Linear* bo) {
- if (bo) {
- push_back(*bo);
- }
- }
explicit SBasis(size_t n, Linear const&l) : d(n, l) {}
SBasis(Coord c0, Coord c1, Coord c2, Coord c3)
@@ -179,6 +182,7 @@ public:
template <typename Iter>
SBasis(Iter first, Iter last) {
assert(std::distance(first, last) % 2 == 0);
+ assert(std::distance(first, last) >= 2);
for (; first != last; ++first) {
--last;
push_back(Linear(*first, *last));
@@ -188,14 +192,14 @@ public:
//IMPL: FragmentConcept
typedef double output_type;
inline bool isZero(double eps=EPSILON) const {
- if(empty()) return true;
+ assert(size() > 0);
for(unsigned i = 0; i < size(); i++) {
if(!(*this)[i].isZero(eps)) return false;
}
return true;
}
inline bool isConstant(double eps=EPSILON) const {
- if (empty()) return true;
+ assert(size() > 0);
if(!(*this)[0].isConstant(eps)) return false;
for (unsigned i = 1; i < size(); i++) {
if(!(*this)[i].isZero(eps)) return false;
@@ -212,6 +216,7 @@ public:
int degreesOfFreedom() const { return size()*2;}
double valueAt(double t) const {
+ assert(size() > 0);
double s = t*(1-t);
double p0 = 0, p1 = 0;
for(unsigned k = size(); k > 0; k--) {
@@ -239,11 +244,11 @@ public:
//MUTATOR PRISON
//remove extra zeros
void normalize() {
- while(!empty() && 0 == back()[0] && 0 == back()[1])
+ while(size() > 1 && back().isZero(0))
pop_back();
}
- void truncate(unsigned k) { if(k < size()) resize(k); }
+ void truncate(unsigned k) { if(k < size()) resize(std::max<size_t>(k, 1)); }
private:
void derive(); // in place version
};
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c416b0dea..ed93d5f14 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -509,8 +509,14 @@ set(inkscape_SRC
#add_inkscape_lib(sp_LIB "${sp_SRC}")
#add_inkscape_lib(inkscape_LIB "${inkscape_SRC}")
-# make executable for INKSCAPE
-add_executable(inkscape ${main_SRC} ${inkscape_SRC} ${sp_SRC})
+# Build everything except main and inkview.c in a CMake "object" library.
+# An object library is just a bunch of .o files. Linking them with main.c or inkview.c
+# we get the inkscape and inkview executables respectively.
+add_library(inkscape_base OBJECT ${inkscape_SRC} ${sp_SRC})
+
+# make executables for inkscape and inkview
+add_executable(inkscape ${main_SRC} $<TARGET_OBJECTS:inkscape_base>)
+add_executable(inkview inkview.cpp $<TARGET_OBJECTS:inkscape_base>)
if(UNIX)
# message after building.
@@ -523,31 +529,28 @@ endif()
add_dependencies(inkscape inkscape_version)
-target_link_libraries(inkscape
- # order from automake
- #sp_LIB
- #nrtype_LIB
-
- #inkscape_LIB
- #sp_LIB # annoying, we need both!
- nrtype_LIB # annoying, we need both!
+set(INKSCAPE_TARGET_LIBS
+ # order from automake
+ #sp_LIB
+ #nrtype_LIB
- croco_LIB
- avoid_LIB
- gdl_LIB
- cola_LIB
- vpsc_LIB
- livarot_LIB
- uemf_LIB
- 2geom_LIB
- depixelize_LIB
- util_LIB
- gc_LIB
+ #inkscape_LIB
+ #sp_LIB # annoying, we need both!
+ nrtype_LIB # annoying, we need both!
- ${INKSCAPE_LIBS}
+ croco_LIB
+ avoid_LIB
+ gdl_LIB
+ cola_LIB
+ vpsc_LIB
+ livarot_LIB
+ uemf_LIB
+ 2geom_LIB
+ depixelize_LIB
+ util_LIB
+ gc_LIB
+ ${INKSCAPE_LIBS}
)
-# TODO
-# make executable for INKVIEW
-#add_executable(inkview inkview.cpp)
-# ...
+target_link_libraries(inkscape ${INKSCAPE_TARGET_LIBS})
+target_link_libraries(inkview ${INKSCAPE_TARGET_LIBS})
diff --git a/src/Makefile.am b/src/Makefile.am
index 7a37f13e8..04e33c471 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -46,7 +46,6 @@ all_libs = \
$(FREETYPE_LIBS) \
$(kdeldadd) \
$(win32ldflags) \
- $(CARBON_LDFLAGS) \
$(LIBWPG_LIBS) \
$(LIBVISIO_LIBS) \
$(LIBCDR_LIBS) \
diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp
index 1594614ac..2a943d16c 100644
--- a/src/display/drawing-image.cpp
+++ b/src/display/drawing-image.cpp
@@ -132,7 +132,7 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar
}
}
- dc.paint(_opacity);
+ dc.paint(1);
} else { // outline; draw a rect instead
diff --git a/src/extension/internal/gdkpixbuf-input.cpp b/src/extension/internal/gdkpixbuf-input.cpp
index f5fab1fa2..f99c9050d 100644
--- a/src/extension/internal/gdkpixbuf-input.cpp
+++ b/src/extension/internal/gdkpixbuf-input.cpp
@@ -86,8 +86,8 @@ GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri)
ir = new ImageResolution(uri);
}
if (ir && ir->ok()) {
- xscale = 960.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi
- yscale = 960.0 / floor(10.*ir->y() + .5);
+ xscale = 960.0 / round(10.*ir->x() + .5); // round-off to 0.1 dpi
+ yscale = 960.0 / round(10.*ir->y() + .5);
} else {
xscale = 96.0 / defaultxdpi;
yscale = 96.0 / defaultxdpi;
diff --git a/src/file.cpp b/src/file.cpp
index 984bf7e08..7ae7d238a 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -1068,6 +1068,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place)
// copy definitions
desktop->doc()->importDefs(clipdoc);
+ Inkscape::XML::Node* clipboard = NULL;
// copy objects
std::vector<Inkscape::XML::Node*> pasted_objects;
for (Inkscape::XML::Node *obj = root->firstChild() ; obj ; obj = obj->next()) {
@@ -1082,6 +1083,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place)
continue;
}
if (!strcmp(obj->name(), "inkscape:clipboard")) {
+ clipboard = obj;
continue;
}
Inkscape::XML::Node *obj_copy = obj->duplicate(target_document->getReprDoc());
@@ -1090,12 +1092,32 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place)
pasted_objects.push_back(obj_copy);
}
- // Change the selection to the freshly pasted objects
+
+ /* take that stuff into account:
+ * if( use && selection->includes(use->get_original()) ){//we are copying something whose parent is also copied (!)
+ * transform = ((SPItem*)(use->get_original()->parent))->i2doc_affine().inverse() * transform;
+ * }
+ *
+ */
+ std::vector<Inkscape::XML::Node*> pasted_objects_not;
+ if(clipboard)
+ for (Inkscape::XML::Node *obj = clipboard->firstChild() ; obj ; obj = obj->next()) {
+ if(target_document->getObjectById(obj->attribute("id"))) continue;
+ Inkscape::XML::Node *obj_copy = obj->duplicate(target_document->getReprDoc());
+ target_parent->appendChild(obj_copy);
+ Inkscape::GC::release(obj_copy);
+ pasted_objects_not.push_back(obj_copy);
+ }
Inkscape::Selection *selection = desktop->getSelection();
+ selection->setReprList(pasted_objects_not);
+ Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false);
+ sp_selection_delete(desktop);
+
+ // Change the selection to the freshly pasted objects
selection->setReprList(pasted_objects);
// 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, false);
// Update (among other things) all curves in paths, for bounds() to work
diff --git a/src/libgdl/gdl-dock-item-grip.c b/src/libgdl/gdl-dock-item-grip.c
index d23eb7f98..9b3810c20 100644
--- a/src/libgdl/gdl-dock-item-grip.c
+++ b/src/libgdl/gdl-dock-item-grip.c
@@ -149,6 +149,8 @@ gdl_dock_item_grip_expose (GtkWidget *widget,
}
+/* see bug #950556: may contribute to regression with GTK2/Quartz */
+#if !defined(GDK_WINDOWING_QUARTZ)
if (gdl_dock_item_or_child_has_focus(grip->item)) {
gtk_paint_focus (gtk_widget_get_style (widget),
@@ -157,6 +159,7 @@ gdl_dock_item_grip_expose (GtkWidget *widget,
&event->area, widget,
NULL, 0, 0, -1, -1);
}
+#endif //GDK_WINDOWING_QUARTZ
return GTK_WIDGET_CLASS (gdl_dock_item_grip_parent_class)->expose_event (widget, event);
}
diff --git a/src/libgdl/gdl-dock-item.c b/src/libgdl/gdl-dock-item.c
index afcd4dfcb..af630e681 100644
--- a/src/libgdl/gdl-dock-item.c
+++ b/src/libgdl/gdl-dock-item.c
@@ -1064,8 +1064,11 @@ gdl_dock_item_paint (GtkWidget *widget,
"dockitem",
0, 0, -1, -1);
+/* see bug #950556: avoid regression with GTK2/Quartz */
+#if !defined(GDK_WINDOWING_QUARTZ)
if (GTK_IS_WIDGET(item->_priv->grip))
gtk_widget_queue_draw (GTK_WIDGET(item->_priv->grip));
+#endif
}
static gint
diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp
index 707897f50..137fe0a0f 100644
--- a/src/libnrtype/Layout-TNG-OutIter.cpp
+++ b/src/libnrtype/Layout-TNG-OutIter.cpp
@@ -507,7 +507,7 @@ void Layout::queryCursorShape(iterator const &it, Geom::Point &position, double
position[Geom::Y] = span->line(this).baseline_y + span->baseline_shift;
}
// up to now *position is the baseline point, not the final point which will be the bottom of the descent
- double vertical_scale = _glyphs.back().vertical_scale;
+ double vertical_scale = _glyphs.empty() ? 1.0 : _glyphs.back().vertical_scale;
if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) {
height = vertical_scale * span->line_height.ascent + span->line_height.descent;
diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h
index 16b8c6137..0871d532e 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);
-
-private:
PathParam bend_path;
+private:
ScalarParam prop_scale;
BoolParam scale_y_rel;
BoolParam vertical_pattern;
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index 6575700c7..0cae1dcb6 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -16,10 +16,12 @@
namespace Inkscape {
namespace LivePathEffect {
-const double HANDLE_CUBIC_GAP = 0.01;
+const double HANDLE_CUBIC_GAP = 0.001;
const double NO_POWER = 0.0;
const double DEFAULT_START_POWER = 0.3334;
const double DEFAULT_END_POWER = 0.6667;
+Geom::PathVector hp;
+void sp_bspline_drawHandle(Geom::Point p, double helper_size);
LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject)
: Effect(lpeobject),
@@ -67,15 +69,115 @@ void LPEBSpline::doOnApply(SPLPEItem const* lpeitem)
}
}
+void
+LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
+{
+ hp_vec.push_back(hp);
+}
+
+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<Parameter *>::iterator it = param_vector.begin();
+ while (it != param_vector.end()) {
+ if ((*it)->widget_is_visible) {
+ Parameter *param = *it;
+ Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
+ if (param->param_key == "weight") {
+ Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0));
+ Gtk::Button *default_weight =
+ Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight"))));
+ default_weight->signal_clicked()
+ .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight));
+ buttons->pack_start(*default_weight, true, true, 2);
+ Gtk::Button *make_cusp =
+ Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp"))));
+ make_cusp->signal_clicked()
+ .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp));
+ buttons->pack_start(*make_cusp, true, true, 2);
+ vbox->pack_start(*buttons, true, true, 2);
+ }
+ if (param->param_key == "weight" || param->param_key == "steps") {
+ Inkscape::UI::Widget::Scalar *widg_registered =
+ Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg));
+ widg_registered->signal_value_changed()
+ .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight));
+ widg = dynamic_cast<Gtk::Widget *>(widg_registered);
+ if (widg) {
+ Gtk::HBox * hbox_weight_steps = dynamic_cast<Gtk::HBox *>(widg);
+ std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children();
+ Gtk::Entry* entry_widget = dynamic_cast<Gtk::Entry *>(childList[1]);
+ entry_widget->set_width_chars(6);
+ }
+ }
+ if (param->param_key == "only_selected") {
+ Gtk::CheckButton *widg_registered =
+ Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
+ widg = dynamic_cast<Gtk::Widget *>(widg_registered);
+ }
+ if (param->param_key == "ignore_cusp") {
+ Gtk::CheckButton *widg_registered =
+ Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
+ widg = dynamic_cast<Gtk::Widget *>(widg_registered);
+ }
+ 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<Gtk::Widget *>(vbox);
+}
+
+void LPEBSpline::toDefaultWeight()
+{
+ changeWeight(DEFAULT_START_POWER);
+}
+
+void LPEBSpline::toMakeCusp()
+{
+ changeWeight(NO_POWER);
+}
+
+void LPEBSpline::toWeight()
+{
+ changeWeight(weight);
+}
+
+void LPEBSpline::changeWeight(double weight_ammount)
+{
+ SPPath *path = dynamic_cast<SPPath *>(sp_lpe_item);
+ if(path) {
+ SPCurve *curve = path->get_curve_for_edit();
+ doBSplineFromWidget(curve, weight_ammount);
+ gchar *str = sp_svg_write_path(curve->get_pathvector());
+ path->getRepr()->setAttribute("inkscape:original-d", str);
+ }
+}
+
void LPEBSpline::doEffect(SPCurve *curve)
{
+ sp_bspline_do_effect(curve, helper_size);
+}
+void sp_bspline_do_effect(SPCurve *curve, double helper_size)
+{
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();
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
@@ -99,20 +201,6 @@ void LPEBSpline::doEffect(SPCurve *curve)
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();
@@ -209,12 +297,11 @@ void LPEBSpline::doEffect(SPCurve *curve)
curve_n->curveto(point_at1, point_at2, node);
}
if(!are_near(node,curve_it1->finalPoint()) && helper_size > 0.0) {
- drawHandle(node, helper_size);
+ sp_bspline_drawHandle(node, helper_size);
}
++curve_it1;
++curve_it2;
}
- //y cerramos la curva
if (path_it->closed()) {
curve_n->closepath_current();
}
@@ -228,8 +315,8 @@ void LPEBSpline::doEffect(SPCurve *curve)
}
}
-void
-LPEBSpline::drawHandle(Geom::Point p, double helper_size)
+
+void sp_bspline_drawHandle(Geom::Point p, double helper_size)
{
char const * svgd = "M 1,0.5 A 0.5,0.5 0 0 1 0.5,1 0.5,0.5 0 0 1 0,0.5 0.5,0.5 0 0 1 0.5,0 0.5,0.5 0 0 1 1,0.5 Z";
Geom::PathVector pathv = sp_svg_read_pathv(svgd);
@@ -240,104 +327,6 @@ LPEBSpline::drawHandle(Geom::Point p, double helper_size)
hp.push_back(pathv[0]);
}
-void
-LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
-{
- hp_vec.push_back(hp);
-}
-
-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<Parameter *>::iterator it = param_vector.begin();
- while (it != param_vector.end()) {
- if ((*it)->widget_is_visible) {
- Parameter *param = *it;
- Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
- if (param->param_key == "weight") {
- Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0));
- Gtk::Button *default_weight =
- Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight"))));
- default_weight->signal_clicked()
- .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight));
- buttons->pack_start(*default_weight, true, true, 2);
- Gtk::Button *make_cusp =
- Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp"))));
- make_cusp->signal_clicked()
- .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp));
- buttons->pack_start(*make_cusp, true, true, 2);
- vbox->pack_start(*buttons, true, true, 2);
- }
- if (param->param_key == "weight" || param->param_key == "steps") {
- Inkscape::UI::Widget::Scalar *widg_registered =
- Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg));
- widg_registered->signal_value_changed()
- .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight));
- widg = dynamic_cast<Gtk::Widget *>(widg_registered);
- if (widg) {
- Gtk::HBox * hbox_weight_steps = dynamic_cast<Gtk::HBox *>(widg);
- std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children();
- Gtk::Entry* entry_widget = dynamic_cast<Gtk::Entry *>(childList[1]);
- entry_widget->set_width_chars(6);
- }
- }
- if (param->param_key == "only_selected") {
- Gtk::CheckButton *widg_registered =
- Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
- widg = dynamic_cast<Gtk::Widget *>(widg_registered);
- }
- if (param->param_key == "ignore_cusp") {
- Gtk::CheckButton *widg_registered =
- Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg));
- widg = dynamic_cast<Gtk::Widget *>(widg_registered);
- }
- 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<Gtk::Widget *>(vbox);
-}
-
-void LPEBSpline::toDefaultWeight()
-{
- changeWeight(DEFAULT_START_POWER);
-}
-
-void LPEBSpline::toMakeCusp()
-{
- changeWeight(NO_POWER);
-}
-
-void LPEBSpline::toWeight()
-{
- changeWeight(weight);
-}
-
-void LPEBSpline::changeWeight(double weight_ammount)
-{
- SPPath *path = dynamic_cast<SPPath *>(sp_lpe_item);
- if(path) {
- SPCurve *curve = path->get_curve_for_edit();
- doBSplineFromWidget(curve, weight_ammount);
- gchar *str = sp_svg_write_path(curve->get_pathvector());
- path->getRepr()->setAttribute("inkscape:original-d", str);
- }
-}
-
void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
{
using Geom::X;
@@ -367,20 +356,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
Geom::D2<Geom::SBasis> sbasis_in;
Geom::D2<Geom::SBasis> sbasis_out;
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();
@@ -390,91 +365,52 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount)
point_at0 = in->first_segment()->initialPoint();
point_at3 = in->first_segment()->finalPoint();
sbasis_in = in->first_segment()->toSBasis();
- if (!only_selected) {
- if (cubic) {
- if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) {
+ if (cubic) {
+ if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) {
+ if (isNodePointSelected(point_at0) || !only_selected) {
point_at1 = sbasis_in.valueAt(weight_ammount);
if (weight_ammount != NO_POWER) {
point_at1 =
Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
}
} else {
- point_at1 = in->first_segment()->initialPoint();
- }
- if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) {
- point_at2 = sbasis_in.valueAt(1 - weight_ammount);
- if (weight_ammount != NO_POWER) {
- point_at2 =
- Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
- }
- } else {
- point_at2 = in->first_segment()->finalPoint();
+ point_at1 = (*cubic)[1];
}
} else {
- if (!ignore_cusp && weight_ammount != NO_POWER) {
- point_at1 = sbasis_in.valueAt(weight_ammount);
- if (weight_ammount != NO_POWER) {
- point_at1 =
- Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
- }
+ point_at1 = in->first_segment()->initialPoint();
+ }
+ if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) {
+ if (isNodePointSelected(point_at3) || !only_selected) {
point_at2 = sbasis_in.valueAt(1 - weight_ammount);
if (weight_ammount != NO_POWER) {
point_at2 =
Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
}
} else {
- point_at1 = in->first_segment()->initialPoint();
- point_at2 = in->first_segment()->finalPoint();
+ point_at2 = (*cubic)[2];
}
+ } else {
+ point_at2 = in->first_segment()->finalPoint();
}
} else {
- if (cubic) {
- if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) {
- if (isNodePointSelected(point_at0)) {
- point_at1 = sbasis_in.valueAt(weight_ammount);
- if (weight_ammount != NO_POWER) {
- point_at1 =
- Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
- }
- } else {
- point_at1 = (*cubic)[1];
- }
+ if (!ignore_cusp && weight_ammount != NO_POWER) {
+ if (isNodePointSelected(point_at0) || !only_selected) {
+ point_at1 = sbasis_in.valueAt(weight_ammount);
+ point_at1 =
+ Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
} else {
point_at1 = in->first_segment()->initialPoint();
}
- if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) {
- if (isNodePointSelected(point_at3)) {
- point_at2 = sbasis_in.valueAt(1 - weight_ammount);
- if (weight_ammount != NO_POWER) {
- point_at2 =
- Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
- }
- } else {
- point_at2 = (*cubic)[2];
- }
+ if (isNodePointSelected(point_at3) || !only_selected) {
+ point_at2 = sbasis_in.valueAt(weight_ammount);
+ point_at2 =
+ Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
} else {
point_at2 = in->first_segment()->finalPoint();
}
} else {
- if (!ignore_cusp && weight_ammount != NO_POWER) {
- if (isNodePointSelected(point_at0)) {
- point_at1 = sbasis_in.valueAt(weight_ammount);
- point_at1 =
- Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP);
- } else {
- point_at1 = in->first_segment()->initialPoint();
- }
- if (isNodePointSelected(point_at3)) {
- point_at2 = sbasis_in.valueAt(weight_ammount);
- point_at2 =
- Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP);
- } else {
- point_at2 = in->first_segment()->finalPoint();
- }
- } else {
- point_at1 = in->first_segment()->initialPoint();
- point_at2 = in->first_segment()->finalPoint();
- }
+ point_at1 = in->first_segment()->initialPoint();
+ point_at2 = in->first_segment()->finalPoint();
}
}
in->reset();
diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h
index fc0f66353..033e85cf0 100644
--- a/src/live_effects/lpe-bspline.h
+++ b/src/live_effects/lpe-bspline.h
@@ -25,14 +25,13 @@ public:
virtual void doOnApply(SPLPEItem const* lpeitem);
virtual void doEffect(SPCurve *curve);
virtual void doBeforeEffect (SPLPEItem const* lpeitem);
- void drawHandle(Geom::Point p, double radiusHelperNodes);
- virtual void doBSplineFromWidget(SPCurve *curve, double value);
+ void doBSplineFromWidget(SPCurve *curve, double value);
void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec);
virtual Gtk::Widget *newWidget();
- virtual void changeWeight(double weightValue);
- virtual void toDefaultWeight();
- virtual void toMakeCusp();
- virtual void toWeight();
+ void changeWeight(double weightValue);
+ void toDefaultWeight();
+ void toMakeCusp();
+ void toWeight();
// TODO make this private
ScalarParam steps;
@@ -42,12 +41,12 @@ private:
BoolParam ignore_cusp;
BoolParam only_selected;
ScalarParam weight;
- Geom::PathVector hp;
LPEBSpline(const LPEBSpline &);
LPEBSpline &operator=(const LPEBSpline &);
};
+void sp_bspline_do_effect(SPCurve *curve, double helper_size);
} //namespace LivePathEffect
} //namespace Inkscape
diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp
index eefd25c7d..0d42596b2 100644
--- a/src/live_effects/lpe-spiro.cpp
+++ b/src/live_effects/lpe-spiro.cpp
@@ -37,6 +37,10 @@ LPESpiro::~LPESpiro()
void
LPESpiro::doEffect(SPCurve * curve)
{
+ sp_spiro_do_effect(curve);
+}
+
+void sp_spiro_do_effect(SPCurve *curve){
using Geom::X;
using Geom::Y;
@@ -54,7 +58,7 @@ LPESpiro::doEffect(SPCurve * curve)
// start of path
{
- Geom::Point p = path_it->front().pointAt(0);
+ Geom::Point p = path_it->initialPoint();
path[ip].x = p[X];
path[ip].y = p[Y];
path[ip].ty = '{' ; // for closed paths, this is overwritten
@@ -64,17 +68,7 @@ LPESpiro::doEffect(SPCurve * curve)
// 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 )
{
diff --git a/src/live_effects/lpe-spiro.h b/src/live_effects/lpe-spiro.h
index edce42280..c8aba53d9 100644
--- a/src/live_effects/lpe-spiro.h
+++ b/src/live_effects/lpe-spiro.h
@@ -27,6 +27,8 @@ private:
LPESpiro& operator=(const LPESpiro&);
};
+void sp_spiro_do_effect(SPCurve *curve);
+
}; //namespace LivePathEffect
}; //namespace Inkscape
diff --git a/src/live_effects/spiro-converters.cpp b/src/live_effects/spiro-converters.cpp
index f116d5256..ee214704c 100644
--- a/src/live_effects/spiro-converters.cpp
+++ b/src/live_effects/spiro-converters.cpp
@@ -21,43 +21,49 @@
namespace Spiro {
void
-ConverterSPCurve::moveto(double x, double y, bool is_open)
+ConverterSPCurve::moveto(double x, double y)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_curve.moveto(x, y);
- if (!is_open) {
- _curve.closepath();
- }
} else {
SPIRO_G_MESSAGE("Spiro: moveto not finite");
}
}
void
-ConverterSPCurve::lineto(double x, double y)
+ConverterSPCurve::lineto(double x, double y, bool close_last)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_curve.lineto(x, y);
+ if (close_last) {
+ _curve.closepath();
+ }
} else {
SPIRO_G_MESSAGE("Spiro: lineto not finite");
}
}
void
-ConverterSPCurve::quadto(double xm, double ym, double x3, double y3)
+ConverterSPCurve::quadto(double xm, double ym, double x3, double y3, bool close_last)
{
if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) {
_curve.quadto(xm, ym, x3, y3);
+ if (close_last) {
+ _curve.closepath();
+ }
} else {
SPIRO_G_MESSAGE("Spiro: quadto not finite");
}
}
void
-ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3)
+ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last)
{
if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) {
_curve.curveto(x1, y1, x2, y2, x3, y3);
+ if (close_last) {
+ _curve.closepath();
+ }
} else {
SPIRO_G_MESSAGE("Spiro: curveto not finite");
}
@@ -71,41 +77,43 @@ ConverterPath::ConverterPath(Geom::Path &path)
}
void
-ConverterPath::moveto(double x, double y, bool is_open)
+ConverterPath::moveto(double x, double y)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_path.start(Geom::Point(x, y));
- _path.close(!is_open);
} else {
SPIRO_G_MESSAGE("spiro moveto not finite");
}
}
void
-ConverterPath::lineto(double x, double y)
+ConverterPath::lineto(double x, double y, bool close_last)
{
if ( IS_FINITE(x) && IS_FINITE(y) ) {
_path.appendNew<Geom::LineSegment>( Geom::Point(x, y) );
+ _path.close(close_last);
} else {
SPIRO_G_MESSAGE("spiro lineto not finite");
}
}
void
-ConverterPath::quadto(double xm, double ym, double x3, double y3)
+ConverterPath::quadto(double xm, double ym, double x3, double y3, bool close_last)
{
if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) {
_path.appendNew<Geom::QuadraticBezier>(Geom::Point(xm, ym), Geom::Point(x3, y3));
+ _path.close(close_last);
} else {
SPIRO_G_MESSAGE("spiro quadto not finite");
}
}
void
-ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3)
+ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last)
{
if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) {
_path.appendNew<Geom::CubicBezier>(Geom::Point(x1, y1), Geom::Point(x2, y2), Geom::Point(x3, y3));
+ _path.close(close_last);
} else {
SPIRO_G_MESSAGE("spiro curveto not finite");
}
diff --git a/src/live_effects/spiro-converters.h b/src/live_effects/spiro-converters.h
index 90855d2d6..6182a5dcd 100644
--- a/src/live_effects/spiro-converters.h
+++ b/src/live_effects/spiro-converters.h
@@ -11,10 +11,10 @@ public:
ConverterBase() {};
virtual ~ConverterBase() {};
- virtual void moveto(double x, double y, bool is_open) = 0;
- virtual void lineto(double x, double y) = 0;
- virtual void quadto(double x1, double y1, double x2, double y2) = 0;
- virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3) = 0;
+ virtual void moveto(double x, double y) = 0;
+ virtual void lineto(double x, double y, bool close_last) = 0;
+ virtual void quadto(double x1, double y1, double x2, double y2, bool close_last) = 0;
+ virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) = 0;
};
@@ -27,10 +27,10 @@ public:
: _curve(curve)
{}
- virtual void moveto(double x, double y, bool is_open);
- virtual void lineto(double x, double y);
- virtual void quadto(double x1, double y1, double x2, double y2);
- virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3);
+ virtual void moveto(double x, double y);
+ virtual void lineto(double x, double y, bool close_last);
+ virtual void quadto(double x1, double y1, double x2, double y2, bool close_last);
+ virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last);
private:
SPCurve &_curve;
@@ -47,10 +47,10 @@ class ConverterPath : public ConverterBase {
public:
ConverterPath(Geom::Path &path);
- virtual void moveto(double x, double y, bool is_open);
- virtual void lineto(double x, double y);
- virtual void quadto(double x1, double y1, double x2, double y2);
- virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3);
+ virtual void moveto(double x, double y);
+ virtual void lineto(double x, double y, bool close_last);
+ virtual void quadto(double x1, double y1, double x2, double y2, bool close_last);
+ virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last);
private:
Geom::Path &_path;
diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp
index 46e53a0da..0ac2815bf 100644
--- a/src/live_effects/spiro.cpp
+++ b/src/live_effects/spiro.cpp
@@ -847,13 +847,13 @@ solve_spiro(spiro_seg *s, const int nseg)
static void
spiro_seg_to_otherpath(const double ks[4],
double x0, double y0, double x1, double y1,
- ConverterBase &bc, int depth)
+ ConverterBase &bc, int depth, bool close_last)
{
double bend = fabs(ks[0]) + fabs(.5 * ks[1]) + fabs(.125 * ks[2]) +
fabs((1./48) * ks[3]);
if (!(bend > 1e-8)) {
- bc.lineto(x1, y1);
+ bc.lineto(x1, y1, close_last);
} else {
double seg_ch = hypot(x1 - x0, y1 - y0);
double seg_th = atan2(y1 - y0, x1 - x0);
@@ -876,7 +876,7 @@ spiro_seg_to_otherpath(const double ks[4],
vl = (scale * (1./3)) * sin(th_even - th_odd);
ur = (scale * (1./3)) * cos(th_even + th_odd);
vr = (scale * (1./3)) * sin(th_even + th_odd);
- bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1);
+ bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1, close_last);
} else {
/* subdivide */
double ksub[4];
@@ -895,11 +895,11 @@ spiro_seg_to_otherpath(const double ks[4],
integrate_spiro(ksub, xysub);
xmid = x0 + cth * xysub[0] - sth * xysub[1];
ymid = y0 + cth * xysub[1] + sth * xysub[0];
- spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1);
+ spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1, false);
ksub[0] += .25 * ks[1] + (1./384) * ks[3];
ksub[1] += .125 * ks[2];
ksub[2] += (1./16) * ks[3];
- spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1);
+ spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1, close_last);
}
}
}
@@ -933,9 +933,10 @@ spiro_to_otherpath(const spiro_seg *s, int n, ConverterBase &bc)
double y1 = s[i + 1].y;
if (i == 0) {
- bc.moveto(x0, y0, s[0].ty == '{');
+ bc.moveto(x0, y0);
}
- spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0);
+ // on the last segment, set the 'close_last' flag if path is closed
+ spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0, (nsegs == n) && (i == n - 1));
}
}
diff --git a/src/sp-factory.cpp b/src/sp-factory.cpp
index 84329eaaf..20472d425 100644
--- a/src/sp-factory.cpp
+++ b/src/sp-factory.cpp
@@ -294,6 +294,8 @@ SPObject *SPFactory::createObject(std::string const& id)
{}
else if (id == "inkscape:clipboard") // SP node not necessary
{}
+ else if (id == "inkscape:_templateinfo") // ?
+ {}
else if (id.empty()) // comments
{}
else {
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 72cd5d7fa..5d96899b1 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -465,7 +465,7 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d
Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document());
// Merging transform
- Geom::Affine ctrans;
+ Geom::Affine ctrans = citem->transform * g;
// We should not apply the group's transformation to both a linked offset AND to its source
if (dynamic_cast<SPOffset *>(citem)) { // Do we have an offset at hand (whether it's dynamic or linked)?
SPItem *source = sp_offset_get_source(dynamic_cast<SPOffset *>(citem));
@@ -476,13 +476,9 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d
source = sp_offset_get_source(dynamic_cast<SPOffset *>(source));
}
if (source != NULL && // If true then we must be dealing with a linked offset ...
- group->isAncestorOf(source) == false) { // ... of which the source is not in the same group
- ctrans = citem->transform * g; // then we should apply the transformation of the group to the offset
- } else {
- ctrans = citem->transform;
+ group->isAncestorOf(source) ) { // ... of which the source is in the same group
+ ctrans = citem->transform; // then we should apply the transformation of the group to the offset
}
- } else {
- ctrans = citem->transform * g;
}
// FIXME: constructing a transform that would fully preserve the appearance of a
diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h
index 902271430..c35ad8411 100644
--- a/src/sp-lpe-item.h
+++ b/src/sp-lpe-item.h
@@ -26,21 +26,21 @@ class SPCurve;
class SPDesktop;
namespace Inkscape{
-namespace Display {
- class TemporaryItem;
-}
-namespace LivePathEffect{
- class LPEObjectReference;
- class Effect;
-}
+ namespace Display {
+ class TemporaryItem;
+ }
+ namespace LivePathEffect{
+ class LPEObjectReference;
+ class Effect;
+ }
}
typedef std::list<Inkscape::LivePathEffect::LPEObjectReference *> PathEffectList;
class SPLPEItem : public SPItem {
public:
- SPLPEItem();
- virtual ~SPLPEItem();
+ SPLPEItem();
+ virtual ~SPLPEItem();
int path_effects_enabled;
@@ -54,20 +54,20 @@ public:
std::vector<LivePathEffectObject const *> const &new_lpeobjs );
- 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, char 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);
+ virtual void update(SPCtx* ctx, unsigned int flags);
+ virtual void modified(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 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, unsigned int flags);
+ virtual Inkscape::XML::Node* write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, unsigned int flags);
- virtual void update_patheffect(bool write);
+ virtual void update_patheffect(bool write);
bool performPathEffect(SPCurve *curve);
diff --git a/src/svg/CMakeLists.txt b/src/svg/CMakeLists.txt
index f9d0bc52d..ff4bb63ab 100644
--- a/src/svg/CMakeLists.txt
+++ b/src/svg/CMakeLists.txt
@@ -2,7 +2,7 @@
set(svg_SRC
css-ostringstream.cpp
path-string.cpp
- sp-svg.def
+ #sp-svg.def
stringstream.cpp
strip-trailing-zeros.cpp
svg-affine.cpp
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();
};
}
diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp
index f7a437163..ce93bccab 100644
--- a/src/xml/repr-util.cpp
+++ b/src/xml/repr-util.cpp
@@ -528,6 +528,7 @@ unsigned int sp_repr_set_svg_double(Inkscape::XML::Node *repr, gchar const *key,
{
g_return_val_if_fail(repr != NULL, FALSE);
g_return_val_if_fail(key != NULL, FALSE);
+ g_return_val_if_fail(val==val, FALSE);//tests for nan
Inkscape::SVGOStringStream os;
os << val;