summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-11-15 17:34:32 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-11-15 17:34:32 +0000
commit69ef82447f23d5ebd3abc6a5903b10bbdb1b12f4 (patch)
treedcaafc31c93eaaf606e1260d99c83b963aba4822 /src
parentignore this commit (diff)
downloadinkscape-69ef82447f23d5ebd3abc6a5903b10bbdb1b12f4.tar.gz
inkscape-69ef82447f23d5ebd3abc6a5903b10bbdb1b12f4.zip
ignore this commit
(bzr r13682.1.10)
Diffstat (limited to 'src')
-rw-r--r--src/knotholder.cpp6
-rw-r--r--src/live_effects/effect.cpp10
-rw-r--r--src/live_effects/effect.h2
-rw-r--r--src/live_effects/lpe-bendpath.cpp4
-rw-r--r--src/live_effects/lpe-fillet-chamfer.cpp76
-rw-r--r--src/live_effects/lpe-fillet-chamfer.h4
-rw-r--r--src/live_effects/lpe-mirror_symmetry.cpp230
-rw-r--r--src/live_effects/lpe-mirror_symmetry.h24
-rw-r--r--src/live_effects/lpegroupbbox.cpp12
-rw-r--r--src/live_effects/parameter/filletchamferpointarray.cpp32
-rw-r--r--src/selection-chemistry.cpp2
-rw-r--r--src/sp-item-group.cpp9
-rw-r--r--src/ui/clipboard.cpp7
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp35
-rw-r--r--src/ui/dialog/lpe-fillet-chamfer-properties.cpp15
-rw-r--r--src/ui/dialog/lpe-fillet-chamfer-properties.h1
16 files changed, 146 insertions, 323 deletions
diff --git a/src/knotholder.cpp b/src/knotholder.cpp
index 28f6f5748..f46daa09e 100644
--- a/src/knotholder.cpp
+++ b/src/knotholder.cpp
@@ -69,12 +69,6 @@ KnotHolder::KnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFun
}
KnotHolder::~KnotHolder() {
- if(SP_IS_LPE_ITEM(item)){
- Inkscape::LivePathEffect::Effect *effect = SP_LPE_ITEM(item)->getCurrentLPE();
- if(effect){
- effect->removeHandles();
- }
- }
sp_object_unref(item);
for (std::list<KnotHolderEntity *>::iterator i = entity.begin(); i != entity.end(); ++i)
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 9997b1662..e49a15dd0 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -106,6 +106,7 @@ const Util::EnumData<EffectType> LPETypeData[] = {
{EXTRUDE, N_("Extrude"), "extrude"},
{LATTICE, N_("Lattice Deformation"), "lattice"},
{LINE_SEGMENT, N_("Line Segment"), "line_segment"},
+ {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
{OFFSET, N_("Offset"), "offset"},
{PARALLEL, N_("Parallel"), "parallel"},
{PATH_LENGTH, N_("Path length"), "path_length"},
@@ -152,7 +153,6 @@ const Util::EnumData<EffectType> LPETypeData[] = {
{PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"},
{FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"},
{INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"},
- {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"},
};
const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
@@ -613,7 +613,7 @@ Effect::registerParameter(Parameter * param)
void
Effect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
using namespace Inkscape::LivePathEffect;
- knot_holder = knotholder;
+
// add handles provided by the effect itself
addKnotHolderEntities(knotholder, desktop, item);
@@ -623,12 +623,6 @@ Effect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
}
}
-void
-Effect::removeHandles(){
- if(knot_holder){
- knot_holder = NULL;
- }
-}
/**
* Return a vector of PathVectors which contain all canvas indicators for this effect.
* This is the function called by external code to get all canvas indicators (effect and its parameters)
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 5d715c7f2..7da76b267 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -101,7 +101,6 @@ public:
// (but spiro lpe still needs it!)
virtual LPEPathFlashType pathFlashType() const { return DEFAULT; }
void addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
- void removeHandles();
std::vector<Geom::PathVector> getCanvasIndicators(SPLPEItem const* lpeitem);
inline bool providesOwnFlashPaths() const {
@@ -161,7 +160,6 @@ protected:
SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.
Glib::ustring const * defaultUnit; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them.
- KnotHolder *knot_holder;
double current_zoom;
std::vector<Geom::Point> selectedNodesPoints;
SPCurve * sp_curve;
diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp
index 968e12518..33171b184 100644
--- a/src/live_effects/lpe-bendpath.cpp
+++ b/src/live_effects/lpe-bendpath.cpp
@@ -137,9 +137,7 @@ LPEBendPath::resetDefaults(SPItem const* item)
Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
Geom::Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
- std::cout << start << "start\n";
- std::cout << start << "end\n";
- std::cout << boundingbox_X.min() << "boundingbox_X.min\n";
+
if ( Geom::are_near(start,end) ) {
end += Geom::Point(1.,0.);
}
diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp
index c89bfbd37..78e24f0b8 100644
--- a/src/live_effects/lpe-fillet-chamfer.cpp
+++ b/src/live_effects/lpe-fillet-chamfer.cpp
@@ -79,7 +79,7 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) :
radius.param_set_range(0., infinity());
radius.param_set_increments(1, 1);
radius.param_set_digits(4);
- chamfer_steps.param_set_range(0, infinity());
+ chamfer_steps.param_set_range(0, 999);
chamfer_steps.param_set_increments(1, 1);
chamfer_steps.param_set_digits(0);
helper_size.param_set_range(0, infinity());
@@ -116,7 +116,7 @@ Gtk::Widget *LPEFilletChamfer::newWidget()
}
} else if (param->param_key == "chamfer_steps") {
Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg));
- widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer));
+ widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamferSubdivisions));
widg = widgRegistered;
if (widg) {
Gtk::HBox *scalarParameter = dynamic_cast<Gtk::HBox *>(widg);
@@ -153,21 +153,26 @@ Gtk::Widget *LPEFilletChamfer::newWidget()
++it;
}
-
- Gtk::VBox *buttonsContainer = Gtk::manage(new Gtk::VBox(true, 0));
+ Gtk::HBox *filletContainer = Gtk::manage(new Gtk::HBox(true, 0));
Gtk::Button *fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet"))));
fillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::fillet));
- buttonsContainer->pack_start(*fillet, true, true, 2);
- Gtk::Button *inverse = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet"))));
- inverse->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverse));
- buttonsContainer->pack_start(*inverse, true, true, 2);
-
+ filletContainer->pack_start(*fillet, true, true, 2);
+ Gtk::Button *inverseFillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet"))));
+ inverseFillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseFillet));
+ filletContainer->pack_start(*inverseFillet, true, true, 2);
+
+ Gtk::HBox *chamferContainer = Gtk::manage(new Gtk::HBox(true, 0));
Gtk::Button *chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer"))));
chamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer));
- buttonsContainer->pack_start(*chamfer, true, true, 2);
- vbox->pack_start(*buttonsContainer, true, true, 2);
+ chamferContainer->pack_start(*chamfer, true, true, 2);
+ Gtk::Button *inverseChamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse chamfer"))));
+ inverseChamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseChamfer));
+ chamferContainer->pack_start(*inverseChamfer, true, true, 2);
+
+ vbox->pack_start(*filletContainer, true, true, 2);
+ vbox->pack_start(*chamferContainer, true, true, 2);
return vbox;
}
@@ -232,17 +237,31 @@ void LPEFilletChamfer::fillet()
doChangeType(path_from_piecewise(pwd2, tolerance), 1);
}
-void LPEFilletChamfer::inverse()
+void LPEFilletChamfer::inverseFillet()
{
Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2();
doChangeType(path_from_piecewise(pwd2, tolerance), 2);
}
+void LPEFilletChamfer::chamferSubdivisions()
+{
+ fillet_chamfer_values.set_chamfer_steps(chamfer_steps);
+ Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2();
+ doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 5000);
+}
+
void LPEFilletChamfer::chamfer()
{
- fillet_chamfer_values.set_chamfer_steps(chamfer_steps + 3);
+ fillet_chamfer_values.set_chamfer_steps(chamfer_steps);
Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2();
- doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 3);
+ doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 3000);
+}
+
+void LPEFilletChamfer::inverseChamfer()
+{
+ fillet_chamfer_values.set_chamfer_steps(chamfer_steps);
+ Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2();
+ doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 4000);
}
void LPEFilletChamfer::refreshKnots()
@@ -333,6 +352,13 @@ void LPEFilletChamfer::doChangeType(std::vector<Geom::Path> const& original_path
toggle = false;
}
if (toggle) {
+ if(type >= 5000){
+ if(filletChamferData[counter][Y] >= 3000 && filletChamferData[counter][Y] < 4000){
+ type = type - 2000;
+ } else if (filletChamferData[counter][Y] >= 4000 && filletChamferData[counter][Y] < 5000){
+ type = type - 1000;
+ }
+ }
result.push_back(Point(filletChamferData[counter][X], type));
} else {
result.push_back(filletChamferData[counter]);
@@ -552,8 +578,8 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in)
} else {
type = std::abs(filletChamferData[counter + 1][Y]);
}
- if (type >= 3) {
- unsigned int chamferSubs = type-2;
+ if (type >= 3000 && type < 4000) {
+ unsigned int chamferSubs = type-2999;
Geom::Path path_chamfer;
path_chamfer.start(path_out.finalPoint());
if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
@@ -567,6 +593,22 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in)
path_out.appendNew<Geom::LineSegment>(chamferStep);
}
path_out.appendNew<Geom::LineSegment>(endArcPoint);
+ } else if (type >= 4000 && type < 5000) {
+ unsigned int chamferSubs = type-3999;
+ Geom::Path path_chamfer;
+ path_chamfer.start(path_out.finalPoint());
+ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
+ ccwToggle = ccwToggle?0:1;
+ path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint);
+ }else{
+ path_chamfer.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint);
+ }
+ double chamfer_stepsTime = 1.0/chamferSubs;
+ for(unsigned int i = 1; i < chamferSubs; i++){
+ Geom::Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i);
+ path_out.appendNew<Geom::LineSegment>(chamferStep);
+ }
+ path_out.appendNew<Geom::LineSegment>(endArcPoint);
} else if (type == 2) {
if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
ccwToggle = ccwToggle?0:1;
@@ -574,7 +616,7 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in)
}else{
path_out.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint);
}
- } else {
+ } else if (type == 1){
if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){
path_out.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint);
} else {
diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h
index e3589197c..0d6a1ff17 100644
--- a/src/live_effects/lpe-fillet-chamfer.h
+++ b/src/live_effects/lpe-fillet-chamfer.h
@@ -56,8 +56,10 @@ public:
void toggleHide();
void toggleFlexFixed();
void chamfer();
+ void chamferSubdivisions();
+ void inverseChamfer();
void fillet();
- void inverse();
+ void inverseFillet();
void updateFillet();
void doUpdateFillet(std::vector<Geom::Path> const& original_pathv, double power);
void doChangeType(std::vector<Geom::Path> const& original_pathv, int type);
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp
index dc9a94b1b..0bb67a4a2 100644
--- a/src/live_effects/lpe-mirror_symmetry.cpp
+++ b/src/live_effects/lpe-mirror_symmetry.cpp
@@ -19,48 +19,23 @@
#include <sp-path.h>
#include <display/curve.h>
#include <svg/path-string.h>
-#include "helper/geom.h"
+
#include <2geom/path.h>
-#include <2geom/path-intersection.h>
#include <2geom/transforms.h>
#include <2geom/affine.h>
-#include "knot-holder-entity.h"
-#include "knotholder.h"
namespace Inkscape {
namespace LivePathEffect {
-namespace MS {
-
-class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity {
-public:
- KnotHolderEntityCenterMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect) {};
- virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
- virtual Geom::Point knot_get() const;
-};
-
-} // namespace MS
-
LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false),
- fusionPaths(_("Fusioned symetry"), _("Fusion right side whith symm"), "fusionPaths", &wr, this, true),
- reverseFusion(_("Reverse fusion"), _("Reverse fusion"), "reverseFusion", &wr, this, false),
- forceX(_("Force horizontal"), _("Force horizontal"), "forceX", &wr, this, false),
- forceY(_("Force vertical"), _("Force vertical"), "forceY", &wr, this, false),
- reflection_line(_("Reflection line:"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L1,0"),
- center(_("Center of mirroring (X or Y)"), _("Center of the mirror"), "center", &wr, this, "Adjust the center of mirroring")
+ reflection_line(_("Reflection line:"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L100,100")
{
show_orig_path = true;
registerParameter( dynamic_cast<Parameter *>(&discard_orig_path) );
- registerParameter( dynamic_cast<Parameter *>(&fusionPaths) );
- registerParameter( dynamic_cast<Parameter *>(&reverseFusion) );
- registerParameter( dynamic_cast<Parameter *>(&forceX) );
- registerParameter( dynamic_cast<Parameter *>(&forceY) );
registerParameter( dynamic_cast<Parameter *>(&reflection_line) );
- registerParameter( dynamic_cast<Parameter *>(&center) );
-
}
LPEMirrorSymmetry::~LPEMirrorSymmetry()
@@ -70,36 +45,7 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry()
void
LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
{
- using namespace Geom;
-
SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
- std::vector<Geom::Path> mline(reflection_line.get_pathvector());
- double dist = distance(mline[0].initialPoint(),mline[0].finalPoint());
- if( !forceX && !forceY ){
- center.param_setValue(mline[0].pointAt(0.5));
- }
- Point A(0,0);
- Point B(0,0);
- if(forceX){
- A = Geom::Point(center[X]+(dist/2.0),center[Y]);
- B = Geom::Point(center[X]-(dist/2.0),center[Y]);
- }
- if(forceY){
- A = Geom::Point(center[X],center[Y]+(dist/2.0));
- B = Geom::Point(center[X],center[Y]-(dist/2.0));
- }
- if( forceX || forceY ){
- lineSeparation.setPoints(A,B);
- Piecewise<D2<SBasis> > rline = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(A[X], B[X]), Linear(A[Y], B[Y])));
- reflection_line.set_new_value(rline, true);
- } else {
- lineSeparation.setPoints(mline[0].initialPoint(),mline[0].finalPoint());
- }
- //Geom::Point const q = lineSeparation.pointAt(0.5)* lpeitem->i2dt_affine().inverse();
- if(knot_holder){
- knot_holder->update_knots();
- }
- //e->knot_set(q, e->knot->drag_origin * lpeitem->i2dt_affine().inverse(), (guint)1);
item->apply_to_clippath(item);
item->apply_to_mask(item);
}
@@ -109,22 +55,19 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem)
{
using namespace Geom;
- original_bbox(lpeitem);
+ // fixme: what happens if the bbox is empty?
+ // fixme: this is probably wrong
+ Geom::Affine t = lpeitem->i2dt_affine();
+ Geom::Rect bbox = *lpeitem->desktopVisualBounds();
- Point A(boundingbox_X.max(), boundingbox_Y.max());
- Point B(boundingbox_X.max(), boundingbox_Y.min());
+ Point A(bbox.left(), bbox.bottom());
+ Point B(bbox.left(), bbox.top());
+ A *= t;
+ B *= t;
Piecewise<D2<SBasis> > rline = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(A[X], B[X]), Linear(A[Y], B[Y])));
reflection_line.set_new_value(rline, true);
}
-int
-LPEMirrorSymmetry::pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X)
-{
- //http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line
- double pos = (B[Geom::X]-A[Geom::X])*(X[Geom::Y]-A[Geom::Y]) - (B[Geom::Y]-A[Geom::Y])*(X[Geom::X]-A[Geom::X]);
- return (pos < 0) ? -1 : (pos > 0);
-}
-
std::vector<Geom::Path>
LPEMirrorSymmetry::doEffect_path (std::vector<Geom::Path> const & path_in)
{
@@ -132,20 +75,15 @@ LPEMirrorSymmetry::doEffect_path (std::vector<Geom::Path> const & path_in)
if ( reflection_line.get_pathvector().empty() ) {
return path_in;
}
- Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in);
- std::vector<Geom::Path> path_out;
- Geom::Path mlineExpanded;
- Geom::Point lineStart = lineSeparation.pointAt(-100000.0);
- Geom::Point lineEnd = lineSeparation.pointAt(100000.0);
- mlineExpanded.start( lineStart);
- mlineExpanded.appendNew<Geom::LineSegment>( lineEnd);
- if (!discard_orig_path && !fusionPaths) {
+ std::vector<Geom::Path> path_out;
+ if (!discard_orig_path) {
path_out = path_in;
}
- Geom::Point A(lineStart);
- Geom::Point B(lineEnd);
+ std::vector<Geom::Path> mline(reflection_line.get_pathvector());
+ Geom::Point A(mline.front().initialPoint());
+ Geom::Point B(mline.back().finalPoint());
Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]);
double hyp = Geom::distance(A, B);
@@ -159,146 +97,14 @@ LPEMirrorSymmetry::doEffect_path (std::vector<Geom::Path> const & path_in)
m = m * sca;
m = m * m2.inverse();
m = m * m1;
-
- if(fusionPaths && !discard_orig_path){
- for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
- path_it != original_pathv.end(); ++path_it) {
- if (path_it->empty()){
- continue;
- }
- std::vector<Geom::Path> temp_path;
- double timeStart = 0.0;
- int position = 0;
- bool end_open = false;
- if (path_it->closed()) {
- const Geom::Curve &closingline = path_it->back_closed();
- if (!are_near(closingline.initialPoint(), closingline.finalPoint())) {
- end_open = true;
- }
- }
- Geom::Path original = (Geom::Path)(*path_it);
- if(end_open && path_it->closed()){
- original.close(false);
- original.appendNew<Geom::LineSegment>( original.initialPoint() );
- original.close(true);
- }
- Geom::Crossings cs = crossings(original, mlineExpanded);
- for(unsigned int i = 0; i < cs.size(); i++) {
- double timeEnd = cs[i].ta;
- Geom::Path portion = original.portion(timeStart, timeEnd);
- Geom::Point middle = portion.pointAt((double)portion.size()/2.0);
- position = pointSideOfLine(lineStart, lineEnd, middle);
- if(reverseFusion){
- position *= -1;
- }
- if(position == -1){
- Geom::Path mirror = portion.reverse() * m;
- mirror.setInitial(portion.finalPoint());
- portion.append(mirror);
- if(i!=0){
- portion.setFinal(portion.initialPoint());
- portion.close();
- }
- temp_path.push_back(portion);
- }
- portion.clear();
- timeStart = timeEnd;
- }
- position = pointSideOfLine(lineStart, lineEnd, original.finalPoint());
- if(reverseFusion){
- position *= -1;
- }
- if(cs.size()!=0 && position == -1){
- Geom::Path portion = original.portion(timeStart, original.size());
- portion = portion.reverse();
- Geom::Path mirror = portion.reverse() * m;
- mirror.setInitial(portion.finalPoint());
- portion.append(mirror);
- portion = portion.reverse();
- if (!original.closed()){
- temp_path.push_back(portion);
- } else {
- if(cs.size() >1 ){
- portion.setFinal(temp_path[0].initialPoint());
- portion.setInitial(temp_path[0].finalPoint());
- temp_path[0].append(portion);
- } else {
- temp_path.push_back(portion);
- }
- temp_path[0].close();
- }
- portion.clear();
- }
- if(cs.size() == 0 && position == -1){
- temp_path.push_back(original);
- temp_path.push_back(original * m);
- }
- path_out.insert(path_out.end(), temp_path.begin(), temp_path.end());
- temp_path.clear();
- }
- }
-
- if (!fusionPaths || discard_orig_path) {
- for (int i = 0; i < static_cast<int>(path_in.size()); ++i) {
- path_out.push_back(path_in[i] * m);
- }
- }
- return path_out;
-}
-
-void
-LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
-{
- using namespace Geom;
-
- PathVector pathv;
- Geom::Path mlineExpanded;
- Geom::Point lineStart = lineSeparation.pointAt(-100000.0);
- Geom::Point lineEnd = lineSeparation.pointAt(100000.0);
- mlineExpanded.start( lineStart);
- mlineExpanded.appendNew<Geom::LineSegment>( lineEnd);
- pathv.push_back(mlineExpanded);
- hp_vec.push_back(pathv);
-}
-
-void
-LPEMirrorSymmetry::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) {
- {
- KnotHolderEntity *e = new MS::KnotHolderEntityCenterMirrorSymmetry(this);
- e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN,
- _("Adjust the center") );
- knotholder->add(e);
+ for (int i = 0; i < static_cast<int>(path_in.size()); ++i) {
+ path_out.push_back(path_in[i] * m);
}
-};
-
-namespace MS {
-
-using namespace Geom;
-
-void
-KnotHolderEntityCenterMirrorSymmetry::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state)
-{
- LPEMirrorSymmetry* lpe = dynamic_cast<LPEMirrorSymmetry *>(_effect);
-
- Geom::Point const s = snap_knot_position(p, state);
-
- lpe->center.param_setValue(s);
-
- // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
- sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
-}
-
-Geom::Point
-KnotHolderEntityCenterMirrorSymmetry::knot_get() const
-{
- LPEMirrorSymmetry const *lpe = dynamic_cast<LPEMirrorSymmetry const*>(_effect);
- return lpe->center;
+ return path_out;
}
-} // namespace CR
-
} //namespace LivePathEffect
} /* namespace Inkscape */
diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h
index 4b2c9aea0..a4a2b86c0 100644
--- a/src/live_effects/lpe-mirror_symmetry.h
+++ b/src/live_effects/lpe-mirror_symmetry.h
@@ -20,17 +20,10 @@
#include "live_effects/parameter/point.h"
#include "live_effects/parameter/path.h"
-#include "live_effects/lpegroupbbox.h"
-
namespace Inkscape {
namespace LivePathEffect {
-namespace MS {
- // we need a separate namespace to avoid clashes with LPEPerpBisector
- class KnotHolderEntityCenterMirrorSymmetry;
-}
-
-class LPEMirrorSymmetry : public Effect, GroupBBoxEffect{
+class LPEMirrorSymmetry : public Effect {
public:
LPEMirrorSymmetry(LivePathEffectObject *lpeobject);
virtual ~LPEMirrorSymmetry();
@@ -39,26 +32,11 @@ public:
virtual void doBeforeEffect (SPLPEItem const* lpeitem);
- virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X);
-
virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in);
- /* the knotholder entity classes must be declared friends */
- friend class MS::KnotHolderEntityCenterMirrorSymmetry;
- void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
-
-protected:
- virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec);
-
private:
BoolParam discard_orig_path;
- BoolParam fusionPaths;
- BoolParam reverseFusion;
- BoolParam forceX;
- BoolParam forceY;
PathParam reflection_line;
- Geom::Line lineSeparation;
- PointParam center;
LPEMirrorSymmetry(const LPEMirrorSymmetry&);
LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&);
diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp
index 78545e9c5..2a1b70a6a 100644
--- a/src/live_effects/lpegroupbbox.cpp
+++ b/src/live_effects/lpegroupbbox.cpp
@@ -8,7 +8,6 @@
#include "live_effects/lpegroupbbox.h"
#include "sp-item.h"
-#include "sp-item-group.h"
namespace Inkscape {
namespace LivePathEffect {
@@ -35,20 +34,9 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute)
}
Geom::OptRect bbox = lpeitem->geometricBounds(transform);
- std::cout << bbox->hasZeroArea() << "=AREA\n";
- if(bbox->hasZeroArea() && SP_IS_GROUP(lpeitem)){
- bbox = (Geom::OptRect)SP_GROUP(lpeitem)->bbox(transform, SPLPEItem::GEOMETRIC_BBOX);
- //GSList const *items = sp_item_group_item_list(SPGroup * group);
- //for ( GSList const *i = items ; i != NULL ; i = i->next ) {
- // bbox.unionWith(SP_ITEM(i->data)->desktopGeometricBounds());
- //}
- }
- std::cout << bbox->hasZeroArea() << "=AREA222\n";
if (bbox) {
boundingbox_X = (*bbox)[Geom::X];
boundingbox_Y = (*bbox)[Geom::Y];
- std::cout << boundingbox_X << "=BBOXX\n";
- std::cout << boundingbox_Y << "=BBOXY\n";
} else {
boundingbox_X = Geom::Interval();
boundingbox_Y = Geom::Interval();
diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp
index cf9ef3132..4e2be6e88 100644
--- a/src/live_effects/parameter/filletchamferpointarray.cpp
+++ b/src/live_effects/parameter/filletchamferpointarray.cpp
@@ -723,7 +723,7 @@ FilletChamferPointArrayParamKnotHolderEntity(
void FilletChamferPointArrayParamKnotHolderEntity::knot_set(Point const &p,
Point const &/*origin*/,
- guint /*state*/)
+ guint state)
{
using namespace Geom;
@@ -733,7 +733,7 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_set(Point const &p,
/// @todo how about item transforms???
Piecewise<D2<SBasis> > const &pwd2 = _pparam->get_pwd2();
//todo: add snapping
- //Geom::Point const s = snap_knot_position(p, state);
+ Geom::Point const s = snap_knot_position(p, state);
double t = nearest_point(p, pwd2[_index]);
if (t == 1) {
t = 0.9999;
@@ -777,13 +777,21 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state)
}else{
using namespace Geom;
int type = (int)_pparam->_vector.at(_index)[Y];
-
+ if (type >=3000 && type < 4000){
+ type = 3;
+ }
+ if (type >=4000 && type < 5000){
+ type = 4;
+ }
switch(type){
case 1:
type = 2;
break;
case 2:
- type = _pparam->chamfer_steps;
+ type = _pparam->chamfer_steps + 3000;
+ break;
+ case 3:
+ type = _pparam->chamfer_steps + 4000;
break;
default:
type = 1;
@@ -793,8 +801,12 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state)
_pparam->param_set_and_write_new_value(_pparam->_vector);
sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
const gchar *tip;
- if (type >= 3) {
- tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ if (type >=3000 && type < 4000){
+ tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
+ } else if (type >=4000 && type < 5000) {
+ tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
"<b>Shift+Click</b> open dialog, "
"<b>Ctrl+Alt+Click</b> reset");
} else if (type == 2) {
@@ -850,8 +862,12 @@ void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder,
continue;
}
const gchar *tip;
- if (_vector[i][Y] >= 3) {
- tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ if (_vector[i][Y] >=3000 && _vector[i][Y] < 4000){
+ tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
+ } else if (_vector[i][Y] >=4000 && _vector[i][Y] < 5000) {
+ tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
"<b>Shift+Click</b> open dialog, "
"<b>Ctrl+Alt+Click</b> reset");
} else if (_vector[i][Y] == 2) {
diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp
index d00e8d702..ffa149cee 100644
--- a/src/selection-chemistry.cpp
+++ b/src/selection-chemistry.cpp
@@ -1643,7 +1643,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons
item->doWriteTransform(item->getRepr(), move, &move, compensate);
} else if (prefs_unmoved) {
- //if (SP_IS_USE(sp_use_get_original(SP_USE(item))))
+ //if (dynamic_cast<SPUse *>(sp_use_get_original(dynamic_cast<SPUse *>(item))))
// clone_move = Geom::identity();
Geom::Affine move = result * clone_move;
item->doWriteTransform(item->getRepr(), move, &t, compensate);
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 613ace5c1..992bca631 100644
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
@@ -662,8 +662,13 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo
{
if ( hasChildren() ) {
for (SPObject *o = firstChild() ; o ; o = o->getNext() ) {
- SPItem *item = dynamic_cast<SPItem *>(o);
- if ( item ) {
+ if ( SPDefs *defs = dynamic_cast<SPDefs *>(o) ) { // select symbols from defs, ignore clips, masks, patterns
+ for (SPObject *defschild = defs->firstChild() ; defschild ; defschild = defschild->getNext() ) {
+ SPGroup *defsgroup = dynamic_cast<SPGroup *>(defschild);
+ if (defsgroup)
+ defsgroup->scaleChildItemsRec(sc, p, false);
+ }
+ } else if ( SPItem *item = dynamic_cast<SPItem *>(o) ) {
SPGroup *group = dynamic_cast<SPGroup *>(item);
if (group && !dynamic_cast<SPBox3D *>(item)) {
/* Using recursion breaks clipping because transforms are applied
diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp
index 931a295d8..153ed9830 100644
--- a/src/ui/clipboard.cpp
+++ b/src/ui/clipboard.cpp
@@ -330,6 +330,13 @@ void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const*
use->setAttribute("xlink:href", id.c_str() );
// Set a default style in <use> rather than <symbol> so it can be changed.
use->setAttribute("style", style );
+
+ Inkscape::XML::Node *nv_repr = sp_desktop_namedview(inkscape_active_desktop())->getRepr();
+ gdouble scale_units = Inkscape::Util::Quantity::convert(1, nv_repr->attribute("inkscape:document-units"), "px");
+ gchar *transform_str = sp_svg_transform_write(Geom::Scale(scale_units, scale_units));
+ use->setAttribute("transform", transform_str);
+ g_free(transform_str);
+
_root->appendChild(use);
// This min and max sets offsets, we don't have any so set to zero.
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index e9c012ff5..eb3857ee7 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -292,11 +292,8 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
effectlist_store->clear();
current_lpeitem = NULL;
- if ( sel && (sel->isEmpty() || sel->singleItem())) {
- SPItem * item= SP_ITEM(current_desktop->currentRoot());
- if(!sel->isEmpty()){
- item = sel->singleItem();
- }
+ if ( sel && !sel->isEmpty() ) {
+ SPItem *item = sel->singleItem();
if ( item ) {
SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
if ( lpeitem ) {
@@ -425,11 +422,8 @@ void
LivePathEffectEditor::onAdd()
{
Inkscape::Selection *sel = _getSelection();
- if ( sel && (sel->isEmpty() || sel->singleItem())) {
- SPItem * item= SP_ITEM(current_desktop->currentRoot());
- if(!sel->isEmpty()){
- item = sel->singleItem();
- }
+ if ( sel && !sel->isEmpty() ) {
+ SPItem *item = sel->singleItem();
if (item) {
if ( dynamic_cast<SPLPEItem *>(item) ) {
// show effectlist dialog
@@ -506,11 +500,8 @@ void
LivePathEffectEditor::onRemove()
{
Inkscape::Selection *sel = _getSelection();
- if ( sel && (sel->isEmpty() || sel->singleItem())) {
- SPItem * item= SP_ITEM(current_desktop->currentRoot());
- if(!sel->isEmpty()){
- item = sel->singleItem();
- }
+ if ( sel && !sel->isEmpty() ) {
+ SPItem *item = sel->singleItem();
SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
if ( lpeitem ) {
lpeitem->removeCurrentPathEffect(false);
@@ -527,11 +518,8 @@ LivePathEffectEditor::onRemove()
void LivePathEffectEditor::onUp()
{
Inkscape::Selection *sel = _getSelection();
- if ( sel && (sel->isEmpty() || sel->singleItem())) {
- SPItem * item= SP_ITEM(current_desktop->currentRoot());
- if(!sel->isEmpty()){
- item = sel->singleItem();
- }
+ if ( sel && !sel->isEmpty() ) {
+ SPItem *item = sel->singleItem();
SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
if ( lpeitem ) {
lpeitem->upCurrentPathEffect();
@@ -547,11 +535,8 @@ void LivePathEffectEditor::onUp()
void LivePathEffectEditor::onDown()
{
Inkscape::Selection *sel = _getSelection();
- if ( sel && (sel->isEmpty() || sel->singleItem())) {
- SPItem * item= SP_ITEM(current_desktop->currentRoot());
- if(!sel->isEmpty()){
- item = sel->singleItem();
- }
+ if ( sel && !sel->isEmpty() ) {
+ SPItem *item = sel->singleItem();
SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
if ( lpeitem ) {
lpeitem->downCurrentPathEffect();
diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
index e55c9f8df..55a19fc51 100644
--- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
+++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp
@@ -79,12 +79,15 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog()
_fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group);
_fillet_chamfer_type_chamfer.set_label(_("Chamfer"));
_fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group);
+ _fillet_chamfer_type_inverse_chamfer.set_label(_("Inverse chamfer"));
+ _fillet_chamfer_type_inverse_chamfer.set_group(_fillet_chamfer_type_group);
mainVBox->pack_start(_layout_table, true, true, 4);
mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4);
mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4);
mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4);
+ mainVBox->pack_start(_fillet_chamfer_type_inverse_chamfer, true, true, 4);
// Buttons
_close_button.set_use_stock(true);
@@ -158,8 +161,10 @@ void FilletChamferPropertiesDialog::_apply()
d_width = 1;
} else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) {
d_width = 2;
+ } else if (_fillet_chamfer_type_inverse_chamfer.get_active() == true) {
+ d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 4000;
} else {
- d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3;
+ d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3000;
}
if (_flexible) {
if (d_pos > 99.99999 || d_pos < 0) {
@@ -229,8 +234,12 @@ void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint)
_fillet_chamfer_type_fillet.set_active(true);
} else if (knotpoint.y() == 2) {
_fillet_chamfer_type_inverse_fillet.set_active(true);
- } else if (knotpoint.y() >= 3) {
- _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3);
+ } else if (knotpoint.y() >= 3000 && knotpoint.y() < 4000) {
+ _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3000);
+ _fillet_chamfer_type_chamfer.set_active(true);
+ } else if (knotpoint.y() >= 4000 && knotpoint.y() < 5000) {
+ _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 4000);
+ _fillet_chamfer_type_inverse_chamfer.set_active(true);
}
}
diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h
index ec87addc5..3807e98c8 100644
--- a/src/ui/dialog/lpe-fillet-chamfer-properties.h
+++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h
@@ -47,6 +47,7 @@ protected:
Gtk::RadioButton _fillet_chamfer_type_fillet;
Gtk::RadioButton _fillet_chamfer_type_inverse_fillet;
Gtk::RadioButton _fillet_chamfer_type_chamfer;
+ Gtk::RadioButton _fillet_chamfer_type_inverse_chamfer;
Gtk::Label _fillet_chamfer_chamfer_subdivisions_label;
Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions;