diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2016-03-24 17:37:34 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2016-03-24 17:37:34 +0000 |
| commit | f72d5b89423864be61cf0399f6177986fc7ccd3b (patch) | |
| tree | bdfa43dac5ce8c27877d4d93de45f2df18ae8db7 /src | |
| parent | update to trunk (diff) | |
| download | inkscape-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.cpp | 255 | ||||
| -rw-r--r-- | src/live_effects/lpe-mirror_symmetry.h | 7 |
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( ¢er); + 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&); |
