summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2016-03-24 17:37:34 +0000
committerJabiertxof <jtx@jtx.marker.es>2016-03-24 17:37:34 +0000
commitf72d5b89423864be61cf0399f6177986fc7ccd3b (patch)
treebdfa43dac5ce8c27877d4d93de45f2df18ae8db7 /src
parentupdate to trunk (diff)
downloadinkscape-f72d5b89423864be61cf0399f6177986fc7ccd3b.tar.gz
inkscape-f72d5b89423864be61cf0399f6177986fc7ccd3b.zip
Fixes and added horizontal and vertical page mode
(bzr r13682.1.38)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-mirror_symmetry.cpp255
-rw-r--r--src/live_effects/lpe-mirror_symmetry.h7
2 files changed, 159 insertions, 103 deletions
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp
index 60ad13fc8..9a2a54a13 100644
--- a/src/live_effects/lpe-mirror_symmetry.cpp
+++ b/src/live_effects/lpe-mirror_symmetry.cpp
@@ -27,11 +27,14 @@
#include <2geom/affine.h>
#include "knot-holder-entity.h"
#include "knotholder.h"
+#include "inkscape.h"
namespace Inkscape {
namespace LivePathEffect {
static const Util::EnumData<ModeType> ModeTypeData[MT_END] = {
+ { MT_V, N_("Vertical Page Center"), "Vertical Page Center, use select tool to move item instead line" },
+ { MT_H, N_("Horizontal Page Center"), "Horizontal Page Center, use select tool to move item instead line" },
{ MT_FREE, N_("Free from reflection line"), "Free from path" },
{ MT_X, N_("X from middle knot"), "X from middle knot" },
{ MT_Y, N_("Y from middle knot"), "Y from middle knot" }
@@ -48,24 +51,38 @@ public:
virtual Geom::Point knot_get() const;
};
+class KnotHolderEntityStartMirrorSymmetry : public LPEKnotHolderEntity {
+public:
+ KnotHolderEntityStartMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){};
+ virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
+ virtual Geom::Point knot_get() const;
+};
+
+class KnotHolderEntityEndMirrorSymmetry : public LPEKnotHolderEntity {
+public:
+ KnotHolderEntityEndMirrorSymmetry(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),
mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE),
discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false),
- fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, true),
+ fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false),
oposite_fuse(_("Oposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false),
- reflection_line(_("Axis of reflection:"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L1,0"),
- center(_("Center of mirroring"), _("Center of the mirror"), "center", &wr, this, "Adjust the center of mirroring")
+ start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"),
+ end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring")
{
show_orig_path = true;
registerParameter(&mode);
registerParameter( &discard_orig_path);
registerParameter( &fuse_paths);
registerParameter( &oposite_fuse);
- registerParameter( &reflection_line);
- registerParameter( &center);
+ registerParameter( &start_point);
+ registerParameter( &end_point);
apply_to_clippath_and_mask = true;
}
@@ -79,51 +96,60 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
{
using namespace Geom;
- SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
Point point_a(boundingbox_X.max(), boundingbox_Y.min());
Point point_b(boundingbox_X.max(), boundingbox_Y.max());
Point point_c(boundingbox_X.max(), boundingbox_Y.middle());
if (mode == MT_Y) {
- point_a = Geom::Point(boundingbox_X.min(),center[Y]);
- point_b = Geom::Point(boundingbox_X.max(),center[Y]);
+ point_a = Geom::Point(boundingbox_X.min(),center_point[Y]);
+ point_b = Geom::Point(boundingbox_X.max(),center_point[Y]);
}
if (mode == MT_X) {
- point_a = Geom::Point(center[X],boundingbox_Y.min());
- point_b = Geom::Point(center[X],boundingbox_Y.max());
+ point_a = Geom::Point(center_point[X],boundingbox_Y.min());
+ point_b = Geom::Point(center_point[X],boundingbox_Y.max());
}
+ line_separation.setPoints(point_a, point_b);
if ( mode == MT_X || mode == MT_Y ) {
- Geom::Path path;
- path.start( point_a );
- path.appendNew<Geom::LineSegment>( point_b );
- reflection_line.set_new_value(path.toPwSb(), true);
- line_separation.setPoints(point_a, point_b);
- center.param_setValue(path.pointAt(0.5), true);
+ start_point.param_setValue(point_a);
+ end_point.param_setValue(point_b);
+ center_point = Geom::middle_point(point_a, point_b);
} else if ( mode == MT_FREE) {
- Geom::PathVector line_m(reflection_line.get_pathvector());
- Geom::Line line_symm;
- line_symm->setPoints(line_m->initialPoint(), line_m->finalPoint());
- Geom::GenericRect bbox(boundingbox_X.min(), boundingbox_Y.min(), boundingbox_X.max(), boundingbox_Y.max());
- line_m[0].initialPoint = bbox->nearestEdgePoint(line_m->initialPoint());
- line_m[0].finalPoint = bbox->nearestEdgePoint(line_m->finalPoint())
- if(!are_near(previous_center,center, 0.01)) {
- Geom::Point trans = center - line_m[0].pointAt(0.5);
- line_m[0] *= Geom::Affine(1,0,0,1,trans[X],trans[Y]);
- point_a = line_m[0].initialPoint();
- point_b = line_m[0].finalPoint();
- reflection_line.set_new_value(line_m[0].toPwSb(), true);
- line_separation.setPoints(point_a, point_b);
+ if(!are_near(previous_center,center_point, 0.01)) {
+ Geom::Point trans = center_point - previous_center;
+ start_point.param_setValue(start_point * trans);
+ end_point.param_setValue(end_point * trans);
+ line_separation.setPoints(start_point, end_point);
} else {
- center.param_setValue(line_m[0].pointAt(0.5), true);
- point_a = line_m[0].initialPoint();
- point_b = line_m[0].finalPoint();
- reflection_line.set_new_value(line_m[0].toPwSb(), true);
- line_separation.setPoints(point_a, point_b);
+ center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point);
+ line_separation.setPoints(start_point, end_point);
+ }
+ } else if ( mode == MT_V){
+ if(SP_ACTIVE_DESKTOP){
+ SPDocument * doc = SP_ACTIVE_DESKTOP->getDocument();
+ Geom::Rect view_box_rect = doc->getViewBox();
+ Geom::Point sp = Geom::Point(view_box_rect.width()/2.0, 0);
+ sp *= lpeitem->transform.inverse();
+ start_point.param_setValue(sp);
+ Geom::Point ep = Geom::Point(view_box_rect.width()/2.0, view_box_rect.height());
+ ep *= lpeitem->transform.inverse();
+ end_point.param_setValue(ep);
+ center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point);
+ line_separation.setPoints(start_point, end_point);
+ }
+ } else { //horizontal page
+ if(SP_ACTIVE_DESKTOP){
+ SPDocument * doc = SP_ACTIVE_DESKTOP->getDocument();
+ Geom::Rect view_box_rect = doc->getViewBox();
+ Geom::Point sp = Geom::Point(0, view_box_rect.height()/2.0);
+ sp *= lpeitem->transform.inverse();
+ start_point.param_setValue(sp);
+ Geom::Point ep = Geom::Point(view_box_rect.width(), view_box_rect.height()/2.0);
+ ep *= lpeitem->transform.inverse();
+ end_point.param_setValue(ep);
+ center_point = Geom::middle_point((Geom::Point)start_point, (Geom::Point)end_point);
+ line_separation.setPoints(start_point, end_point);
}
- previous_center = center;
}
-
- item->apply_to_clippath(item);
- item->apply_to_mask(item);
+ previous_center = center_point;
}
void
@@ -136,23 +162,18 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem)
Point point_a(boundingbox_X.max(), boundingbox_Y.min());
Point point_b(boundingbox_X.max(), boundingbox_Y.max());
Point point_c(boundingbox_X.max(), boundingbox_Y.middle());
- Geom::Path path;
- path.start( point_a );
- path.appendNew<Geom::LineSegment>( point_b );
- reflection_line.set_new_value(path.toPwSb(), true);
- center.param_setValue(point_c);
- previous_center = center;
+ start_point.param_setValue(point_a);
+ start_point.param_update_default(point_a);
+ end_point.param_setValue(point_b);
+ end_point.param_update_default(point_b);
+ center_point = point_c;
+ previous_center = center_point;
}
Geom::PathVector
LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
{
- // Don't allow empty path parameter:
- Geom::PathVector line_m(reflection_line.get_pathvector());
- if ( line_m.empty() ) {
- return path_in;
- }
Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in);
Geom::PathVector path_out;
@@ -183,7 +204,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
if (path_it->empty()) {
continue;
}
- Geom::PathVector temp_path;
+ Geom::PathVector tmp_path;
double time_start = 0.0;
int position = 0;
bool end_open = false;
@@ -193,65 +214,88 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
end_open = true;
}
}
- Geom::Path original = path_it;
+ Geom::Path original = *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, line_m);
- for (unsigned int i = 0; i < cs.size(); i++) {
- double timeEnd = cs[i].ta;
- Geom::Path portion = original.portion(time_start, timeEnd);
- Geom::Point middle = portion.pointAt((double)portion.size()/2.0);
- position = Geom::sgn(Geom::cross(point_b - point_a, middle - point_a));
- if (oposite_fuse) {
- position *= -1;
- }
- if (position == 1) {
- Geom::Path mirror = portion.reversed() * m;
- mirror.setInitial(portion.finalPoint());
- portion.append(mirror);
- if(i!=0) {
- portion.setFinal(portion.initialPoint());
- portion.close();
+ Geom::Point s = start_point;
+ Geom::Point e = end_point;
+ double dir = line_separation.angle();
+ double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
+ Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max()));
+ double size_divider = Geom::distance(center_point, bbox) + diagonal;
+ s = Geom::Point::polar(dir,size_divider) + center_point;
+ e = Geom::Point::polar(dir + Geom::rad_from_deg(180),size_divider) + center_point;
+ Geom::Path divider = Geom::Path(s);
+ divider.appendNew<Geom::LineSegment>(e);
+ Geom::Crossings cs = crossings(original, divider);
+ std::vector<double> crossed;
+ for(unsigned int i = 0; i < cs.size(); i++) {
+ crossed.push_back(cs[i].ta);
+ }
+ std::sort(crossed.begin(), crossed.end());
+ for (unsigned int i = 0; i < crossed.size(); i++) {
+ double time_end = crossed[i];
+ if (time_start != time_end && time_end - time_start > Geom::EPSILON) {
+ Geom::Path portion = original.portion(time_start, time_end);
+ if (!portion.empty()) {
+ Geom::Point middle = portion.pointAt((double)portion.size()/2.0);
+ position = Geom::sgn(Geom::cross(e - s, middle - s));
+ if (!oposite_fuse) {
+ position *= -1;
+ }
+ if (position == 1) {
+ Geom::Path mirror = portion.reversed() * m;
+ mirror.setInitial(portion.finalPoint());
+ portion.append(mirror);
+ if(i!=0) {
+ portion.setFinal(portion.initialPoint());
+ portion.close();
+ }
+ tmp_path.push_back(portion);
+ }
+ portion.clear();
}
- temp_path.push_back(portion);
}
- portion.clear();
- time_start = timeEnd;
+ time_start = time_end;
}
- position = position = Geom::sgn(Geom::cross(point_b - point_a, original.finalPoint() - point_a ));
- if (oposite_fuse) {
+ position = Geom::sgn(Geom::cross(e - s, original.finalPoint() - s));
+ if (!oposite_fuse) {
position *= -1;
}
if (cs.size()!=0 && position == 1) {
- Geom::Path portion = original.portion(time_start, original.size());
- portion = portion.reversed();
- Geom::Path mirror = portion.reversed() * m;
- mirror.setInitial(portion.finalPoint());
- portion.append(mirror);
- portion = portion.reversed();
- 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);
+ if (time_start != original.size() && original.size() - time_start > Geom::EPSILON) {
+ Geom::Path portion = original.portion(time_start, original.size());
+ if (!portion.empty()) {
+ portion = portion.reversed();
+ Geom::Path mirror = portion.reversed() * m;
+ mirror.setInitial(portion.finalPoint());
+ portion.append(mirror);
+ portion = portion.reversed();
+ if (!original.closed()) {
+ tmp_path.push_back(portion);
+ } else {
+ if (cs.size() > 1 && tmp_path.size() > 0 && tmp_path[0].size() > 0 ) {
+ portion.setFinal(tmp_path[0].initialPoint());
+ portion.setInitial(tmp_path[0].finalPoint());
+ tmp_path[0].append(portion);
+ } else {
+ tmp_path.push_back(portion);
+ }
+ tmp_path[0].close();
+ }
+ portion.clear();
}
- temp_path[0].close();
}
- portion.clear();
}
if (cs.size() == 0 && position == 1) {
- temp_path.push_back(original);
- temp_path.push_back(original * m);
+ tmp_path.push_back(original);
+ tmp_path.push_back(original * m);
}
- path_out.insert(path_out.end(), temp_path.begin(), temp_path.end());
- temp_path.clear();
+ path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end());
+ tmp_path.clear();
}
}
@@ -269,19 +313,28 @@ LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector
{
using namespace Geom;
hp_vec.clear();
- hp_vec.push_back(reflection_line.get_pathvector());
+ Geom::Path path;
+ Geom::Point s = start_point;
+ Geom::Point e = end_point;
+ path.start( s );
+ path.appendNew<Geom::LineSegment>( e );
+ Geom::PathVector helper;
+ helper.push_back(path);
+ hp_vec.push_back(helper);
}
void
LPEMirrorSymmetry::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item)
{
+ SPKnotShapeType knot_shape = SP_KNOT_SHAPE_CIRCLE;
+ SPKnotModeType knot_mode = SP_KNOT_MODE_XOR;
+ guint32 knot_color = 0x0000ff00;
{
- KnotHolderEntity *e = new MS::KnotHolderEntityCenterMirrorSymmetry(this);
- e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN,
- _("Adjust the center") );
- knotholder->add(e);
+ KnotHolderEntity *c = new MS::KnotHolderEntityCenterMirrorSymmetry(this);
+ c->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN,
+ _("Adjust the center"), knot_shape, knot_mode, knot_color );
+ knotholder->add(c);
}
-
};
namespace MS {
@@ -293,7 +346,7 @@ KnotHolderEntityCenterMirrorSymmetry::knot_set(Geom::Point const &p, Geom::Point
{
LPEMirrorSymmetry* lpe = dynamic_cast<LPEMirrorSymmetry *>(_effect);
Geom::Point const s = snap_knot_position(p, state);
- lpe->center.param_setValue(s);
+ lpe->center_point = 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);
@@ -303,7 +356,7 @@ Geom::Point
KnotHolderEntityCenterMirrorSymmetry::knot_get() const
{
LPEMirrorSymmetry const *lpe = dynamic_cast<LPEMirrorSymmetry const*>(_effect);
- return lpe->center;
+ return lpe->center_point;
}
} // namespace CR
diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h
index cd6f2a0ce..3a244cb7e 100644
--- a/src/live_effects/lpe-mirror_symmetry.h
+++ b/src/live_effects/lpe-mirror_symmetry.h
@@ -32,6 +32,8 @@ class KnotHolderEntityCenterMirrorSymmetry;
}
enum ModeType {
+ MT_V,
+ MT_H,
MT_FREE,
MT_X,
MT_Y,
@@ -57,10 +59,11 @@ private:
BoolParam discard_orig_path;
BoolParam fuse_paths;
BoolParam oposite_fuse;
- PathParam reflection_line;
+ PointParam start_point;
+ PointParam end_point;
Geom::Line line_separation;
Geom::Point previous_center;
- PointParam center;
+ Geom::Point center_point;
LPEMirrorSymmetry(const LPEMirrorSymmetry&);
LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&);